commit 11791459c4801538b389cdedaab3cc0d813230a0 parent f9ccf619aaeb3d2677940078c80847383ba9120a Author: AndiAJ <andiaj@users.noreply.github.com> Date: Thu, 18 Dec 2025 13:41:52 +0000 Bug 2006308 - Enable composable toolbar and main menu in UI tests r=aaronmt,petru Differential Revision: https://phabricator.services.mozilla.com/D276643 Diffstat:
130 files changed, 6550 insertions(+), 8402 deletions(-)
diff --git a/mobile/android/android-components/components/compose/awesomebar/src/main/java/mozilla/components/compose/browser/awesomebar/AwesomeBar.kt b/mobile/android/android-components/components/compose/awesomebar/src/main/java/mozilla/components/compose/browser/awesomebar/AwesomeBar.kt @@ -14,6 +14,9 @@ import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.platform.testTag +import androidx.compose.ui.semantics.semantics +import androidx.compose.ui.semantics.testTag +import androidx.compose.ui.semantics.testTagsAsResourceId import mozilla.components.compose.browser.awesomebar.internal.SuggestionFetcher import mozilla.components.compose.browser.awesomebar.internal.Suggestions import mozilla.components.concept.awesomebar.AwesomeBar @@ -94,7 +97,10 @@ fun AwesomeBar( Column( modifier = Modifier .fillMaxWidth() - .testTag("mozac.awesomebar") + .semantics { + testTagsAsResourceId = true + testTag = "mozac.awesomebar" + } .background(colors.background), ) { if (groups.isEmpty()) return diff --git a/mobile/android/android-components/components/compose/base/src/main/java/mozilla/components/compose/base/progressbar/AnimatedProgressBar.kt b/mobile/android/android-components/components/compose/base/src/main/java/mozilla/components/compose/base/progressbar/AnimatedProgressBar.kt @@ -39,6 +39,9 @@ import androidx.compose.ui.graphics.drawscope.drawIntoCanvas import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.platform.LocalLayoutDirection import androidx.compose.ui.platform.LocalView +import androidx.compose.ui.semantics.ProgressBarRangeInfo +import androidx.compose.ui.semantics.progressBarRangeInfo +import androidx.compose.ui.semantics.semantics import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.PreviewLightDark import androidx.compose.ui.unit.Dp @@ -152,7 +155,17 @@ fun AnimatedProgressBar( } } - Canvas(modifier.fillMaxWidth()) { + Canvas( + modifier + .fillMaxWidth() + .semantics { + progressBarRangeInfo = ProgressBarRangeInfo( + current = animatedProgress.toFloat(), + range = 0f..100f, + steps = 100, + ) + }, + ) { val width = this.size.width val height = this.size.height diff --git a/mobile/android/android-components/components/compose/browser-toolbar/src/main/java/mozilla/components/compose/browser/toolbar/concept/BrowserToolbarTestTags.kt b/mobile/android/android-components/components/compose/browser-toolbar/src/main/java/mozilla/components/compose/browser/toolbar/concept/BrowserToolbarTestTags.kt @@ -29,6 +29,11 @@ object BrowserToolbarTestTags { const val ADDRESSBAR_URL = "ADDRESSBAR_URL" /** + * Test tag for the page load progress bar. + */ + const val ADDRESSBAR_PROGRESSBAR = "ADDRESSBAR_PROGRESSBAR" + + /** * Test tag for the unified search selector. */ const val SEARCH_SELECTOR = "SEARCH_SELECTOR" diff --git a/mobile/android/android-components/components/compose/browser-toolbar/src/main/java/mozilla/components/compose/browser/toolbar/ui/FullDisplayToolbar.kt b/mobile/android/android-components/components/compose/browser-toolbar/src/main/java/mozilla/components/compose/browser/toolbar/ui/FullDisplayToolbar.kt @@ -21,6 +21,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.testTag import androidx.compose.ui.semantics.semantics +import androidx.compose.ui.semantics.testTag import androidx.compose.ui.semantics.testTagsAsResourceId import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.PreviewLightDark @@ -34,6 +35,7 @@ import mozilla.components.compose.base.theme.privateColorPalette import mozilla.components.compose.browser.toolbar.ActionContainer import mozilla.components.compose.browser.toolbar.R import mozilla.components.compose.browser.toolbar.concept.Action +import mozilla.components.compose.browser.toolbar.concept.BrowserToolbarTestTags.ADDRESSBAR_PROGRESSBAR import mozilla.components.compose.browser.toolbar.concept.BrowserToolbarTestTags.ADDRESSBAR_URL_BOX import mozilla.components.compose.browser.toolbar.concept.PageOrigin import mozilla.components.compose.browser.toolbar.store.BrowserToolbarInteraction.BrowserToolbarEvent @@ -186,7 +188,11 @@ internal fun FullDisplayToolbar( progress = progressBarConfig.progress, color = progressBarConfig.color, trackColor = Color.Transparent, - modifier = Modifier.align( + modifier = Modifier + .semantics { + testTag = ADDRESSBAR_PROGRESSBAR + } + .align( when (gravity) { Top -> Alignment.BottomCenter Bottom -> Alignment.TopCenter diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/experimentintegration/GenericExperimentIntegrationTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/experimentintegration/GenericExperimentIntegrationTest.kt @@ -4,6 +4,7 @@ package org.mozilla.fenix.experimentintegration +import androidx.compose.ui.test.junit4.AndroidComposeTestRule import androidx.test.platform.app.InstrumentationRegistry import org.junit.After import org.junit.Before @@ -18,9 +19,12 @@ class GenericExperimentIntegrationTest { private val experimentName = InstrumentationRegistry.getArguments().getString("EXP_NAME", "Viewpoint") @get:Rule - val activityTestRule = HomeActivityTestRule( - isPWAsPromptEnabled = false, - ) + val composeTestRule = + AndroidComposeTestRule( + HomeActivityTestRule( + isPWAsPromptEnabled = false, + ), + ) { it.activity } @Before fun setUp() { @@ -34,9 +38,9 @@ class GenericExperimentIntegrationTest { @Test fun disableStudiesViaStudiesToggle() { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openExperimentsMenu { verifyExperimentEnrolled(experimentName) }.goBack { @@ -49,9 +53,9 @@ class GenericExperimentIntegrationTest { @Test fun verifyStudiesAreDisabled() { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openSettingsSubMenuDataCollection { clickStudiesOption() verifyStudiesToggle(false) @@ -60,9 +64,9 @@ class GenericExperimentIntegrationTest { @Test fun testExperimentEnrolled() { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openExperimentsMenu { verifyExperimentEnrolled(experimentName) } @@ -70,9 +74,9 @@ class GenericExperimentIntegrationTest { @Test fun testExperimentUnenrolled() { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openExperimentsMenu { verifyExperimentExists(experimentName) verifyExperimentNotEnrolled(experimentName) @@ -81,9 +85,9 @@ class GenericExperimentIntegrationTest { @Test fun testExperimentUnenrolledViaSecretMenu() { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openExperimentsMenu { verifyExperimentExists(experimentName) verifyExperimentEnrolled(experimentName) diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/experimentintegration/SurveyExperimentIntegrationTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/experimentintegration/SurveyExperimentIntegrationTest.kt @@ -5,6 +5,7 @@ package org.mozilla.fenix.experimentintegration import android.content.pm.ActivityInfo +import androidx.compose.ui.test.junit4.AndroidComposeTestRule import org.junit.After import org.junit.Before import org.junit.Rule @@ -23,10 +24,13 @@ class SurveyExperimentIntegrationTest { private val experimentName = "Viewpoint" @get:Rule - val activityTestRule = HomeActivityTestRule( - isPWAsPromptEnabled = false, - isDeleteSitePermissionsEnabled = true, - ) + val composeTestRule = + AndroidComposeTestRule( + HomeActivityTestRule( + isPWAsPromptEnabled = false, + isDeleteSitePermissionsEnabled = true, + ), + ) { it.activity } @Before fun setUp() { @@ -39,9 +43,9 @@ class SurveyExperimentIntegrationTest { } fun checkExperimentExists() { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openExperimentsMenu { verifyExperimentExists(experimentName) } @@ -49,8 +53,8 @@ class SurveyExperimentIntegrationTest { @Test fun checkSurveyNavigatesCorrectly() { - surveyScreen { - verifySurveyButton() + surveyScreen(composeTestRule) { + verifySurveyButton(composeTestRule) }.clickSurveyButton { verifyUrl(surveyURL) } @@ -60,8 +64,8 @@ class SurveyExperimentIntegrationTest { @Test fun checkSurveyNoThanksNavigatesCorrectly() { - surveyScreen { - verifySurveyNoThanksButton() + surveyScreen(composeTestRule) { + verifySurveyNoThanksButton(composeTestRule) }.clickNoThanksSurveyButton { verifyTabCounter("0") } @@ -71,7 +75,7 @@ class SurveyExperimentIntegrationTest { @Test fun checkHomescreenSurveyDismissesCorrectly() { - surveyScreen { + surveyScreen(composeTestRule) { verifyHomeScreenSurveyCloseButton(true) }.clickHomeScreenSurveyCloseButton { verifyTabCounter("0") @@ -83,10 +87,10 @@ class SurveyExperimentIntegrationTest { @Test fun checkSurveyLandscapeLooksCorrect() { - activityTestRule.activity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE - surveyScreen { - verifySurveyNoThanksButton() - verifySurveyButton() + composeTestRule.activity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE + surveyScreen(composeTestRule) { + verifySurveyNoThanksButton(composeTestRule) + verifySurveyButton(composeTestRule) }.clickNoThanksSurveyButton { verifyTabCounter("0") } diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/helpers/AppAndSystemHelper.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/helpers/AppAndSystemHelper.kt @@ -20,6 +20,7 @@ import android.provider.Settings import android.util.Log import androidx.appcompat.app.AppCompatDelegate import androidx.compose.ui.test.junit4.AndroidComposeTestRule +import androidx.compose.ui.test.junit4.ComposeTestRule import androidx.core.net.toUri import androidx.core.os.LocaleListCompat import androidx.test.espresso.Espresso @@ -381,7 +382,7 @@ object AppAndSystemHelper { } } - fun assertNativeAppOpens(appPackageName: String, url: String = "") { + fun assertNativeAppOpens(composeTestRule: ComposeTestRule, appPackageName: String, url: String = "") { if (isPackageInstalled(appPackageName)) { Log.i(TAG, "assertNativeAppOpens: Waiting for the device to be idle $waitingTimeShort ms.") mDevice.waitForIdle(waitingTimeShort) @@ -398,7 +399,7 @@ object AppAndSystemHelper { forceCloseApp(appPackageName) } else { Log.i(TAG, "assertNativeAppOpens: Trying to verify the page redirect URL.") - BrowserRobot().verifyUrl(url) + BrowserRobot(composeTestRule).verifyUrl(url) Log.i(TAG, "assertNativeAppOpens: Verified the page redirect URL.") } } diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/helpers/HomeActivityTestRule.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/helpers/HomeActivityTestRule.kt @@ -62,8 +62,8 @@ class HomeActivityTestRule( isUnifiedTrustPanelEnabled: Boolean = false, etpPolicy: ETPPolicy = getETPPolicy(settings), isLocationPermissionEnabled: SitePermissionsRules.Action = getFeaturePermission(PhoneFeature.LOCATION, settings), - isComposableToolbarEnabled: Boolean = false, - isMenuRedesignEnabled: Boolean = false, + isComposableToolbarEnabled: Boolean = true, + isMenuRedesignEnabled: Boolean = true, isMenuRedesignCFREnabled: Boolean = false, isPageLoadTranslationsPromptEnabled: Boolean = false, isMicrosurveyEnabled: Boolean = settings.microsurveyFeatureEnabled, @@ -152,7 +152,6 @@ class HomeActivityTestRule( isWallpaperOnboardingEnabled = false, isOpenInAppBannerEnabled = false, isMicrosurveyEnabled = false, - isComposableToolbarEnabled = false, // workaround for toolbar at top position by default // remove with https://bugzilla.mozilla.org/show_bug.cgi?id=1917640 shouldUseBottomToolbar = true, @@ -196,8 +195,8 @@ class HomeActivityIntentTestRule internal constructor( isUnifiedTrustPanelEnabled: Boolean = false, etpPolicy: ETPPolicy = getETPPolicy(settings), isLocationPermissionEnabled: SitePermissionsRules.Action = getFeaturePermission(PhoneFeature.LOCATION, settings), - isComposableToolbarEnabled: Boolean = false, - isMenuRedesignEnabled: Boolean = false, + isComposableToolbarEnabled: Boolean = true, + isMenuRedesignEnabled: Boolean = true, isMenuRedesignCFREnabled: Boolean = false, isPageLoadTranslationsPromptEnabled: Boolean = false, isMicrosurveyEnabled: Boolean = settings.microsurveyFeatureEnabled, @@ -331,7 +330,6 @@ class HomeActivityIntentTestRule internal constructor( isWallpaperOnboardingEnabled = false, isOpenInAppBannerEnabled = false, isMicrosurveyEnabled = false, - isComposableToolbarEnabled = false, // workaround for toolbar at top position by default // remove with https://bugzilla.mozilla.org/show_bug.cgi?id=1917640 shouldUseBottomToolbar = true, diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/syncintegration/SyncIntegrationTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/syncintegration/SyncIntegrationTest.kt @@ -38,7 +38,7 @@ class SyncIntegrationTest { private lateinit var mockWebServer: MockWebServer @get:Rule - val activityTestRule = AndroidComposeTestRule(HomeActivityIntentTestRule()) { it.activity } + val composeTestRule = AndroidComposeTestRule(HomeActivityIntentTestRule()) { it.activity } @Before fun setUp() { @@ -63,9 +63,9 @@ class SyncIntegrationTest { // Let's wait until homescreen is shown to go to three dot menu TestAssetHelper.waitingTime mDevice.waitNotNull(Until.findObjects(By.res("org.mozilla.fenix.debug:id/counter_root"))) - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openHistory { + }.clickHistoryButton { } historyAfterSyncIsShown() } @@ -76,9 +76,9 @@ class SyncIntegrationTest { fun syncBookmarksTest() { signInFxSync() tapReturnToPreviousApp() - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openBookmarksMenu(activityTestRule) {} + }.clickBookmarksButton {} bookmarkAfterSyncIsShown() } @@ -110,9 +110,9 @@ class SyncIntegrationTest { // Login item Desktop -> Fenix @Test fun synLoginsTest() { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openLoginsAndPasswordSubMenu { }.openSyncLogins { // Tap to sign in from Logins menu @@ -127,12 +127,12 @@ class SyncIntegrationTest { verifyDefaultView() // Sync logings option is set to Off, no synced logins yet verifyDefaultViewBeforeSyncComplete() - }.openSavedLogins { + }.openSavedLogins(composeTestRule) { // Discard the secure your device message tapSetupLater() // Check the logins synced verifySavedLoginsAfterSync() - }.goBack(activityTestRule) { + }.goBack { // After checking the synced logins // on Logins and Passwords menu the Sync passwords option is set to On verifyDefaultViewAfterSync() @@ -197,10 +197,10 @@ class SyncIntegrationTest { } fun signInFxSync() { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { verifySettingsButton() - }.openSettings {} + }.clickSettingsButton {} settingsAccount() useEmailInsteadButton() diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/AboutURITest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/AboutURITest.kt @@ -4,6 +4,7 @@ package org.mozilla.fenix.ui +import androidx.compose.ui.test.junit4.AndroidComposeTestRule import androidx.core.net.toUri import org.junit.Rule import org.junit.Test @@ -13,14 +14,17 @@ import org.mozilla.fenix.ui.robots.navigationToolbar class AboutURITest : TestSetup() { @get:Rule - val activityIntentTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides() + val composeTestRule = + AndroidComposeTestRule( + HomeActivityIntentTestRule.withDefaultSettingsOverrides(), + ) { it.activity } // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2944327 @Test fun verifyWebCompatPageIsLoadingTest() { val webCompatPage = "about:compat" - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(webCompatPage.toUri()) { verifyUrl(webCompatPage) diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/AddressAutofillTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/AddressAutofillTest.kt @@ -5,6 +5,7 @@ package org.mozilla.fenix.ui import androidx.compose.ui.test.junit4.AndroidComposeTestRule +import androidx.test.espresso.Espresso.closeSoftKeyboard import org.junit.Rule import org.junit.Test import org.mozilla.fenix.customannotations.SmokeTest @@ -66,6 +67,7 @@ class AddressAutofillTest : TestSetup() { autofillScreen(composeTestRule) { fillAndSaveAddress( + composeTestRule, navigateToAutofillSettings = FirstAddressAutofillDetails.navigateToAutofillSettings, isAddressAutofillEnabled = FirstAddressAutofillDetails.isAddressAutofillEnabled, userHasSavedAddress = FirstAddressAutofillDetails.userHasSavedAddress, @@ -79,13 +81,14 @@ class AddressAutofillTest : TestSetup() { emailAddress = FirstAddressAutofillDetails.emailAddress, ) }.goBack { - }.goBack { + }.goBack(composeTestRule) { } - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(addressFormPage.url) { - clickPageObject(itemWithResId("streetAddress")) + clickPageObject(composeTestRule, itemWithResId("streetAddress")) clickSelectAddressButton() clickPageObject( + composeTestRule, itemWithResIdContainingText( "$packageName:id/address_name", "Harrison Street", @@ -102,6 +105,7 @@ class AddressAutofillTest : TestSetup() { fun deleteSavedAddressTest() { autofillScreen(composeTestRule) { fillAndSaveAddress( + composeTestRule, navigateToAutofillSettings = FirstAddressAutofillDetails.navigateToAutofillSettings, isAddressAutofillEnabled = FirstAddressAutofillDetails.isAddressAutofillEnabled, userHasSavedAddress = FirstAddressAutofillDetails.userHasSavedAddress, @@ -128,9 +132,9 @@ class AddressAutofillTest : TestSetup() { // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/1836840 @Test fun verifyAddAddressViewTest() { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openAutofillSubMenu(composeTestRule) { waitForAppWindowToBeUpdated() clickAddAddressButton() @@ -145,6 +149,7 @@ class AddressAutofillTest : TestSetup() { fun verifyEditAddressViewTest() { autofillScreen(composeTestRule) { fillAndSaveAddress( + composeTestRule, navigateToAutofillSettings = FirstAddressAutofillDetails.navigateToAutofillSettings, isAddressAutofillEnabled = FirstAddressAutofillDetails.isAddressAutofillEnabled, userHasSavedAddress = FirstAddressAutofillDetails.userHasSavedAddress, @@ -170,6 +175,7 @@ class AddressAutofillTest : TestSetup() { autofillScreen(composeTestRule) { fillAndSaveAddress( + composeTestRule, navigateToAutofillSettings = FirstAddressAutofillDetails.navigateToAutofillSettings, isAddressAutofillEnabled = FirstAddressAutofillDetails.isAddressAutofillEnabled, userHasSavedAddress = FirstAddressAutofillDetails.userHasSavedAddress, @@ -186,12 +192,14 @@ class AddressAutofillTest : TestSetup() { exitMenu() - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(addressFormPage.url) { - clickPageObject(itemWithResId("streetAddress")) + clickPageObject(composeTestRule, itemWithResId("streetAddress")) verifySelectAddressButtonExists(true) + closeSoftKeyboard() + waitForAppWindowToBeUpdated() }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openAutofillSubMenu(composeTestRule) { clickSaveAndAutofillAddressesOption() verifyAddressAutofillSection(false, true) @@ -199,9 +207,9 @@ class AddressAutofillTest : TestSetup() { exitMenu() - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(addressFormPage.url) { - clickPageObject(itemWithResId("streetAddress")) + clickPageObject(composeTestRule, itemWithResId("streetAddress")) verifySelectAddressButtonExists(false) } } @@ -213,6 +221,7 @@ class AddressAutofillTest : TestSetup() { autofillScreen(composeTestRule) { fillAndSaveAddress( + composeTestRule, navigateToAutofillSettings = FirstAddressAutofillDetails.navigateToAutofillSettings, isAddressAutofillEnabled = FirstAddressAutofillDetails.isAddressAutofillEnabled, userHasSavedAddress = FirstAddressAutofillDetails.userHasSavedAddress, @@ -229,13 +238,13 @@ class AddressAutofillTest : TestSetup() { exitMenu() - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(addressFormPage.url) { - clickPageObject(itemWithResId("streetAddress")) + clickPageObject(composeTestRule, itemWithResId("streetAddress")) clickSelectAddressButton() - }.clickManageAddressButton(composeTestRule) { + }.clickManageAddressButton { verifyAutofillToolbarTitle() - }.goBackToBrowser { + }.goBackToBrowser(composeTestRule) { verifySaveLoginPromptIsNotDisplayed() } } @@ -247,6 +256,7 @@ class AddressAutofillTest : TestSetup() { autofillScreen(composeTestRule) { fillAndSaveAddress( + composeTestRule, navigateToAutofillSettings = FirstAddressAutofillDetails.navigateToAutofillSettings, isAddressAutofillEnabled = FirstAddressAutofillDetails.isAddressAutofillEnabled, userHasSavedAddress = FirstAddressAutofillDetails.userHasSavedAddress, @@ -262,6 +272,7 @@ class AddressAutofillTest : TestSetup() { clickManageAddressesButton() clickAddAddressButton() fillAndSaveAddress( + composeTestRule, navigateToAutofillSettings = SecondAddressAutofillDetails.navigateToAutofillSettings, name = SecondAddressAutofillDetails.name, streetAddress = SecondAddressAutofillDetails.streetAddress, @@ -277,11 +288,12 @@ class AddressAutofillTest : TestSetup() { exitMenu() - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(addressFormPage.url) { - clickPageObject(itemWithResId("streetAddress")) + clickPageObject(composeTestRule, itemWithResId("streetAddress")) clickSelectAddressButton() clickPageObject( + composeTestRule, itemWithResIdContainingText( "$packageName:id/address_name", "Harrison Street", @@ -289,9 +301,10 @@ class AddressAutofillTest : TestSetup() { ) verifyAutofilledAddress("Harrison Street") clearAddressForm() - clickPageObject(itemWithResId("streetAddress")) + clickPageObject(composeTestRule, itemWithResId("streetAddress")) clickSelectAddressButton() clickPageObject( + composeTestRule, itemWithResIdContainingText( "$packageName:id/address_name", "Fort Street", @@ -306,6 +319,7 @@ class AddressAutofillTest : TestSetup() { fun verifySavedAddressCanBeEditedTest() { autofillScreen(composeTestRule) { fillAndSaveAddress( + composeTestRule, navigateToAutofillSettings = FirstAddressAutofillDetails.navigateToAutofillSettings, isAddressAutofillEnabled = FirstAddressAutofillDetails.isAddressAutofillEnabled, userHasSavedAddress = FirstAddressAutofillDetails.userHasSavedAddress, @@ -321,6 +335,7 @@ class AddressAutofillTest : TestSetup() { clickManageAddressesButton() clickSavedAddress(composeTestRule, FirstAddressAutofillDetails.name) fillAndSaveAddress( + composeTestRule, navigateToAutofillSettings = SecondAddressAutofillDetails.navigateToAutofillSettings, name = SecondAddressAutofillDetails.name, streetAddress = SecondAddressAutofillDetails.streetAddress, @@ -338,9 +353,9 @@ class AddressAutofillTest : TestSetup() { // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/1836848 @Test fun verifyStateFieldUpdatesInAccordanceWithCountryFieldTest() { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openAutofillSubMenu(composeTestRule) { verifyAddressAutofillSection(true, false) clickAddAddressButton() @@ -361,6 +376,7 @@ class AddressAutofillTest : TestSetup() { autofillScreen(composeTestRule) { fillAndSaveAddress( + composeTestRule, navigateToAutofillSettings = FirstAddressAutofillDetails.navigateToAutofillSettings, isAddressAutofillEnabled = FirstAddressAutofillDetails.isAddressAutofillEnabled, userHasSavedAddress = FirstAddressAutofillDetails.userHasSavedAddress, @@ -377,11 +393,12 @@ class AddressAutofillTest : TestSetup() { exitMenu() - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(addressFormPage.url) { - clickPageObject(itemWithResId("streetAddress")) + clickPageObject(composeTestRule, itemWithResId("streetAddress")) clickSelectAddressButton() clickPageObject( + composeTestRule, itemWithResIdContainingText( "$packageName:id/address_name", "Harrison Street", @@ -398,6 +415,7 @@ class AddressAutofillTest : TestSetup() { fun verifyAutofillAddressSectionTest() { autofillScreen(composeTestRule) { fillAndSaveAddress( + composeTestRule, navigateToAutofillSettings = FirstAddressAutofillDetails.navigateToAutofillSettings, isAddressAutofillEnabled = FirstAddressAutofillDetails.isAddressAutofillEnabled, userHasSavedAddress = FirstAddressAutofillDetails.userHasSavedAddress, diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/AppLinksTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/AppLinksTest.kt @@ -13,6 +13,7 @@ import androidx.test.espresso.intent.matcher.IntentMatchers.hasAction import androidx.test.espresso.intent.matcher.IntentMatchers.hasDataString import org.hamcrest.Matchers.equalTo import org.junit.Before +import org.junit.Ignore import org.junit.Rule import org.junit.Test import org.mozilla.fenix.helpers.AppAndSystemHelper.assertNativeAppOpens @@ -23,6 +24,7 @@ import org.mozilla.fenix.helpers.MatcherHelper.itemWithResIdAndText import org.mozilla.fenix.helpers.OpenLinksInApp import org.mozilla.fenix.helpers.TestAssetHelper import org.mozilla.fenix.helpers.TestAssetHelper.appLinksRedirectAsset +import org.mozilla.fenix.helpers.TestAssetHelper.getGenericAsset import org.mozilla.fenix.helpers.TestHelper.mDevice import org.mozilla.fenix.helpers.TestSetup import org.mozilla.fenix.helpers.perf.DetectMemoryLeaksRule @@ -51,14 +53,6 @@ class AppLinksTest : TestSetup() { @get:Rule val memoryLeaksRule = DetectMemoryLeaksRule() - lateinit var externalLinksPage: TestAssetHelper.TestAsset - - @Before - override fun setUp() { - super.setUp() - externalLinksPage = mockWebServer.appLinksRedirectAsset - } - /** * User setting: Ask * Tests that when opening a youtube:// scheme link under “Ask”, the app prompt appears. @@ -67,11 +61,13 @@ class AppLinksTest : TestSetup() { */ @Test fun askBeforeOpeningLinkInAppYoutubeSchemeCancelTest() { - navigationToolbar { + val externalLinksPage = mockWebServer.appLinksRedirectAsset + + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(externalLinksPage.url) { - clickPageObject(youtubeSchemaUrlLink) + clickPageObject(composeTestRule, youtubeSchemaUrlLink) verifyOpenLinkInAnotherAppPrompt(appName = "YouTube") - clickPageObject(itemWithResIdAndText("android:id/button2", "Cancel")) + clickPageObject(composeTestRule, itemWithResIdAndText("android:id/button2", "Cancel")) mDevice.waitForIdle() verifyUrl(externalLinksPage.url.toString()) } @@ -85,9 +81,11 @@ class AppLinksTest : TestSetup() { */ @Test fun askBeforeOpeningLinkWithIntentSchemeTest() { - navigationToolbar { + val externalLinksPage = mockWebServer.appLinksRedirectAsset + + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(externalLinksPage.url) { - clickPageObject(intentSchemaUrlLink) + clickPageObject(composeTestRule, intentSchemaUrlLink) mDevice.waitForIdle() verifyOpenLinkInAnotherAppPromptIsNotShown() verifyUrl(externalLinksPage.url.toString()) @@ -102,14 +100,16 @@ class AppLinksTest : TestSetup() { */ @Test fun askBeforeOpeningLinkInAppYoutubeSchemeCancelMultiTapTest() { - navigationToolbar { + val externalLinksPage = mockWebServer.appLinksRedirectAsset + + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(externalLinksPage.url) { - clickPageObject(youtubeSchemaUrlLink) + clickPageObject(composeTestRule, youtubeSchemaUrlLink) verifyOpenLinkInAnotherAppPrompt(appName = "YouTube") - clickPageObject(itemWithResIdAndText("android:id/button2", "Cancel")) + clickPageObject(composeTestRule, itemWithResIdAndText("android:id/button2", "Cancel")) mDevice.waitForIdle() verifyUrl(externalLinksPage.url.toString()) - clickPageObject(youtubeSchemaUrlLink) + clickPageObject(composeTestRule, youtubeSchemaUrlLink) mDevice.waitForIdle() verifyUrl(externalLinksPage.url.toString()) verifyOpenLinkInAnotherAppPromptIsNotShown() @@ -127,19 +127,21 @@ class AppLinksTest : TestSetup() { */ @Test fun askBeforeOpeningLinkInAppYoutubeSchemeCancelOnlyAffectCurrentTabTest() { - navigationToolbar { + val externalLinksPage = mockWebServer.appLinksRedirectAsset + + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(externalLinksPage.url) { - clickPageObject(youtubeSchemaUrlLink) + clickPageObject(composeTestRule, youtubeSchemaUrlLink) verifyOpenLinkInAnotherAppPrompt(appName = "YouTube") - clickPageObject(itemWithResIdAndText("android:id/button2", "Cancel")) + clickPageObject(composeTestRule, itemWithResIdAndText("android:id/button2", "Cancel")) mDevice.waitForIdle() verifyUrl(externalLinksPage.url.toString()) }.openTabDrawer(composeTestRule) { }.openNewTab { }.submitQuery(externalLinksPage.url.toString()) { - clickPageObject(youtubeSchemaUrlLink) + clickPageObject(composeTestRule, youtubeSchemaUrlLink) verifyOpenLinkInAnotherAppPrompt(appName = "YouTube") - clickPageObject(itemWithResIdAndText("android:id/button2", "Cancel")) + clickPageObject(composeTestRule, itemWithResIdAndText("android:id/button2", "Cancel")) mDevice.waitForIdle() verifyUrl(externalLinksPage.url.toString()) } @@ -153,13 +155,15 @@ class AppLinksTest : TestSetup() { */ @Test fun neverOpeningLinkInAppYoutubeTest() { + val externalLinksPage = mockWebServer.appLinksRedirectAsset + composeTestRule.activityRule.applySettingsExceptions { it.openLinksInExternalApp = OpenLinksInApp.NEVER } - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(externalLinksPage.url) { - clickPageObject(youtubeUrlLink) + clickPageObject(composeTestRule, youtubeUrlLink) mDevice.waitForIdle() verifyOpenLinkInAnotherAppPromptIsNotShown() verifyUrl("youtube.com") @@ -174,15 +178,17 @@ class AppLinksTest : TestSetup() { */ @Test fun neverOpeningLinkInAppYoutubeSchemeCancelTest() { + val externalLinksPage = mockWebServer.appLinksRedirectAsset + composeTestRule.activityRule.applySettingsExceptions { it.openLinksInExternalApp = OpenLinksInApp.NEVER } - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(externalLinksPage.url) { - clickPageObject(youtubeSchemaUrlLink) + clickPageObject(composeTestRule, youtubeSchemaUrlLink) verifyOpenLinkInAnotherAppPrompt(appName = "YouTube") - clickPageObject(itemWithResIdAndText("android:id/button2", "Cancel")) + clickPageObject(composeTestRule, itemWithResIdAndText("android:id/button2", "Cancel")) mDevice.waitForIdle() verifyUrl(externalLinksPage.url.toString()) } @@ -196,11 +202,13 @@ class AppLinksTest : TestSetup() { */ @Test fun askBeforeOpeningLinkInAppYoutubeCancelTest() { - navigationToolbar { + val externalLinksPage = mockWebServer.appLinksRedirectAsset + + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(externalLinksPage.url) { - clickPageObject(youtubeUrlLink) + clickPageObject(composeTestRule, youtubeUrlLink) verifyOpenLinkInAnotherAppPrompt(appName = "YouTube") - clickPageObject(itemWithResIdAndText("android:id/button2", "Cancel")) + clickPageObject(composeTestRule, itemWithResIdAndText("android:id/button2", "Cancel")) mDevice.waitForIdle() verifyUrl("youtube.com") } @@ -213,9 +221,11 @@ class AppLinksTest : TestSetup() { */ @Test fun appLinksRedirectPhoneLinkPromptTest() { - navigationToolbar { + val externalLinksPage = mockWebServer.appLinksRedirectAsset + + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(externalLinksPage.url) { - clickPageObject(phoneUrlLink) + clickPageObject(composeTestRule, phoneUrlLink) verifyOpenLinkInAnotherAppPrompt(appName = "Phone") } } @@ -228,11 +238,13 @@ class AppLinksTest : TestSetup() { */ @Test fun askBeforeOpeningLinkInAppPhoneCancelTest() { - navigationToolbar { + val externalLinksPage = mockWebServer.appLinksRedirectAsset + + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(externalLinksPage.url) { - clickPageObject(phoneUrlLink) + clickPageObject(composeTestRule, phoneUrlLink) verifyOpenLinkInAnotherAppPrompt(appName = "Phone") - clickPageObject(itemWithResIdAndText("android:id/button2", "Cancel")) + clickPageObject(composeTestRule, itemWithResIdAndText("android:id/button2", "Cancel")) mDevice.waitForIdle() verifyUrl(externalLinksPage.url.toString()) } @@ -246,15 +258,17 @@ class AppLinksTest : TestSetup() { */ @Test fun alwaysOpenPhoneLinkInAppTest() { + val externalLinksPage = mockWebServer.appLinksRedirectAsset + composeTestRule.activityRule.applySettingsExceptions { it.openLinksInExternalApp = OpenLinksInApp.ALWAYS } - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(externalLinksPage.url) { - clickPageObject(phoneUrlLink) + clickPageObject(composeTestRule, phoneUrlLink) mDevice.waitForIdle() - assertNativeAppOpens(Constants.PackageName.PHONE_APP, phoneSchemaLink) + assertNativeAppOpens(composeTestRule, Constants.PackageName.PHONE_APP, phoneSchemaLink) } } @@ -266,13 +280,15 @@ class AppLinksTest : TestSetup() { */ @Test fun askBeforeOpeningPhoneLinkInAcceptTest() { - navigationToolbar { + val externalLinksPage = mockWebServer.appLinksRedirectAsset + + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(externalLinksPage.url) { - clickPageObject(phoneUrlLink) + clickPageObject(composeTestRule, phoneUrlLink) verifyOpenLinkInAnotherAppPrompt(appName = "Phone") - clickPageObject(itemWithResIdAndText("android:id/button1", "Open")) + clickPageObject(composeTestRule, itemWithResIdAndText("android:id/button1", "Open")) mDevice.waitForIdle() - assertNativeAppOpens(Constants.PackageName.PHONE_APP, phoneSchemaLink) + assertNativeAppOpens(composeTestRule, Constants.PackageName.PHONE_APP, phoneSchemaLink) mDevice.waitForIdle() verifyUrl(externalLinksPage.url.toString()) } @@ -285,9 +301,11 @@ class AppLinksTest : TestSetup() { */ @Test fun appLinksNewTabRedirectAskTest() { - navigationToolbar { + val externalLinksPage = mockWebServer.appLinksRedirectAsset + + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(externalLinksPage.url) { - clickPageObject(formRedirectLink) + clickPageObject(composeTestRule, formRedirectLink) verifyOpenLinkInAnotherAppPrompt(appName = "Phone") } } @@ -299,15 +317,17 @@ class AppLinksTest : TestSetup() { */ @Test fun appLinksNewTabRedirectAlwaysTest() { + val externalLinksPage = mockWebServer.appLinksRedirectAsset + composeTestRule.activityRule.applySettingsExceptions { it.openLinksInExternalApp = OpenLinksInApp.ALWAYS } - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(externalLinksPage.url) { - clickPageObject(formRedirectLink) + clickPageObject(composeTestRule, formRedirectLink) mDevice.waitForIdle() - assertNativeAppOpens(Constants.PackageName.PHONE_APP, phoneSchemaLink) + assertNativeAppOpens(composeTestRule, Constants.PackageName.PHONE_APP, phoneSchemaLink) } } @@ -318,13 +338,15 @@ class AppLinksTest : TestSetup() { */ @Test fun appLinksNewTabRedirectNeverTest() { + val externalLinksPage = mockWebServer.appLinksRedirectAsset + composeTestRule.activityRule.applySettingsExceptions { it.openLinksInExternalApp = OpenLinksInApp.NEVER } - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(externalLinksPage.url) { - clickPageObject(formRedirectLink) + clickPageObject(composeTestRule, formRedirectLink) verifyOpenLinkInAnotherAppPrompt(appName = "Phone") } } @@ -337,6 +359,8 @@ class AppLinksTest : TestSetup() { */ @Test fun marketingIntentWhenOpeningLinkWithoutApp() { + val externalLinksPage = mockWebServer.appLinksRedirectAsset + // Use ACTION_DIAL as a non-ACTION_VIEW intent to verify that the marketing flow always // launches with ACTION_VIEW instead of reusing the original intent action. intending(hasAction(Intent.ACTION_DIAL)).respondWith( @@ -346,10 +370,10 @@ class AppLinksTest : TestSetup() { ), ) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(externalLinksPage.url) { - clickPageObject(intentSchemeWithExampleAppLink) - clickPageObject(itemWithResIdAndText("android:id/button1", "Open")) + clickPageObject(composeTestRule, intentSchemeWithExampleAppLink) + clickPageObject(composeTestRule, itemWithResIdAndText("android:id/button1", "Open")) mDevice.waitForIdle() intended(hasAction(Intent.ACTION_VIEW)) intended(hasDataString(equalTo("market://details?id=com.example.app"))) @@ -364,11 +388,13 @@ class AppLinksTest : TestSetup() { */ @Test fun appLinksBrowserFallbackURLTest() { - navigationToolbar { + val externalLinksPage = mockWebServer.appLinksRedirectAsset + + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(externalLinksPage.url) { - clickPageObject(phoneWithFallbackLink) + clickPageObject(composeTestRule, phoneWithFallbackLink) verifyOpenLinkInAnotherAppPrompt(appName = "Phone") - clickPageObject(itemWithResIdAndText("android:id/button2", "Cancel")) + clickPageObject(composeTestRule, itemWithResIdAndText("android:id/button2", "Cancel")) mDevice.waitForIdle() verifyUrl("mozilla.org") } @@ -381,9 +407,11 @@ class AppLinksTest : TestSetup() { */ @Test fun linkWithAndroidFallbackLinkTest() { - navigationToolbar { + val externalLinksPage = mockWebServer.appLinksRedirectAsset + + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(externalLinksPage.url) { - clickPageObject(linkWithAndroidFallbackLink) + clickPageObject(composeTestRule, linkWithAndroidFallbackLink) mDevice.waitForIdle() verifyUrl("mozilla.org") } @@ -396,9 +424,11 @@ class AppLinksTest : TestSetup() { */ @Test fun linkWithFallbackLinkTest() { - navigationToolbar { + val externalLinksPage = mockWebServer.appLinksRedirectAsset + + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(externalLinksPage.url) { - clickPageObject(linkWithFallbackLink) + clickPageObject(composeTestRule, linkWithFallbackLink) mDevice.waitForIdle() verifyUrl("mozilla.org") } @@ -411,9 +441,11 @@ class AppLinksTest : TestSetup() { */ @Test fun linkWithBrowserFallbackLinkTest() { - navigationToolbar { + val externalLinksPage = mockWebServer.appLinksRedirectAsset + + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(externalLinksPage.url) { - clickPageObject(linkWithBrowserFallbackLink) + clickPageObject(composeTestRule, linkWithBrowserFallbackLink) mDevice.waitForIdle() verifyUrl("mozilla.org") } diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/BookmarksTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/BookmarksTest.kt @@ -42,7 +42,6 @@ class BookmarksTest : TestSetup() { val composeTestRule = AndroidComposeTestRule( HomeActivityIntentTestRule( - isMenuRedesignEnabled = false, isMenuRedesignCFREnabled = false, shouldUseBottomToolbar = true, ), @@ -56,9 +55,9 @@ class BookmarksTest : TestSetup() { createBookmarkItem(website.url.toString(), website.title, null) - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openBookmarksMenu(composeTestRule) { + }.clickBookmarksButton { verifyBookmarkTitle("Test_Page_1") createFolder(bookmarkFolderName) verifyFolderTitle(bookmarkFolderName) @@ -95,10 +94,10 @@ class BookmarksTest : TestSetup() { fun editBookmarksNameAndUrlTest() { val defaultWebPage = mockWebServer.getGenericAsset(1) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(defaultWebPage.url) { }.openThreeDotMenu { - }.bookmarkPage { + }.clickBookmarkThisPageButton { verifySnackBarText("Saved in “Bookmarks”") clickSnackbarButton(composeTestRule, "EDIT") } @@ -108,9 +107,9 @@ class BookmarksTest : TestSetup() { changeBookmarkUrl(testBookmark.url) saveEditBookmark() } - browserScreen { + browserScreen(composeTestRule) { }.openThreeDotMenu { - }.openBookmarksMenu(composeTestRule) { + }.clickBookmarksButton { verifyBookmarkTitle(testBookmark.title) verifyBookmarkedURL("https://www.example.com/") }.openBookmarkWithTitle(testBookmark.title) { @@ -126,9 +125,9 @@ class BookmarksTest : TestSetup() { createBookmarkItem(defaultWebPage.url.toString(), defaultWebPage.title, null) - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openBookmarksMenu(composeTestRule) { + }.clickBookmarksButton { }.openThreeDotMenu(defaultWebPage.title) { }.clickShare { verifyShareTabLayout() @@ -153,17 +152,17 @@ class BookmarksTest : TestSetup() { createBookmarkItem(webPages[0].url.toString(), webPages[0].title, null) createBookmarkItem(webPages[1].url.toString(), webPages[1].title, null) - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openBookmarksMenu(composeTestRule) { + }.clickBookmarksButton { longClickBookmarkedItem(webPages[0].title) selectBookmarkedItem(webPages[1].title) } - multipleSelectionToolbar { + multipleSelectionToolbar(composeTestRule) { verifyMultiSelectionCounter(2, composeTestRule) clickMultiSelectThreeDotButton(composeTestRule) - }.clickOpenInNewTabButton(composeTestRule) { + }.clickOpenInNewTabButton { verifyTabTrayIsOpen() verifyNormalBrowsingButtonIsSelected() verifyNormalTabsList() @@ -183,14 +182,14 @@ class BookmarksTest : TestSetup() { createBookmarkItem(webPages[0].url.toString(), webPages[0].title, null) createBookmarkItem(webPages[1].url.toString(), webPages[1].title, null) - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openBookmarksMenu(composeTestRule) { + }.clickBookmarksButton { longClickBookmarkedItem(webPages[0].title) selectBookmarkedItem(webPages[1].title) } - multipleSelectionToolbar { + multipleSelectionToolbar(composeTestRule) { verifyMultiSelectionCounter(2, composeTestRule) clickMultiSelectThreeDotButton(composeTestRule) clickMultiSelectDeleteButton(composeTestRule) @@ -204,7 +203,7 @@ class BookmarksTest : TestSetup() { selectBookmarkedItem(webPages[1].title) } - multipleSelectionToolbar { + multipleSelectionToolbar(composeTestRule) { verifyMultiSelectionCounter(2, composeTestRule) clickMultiSelectThreeDotButton(composeTestRule) clickMultiSelectDeleteButton(composeTestRule) @@ -228,33 +227,33 @@ class BookmarksTest : TestSetup() { createBookmarkItem(firstWebPage.url.toString(), firstWebPage.title, null, newFolder) createBookmarkItem(secondWebPage.url.toString(), secondWebPage.title, null) - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openBookmarksMenu(composeTestRule) { + }.clickBookmarksButton { }.clickSearchButton { // Search for a valid term typeSearch(firstWebPage.title) - verifySearchSuggestionsAreDisplayed(composeTestRule, firstWebPage.url.toString()) - verifySuggestionsAreNotDisplayed(composeTestRule, secondWebPage.url.toString()) + verifySearchSuggestionsAreDisplayed(firstWebPage.url.toString()) + verifySuggestionsAreNotDisplayed(secondWebPage.url.toString()) // Search for invalid term typeSearch("Android") - verifySuggestionsAreNotDisplayed(composeTestRule, firstWebPage.url.toString()) - verifySuggestionsAreNotDisplayed(composeTestRule, secondWebPage.url.toString()) + verifySuggestionsAreNotDisplayed(firstWebPage.url.toString()) + verifySuggestionsAreNotDisplayed(secondWebPage.url.toString()) } } // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2833710 + @Ignore("Disabled after enabling the composable toolbar and main menu: https://bugzilla.mozilla.org/show_bug.cgi?id=2006295") @Test fun verifySearchBookmarksViewTest() { val defaultWebPage = mockWebServer.getGenericAsset(1) createBookmarkItem(defaultWebPage.url.toString(), defaultWebPage.title, null) - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openBookmarksMenu(composeTestRule) { + }.clickBookmarksButton { }.clickSearchButton { - verifySearchView() verifySearchToolbar(true) verifySearchSelectorButton() verifySearchEngineIcon("Bookmarks") @@ -266,16 +265,16 @@ class BookmarksTest : TestSetup() { composeBookmarksMenu(composeTestRule) { }.goBackToBrowserScreen { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openCustomizeSubMenu { clickTopToolbarToggle() } exitMenu() - browserScreen { + browserScreen(composeTestRule) { }.openThreeDotMenu { - }.openBookmarksMenu(composeTestRule) { + }.clickBookmarksButton { }.clickSearchButton { verifySearchToolbar(true) verifySearchEngineIcon("Bookmarks") @@ -290,10 +289,10 @@ class BookmarksTest : TestSetup() { fun verifyAddBookmarkButtonTest() { val defaultWebPage = mockWebServer.getGenericAsset(1) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(defaultWebPage.url) { }.openThreeDotMenu { - }.bookmarkPage { + }.clickBookmarkThisPageButton { verifySnackBarText("Saved in “Bookmarks”") clickSnackbarButton(composeTestRule, "EDIT") } @@ -310,10 +309,10 @@ class BookmarksTest : TestSetup() { fun createBookmarkFolderTest() { val defaultWebPage = mockWebServer.getGenericAsset(1) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(defaultWebPage.url) { }.openThreeDotMenu { - }.bookmarkPage { + }.clickBookmarkThisPageButton { verifySnackBarText("Saved in “Bookmarks”") clickSnackbarButton(composeTestRule, "EDIT") } @@ -325,9 +324,9 @@ class BookmarksTest : TestSetup() { saveNewFolder() navigateUp() } - browserScreen { + browserScreen(composeTestRule) { }.openThreeDotMenu { - }.openBookmarksMenu(composeTestRule) { + }.clickBookmarksButton { verifyFolderTitle(bookmarkFolderName) verifyBookmarkFolderDescription(numberOfBookmarksInFolder = "1") selectFolder(bookmarkFolderName) @@ -342,9 +341,9 @@ class BookmarksTest : TestSetup() { createBookmarkItem(defaultWebPage.url.toString(), defaultWebPage.title, null) - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openBookmarksMenu(composeTestRule) { + }.clickBookmarksButton { }.openThreeDotMenu(defaultWebPage.title) { }.clickCopy { waitForBookmarksSnackBarToBeGone(snackbarText = "URL copied") @@ -362,9 +361,9 @@ class BookmarksTest : TestSetup() { createBookmarkItem(defaultWebPage.url.toString(), defaultWebPage.title, null) - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openBookmarksMenu(composeTestRule) { + }.clickBookmarksButton { }.openThreeDotMenu(defaultWebPage.title) { }.clickOpenInNewTab { verifyTabTrayIsOpen() @@ -372,7 +371,7 @@ class BookmarksTest : TestSetup() { }.closeTabDrawer { }.goBack { }.openThreeDotMenu { - }.openBookmarksMenu(composeTestRule) { + }.clickBookmarksButton { }.openBookmarkWithTitle(defaultWebPage.title) { verifyUrl(defaultWebPage.url.toString()) } @@ -385,9 +384,9 @@ class BookmarksTest : TestSetup() { createBookmarkItem(defaultWebPage.url.toString(), defaultWebPage.title, null) - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openBookmarksMenu(composeTestRule) { + }.clickBookmarksButton { }.openThreeDotMenu(defaultWebPage.title) { }.clickOpenInPrivateTab { verifyTabTrayIsOpen() @@ -402,9 +401,9 @@ class BookmarksTest : TestSetup() { createBookmarkItem(defaultWebPage.url.toString(), defaultWebPage.title, null) - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openBookmarksMenu(composeTestRule) { + }.clickBookmarksButton { }.openThreeDotMenu(defaultWebPage.title) { }.clickDelete { clickSnackbarButton(composeTestRule, "UNDO") @@ -430,9 +429,9 @@ class BookmarksTest : TestSetup() { createBookmarkItem(webPages[2].url.toString(), webPages[2].title, null, subFolderGuid) createBookmarkItem(webPages[3].url.toString(), webPages[3].title, null, rootFolderGuid) - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openBookmarksMenu(composeTestRule) { + }.clickBookmarksButton { }.openThreeDotMenu("root") { }.clickOpenAllInTabs(composeTestRule) { verifyTabTrayIsOpen() @@ -461,9 +460,9 @@ class BookmarksTest : TestSetup() { createBookmarkItem(webPages[0].url.toString(), webPages[0].title, null, rootFolderGuid) createBookmarkItem(webPages[1].url.toString(), webPages[1].title, null, subFolderGuid) - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openBookmarksMenu(composeTestRule) { + }.clickBookmarksButton { }.openThreeDotMenu("root") { }.clickOpenAllInPrivateTabs(composeTestRule) { verifyTabTrayIsOpen() diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/BrowsingErrorPagesTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/BrowsingErrorPagesTest.kt @@ -4,11 +4,11 @@ package org.mozilla.fenix.ui +import androidx.compose.ui.test.junit4.AndroidComposeTestRule import androidx.core.net.toUri import org.junit.Ignore import org.junit.Rule import org.junit.Test -import org.mozilla.fenix.R import org.mozilla.fenix.customannotations.SmokeTest import org.mozilla.fenix.helpers.AppAndSystemHelper.setNetworkEnabled import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource @@ -38,7 +38,10 @@ class BrowsingErrorPagesTest : TestSetup() { getStringResource(errorpagesR.string.mozac_browser_errorpages_safe_harmful_uri_title) @get:Rule - val mActivityTestRule = HomeActivityTestRule.withDefaultSettingsOverrides() + val composeTestRule = + AndroidComposeTestRule( + HomeActivityTestRule.withDefaultSettingsOverrides(), + ) { it.activity } @get:Rule val memoryLeaksRule = DetectMemoryLeaksRule() @@ -53,7 +56,7 @@ class BrowsingErrorPagesTest : TestSetup() { fun verifyMalwareWebsiteWarningMessageTest() { val malwareURl = "http://itisatrap.org/firefox/its-an-attack.html" - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(malwareURl.toUri()) { verifyPageContent(malwareWarning) } @@ -65,7 +68,7 @@ class BrowsingErrorPagesTest : TestSetup() { fun verifyPhishingWebsiteWarningMessageTest() { val phishingURl = "http://itisatrap.org/firefox/its-a-trap.html" - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(phishingURl.toUri()) { verifyPageContent(phishingWarning) } @@ -77,7 +80,7 @@ class BrowsingErrorPagesTest : TestSetup() { fun verifyUnwantedSoftwareWebsiteWarningMessageTest() { val unwantedURl = "http://itisatrap.org/firefox/unwanted.html" - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(unwantedURl.toUri()) { verifyPageContent(unwantedSoftwareWarning) } @@ -89,7 +92,7 @@ class BrowsingErrorPagesTest : TestSetup() { fun verifyHarmfulWebsiteWarningMessageTest() { val harmfulURl = "https://itisatrap.org/firefox/harmful.html" - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(harmfulURl.toUri()) { verifyPageContent(harmfulSiteWarning) } @@ -102,14 +105,14 @@ class BrowsingErrorPagesTest : TestSetup() { fun verifyConnectionInterruptedErrorMessageTest() { val testUrl = mockWebServer.getGenericAsset(1) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(testUrl.url) { waitForPageToLoad() verifyPageContent(testUrl.content) // Disconnecting the server mockWebServer.shutdown() }.openThreeDotMenu { - }.refreshPage { + }.clickRefreshButton { waitForPageToLoad() verifyConnectionErrorMessage() } @@ -120,11 +123,11 @@ class BrowsingErrorPagesTest : TestSetup() { fun verifyAddressNotFoundErrorMessageTest() { val url = "ww.example.com" - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(url.toUri()) { waitForPageToLoad(pageLoadWaitingTime = waitingTimeLong) verifyAddressNotFoundErrorMessage() - clickPageObject(itemWithResId("errorTryAgain")) + clickPageObject(composeTestRule, itemWithResId("errorTryAgain")) verifyAddressNotFoundErrorMessage() } } @@ -137,15 +140,15 @@ class BrowsingErrorPagesTest : TestSetup() { setNetworkEnabled(false) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(url.toUri()) { verifyNoInternetConnectionErrorMessage() } setNetworkEnabled(true) - browserScreen { - clickPageObject(itemWithResId("errorTryAgain")) + browserScreen(composeTestRule) { + clickPageObject(composeTestRule, itemWithResId("errorTryAgain")) waitForPageToLoad(pageLoadWaitingTime = waitingTimeLong) verifyPageContent("Example Domain") } diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CollectionTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CollectionTest.kt @@ -55,15 +55,15 @@ class CollectionTest : TestSetup() { val firstWebPage = mockWebServer.getGenericAsset(1) val secondWebPage = mockWebServer.getGenericAsset(2) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(firstWebPage.url) { mDevice.waitForIdle() }.openTabDrawer(composeTestRule) { }.openNewTab { }.submitQuery(secondWebPage.url.toString()) { mDevice.waitForIdle() - }.goToHomescreen(composeTestRule) { - }.clickSaveTabsToCollectionButton(composeTestRule) { + }.goToHomescreen { + }.clickSaveTabsToCollectionButton { longClickTab(firstWebPage.title) selectTab(secondWebPage.title, numberOfSelectedTabs = 2) verifyTabsMultiSelectionCounter(2) @@ -77,8 +77,8 @@ class CollectionTest : TestSetup() { }.closeTabDrawer { } - homeScreen { - verifyCollectionIsDisplayed(composeTestRule, collectionName) + homeScreen(composeTestRule) { + verifyCollectionIsDisplayed(collectionName) } } @@ -87,10 +87,11 @@ class CollectionTest : TestSetup() { fun createFirstCollectionFromMainMenuTest() { val defaultWebPage = mockWebServer.getGenericAsset(1) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(defaultWebPage.url) { }.openThreeDotMenu { - }.openSaveToCollection { + clickTheMoreButton() + }.clickSaveToCollectionButton { verifyCollectionNameTextField() }.typeCollectionNameAndSave(collectionName) { verifySnackBarText("Collection saved") @@ -112,39 +113,39 @@ class CollectionTest : TestSetup() { title = collectionName, ) - homeScreen { - verifyCollectionIsDisplayed(composeTestRule, collectionName) - }.expandCollection(composeTestRule, collectionName) { - verifyTabSavedInCollection(composeTestRule, webPage.title) - verifyTabSavedInCollection(composeTestRule, webPage2.title) - verifyShareCollectionButtonIsVisible(composeTestRule, true) - verifyCollectionMenuIsVisible(true, composeTestRule) + homeScreen(composeTestRule) { + verifyCollectionIsDisplayed(collectionName) + }.expandCollection(collectionName) { + verifyTabSavedInCollection(webPage.title) + verifyTabSavedInCollection(webPage2.title) + verifyShareCollectionButtonIsVisible(true) + verifyCollectionMenuIsVisible(true) verifyCollectionItemRemoveButtonIsVisible(webPage.title, true) - }.collapseCollection(composeTestRule, collectionName) {} + }.collapseCollection(collectionName) {} - collectionRobot { - verifyTabSavedInCollection(composeTestRule, webPage.title, false) - verifyShareCollectionButtonIsVisible(composeTestRule, false) - verifyCollectionMenuIsVisible(false, composeTestRule) - verifyCollectionTabUrl(composeTestRule, false, webPageUrl) + collectionRobot(composeTestRule) { + verifyTabSavedInCollection(webPage.title, false) + verifyShareCollectionButtonIsVisible(false) + verifyCollectionMenuIsVisible(false) + verifyCollectionTabUrl(false, webPageUrl) verifyCollectionItemRemoveButtonIsVisible(webPage.title, false) } - homeScreen { - verifyCollectionIsDisplayed(composeTestRule, collectionName) - }.expandCollection(composeTestRule, collectionName) { - verifyTabSavedInCollection(composeTestRule, webPage.title) - verifyCollectionTabUrl(composeTestRule, true, webPageUrl) - verifyShareCollectionButtonIsVisible(composeTestRule, true) - verifyCollectionMenuIsVisible(true, composeTestRule) + homeScreen(composeTestRule) { + verifyCollectionIsDisplayed(collectionName) + }.expandCollection(collectionName) { + verifyTabSavedInCollection(webPage.title) + verifyCollectionTabUrl(true, webPageUrl) + verifyShareCollectionButtonIsVisible(true) + verifyCollectionMenuIsVisible(true) verifyCollectionItemRemoveButtonIsVisible(webPage.title, true) - }.collapseCollection(composeTestRule, collectionName) {} + }.collapseCollection(collectionName) {} - collectionRobot { - verifyTabSavedInCollection(composeTestRule, webPage.title, false) - verifyShareCollectionButtonIsVisible(composeTestRule, false) - verifyCollectionMenuIsVisible(false, composeTestRule) - verifyCollectionTabUrl(composeTestRule, false, webPageUrl) + collectionRobot(composeTestRule) { + verifyTabSavedInCollection(webPage.title, false) + verifyShareCollectionButtonIsVisible(false) + verifyCollectionMenuIsVisible(false) + verifyCollectionTabUrl(false, webPageUrl) verifyCollectionItemRemoveButtonIsVisible(webPage.title, false) } } @@ -163,11 +164,11 @@ class CollectionTest : TestSetup() { title = collectionName, ) - homeScreen { - verifyCollectionIsDisplayed(composeTestRule, collectionName) - }.expandCollection(composeTestRule, collectionName) { - clickCollectionThreeDotButton(composeTestRule) - selectOpenTabs(composeTestRule) + homeScreen(composeTestRule) { + verifyCollectionIsDisplayed(collectionName) + }.expandCollection(collectionName) { + clickCollectionThreeDotButton() + selectOpenTabs() } composeTabDrawer(composeTestRule) { verifyExistingOpenTabs(firstTestPage.title, secondTestPage.title) @@ -190,10 +191,10 @@ class CollectionTest : TestSetup() { title = collectionName, ) - homeScreen { - verifyCollectionIsDisplayed(composeTestRule, collectionName) - }.expandCollection(composeTestRule, collectionName) { - }.clickShareCollectionButton(composeTestRule) { + homeScreen(composeTestRule) { + verifyCollectionIsDisplayed(collectionName) + }.expandCollection(collectionName) { + }.clickShareCollectionButton { verifyShareTabsOverlay(firstWebsite.title, secondWebsite.title) verifySharingWithSelectedApp(sharingApp, urlString, collectionName) } @@ -213,14 +214,14 @@ class CollectionTest : TestSetup() { title = collectionName, ) - homeScreen { - verifyCollectionIsDisplayed(composeTestRule, collectionName) - }.expandCollection(composeTestRule, collectionName) { - clickCollectionThreeDotButton(composeTestRule) - selectDeleteCollection(composeTestRule) + homeScreen(composeTestRule) { + verifyCollectionIsDisplayed(collectionName) + }.expandCollection(collectionName) { + clickCollectionThreeDotButton() + selectDeleteCollection() } - homeScreen { - verifyNoCollectionsText(composeTestRule) + homeScreen(composeTestRule) { + verifyNoCollectionsText() } } @@ -237,18 +238,19 @@ class CollectionTest : TestSetup() { title = collectionName, ) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(secondWebPage.url) { verifyPageContent(secondWebPage.content) }.openThreeDotMenu { - }.openSaveToCollection { + clickTheMoreButton() + }.clickSaveToCollectionButton { }.selectExistingCollection(collectionName) { verifySnackBarText("Tab saved") - }.goToHomescreen(composeTestRule) { - verifyCollectionIsDisplayed(composeTestRule, collectionName) - }.expandCollection(composeTestRule, collectionName) { - verifyTabSavedInCollection(composeTestRule, firstWebPage.title) - verifyTabSavedInCollection(composeTestRule, secondWebPage.title) + }.goToHomescreen { + verifyCollectionIsDisplayed(collectionName) + }.expandCollection(collectionName) { + verifyTabSavedInCollection(firstWebPage.title) + verifyTabSavedInCollection(secondWebPage.title) } } @@ -264,17 +266,17 @@ class CollectionTest : TestSetup() { title = collectionName, ) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(secondWebPage.url) { - }.goToHomescreen(composeTestRule) { - verifyCollectionIsDisplayed(composeTestRule, collectionName) - }.expandCollection(composeTestRule, collectionName) { - clickCollectionThreeDotButton(composeTestRule) - selectAddTabToCollection(composeTestRule) + }.goToHomescreen { + verifyCollectionIsDisplayed(collectionName) + }.expandCollection(collectionName) { + clickCollectionThreeDotButton() + selectAddTabToCollection() verifyTabsSelectedCounterText(1) saveTabsSelectedForCollection() verifySnackBarText("Tab saved") - verifyTabSavedInCollection(composeTestRule, secondWebPage.title) + verifyTabSavedInCollection(secondWebPage.title) } } @@ -289,15 +291,15 @@ class CollectionTest : TestSetup() { title = collectionName, ) - homeScreen { - verifyCollectionIsDisplayed(composeTestRule, collectionName) - }.expandCollection(composeTestRule, collectionName) { - clickCollectionThreeDotButton(composeTestRule) - selectRenameCollection(composeTestRule) + homeScreen(composeTestRule) { + verifyCollectionIsDisplayed(collectionName) + }.expandCollection(collectionName) { + clickCollectionThreeDotButton() + selectRenameCollection() }.typeCollectionNameAndSave(secondCollectionName) {} - homeScreen { - verifyCollectionIsDisplayed(composeTestRule, secondCollectionName) + homeScreen(composeTestRule) { + verifyCollectionIsDisplayed(secondCollectionName) } } @@ -307,7 +309,7 @@ class CollectionTest : TestSetup() { val firstWebPage = mockWebServer.getGenericAsset(1) val secondWebPage = mockWebServer.getGenericAsset(2) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(firstWebPage.url) { }.openTabDrawer(composeTestRule) { }.openNewTab { @@ -320,8 +322,8 @@ class CollectionTest : TestSetup() { verifySnackBarText("Collection saved") waitUntilSnackbarGone() }.closeTabDrawer { - }.goToHomescreen(composeTestRule) { - verifyCollectionIsDisplayed(composeTestRule, collectionName) + }.goToHomescreen { + verifyCollectionIsDisplayed(collectionName) } } @@ -336,14 +338,14 @@ class CollectionTest : TestSetup() { title = collectionName, ) - homeScreen { - verifyCollectionIsDisplayed(composeTestRule, collectionName) - }.expandCollection(composeTestRule, collectionName) { - verifyTabSavedInCollection(composeTestRule, webPage.title, true) + homeScreen(composeTestRule) { + verifyCollectionIsDisplayed(collectionName) + }.expandCollection(collectionName) { + verifyTabSavedInCollection(webPage.title, true) removeTabFromCollection(webPage.title) } - homeScreen { - verifyCollectionIsDisplayed(composeTestRule, collectionName, false) + homeScreen(composeTestRule) { + verifyCollectionIsDisplayed(collectionName, false) } } @@ -360,13 +362,13 @@ class CollectionTest : TestSetup() { title = collectionName, ) - homeScreen { - verifyCollectionIsDisplayed(composeTestRule, collectionName) - }.expandCollection(composeTestRule, collectionName) { - verifyTabSavedInCollection(composeTestRule, testPage1.title, true) - verifyTabSavedInCollection(composeTestRule, testPage2.title, true) + homeScreen(composeTestRule) { + verifyCollectionIsDisplayed(collectionName) + }.expandCollection(collectionName) { + verifyTabSavedInCollection(testPage1.title, true) + verifyTabSavedInCollection(testPage2.title, true) swipeTabLeft(testPage2.title) - verifyTabSavedInCollection(composeTestRule, testPage2.title, false) + verifyTabSavedInCollection(testPage2.title, false) } } @@ -383,13 +385,13 @@ class CollectionTest : TestSetup() { title = collectionName, ) - homeScreen { - verifyCollectionIsDisplayed(composeTestRule, collectionName) - }.expandCollection(composeTestRule, collectionName) { - verifyTabSavedInCollection(composeTestRule, testPage1.title, true) - verifyTabSavedInCollection(composeTestRule, testPage2.title, true) + homeScreen(composeTestRule) { + verifyCollectionIsDisplayed(collectionName) + }.expandCollection(collectionName) { + verifyTabSavedInCollection(testPage1.title, true) + verifyTabSavedInCollection(testPage2.title, true) swipeTabRight(testPage2.title) - verifyTabSavedInCollection(composeTestRule, testPage2.title, false) + verifyTabSavedInCollection(testPage2.title, false) } } @@ -404,15 +406,15 @@ class CollectionTest : TestSetup() { title = collectionName, ) - homeScreen { - verifyCollectionIsDisplayed(composeTestRule, collectionName) - }.expandCollection(composeTestRule, collectionName) { - verifyTabSavedInCollection(composeTestRule, testPage.title, true) + homeScreen(composeTestRule) { + verifyCollectionIsDisplayed(collectionName) + }.expandCollection(collectionName) { + verifyTabSavedInCollection(testPage.title, true) swipeTabLeft(testPage.title) - verifyTabSavedInCollection(composeTestRule, testPage.title, false) + verifyTabSavedInCollection(testPage.title, false) } - homeScreen { - verifyCollectionIsDisplayed(composeTestRule, collectionName, false) + homeScreen(composeTestRule) { + verifyCollectionIsDisplayed(collectionName, false) } } @@ -422,7 +424,7 @@ class CollectionTest : TestSetup() { val firstWebPage = mockWebServer.getGenericAsset(1) val secondWebPage = mockWebServer.getGenericAsset(2) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(firstWebPage.url) { waitForPageToLoad() }.openTabDrawer(composeTestRule) { @@ -444,10 +446,10 @@ class CollectionTest : TestSetup() { composeTabDrawer(composeTestRule) { }.closeTabDrawer { - }.goToHomescreen(composeTestRule) { - }.expandCollection(composeTestRule, collectionName) { - verifyTabSavedInCollection(composeTestRule, firstWebPage.title) - verifyTabSavedInCollection(composeTestRule, secondWebPage.title) + }.goToHomescreen { + }.expandCollection(collectionName) { + verifyTabSavedInCollection(firstWebPage.title) + verifyTabSavedInCollection(secondWebPage.title) } } @@ -456,7 +458,7 @@ class CollectionTest : TestSetup() { fun navigateBackInCollectionFlowTest() { val webPage = mockWebServer.getGenericAsset(1) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(webPage.url) { }.openTabDrawer(composeTestRule) { createCollection(webPage.title, collectionName = collectionName) @@ -464,14 +466,16 @@ class CollectionTest : TestSetup() { waitUntilSnackbarGone() }.closeTabDrawer { }.openThreeDotMenu { - }.openSaveToCollection { + clickTheMoreButton() + }.clickSaveToCollectionButton { verifySelectCollectionScreen() goBackInCollectionFlow() } - browserScreen { + browserScreen(composeTestRule) { }.openThreeDotMenu { - }.openSaveToCollection { + clickTheMoreButton() + }.clickSaveToCollectionButton { verifySelectCollectionScreen() clickAddNewCollection() verifyCollectionNameTextField() @@ -480,7 +484,7 @@ class CollectionTest : TestSetup() { goBackInCollectionFlow() } // verify the browser layout is visible - browserScreen { + browserScreen(composeTestRule) { verifyMenuButton() } } diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ContextMenusTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ContextMenusTest.kt @@ -69,10 +69,10 @@ class ContextMenusTest : TestSetup() { val pageLinks = mockWebServer.getGenericAsset(4) val genericURL = mockWebServer.getGenericAsset(1) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(pageLinks.url) { mDevice.waitForIdle() - longClickPageObject(itemWithText("Link 1")) + longClickPageObject(composeTestRule, itemWithText("Link 1")) verifyContextMenuForLocalHostLinks(genericURL.url) clickContextMenuItem("Open link in new tab") verifySnackBarText("New tab opened") @@ -91,10 +91,10 @@ class ContextMenusTest : TestSetup() { val pageLinks = mockWebServer.getGenericAsset(4) val genericURL = mockWebServer.getGenericAsset(2) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(pageLinks.url) { mDevice.waitForIdle() - longClickPageObject(itemWithText("Link 2")) + longClickPageObject(composeTestRule, itemWithText("Link 2")) verifyContextMenuForLocalHostLinks(genericURL.url) clickContextMenuItem("Open link in private tab") verifySnackBarText("New private tab opened") @@ -112,10 +112,10 @@ class ContextMenusTest : TestSetup() { val pageLinks = mockWebServer.getGenericAsset(4) val genericURL = mockWebServer.getGenericAsset(3) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(pageLinks.url) { mDevice.waitForIdle() - longClickPageObject(itemWithText("Link 3")) + longClickPageObject(composeTestRule, itemWithText("Link 3")) verifyContextMenuForLocalHostLinks(genericURL.url) clickContextMenuItem("Copy link") verifySnackBarText("Link copied to clipboard") @@ -130,10 +130,10 @@ class ContextMenusTest : TestSetup() { val pageLinks = mockWebServer.getGenericAsset(4) val genericURL = mockWebServer.getGenericAsset(3) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(pageLinks.url) { mDevice.waitForIdle() - longClickPageObject(itemWithText("Link 3")) + longClickPageObject(composeTestRule, itemWithText("Link 3")) verifyContextMenuForLocalHostLinks(genericURL.url) clickContextMenuItem("Copy link text") verifySnackBarText("Link text copied to clipboard") @@ -146,10 +146,10 @@ class ContextMenusTest : TestSetup() { val pageLinks = mockWebServer.getGenericAsset(4) val genericURL = mockWebServer.getGenericAsset(1) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(pageLinks.url) { mDevice.waitForIdle() - longClickPageObject(itemWithText("Link 1")) + longClickPageObject(composeTestRule, itemWithText("Link 1")) verifyContextMenuForLocalHostLinks(genericURL.url) clickContextMenuItem("Share link") shareOverlay { @@ -165,10 +165,10 @@ class ContextMenusTest : TestSetup() { val pageLinks = mockWebServer.getGenericAsset(4) val imageResource = mockWebServer.imageAsset - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(pageLinks.url) { mDevice.waitForIdle() - longClickPageObject(itemWithText("test_link_image")) + longClickPageObject(composeTestRule, itemWithText("test_link_image")) verifyLinkImageContextMenuItems(imageResource.url) clickContextMenuItem("Open image in new tab") verifySnackBarText("New tab opened") @@ -183,10 +183,10 @@ class ContextMenusTest : TestSetup() { val pageLinks = mockWebServer.getGenericAsset(4) val imageResource = mockWebServer.imageAsset - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(pageLinks.url) { mDevice.waitForIdle() - longClickPageObject(itemWithText("test_link_image")) + longClickPageObject(composeTestRule, itemWithText("test_link_image")) verifyLinkImageContextMenuItems(imageResource.url) clickContextMenuItem("Copy image location") verifySnackBarText("Link copied to clipboard") @@ -202,15 +202,15 @@ class ContextMenusTest : TestSetup() { val pageLinks = mockWebServer.getGenericAsset(4) val imageResource = mockWebServer.imageAsset - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(pageLinks.url) { mDevice.waitForIdle() - longClickPageObject(itemWithText("test_link_image")) + longClickPageObject(composeTestRule, itemWithText("test_link_image")) verifyLinkImageContextMenuItems(imageResource.url) clickContextMenuItem("Save image") } - downloadRobot { + downloadRobot(composeTestRule) { verifyDownloadCompleteSnackbar(fileName = "rabbit.jpg") clickSnackbarButton(composeTestRule = composeTestRule, "OPEN") verifyPhotosAppOpens() @@ -224,16 +224,16 @@ class ContextMenusTest : TestSetup() { val genericURL = mockWebServer.getGenericAsset(1) val imageResource = mockWebServer.imageAsset - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(pageLinks.url) { mDevice.waitForIdle() - longClickPageObject(itemWithText("Link 1")) + longClickPageObject(composeTestRule, itemWithText("Link 1")) verifyContextMenuForLocalHostLinks(genericURL.url) dismissContentContextMenu() - longClickPageObject(itemWithText("test_link_image")) + longClickPageObject(composeTestRule, itemWithText("test_link_image")) verifyLinkImageContextMenuItems(imageResource.url) dismissContentContextMenu() - longClickPageObject(itemWithText("test_no_link_image")) + longClickPageObject(composeTestRule, itemWithText("test_no_link_image")) verifyNoLinkImageContextMenuItems(imageResource.url) } } @@ -243,12 +243,12 @@ class ContextMenusTest : TestSetup() { fun verifyPDFContextMenuLinkVariationsTest() { val genericURL = mockWebServer.getGenericAsset(3) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(genericURL.url) { - clickPageObject(itemWithText("PDF form file")) + clickPageObject(composeTestRule, itemWithText("PDF form file")) waitForPageToLoad() - clickPageObject(itemWithResIdAndText("android:id/button2", "Cancel")) - longClickPageObject(itemWithText("Wikipedia link")) + clickPageObject(composeTestRule, itemWithResIdAndText("android:id/button2", "Cancel")) + longClickPageObject(composeTestRule, itemWithText("Wikipedia link")) verifyContextMenuForLinksToOtherHosts("wikipedia.org".toUri()) dismissContentContextMenu() // Some options are missing from the linked and non liked images context menus in PDF files @@ -264,9 +264,9 @@ class ContextMenusTest : TestSetup() { fun verifyOpenLinkInAppContextMenuOptionTest() { val defaultWebPage = mockWebServer.externalLinksAsset - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(defaultWebPage.url) { - longClickPageObject(itemContainingText("Youtube full link")) + longClickPageObject(composeTestRule, itemContainingText("Youtube full link")) verifyContextMenuForLinksToOtherApps("youtube.com") clickContextMenuItem("Open link in external app") assertExternalAppOpens(YOUTUBE_APP) diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CookieBannerBlockerTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CookieBannerBlockerTest.kt @@ -4,6 +4,7 @@ package org.mozilla.fenix.ui +import androidx.compose.ui.test.junit4.AndroidComposeTestRule import androidx.core.net.toUri import org.junit.Ignore import org.junit.Rule @@ -24,7 +25,12 @@ import org.mozilla.fenix.ui.robots.navigationToolbar @Ignore("Disabled feature in: https://bugzilla.mozilla.org/show_bug.cgi?id=1940418") class CookieBannerBlockerTest : TestSetup() { @get:Rule - val activityTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides(skipOnboarding = true) + val composeTestRule = + AndroidComposeTestRule( + HomeActivityIntentTestRule.withDefaultSettingsOverrides( + skipOnboarding = true, + ), + ) { it.activity } @get:Rule val memoryLeaksRule = DetectMemoryLeaksRule() @@ -34,9 +40,9 @@ class CookieBannerBlockerTest : TestSetup() { @Test fun verifyCookieBannerBlockerSettingsOptionTest() { runWithCondition(appContext.settings().shouldUseCookieBannerPrivateMode) { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { verifyCookieBannerBlockerButton(enabled = true) } } @@ -47,10 +53,10 @@ class CookieBannerBlockerTest : TestSetup() { @Test fun verifyCFRAfterBlockingTheCookieBanner() { runWithCondition(appContext.settings().shouldUseCookieBannerPrivateMode) { - homeScreen { + homeScreen(composeTestRule) { }.togglePrivateBrowsingMode() - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser("materiel.net".toUri()) { verifyCookieBannerExists(exists = false) verifyCookieBannerBlockerCFRExists(exists = true) diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CrashReportingTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CrashReportingTest.kt @@ -5,6 +5,7 @@ package org.mozilla.fenix.ui import androidx.compose.ui.test.junit4.AndroidComposeTestRule +import androidx.core.net.toUri import org.junit.Rule import org.junit.Test import org.mozilla.fenix.customannotations.SmokeTest @@ -21,7 +22,7 @@ import org.mozilla.fenix.ui.robots.navigationToolbar class CrashReportingTest : TestSetup() { @get:Rule - val activityTestRule = AndroidComposeTestRule( + val composeTestRule = AndroidComposeTestRule( HomeActivityIntentTestRule( isPocketEnabled = false, isWallpaperOnboardingEnabled = false, @@ -34,11 +35,10 @@ class CrashReportingTest : TestSetup() { // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/308906 @Test fun closeTabFromCrashedTabReporterTest() { - homeScreen { - }.openNavigationToolbar { - }.openTabCrashReporter { + navigationToolbar(composeTestRule) { + }.enterURLAndEnterToBrowser("about:crashcontent".toUri()) { }.clickTabCrashedCloseButton { - }.openTabDrawer(activityTestRule) { + }.openTabDrawer { verifyNoOpenTabsInNormalBrowsing() } } @@ -48,13 +48,12 @@ class CrashReportingTest : TestSetup() { fun restoreTabFromTabCrashedReporterTest() { val website = mockWebServer.getGenericAsset(1) - homeScreen { - }.openNavigationToolbar { - }.enterURLAndEnterToBrowser(website.url) {} - - navigationToolbar { - }.openTabCrashReporter { - clickPageObject(itemWithResId("$packageName:id/restoreTabButton")) + navigationToolbar(composeTestRule) { + }.enterURLAndEnterToBrowser(website.url) { + } + navigationToolbar(composeTestRule) { + }.enterURLAndEnterToBrowser("about:crashcontent".toUri()) { + clickPageObject(composeTestRule, itemWithResId("$packageName:id/restoreTabButton")) verifyPageContent(website.content) } } @@ -66,25 +65,24 @@ class CrashReportingTest : TestSetup() { val firstWebPage = mockWebServer.getGenericAsset(1) val secondWebPage = mockWebServer.getGenericAsset(2) - homeScreen { - }.openNavigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(firstWebPage.url) { mDevice.waitForIdle() - }.openTabDrawer(activityTestRule) { + }.openTabDrawer(composeTestRule) { }.openNewTab { }.submitQuery(secondWebPage.url.toString()) { waitForPageToLoad() } - navigationToolbar { - }.openTabCrashReporter { + navigationToolbar(composeTestRule) { + }.enterURLAndEnterToBrowser("about:crashcontent".toUri()) { verifyTabCrashReporterView() - }.openTabDrawer(activityTestRule) { + }.openTabDrawer(composeTestRule) { verifyExistingOpenTabs(firstWebPage.title) verifyExistingOpenTabs(secondWebPage.title) }.closeTabDrawer { - }.goToHomescreen(activityTestRule) { - verifyExistingTopSitesList(activityTestRule) + }.goToHomescreen { + verifyExistingTopSitesList() }.openThreeDotMenu { verifySettingsButton() } diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CreditCardAutofillTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CreditCardAutofillTest.kt @@ -5,6 +5,7 @@ package org.mozilla.fenix.ui import androidx.compose.ui.test.junit4.AndroidComposeTestRule +import androidx.test.espresso.Espresso.closeSoftKeyboard import org.junit.Rule import org.junit.Test import org.mozilla.fenix.customannotations.SkipLeaks @@ -17,6 +18,7 @@ import org.mozilla.fenix.helpers.MatcherHelper.itemWithResIdContainingText import org.mozilla.fenix.helpers.TestAssetHelper.creditCardFormAsset import org.mozilla.fenix.helpers.TestHelper.exitMenu import org.mozilla.fenix.helpers.TestHelper.packageName +import org.mozilla.fenix.helpers.TestHelper.waitForAppWindowToBeUpdated import org.mozilla.fenix.helpers.TestSetup import org.mozilla.fenix.helpers.perf.DetectMemoryLeaksRule import org.mozilla.fenix.ui.robots.clickPageObject @@ -58,9 +60,9 @@ class CreditCardAutofillTest : TestSetup() { fun verifyCreditCardAutofillTest() { val creditCardFormPage = mockWebServer.creditCardFormAsset - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openAutofillSubMenu(composeTestRule) { clickAddCreditCardButton() fillAndSaveCreditCard( @@ -74,13 +76,14 @@ class CreditCardAutofillTest : TestSetup() { clickSecuredCreditCardsLaterButton() }.goBackToAutofillSettings { }.goBack { - }.goBack { + }.goBack(composeTestRule) { } - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(creditCardFormPage.url) { clickCreditCardNumberTextBox() - clickPageObject(itemWithResId("$packageName:id/select_credit_card_header")) + clickPageObject(composeTestRule, itemWithResId("$packageName:id/select_credit_card_header")) clickPageObject( + composeTestRule, itemWithResIdContainingText( "$packageName:id/credit_card_number", MockCreditCard1.MOCK_LAST_CARD_DIGITS, @@ -94,9 +97,9 @@ class CreditCardAutofillTest : TestSetup() { @SmokeTest @Test fun deleteSavedCreditCardUsingToolbarButtonTest() { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openAutofillSubMenu(composeTestRule) { clickAddCreditCardButton() fillAndSaveCreditCard( @@ -121,9 +124,9 @@ class CreditCardAutofillTest : TestSetup() { @SmokeTest @Test fun deleteSavedCreditCardUsingMenuButtonTest() { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openAutofillSubMenu(composeTestRule) { clickAddCreditCardButton() fillAndSaveCreditCard( @@ -147,9 +150,9 @@ class CreditCardAutofillTest : TestSetup() { // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/1512788 @Test fun verifyCreditCardsSectionTest() { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openAutofillSubMenu(composeTestRule) { verifyCreditCardsAutofillSection(true, false) clickAddCreditCardButton() @@ -173,9 +176,9 @@ class CreditCardAutofillTest : TestSetup() { fun verifyManageCreditCardsPromptOptionTest() { val creditCardFormPage = mockWebServer.creditCardFormAsset - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openAutofillSubMenu(composeTestRule) { clickAddCreditCardButton() fillAndSaveCreditCard( @@ -188,12 +191,12 @@ class CreditCardAutofillTest : TestSetup() { exitMenu() - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(creditCardFormPage.url) { clickCreditCardNumberTextBox() - clickPageObject(itemWithResId("$packageName:id/select_credit_card_header")) - }.clickManageCreditCardsButton(composeTestRule) { - }.goBackToBrowser { + clickPageObject(composeTestRule, itemWithResId("$packageName:id/select_credit_card_header")) + }.clickManageCreditCardsButton { + }.goBackToBrowser(composeTestRule) { verifySelectCreditCardPromptExists(false) } } @@ -203,9 +206,9 @@ class CreditCardAutofillTest : TestSetup() { fun verifyCreditCardsAutofillToggleTest() { val creditCardFormPage = mockWebServer.creditCardFormAsset - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openAutofillSubMenu(composeTestRule) { verifyCreditCardsAutofillSection(true, false) clickAddCreditCardButton() @@ -219,12 +222,14 @@ class CreditCardAutofillTest : TestSetup() { exitMenu() - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(creditCardFormPage.url) { clickCreditCardNumberTextBox() verifySelectCreditCardPromptExists(true) + closeSoftKeyboard() + waitForAppWindowToBeUpdated() }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openAutofillSubMenu(composeTestRule) { clickSaveAndAutofillCreditCardsOption() verifyCreditCardsAutofillSection(false, true) @@ -232,7 +237,7 @@ class CreditCardAutofillTest : TestSetup() { exitMenu() - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(creditCardFormPage.url) { clickCreditCardNumberTextBox() verifySelectCreditCardPromptExists(false) @@ -242,9 +247,9 @@ class CreditCardAutofillTest : TestSetup() { // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/1512795 @Test fun verifyEditCardsViewTest() { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openAutofillSubMenu(composeTestRule) { verifyCreditCardsAutofillSection(true, false) clickAddCreditCardButton() @@ -280,9 +285,9 @@ class CreditCardAutofillTest : TestSetup() { fun verifyEditedCardIsSavedTest() { val creditCardFormPage = mockWebServer.creditCardFormAsset - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openAutofillSubMenu(composeTestRule) { verifyCreditCardsAutofillSection(true, false) clickAddCreditCardButton() @@ -309,11 +314,12 @@ class CreditCardAutofillTest : TestSetup() { exitMenu() - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(creditCardFormPage.url) { clickCreditCardNumberTextBox() - clickPageObject(itemWithResId("$packageName:id/select_credit_card_header")) + clickPageObject(composeTestRule, itemWithResId("$packageName:id/select_credit_card_header")) clickPageObject( + composeTestRule, itemWithResIdContainingText( "$packageName:id/credit_card_number", MockCreditCard2.MOCK_LAST_CARD_DIGITS, @@ -327,9 +333,9 @@ class CreditCardAutofillTest : TestSetup() { @Test @SkipLeaks(reasons = ["https://bugzilla.mozilla.org/show_bug.cgi?id=1935999"]) fun verifyCreditCardCannotBeSavedWithoutCardNumberOrNameTest() { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openAutofillSubMenu(composeTestRule) { verifyCreditCardsAutofillSection(true, false) clickAddCreditCardButton() @@ -364,9 +370,9 @@ class CreditCardAutofillTest : TestSetup() { fun verifyMultipleCreditCardsCanBeAddedTest() { val creditCardFormPage = mockWebServer.creditCardFormAsset - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openAutofillSubMenu(composeTestRule) { verifyCreditCardsAutofillSection(true, false) clickAddCreditCardButton() @@ -397,15 +403,16 @@ class CreditCardAutofillTest : TestSetup() { exitMenu() - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(creditCardFormPage.url) { clickCreditCardNumberTextBox() - clickPageObject(itemWithResId("$packageName:id/select_credit_card_header")) + clickPageObject(composeTestRule, itemWithResId("$packageName:id/select_credit_card_header")) verifyCreditCardSuggestion( MockCreditCard1.MOCK_LAST_CARD_DIGITS, MockCreditCard2.MOCK_LAST_CARD_DIGITS, ) clickPageObject( + composeTestRule, itemWithResIdContainingText( "$packageName:id/credit_card_number", MockCreditCard2.MOCK_LAST_CARD_DIGITS, @@ -420,7 +427,7 @@ class CreditCardAutofillTest : TestSetup() { fun verifyDoNotSaveCreditCardFromPromptTest() { val creditCardFormPage = mockWebServer.creditCardFormAsset - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(creditCardFormPage.url) { fillAndSaveCreditCard( MockCreditCard1.MOCK_CREDIT_CARD_NUMBER, @@ -430,7 +437,7 @@ class CreditCardAutofillTest : TestSetup() { clickNegativeSaveCreditCardPromptButton() verifyUpdateOrSaveCreditCardPromptExists(exists = false) }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openAutofillSubMenu(composeTestRule) { verifyCreditCardsAutofillSection(true, false) } @@ -441,17 +448,17 @@ class CreditCardAutofillTest : TestSetup() { fun verifySaveCreditCardFromPromptTest() { val creditCardFormPage = mockWebServer.creditCardFormAsset - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(creditCardFormPage.url) { fillAndSaveCreditCard( MockCreditCard1.MOCK_CREDIT_CARD_NUMBER, MockCreditCard1.MOCK_NAME_ON_CARD, MockCreditCard1.MOCK_EXPIRATION_MONTH_AND_YEAR, ) - clickPageObject(itemWithResId("$packageName:id/save_confirm")) + clickPageObject(composeTestRule, itemWithResId("$packageName:id/save_confirm")) verifyUpdateOrSaveCreditCardPromptExists(exists = false) }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openAutofillSubMenu(composeTestRule) { verifyCreditCardsAutofillSection(true, true) clickManageSavedCreditCardsButton() @@ -468,9 +475,9 @@ class CreditCardAutofillTest : TestSetup() { fun verifyCancelCreditCardUpdatePromptTest() { val creditCardFormPage = mockWebServer.creditCardFormAsset - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openAutofillSubMenu(composeTestRule) { verifyCreditCardsAutofillSection(true, false) clickAddCreditCardButton() @@ -487,11 +494,12 @@ class CreditCardAutofillTest : TestSetup() { exitMenu() - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(creditCardFormPage.url) { clickCreditCardNumberTextBox() - clickPageObject(itemWithResId("$packageName:id/select_credit_card_header")) + clickPageObject(composeTestRule, itemWithResId("$packageName:id/select_credit_card_header")) clickPageObject( + composeTestRule, itemWithResIdContainingText( "$packageName:id/credit_card_number", MockCreditCard2.MOCK_LAST_CARD_DIGITS, @@ -503,7 +511,7 @@ class CreditCardAutofillTest : TestSetup() { clickNegativeSaveCreditCardPromptButton() verifyUpdateOrSaveCreditCardPromptExists(false) }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openAutofillSubMenu(composeTestRule) { verifyCreditCardsAutofillSection(true, true) clickManageSavedCreditCardsButton() @@ -519,9 +527,9 @@ class CreditCardAutofillTest : TestSetup() { fun verifyConfirmCreditCardUpdatePromptTest() { val creditCardFormPage = mockWebServer.creditCardFormAsset - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openAutofillSubMenu(composeTestRule) { verifyCreditCardsAutofillSection(true, false) clickAddCreditCardButton() @@ -538,11 +546,12 @@ class CreditCardAutofillTest : TestSetup() { exitMenu() - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(creditCardFormPage.url) { clickCreditCardNumberTextBox() - clickPageObject(itemWithResId("$packageName:id/select_credit_card_header")) + clickPageObject(composeTestRule, itemWithResId("$packageName:id/select_credit_card_header")) clickPageObject( + composeTestRule, itemWithResIdContainingText( "$packageName:id/credit_card_number", MockCreditCard2.MOCK_LAST_CARD_DIGITS, @@ -551,10 +560,10 @@ class CreditCardAutofillTest : TestSetup() { verifyAutofilledCreditCard(MockCreditCard2.MOCK_CREDIT_CARD_NUMBER) changeCreditCardExpiryDate(MockCreditCard1.MOCK_EXPIRATION_MONTH_AND_YEAR) clickCreditCardFormSubmitButton() - clickPageObject(itemWithResId("$packageName:id/save_confirm")) + clickPageObject(composeTestRule, itemWithResId("$packageName:id/save_confirm")) verifyUpdateOrSaveCreditCardPromptExists(false) }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openAutofillSubMenu(composeTestRule) { verifyCreditCardsAutofillSection(true, true) clickManageSavedCreditCardsButton() @@ -568,9 +577,9 @@ class CreditCardAutofillTest : TestSetup() { // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/1512791 @Test fun verifyCreditCardRedirectionsToAutofillSectionAfterInterruptionTest() { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openAutofillSubMenu(composeTestRule) { verifyCreditCardsAutofillSection(true, false) clickAddCreditCardButton() diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CustomTabsTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/CustomTabsTest.kt @@ -6,11 +6,13 @@ package org.mozilla.fenix.ui +import androidx.compose.ui.test.junit4.AndroidComposeTestRule import androidx.core.net.toUri import androidx.test.rule.ActivityTestRule import org.junit.Rule import org.junit.Test import org.mozilla.fenix.IntentReceiverActivity +import org.mozilla.fenix.customannotations.SkipLeaks import org.mozilla.fenix.customannotations.SmokeTest import org.mozilla.fenix.helpers.AppAndSystemHelper.openAppFromExternalLink import org.mozilla.fenix.helpers.DataGenerationHelper.createCustomTabIntent @@ -29,10 +31,7 @@ import org.mozilla.fenix.ui.robots.clickPageObject import org.mozilla.fenix.ui.robots.customTabScreen import org.mozilla.fenix.ui.robots.enhancedTrackingProtection import org.mozilla.fenix.ui.robots.homeScreen -import org.mozilla.fenix.ui.robots.navigationToolbar import org.mozilla.fenix.ui.robots.notificationShade -import org.mozilla.fenix.ui.robots.openEditURLView -import org.mozilla.fenix.ui.robots.searchScreen class CustomTabsTest : TestSetup() { private val customMenuItem = "TestMenuItem" @@ -45,7 +44,10 @@ class CustomTabsTest : TestSetup() { private val loginPage = "https://mozilla-mobile.github.io/testapp/loginForm" @get:Rule - val activityTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides() + val composeTestRule = + AndroidComposeTestRule( + HomeActivityIntentTestRule.withDefaultSettingsOverrides(), + ) { it.activity } @get:Rule val intentReceiverActivityTestRule = ActivityTestRule( @@ -68,23 +70,23 @@ class CustomTabsTest : TestSetup() { ), ) - customTabScreen { + customTabScreen(composeTestRule) { waitForPageToLoad(pageLoadWaitingTime = waitingTimeLong) fillAndSubmitLoginCredentials("mozilla", "firefox") } - browserScreen { + browserScreen(composeTestRule) { verifySaveLoginPromptIsDisplayed() - clickPageObject(itemWithText("Save")) + clickPageObject(composeTestRule, itemWithText("Save")) } openAppFromExternalLink(loginPage) - browserScreen { + browserScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openLoginsAndPasswordSubMenu { - }.openSavedLogins { + }.openSavedLogins(composeTestRule) { verifySecurityPromptForLogins() tapSetupLater() verifySavedLoginsSectionUsername("mozilla") @@ -103,17 +105,15 @@ class CustomTabsTest : TestSetup() { ), ) - customTabScreen { - longCLickAndCopyToolbarUrl() + customTabScreen(composeTestRule) { + verifyCustomTabUrl(customTabPage.url.toString()) + longClickAndCopyToolbarUrl() } openAppFromExternalLink(customTabPage.url.toString()) - navigationToolbar { - openEditURLView() - } - - searchScreen { + browserScreen(composeTestRule) { + }.openSearch { clickClearButton() longClickToolbar() clickPasteText() @@ -135,11 +135,11 @@ class CustomTabsTest : TestSetup() { ), ) - customTabScreen { + customTabScreen(composeTestRule) { waitForPageToLoad(pageLoadWaitingTime = waitingTimeLong) } - browserScreen { + browserScreen(composeTestRule) { }.clickDownloadLink(downloadFile) { verifyDownloadPrompt(downloadFile) }.clickDownload { @@ -157,6 +157,7 @@ class CustomTabsTest : TestSetup() { @SmokeTest @Test fun verifyCustomTabMenuItemsTest() { + val customMenuItem = "TestMenuItem" val customTabPage = mockWebServer.getGenericAsset(1) intentReceiverActivityTestRule.launchActivity( @@ -166,17 +167,10 @@ class CustomTabsTest : TestSetup() { ), ) - customTabScreen { + customTabScreen(composeTestRule) { verifyCustomTabCloseButton() }.openMainMenu { - verifyPoweredByTextIsDisplayed() - verifyCustomMenuItem(customMenuItem) - verifyDesktopSiteButtonExists() - verifyFindInPageButtonExists() - verifyOpenInBrowserButtonExists() - verifyBackButtonExists() - verifyForwardButtonExists() - verifyRefreshButtonExists() + verifyCustomTabsMainMenuItems(customMenuItem, true) } } @@ -193,31 +187,15 @@ class CustomTabsTest : TestSetup() { ), ) - customTabScreen { + customTabScreen(composeTestRule) { verifyCustomTabCloseButton() }.openMainMenu { - }.clickOpenInBrowserButton { + }.clickOpenInBrowserButtonFromRedesignedToolbar { + verifyPageContent(customTabPage.content) verifyTabCounter("1") } } - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2239548 - @Test - fun shareCustomTabUsingToolbarButtonTest() { - val customTabPage = mockWebServer.getGenericAsset(1) - - intentReceiverActivityTestRule.launchActivity( - createCustomTabIntent( - customTabPage.url.toString(), - ), - ) - - customTabScreen { - }.clickShareButton { - verifyShareTabLayout() - } - } - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/249643 @Test fun verifyCustomTabViewItemsTest() { @@ -230,17 +208,16 @@ class CustomTabsTest : TestSetup() { ), ) - customTabScreen { + customTabScreen(composeTestRule) { verifyCustomTabCloseButton() verifyCustomTabsSiteInfoButton() verifyCustomTabToolbarTitle(customTabPage.title) verifyCustomTabUrl(customTabPage.url.toString()) verifyCustomTabActionButton(customTabActionButton) - verifyCustomTabsShareButton() verifyMainMenuButton() clickCustomTabCloseButton() } - homeScreen { + homeScreen(composeTestRule) { verifyHomeScreenAppBarItems() } } @@ -257,25 +234,25 @@ class CustomTabsTest : TestSetup() { ), ) - customTabScreen { - clickPageObject(itemWithText("PDF form file")) - clickPageObject(itemWithResIdAndText("android:id/button2", "Cancel")) + customTabScreen(composeTestRule) { + clickPageObject(composeTestRule, itemWithText("PDF form file")) + clickPageObject(composeTestRule, itemWithResIdAndText("android:id/button2", "Cancel")) waitForPageToLoad() verifyPDFReaderToolbarItems() verifyCustomTabCloseButton() verifyCustomTabsSiteInfoButton() - verifyCustomTabToolbarTitle("pdfForm.pdf") + verifyCustomTabToolbarTitle("Untitled document - pdfForm.pdf") verifyCustomTabUrl(pdfFormResource.url.toString()) - verifyCustomTabsShareButton() verifyMainMenuButton() clickCustomTabCloseButton() } - homeScreen { + homeScreen(composeTestRule) { verifyHomeScreenAppBarItems() } } // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2239117 + @SkipLeaks(reasons = ["https://bugzilla.mozilla.org/show_bug.cgi?id=2006672"]) @Test fun verifyCustomTabETPSheetAndToggleTest() { val customTabPage = mockWebServer.getGenericAsset(1) @@ -287,19 +264,19 @@ class CustomTabsTest : TestSetup() { ), ) - enhancedTrackingProtection { - }.openEnhancedTrackingProtectionSheet { + browserScreen(composeTestRule) { + }.openSiteSecuritySheet { verifyEnhancedTrackingProtectionSheetStatus(status = "ON", state = true) }.toggleEnhancedTrackingProtectionFromSheet { verifyEnhancedTrackingProtectionSheetStatus(status = "OFF", state = false) - }.closeEnhancedTrackingProtectionSheet { + }.closeSiteSecuritySheet(composeTestRule) { } openAppFromExternalLink(customTabPage.url.toString()) - browserScreen { + browserScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openEnhancedTrackingProtectionSubMenu { switchEnhancedTrackingProtectionToggle() verifyEnhancedTrackingProtectionOptionsEnabled(enabled = false) @@ -307,7 +284,7 @@ class CustomTabsTest : TestSetup() { exitMenu() - browserScreen { + browserScreen(composeTestRule) { }.goBack { // Actually exiting to the previously opened custom tab } diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/DeepLinkTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/DeepLinkTest.kt @@ -27,13 +27,10 @@ import org.mozilla.fenix.ui.robots.DeepLinkRobot **/ class DeepLinkTest : TestSetup() { - private val robot = DeepLinkRobot() - @get:Rule - val activityTestRule = + val composeTestRule = AndroidComposeTestRule( HomeActivityIntentTestRule( - isMenuRedesignEnabled = false, isMenuRedesignCFREnabled = false, ), ) { it.activity } @@ -41,14 +38,16 @@ class DeepLinkTest : TestSetup() { @get:Rule val memoryLeaksRule = DetectMemoryLeaksRule() + private val robot = DeepLinkRobot(composeTestRule) + @Test fun openHomeScreen() { robot.openHomeScreen { - verifyHomeComponent(activityTestRule) + verifyHomeComponent() } robot.openSettings { /* move away from the home screen */ } robot.openHomeScreen { - verifyHomeComponent(activityTestRule) + verifyHomeComponent() } } @@ -63,7 +62,7 @@ class DeepLinkTest : TestSetup() { @Test fun openBookmarks() { - robot.openBookmarks(activityTestRule) { + robot.openBookmarks(composeTestRule) { // verify we can see headings. verifyEmptyBookmarksMenuView() } @@ -79,7 +78,7 @@ class DeepLinkTest : TestSetup() { @Test fun openCollections() { robot.openCollections { - verifyCollectionsHeader(activityTestRule) + verifyCollectionsHeader() } } diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/DownloadFileTypesTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/DownloadFileTypesTest.kt @@ -11,6 +11,7 @@ import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.Parameterized import org.mozilla.fenix.customannotations.SmokeTest +import org.mozilla.fenix.helpers.HomeActivityIntentTestRule import org.mozilla.fenix.helpers.HomeActivityTestRule import org.mozilla.fenix.helpers.TestSetup import org.mozilla.fenix.ui.robots.browserScreen @@ -29,9 +30,9 @@ class DownloadFileTypesTest(fileName: String) : TestSetup() { private var downloadFile: String = fileName @get:Rule - val activityTestRule = + val composeTestRule = AndroidComposeTestRule( - HomeActivityTestRule.withDefaultSettingsOverrides(), + HomeActivityIntentTestRule.withDefaultSettingsOverrides(), ) { it.activity } companion object { @@ -55,15 +56,16 @@ class DownloadFileTypesTest(fileName: String) : TestSetup() { @SmokeTest @Test fun allFilesAppearInDownloadsMenuTest() { - downloadRobot { + downloadRobot(composeTestRule) { openPageAndDownloadFile(url = downloadTestPage.toUri(), downloadFile = downloadFile) verifyDownloadCompleteSnackbar(fileName = downloadFile) } - browserScreen { + browserScreen(composeTestRule) { }.openThreeDotMenu { - }.openDownloadsManager { - verifyDownloadedFileExistsInDownloadsList(activityTestRule, downloadFile) - }.exitDownloadsManagerToBrowser(activityTestRule) { } + }.clickDownloadsButton { + verifyDownloadedFileExistsInDownloadsList(downloadFile) + }.exitDownloadsManagerToBrowser { + } } } diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/DownloadTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/DownloadTest.kt @@ -52,7 +52,7 @@ class DownloadTest : TestSetup() { private var downloadFile: String = "" @get:Rule - val activityTestRule = + val composeTestRule = AndroidComposeTestRule( HomeActivityTestRule.withDefaultSettingsOverrides(), ) { it.activity } @@ -66,10 +66,10 @@ class DownloadTest : TestSetup() { // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/243844 @Test fun verifyTheDownloadPromptsTest() { - downloadRobot { + downloadRobot(composeTestRule) { openPageAndDownloadFile(url = downloadTestPage.toUri(), downloadFile = "web_icon.png") verifyDownloadCompleteSnackbar(fileName = "web_icon.png") - clickSnackbarButton(composeTestRule = activityTestRule, "OPEN") + clickSnackbarButton(composeTestRule = this@DownloadTest.composeTestRule, "OPEN") verifyPhotosAppOpens() } } @@ -78,22 +78,22 @@ class DownloadTest : TestSetup() { @Ignore("Failing, see https://bugzilla.mozilla.org/show_bug.cgi?id=1987355") @Test fun verifyTheDownloadFailedNotificationsTest() { - downloadRobot { + downloadRobot(composeTestRule) { openPageAndDownloadFile(url = downloadTestPage.toUri(), downloadFile = "1GB.zip") setNetworkEnabled(enabled = false) - verifyDownloadFailedSnackbar(activityTestRule, fileName = "1GB.zip") - clickSnackbarButton(composeTestRule = activityTestRule, "DETAILS") + verifyDownloadFailedSnackbar(fileName = "1GB.zip") + clickSnackbarButton(composeTestRule, "DETAILS") }.openNotificationShade { verifySystemNotificationExists("Download failed") - }.closeNotificationTray { + }.closeNotificationTray(composeTestRule) { } - downloadRobot { - verifyDownloadFileFailedMessage(activityTestRule, "1GB.zip") + downloadRobot(composeTestRule) { + verifyDownloadFileFailedMessage("1GB.zip") setNetworkEnabled(enabled = true) - clickTryAgainDownloadMenuButton(activityTestRule) - verifyPauseDownloadMenuButtonButton(activityTestRule) + clickTryAgainDownloadMenuButton() + verifyPauseDownloadMenuButtonButton() } - downloadRobot { + downloadRobot(composeTestRule) { }.openNotificationShade { expandNotificationMessage("1GB.zip") clickDownloadNotificationControlButton("CANCEL") @@ -102,9 +102,10 @@ class DownloadTest : TestSetup() { } // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2298616 + @SkipLeaks(reasons = ["https://bugzilla.mozilla.org/show_bug.cgi?id=2006672"]) @Test fun verifyDownloadCompleteNotificationTest() { - downloadRobot { + downloadRobot(composeTestRule) { openPageAndDownloadFile(url = downloadTestPage.toUri(), downloadFile = "web_icon.png") verifyDownloadCompleteSnackbar(fileName = "web_icon.png") waitUntilDownloadSnackbarGone() @@ -118,20 +119,22 @@ class DownloadTest : TestSetup() { mDevice.openNotification() verifySystemNotificationExists("Download completed") swipeDownloadNotification( + composeTestRule, direction = "Left", shouldDismissNotification = true, canExpandNotification = false, notificationItem = "web_icon.png", ) verifySystemNotificationDoesNotExist("Firefox Fenix") - }.closeNotificationTray {} + }.closeNotificationTray(composeTestRule) { + } } // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/451563 @SmokeTest @Test fun pauseResumeCancelDownloadTest() { - downloadRobot { + downloadRobot(composeTestRule) { openPageAndDownloadFile(url = downloadTestPage.toUri(), downloadFile = "3GB.zip") verifySnackBarText("Download in progress") waitUntilDownloadSnackbarGone() @@ -146,25 +149,25 @@ class DownloadTest : TestSetup() { verifySystemNotificationDoesNotExist("3GB.zip") mDevice.pressBack() } - browserScreen { + browserScreen(composeTestRule) { }.openThreeDotMenu { - }.openDownloadsManager { - verifyEmptyDownloadsList(activityTestRule) + }.clickDownloadsButton { + verifyEmptyDownloadsList() } } // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2301474 @Test fun openDownloadedFileFromDownloadsMenuTest() { - downloadRobot { + downloadRobot(composeTestRule) { openPageAndDownloadFile(url = downloadTestPage.toUri(), downloadFile = "web_icon.png") verifyDownloadCompleteSnackbar(fileName = "web_icon.png") } - browserScreen { + browserScreen(composeTestRule) { }.openThreeDotMenu { - }.openDownloadsManager { - verifyDownloadedFileExistsInDownloadsList(activityTestRule, "web_icon.png") - clickDownloadedItem(activityTestRule, "web_icon.png") + }.clickDownloadsButton { + verifyDownloadedFileExistsInDownloadsList("web_icon.png") + clickDownloadedItem("web_icon.png") verifyPhotosAppOpens() mDevice.pressBack() } @@ -174,20 +177,20 @@ class DownloadTest : TestSetup() { @Test @SkipLeaks(reasons = ["https://bugzilla.mozilla.org/show_bug.cgi?id=2004099"]) fun deleteDownloadedFileTest() { - downloadRobot { + downloadRobot(composeTestRule) { openPageAndDownloadFile(url = downloadTestPage.toUri(), downloadFile = "smallZip.zip") } - browserScreen { + browserScreen(composeTestRule) { }.openThreeDotMenu { - }.openDownloadsManager { - verifyDownloadedFileExistsInDownloadsList(activityTestRule, "smallZip.zip") - clickDownloadItemMenuIcon(activityTestRule, "smallZip.zip") - deleteDownloadedItem(activityTestRule, "smallZip.zip") - clickSnackbarButton(activityTestRule, "Undo") - verifyDownloadedFileExistsInDownloadsList(activityTestRule, "smallZip.zip") - clickDownloadItemMenuIcon(activityTestRule, "smallZip.zip") - deleteDownloadedItem(activityTestRule, "smallZip.zip") - verifyEmptyDownloadsList(activityTestRule) + }.clickDownloadsButton { + verifyDownloadedFileExistsInDownloadsList("smallZip.zip") + clickDownloadItemMenuIcon("smallZip.zip") + deleteDownloadedItem("smallZip.zip") + clickSnackbarButton(composeTestRule, "Undo") + verifyDownloadedFileExistsInDownloadsList("smallZip.zip") + clickDownloadItemMenuIcon("smallZip.zip") + deleteDownloadedItem("smallZip.zip") + verifyEmptyDownloadsList() } } @@ -197,84 +200,84 @@ class DownloadTest : TestSetup() { val firstDownloadedFile = "smallZip.zip" val secondDownloadedFile = "textfile.txt" - downloadRobot { + downloadRobot(composeTestRule) { openPageAndDownloadFile(url = downloadTestPage.toUri(), downloadFile = firstDownloadedFile) verifyDownloadCompleteSnackbar(fileName = firstDownloadedFile) } - browserScreen { + browserScreen(composeTestRule) { }.clickDownloadLink(secondDownloadedFile) { }.clickDownload { verifyDownloadCompleteSnackbar(fileName = secondDownloadedFile) } - browserScreen { + browserScreen(composeTestRule) { }.openThreeDotMenu { - }.openDownloadsManager { - verifyDownloadedFileExistsInDownloadsList(activityTestRule, firstDownloadedFile) - verifyDownloadedFileExistsInDownloadsList(activityTestRule, secondDownloadedFile) - longClickDownloadedItem(activityTestRule, firstDownloadedFile) - clickDownloadedItem(activityTestRule, secondDownloadedFile) - openMultiSelectMoreOptionsMenu(activityTestRule) - clickMultiSelectRemoveButton(activityTestRule) - clickMultiSelectDeleteDialogButton(activityTestRule) - clickSnackbarButton(activityTestRule, "Undo") - verifyDownloadedFileExistsInDownloadsList(activityTestRule, firstDownloadedFile) - verifyDownloadedFileExistsInDownloadsList(activityTestRule, secondDownloadedFile) - longClickDownloadedItem(activityTestRule, firstDownloadedFile) - clickDownloadedItem(activityTestRule, secondDownloadedFile) - openMultiSelectMoreOptionsMenu(activityTestRule) - clickMultiSelectRemoveButton(activityTestRule) - clickMultiSelectDeleteDialogButton(activityTestRule) - verifyEmptyDownloadsList(activityTestRule) + }.clickDownloadsButton { + verifyDownloadedFileExistsInDownloadsList(firstDownloadedFile) + verifyDownloadedFileExistsInDownloadsList(secondDownloadedFile) + longClickDownloadedItem(firstDownloadedFile) + clickDownloadedItem(secondDownloadedFile) + openMultiSelectMoreOptionsMenu() + clickMultiSelectRemoveButton() + clickMultiSelectDeleteDialogButton() + clickSnackbarButton(composeTestRule, "Undo") + verifyDownloadedFileExistsInDownloadsList(firstDownloadedFile) + verifyDownloadedFileExistsInDownloadsList(secondDownloadedFile) + longClickDownloadedItem(firstDownloadedFile) + clickDownloadedItem(secondDownloadedFile) + openMultiSelectMoreOptionsMenu() + clickMultiSelectRemoveButton() + clickMultiSelectDeleteDialogButton() + verifyEmptyDownloadsList() } } // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2301537 @Test fun fileDeletedFromStorageIsDeletedEverywhereTest() { - downloadRobot { + downloadRobot(composeTestRule) { openPageAndDownloadFile(url = downloadTestPage.toUri(), downloadFile = "smallZip.zip") verifyDownloadCompleteSnackbar(fileName = "smallZip.zip") } - browserScreen { + browserScreen(composeTestRule) { }.openThreeDotMenu { - }.openDownloadsManager { - verifyDownloadedFileExistsInDownloadsList(activityTestRule, "smallZip.zip") + }.clickDownloadsButton { + verifyDownloadedFileExistsInDownloadsList("smallZip.zip") deleteDownloadedFileOnStorage("smallZip.zip") - }.exitDownloadsManagerToBrowser(activityTestRule) { + }.exitDownloadsManagerToBrowser { }.openThreeDotMenu { - }.openDownloadsManager { - verifyEmptyDownloadsList(activityTestRule) - }.exitDownloadsManagerToBrowser(activityTestRule) { + }.clickDownloadsButton { + verifyEmptyDownloadsList() + }.exitDownloadsManagerToBrowser { } - downloadRobot { + downloadRobot(composeTestRule) { openPageAndDownloadFile(url = downloadTestPage.toUri(), downloadFile = "smallZip.zip") verifyDownloadCompleteSnackbar(fileName = "smallZip.zip") } - browserScreen { + browserScreen(composeTestRule) { }.openThreeDotMenu { - }.openDownloadsManager { - verifyDownloadedFileExistsInDownloadsList(activityTestRule, "smallZip.zip") + }.clickDownloadsButton { + verifyDownloadedFileExistsInDownloadsList("smallZip.zip") } } // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2466505 @Test fun systemNotificationCantBeDismissedWhileInProgressTest() { - downloadRobot { + downloadRobot(composeTestRule) { openPageAndDownloadFile(url = downloadTestPage.toUri(), downloadFile = "3GB.zip") } - browserScreen { + browserScreen(composeTestRule) { }.openNotificationShade { - swipeDownloadNotification(direction = "Left", shouldDismissNotification = false, notificationItem = "3GB.zip") + swipeDownloadNotification(composeTestRule, direction = "Left", shouldDismissNotification = false, notificationItem = "3GB.zip") expandNotificationMessage("3GB.zip") clickDownloadNotificationControlButton("PAUSE") notificationShade { - }.closeNotificationTray { + }.closeNotificationTray(composeTestRule) { } - browserScreen { + browserScreen(composeTestRule) { }.openNotificationShade { - swipeDownloadNotification(direction = "Right", shouldDismissNotification = true, notificationItem = "3GB.zip") + swipeDownloadNotification(composeTestRule, direction = "Right", shouldDismissNotification = true, notificationItem = "3GB.zip") verifySystemNotificationDoesNotExist("3GB.zip") } } @@ -284,15 +287,16 @@ class DownloadTest : TestSetup() { @Ignore("Failing, see https://bugzilla.mozilla.org/show_bug.cgi?id=1987355") @Test fun notificationCanBeDismissedIfDownloadIsInterruptedTest() { - downloadRobot { + downloadRobot(composeTestRule) { openPageAndDownloadFile(url = downloadTestPage.toUri(), downloadFile = "1GB.zip") setNetworkEnabled(enabled = false) - verifyDownloadFailedSnackbar(activityTestRule, fileName = "1GB.zip") + verifyDownloadFailedSnackbar(fileName = "1GB.zip") } - browserScreen { + browserScreen(composeTestRule) { }.openNotificationShade { verifySystemNotificationExists("Download failed") swipeDownloadNotification( + composeTestRule, direction = "Left", shouldDismissNotification = true, canExpandNotification = true, @@ -305,16 +309,16 @@ class DownloadTest : TestSetup() { // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/1632384 @Test fun warningWhenClosingPrivateTabsWhileDownloadingTest() { - homeScreen { + homeScreen(composeTestRule) { }.togglePrivateBrowsingMode() - downloadRobot { + downloadRobot(composeTestRule) { openPageAndDownloadFile(url = downloadTestPage.toUri(), downloadFile = "3GB.zip") } - browserScreen { - }.openTabDrawer(activityTestRule) { + browserScreen(composeTestRule) { + }.openTabDrawer(composeTestRule) { closeTab() } - browserScreen { + browserScreen(composeTestRule) { verifyCancelPrivateDownloadsPrompt("1") clickStayInPrivateBrowsingPromptButton() }.openNotificationShade { @@ -331,16 +335,16 @@ class DownloadTest : TestSetup() { // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2302663 @Test fun cancelActivePrivateBrowsingDownloadsTest() { - homeScreen { + homeScreen(composeTestRule) { }.togglePrivateBrowsingMode() - downloadRobot { + downloadRobot(composeTestRule) { openPageAndDownloadFile(url = downloadTestPage.toUri(), downloadFile = "3GB.zip") } - browserScreen { - }.openTabDrawer(activityTestRule) { + browserScreen(composeTestRule) { + }.openTabDrawer(composeTestRule) { closeTab() } - browserScreen { + browserScreen(composeTestRule) { verifyCancelPrivateDownloadsPrompt("1") clickCancelPrivateDownloadsPromptButton() }.openNotificationShade { @@ -356,19 +360,19 @@ class DownloadTest : TestSetup() { val genericURL = mockWebServer.getGenericAsset(3) downloadFile = "pdfForm.pdf" - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(genericURL.url) { - clickPageObject(itemWithText("PDF form file")) + clickPageObject(composeTestRule, itemWithText("PDF form file")) waitForPageToLoad() - clickPageObject(itemWithResIdAndText("android:id/button2", "Cancel")) + clickPageObject(composeTestRule, itemWithResIdAndText("android:id/button2", "Cancel")) fillPdfForm("Firefox") }.openThreeDotMenu { }.clickShareButton { - }.clickSaveAsPDF { + }.clickSaveAsPDF(composeTestRule) { verifyDownloadPrompt(downloadFile) }.clickDownload { verifyDownloadCompleteSnackbar(fileName = downloadFile) - clickSnackbarButton(composeTestRule = activityTestRule, "OPEN") + clickSnackbarButton(composeTestRule = composeTestRule, "OPEN") assertExternalAppOpens(GOOGLE_DOCS) } } @@ -379,18 +383,18 @@ class DownloadTest : TestSetup() { fun restartDownloadFromAppNotificationAfterConnectionIsInterruptedTest() { downloadFile = "3GB.zip" - downloadRobot { + downloadRobot(composeTestRule) { openPageAndDownloadFile(url = downloadTestPage.toUri(), downloadFile = "3GB.zip") setNetworkEnabled(false) - verifyDownloadFailedSnackbar(activityTestRule, fileName = "3GB.zip") + verifyDownloadFailedSnackbar(fileName = "3GB.zip") setNetworkEnabled(true) - clickSnackbarButton(composeTestRule = activityTestRule, "DETAILS") - verifyDownloadFileFailedMessage(activityTestRule, "3GB.zip") + clickSnackbarButton(composeTestRule, "DETAILS") + verifyDownloadFileFailedMessage("3GB.zip") setNetworkEnabled(enabled = true) - clickTryAgainDownloadMenuButton(activityTestRule) - verifyPauseDownloadMenuButtonButton(activityTestRule) + clickTryAgainDownloadMenuButton() + verifyPauseDownloadMenuButtonButton() } - downloadRobot { + downloadRobot(composeTestRule) { }.openNotificationShade { expandNotificationMessage("3GB.zip") clickDownloadNotificationControlButton("CANCEL") @@ -404,40 +408,40 @@ class DownloadTest : TestSetup() { val firstDownloadedFile = "smallZip.zip" val secondDownloadedFile = "web_icon.png" - downloadRobot { + downloadRobot(composeTestRule) { openPageAndDownloadFile(url = downloadTestPage.toUri(), downloadFile = firstDownloadedFile) verifyDownloadCompleteSnackbar(fileName = firstDownloadedFile) } - browserScreen { + browserScreen(composeTestRule) { }.clickDownloadLink(secondDownloadedFile) { }.clickDownload { verifyDownloadCompleteSnackbar(fileName = secondDownloadedFile) } - browserScreen { + browserScreen(composeTestRule) { }.openThreeDotMenu { - }.openDownloadsManager { - clickDownloadsFilter("Images", composeTestRule = activityTestRule) - verifyDownloadedFileExistsInDownloadsList(activityTestRule, secondDownloadedFile) - verifyDownloadFileIsNotDisplayed(activityTestRule, firstDownloadedFile) + }.clickDownloadsButton { + clickDownloadsFilter("Images") + verifyDownloadedFileExistsInDownloadsList(secondDownloadedFile) + verifyDownloadFileIsNotDisplayed(firstDownloadedFile) } } // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2987000 @Test fun shareDownloadedFileTest() { - downloadRobot { + downloadRobot(composeTestRule) { openPageAndDownloadFile(url = downloadTestPage.toUri(), downloadFile = "web_icon.png") verifyDownloadCompleteSnackbar(fileName = "web_icon.png") } - browserScreen { + browserScreen(composeTestRule) { }.openThreeDotMenu { - }.openDownloadsManager { - verifyDownloadedFileExistsInDownloadsList(activityTestRule, "web_icon.png") - clickDownloadItemMenuIcon(activityTestRule, "web_icon.png") - }.shareDownloadedItem(activityTestRule, "web_icon.png") { + }.clickDownloadsButton { + verifyDownloadedFileExistsInDownloadsList("web_icon.png") + clickDownloadItemMenuIcon("web_icon.png") + }.shareDownloadedItem("web_icon.png") { expandAndroidShareLayout("Gmail") clickSharingApp("Gmail", GMAIL_APP) - assertNativeAppOpens(GMAIL_APP) + assertNativeAppOpens(composeTestRule, GMAIL_APP) } } @@ -447,9 +451,9 @@ class DownloadTest : TestSetup() { fun downloadRestartAfterConnectionIsReestablishedTest() { downloadFile = "3GB.zip" - downloadRobot { + downloadRobot(composeTestRule) { openPageAndDownloadFile(url = downloadTestPage.toUri(), downloadFile = "3GB.zip") - downloadRobot { + downloadRobot(composeTestRule) { }.openNotificationShade { expandNotificationMessage("3GB.zip") clickDownloadNotificationControlButton("PAUSE") diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/EnhancedTrackingProtectionTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/EnhancedTrackingProtectionTest.kt @@ -44,7 +44,7 @@ import org.mozilla.fenix.ui.robots.navigationToolbar class EnhancedTrackingProtectionTest : TestSetup() { @get:Rule - val activityTestRule = + val composeTestRule = AndroidComposeTestRule( HomeActivityIntentTestRule.withDefaultSettingsOverrides(), ) { it.activity } @@ -55,9 +55,9 @@ class EnhancedTrackingProtectionTest : TestSetup() { // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/416046 @Test fun testETPSettingsItemsAndSubMenus() { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { verifyEnhancedTrackingProtectionButton() verifySettingsOptionSummary("Enhanced Tracking Protection", "Standard") }.openEnhancedTrackingProtectionSubMenu { @@ -84,7 +84,7 @@ class EnhancedTrackingProtectionTest : TestSetup() { verifyTPExceptionsDefaultView() openExceptionsLearnMoreLink() } - browserScreen { + browserScreen(composeTestRule) { waitForPageToLoad(pageLoadWaitingTime = waitingTimeLong) verifyETPLearnMoreURL() } @@ -95,9 +95,9 @@ class EnhancedTrackingProtectionTest : TestSetup() { fun verifyETPStateIsReflectedInTPSheetTest() { val genericPage = mockWebServer.getGenericAsset(1) - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openEnhancedTrackingProtectionSubMenu { switchEnhancedTrackingProtectionToggle() verifyEnhancedTrackingProtectionOptionsEnabled(false) @@ -106,21 +106,19 @@ class EnhancedTrackingProtectionTest : TestSetup() { exitMenu() } - navigationToolbar { - }.enterURLAndEnterToBrowser(genericPage.url) { } - enhancedTrackingProtection { - }.openEnhancedTrackingProtectionSheet { + navigationToolbar(composeTestRule) { + }.enterURLAndEnterToBrowser(genericPage.url) { + }.openSiteSecuritySheet { verifyETPSwitchVisibility(false) - }.closeEnhancedTrackingProtectionSheet { + }.closeSiteSecuritySheet(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openEnhancedTrackingProtectionSubMenu { switchEnhancedTrackingProtectionToggle() verifyEnhancedTrackingProtectionOptionsEnabled(true) }.goBack { - }.goBackToBrowser { } - enhancedTrackingProtection { - }.openEnhancedTrackingProtectionSheet { + }.goBackToBrowser(composeTestRule) { + }.openSiteSecuritySheet { verifyETPSwitchVisibility(true) } } @@ -133,26 +131,24 @@ class EnhancedTrackingProtectionTest : TestSetup() { val firstPage = mockWebServer.getGenericAsset(1) val secondPage = "https://mozilla-mobile.github.io/testapp" - navigationToolbar { - }.enterURLAndEnterToBrowser(firstPage.url) {} - enhancedTrackingProtection { - }.openEnhancedTrackingProtectionSheet { + navigationToolbar(composeTestRule) { + }.enterURLAndEnterToBrowser(firstPage.url) { + }.openSiteSecuritySheet { }.toggleEnhancedTrackingProtectionFromSheet { verifyEnhancedTrackingProtectionSheetStatus("OFF", false) - }.closeEnhancedTrackingProtectionSheet { - }.openNavigationToolbar { + }.closeSiteSecuritySheet(composeTestRule) { + } + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(secondPage.toUri()) { verifyPageContent("Lets test!") - } - enhancedTrackingProtection { - }.openEnhancedTrackingProtectionSheet { + }.openSiteSecuritySheet { verifyEnhancedTrackingProtectionSheetStatus("ON", true) }.toggleEnhancedTrackingProtectionFromSheet { verifyEnhancedTrackingProtectionSheetStatus("OFF", false) } - restartApp(activityTestRule.activityRule) - enhancedTrackingProtection { - }.openEnhancedTrackingProtectionSheet { + restartApp(composeTestRule.activityRule) + browserScreen(composeTestRule) { + }.openSiteSecuritySheet { verifyEnhancedTrackingProtectionSheetStatus("OFF", false) } } @@ -162,29 +158,27 @@ class EnhancedTrackingProtectionTest : TestSetup() { fun enablingETPOnAWebsiteRemovesItFromTheExceptionListTest() { val trackingPage = mockWebServer.enhancedTrackingProtectionAsset - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(trackingPage.url) { verifyUrl(trackingPage.url.toString()) - } - enhancedTrackingProtection { - }.openEnhancedTrackingProtectionSheet { + }.openSiteSecuritySheet { }.toggleEnhancedTrackingProtectionFromSheet { verifyEnhancedTrackingProtectionSheetStatus("OFF", false) - }.closeEnhancedTrackingProtectionSheet { + }.closeSiteSecuritySheet(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openEnhancedTrackingProtectionSubMenu { }.openExceptions { verifySiteExceptionExists(trackingPage.url.host.toString(), true) exitMenu() } - enhancedTrackingProtection { - }.openEnhancedTrackingProtectionSheet { + browserScreen(composeTestRule) { + }.openSiteSecuritySheet { }.toggleEnhancedTrackingProtectionFromSheet { verifyEnhancedTrackingProtectionSheetStatus("ON", true) - }.closeEnhancedTrackingProtectionSheet { + }.closeSiteSecuritySheet(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openEnhancedTrackingProtectionSubMenu { }.openExceptions { verifySiteExceptionExists(trackingPage.url.host.toString(), false) @@ -198,24 +192,22 @@ class EnhancedTrackingProtectionTest : TestSetup() { val firstPage = mockWebServer.getGenericAsset(1) val secondPage = "https://mozilla-mobile.github.io/testapp" - navigationToolbar { - }.enterURLAndEnterToBrowser(firstPage.url) {} - enhancedTrackingProtection { - }.openEnhancedTrackingProtectionSheet { + navigationToolbar(composeTestRule) { + }.enterURLAndEnterToBrowser(firstPage.url) { + }.openSiteSecuritySheet { }.toggleEnhancedTrackingProtectionFromSheet { verifyEnhancedTrackingProtectionSheetStatus("OFF", false) - }.closeEnhancedTrackingProtectionSheet { - }.openNavigationToolbar { + }.closeSiteSecuritySheet(composeTestRule) { + } + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(secondPage.toUri()) { verifyPageContent("Lets test!") - } - enhancedTrackingProtection { - }.openEnhancedTrackingProtectionSheet { + }.openSiteSecuritySheet { }.toggleEnhancedTrackingProtectionFromSheet { verifyEnhancedTrackingProtectionSheetStatus("OFF", false) - }.closeEnhancedTrackingProtectionSheet { + }.closeSiteSecuritySheet(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openEnhancedTrackingProtectionSubMenu { }.openExceptions { removeOneSiteException(secondPage.toUri().host.toString()) @@ -223,8 +215,8 @@ class EnhancedTrackingProtectionTest : TestSetup() { verifyTPExceptionsDefaultView() exitMenu() } - enhancedTrackingProtection { - }.openEnhancedTrackingProtectionSheet { + browserScreen(composeTestRule) { + }.openSiteSecuritySheet { verifyEnhancedTrackingProtectionSheetStatus("ON", true) } } @@ -235,33 +227,32 @@ class EnhancedTrackingProtectionTest : TestSetup() { val genericPage = mockWebServer.getGenericAsset(1) val trackingProtectionTest = mockWebServer.enhancedTrackingProtectionAsset.url - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { verifyEnhancedTrackingProtectionButton() verifySettingsOptionSummary("Enhanced Tracking Protection", "Standard") exitMenu() } // browsing a generic page to allow GV to load on a fresh run - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(genericPage.url) { verifyPageContent(genericPage.content) - }.openNavigationToolbar { + } + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(trackingProtectionTest) { verifyTrackingProtectionWebContent("social not blocked") verifyTrackingProtectionWebContent("ads not blocked") verifyTrackingProtectionWebContent("analytics not blocked") verifyTrackingProtectionWebContent("Fingerprinting blocked") verifyTrackingProtectionWebContent("Cryptomining blocked") - } - enhancedTrackingProtection { - }.openEnhancedTrackingProtectionSheet { + }.openSiteSecuritySheet { verifyEnhancedTrackingProtectionSheetStatus("ON", true) }.openDetails { // Third-party cookie tracker blocking in Nightly was disabled: https://bugzilla.mozilla.org/show_bug.cgi?id=1935156 - if (activityTestRule.activity.components.core.engine.version.releaseChannel == EngineReleaseChannel.BETA && - activityTestRule.activity.components.core.engine.version.releaseChannel == EngineReleaseChannel.RELEASE + if (composeTestRule.activity.components.core.engine.version.releaseChannel == EngineReleaseChannel.BETA && + composeTestRule.activity.components.core.engine.version.releaseChannel == EngineReleaseChannel.RELEASE ) { verifyCrossSiteCookiesBlocked(true) navigateBackToDetails() @@ -271,7 +262,7 @@ class EnhancedTrackingProtectionTest : TestSetup() { verifyFingerprintersBlocked(true) navigateBackToDetails() verifyTrackingContentBlocked(false) - }.closeEnhancedTrackingProtectionSheet {} + }.closeEnhancedTrackingProtectionSheet(composeTestRule) {} } // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/417441 @@ -281,31 +272,29 @@ class EnhancedTrackingProtectionTest : TestSetup() { val genericPage = mockWebServer.getGenericAsset(1) val trackingProtectionTest = mockWebServer.enhancedTrackingProtectionAsset.url - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { verifyEnhancedTrackingProtectionButton() verifySettingsOptionSummary("Enhanced Tracking Protection", "Strict") exitMenu() } // browsing a generic page to allow GV to load on a fresh run - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(genericPage.url) { - }.openTabDrawer(activityTestRule) { + }.openTabDrawer(composeTestRule) { closeTab() } - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(trackingProtectionTest) { verifyTrackingProtectionWebContent("social blocked") verifyTrackingProtectionWebContent("ads blocked") verifyTrackingProtectionWebContent("analytics blocked") verifyTrackingProtectionWebContent("Fingerprinting blocked") verifyTrackingProtectionWebContent("Cryptomining blocked") - } - enhancedTrackingProtection { - }.openEnhancedTrackingProtectionSheet { + }.openSiteSecuritySheet { verifyEnhancedTrackingProtectionSheetStatus("ON", true) }.openDetails { verifySocialMediaTrackersBlocked(true) @@ -326,9 +315,9 @@ class EnhancedTrackingProtectionTest : TestSetup() { val genericWebPage = mockWebServer.getGenericAsset(1) val trackingPage = mockWebServer.enhancedTrackingProtectionAsset - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openEnhancedTrackingProtectionSubMenu { selectTrackingProtectionOption("Custom") verifyCustomTrackingProtectionSettings() @@ -337,19 +326,17 @@ class EnhancedTrackingProtectionTest : TestSetup() { exitMenu() } - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(genericWebPage.url) { - }.openNavigationToolbar { + } + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(trackingPage.url) { verifyTrackingProtectionWebContent("social blocked") verifyTrackingProtectionWebContent("ads blocked") verifyTrackingProtectionWebContent("analytics blocked") verifyTrackingProtectionWebContent("Fingerprinting blocked") verifyTrackingProtectionWebContent("Cryptomining blocked") - } - - enhancedTrackingProtection { - }.openEnhancedTrackingProtectionSheet { + }.openSiteSecuritySheet { }.openDetails { verifyCryptominersBlocked(true) navigateBackToDetails() @@ -370,29 +357,29 @@ class EnhancedTrackingProtectionTest : TestSetup() { val genericWebPage = mockWebServer.getGenericAsset(1) val trackingPage = mockWebServer.enhancedTrackingProtectionAsset - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openEnhancedTrackingProtectionSubMenu { selectTrackingProtectionOption("Custom") verifyCustomTrackingProtectionSettings() selectTrackingProtectionOption("Isolate cross-site cookies") selectTrackingProtectionOption("All cookies (will cause websites to break)") selectTrackingProtectionOption("Tracking content") - }.goBackToHomeScreen { + }.goBackToHomeScreen(composeTestRule) { mDevice.waitForIdle() - }.openNavigationToolbar { + } + navigationToolbar(composeTestRule) { // browsing a basic page to allow GV to load on a fresh run }.enterURLAndEnterToBrowser(genericWebPage.url) { waitForPageToLoad() - }.openNavigationToolbar { + } + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(trackingPage.url) { verifyTrackingProtectionWebContent("social not blocked") verifyTrackingProtectionWebContent("ads not blocked") verifyTrackingProtectionWebContent("analytics not blocked") - } - enhancedTrackingProtection { - }.openEnhancedTrackingProtectionSheet { + }.openSiteSecuritySheet { }.openDetails { verifyCrossSiteCookiesBlocked(true) navigateBackToDetails() @@ -410,9 +397,9 @@ class EnhancedTrackingProtectionTest : TestSetup() { val genericWebPage = mockWebServer.getGenericAsset(1) val trackingPage = mockWebServer.enhancedTrackingProtectionAsset - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openEnhancedTrackingProtectionSubMenu { selectTrackingProtectionOption("Custom") verifyCustomTrackingProtectionSettings() @@ -422,13 +409,15 @@ class EnhancedTrackingProtectionTest : TestSetup() { selectTrackingProtectionOption("Known Fingerprinters") selectTrackingProtectionOption("Suspected Fingerprinters") selectTrackingProtectionOption("Redirect Trackers") - }.goBackToHomeScreen { + }.goBackToHomeScreen(composeTestRule) { mDevice.waitForIdle() - }.openNavigationToolbar { + } + navigationToolbar(composeTestRule) { // browsing a basic page to allow GV to load on a fresh run }.enterURLAndEnterToBrowser(genericWebPage.url) { waitForPageToLoad() - }.openNavigationToolbar { + } + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(trackingPage.url) { verifyTrackingProtectionWebContent("social not blocked") verifyTrackingProtectionWebContent("ads not blocked") @@ -444,44 +433,44 @@ class EnhancedTrackingProtectionTest : TestSetup() { val genericWebPage = mockWebServer.getGenericAsset(1) val trackingPage = mockWebServer.enhancedTrackingProtectionAsset - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openEnhancedTrackingProtectionSubMenu { verifyEnhancedTrackingProtectionOptionsEnabled() selectTrackingProtectionOption("Custom") verifyCustomTrackingProtectionSettings() selectTrackingProtectionOption("In all tabs") selectTrackingProtectionOption("Only in Private tabs") - }.goBackToHomeScreen { - }.openNavigationToolbar { + }.goBackToHomeScreen(composeTestRule) { + } + navigationToolbar(composeTestRule) { // browsing a basic page to allow GV to load on a fresh run }.enterURLAndEnterToBrowser(genericWebPage.url) { waitForPageToLoad() - }.openNavigationToolbar { + } + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(trackingPage.url) { verifyTrackingProtectionWebContent("social not blocked") verifyTrackingProtectionWebContent("ads not blocked") verifyTrackingProtectionWebContent("analytics not blocked") verifyTrackingProtectionWebContent("Fingerprinting blocked") verifyTrackingProtectionWebContent("Cryptomining blocked") - }.goToHomescreen(activityTestRule) { + }.goToHomescreen { }.togglePrivateBrowsingMode() - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(trackingPage.url) { verifyTrackingProtectionWebContent("social blocked") verifyTrackingProtectionWebContent("ads blocked") verifyTrackingProtectionWebContent("analytics blocked") verifyTrackingProtectionWebContent("Fingerprinting blocked") verifyTrackingProtectionWebContent("Cryptomining blocked") - } - enhancedTrackingProtection { - }.openEnhancedTrackingProtectionSheet { + }.openSiteSecuritySheet { }.openDetails { // Third-party cookie tracker blocking in Nightly was disabled: https://bugzilla.mozilla.org/show_bug.cgi?id=1935156 if ( - activityTestRule.activity.components.core.engine.version.releaseChannel == EngineReleaseChannel.BETA && - activityTestRule.activity.components.core.engine.version.releaseChannel == EngineReleaseChannel.RELEASE + composeTestRule.activity.components.core.engine.version.releaseChannel == EngineReleaseChannel.BETA && + composeTestRule.activity.components.core.engine.version.releaseChannel == EngineReleaseChannel.RELEASE ) { verifyCrossSiteCookiesBlocked(true) navigateBackToDetails() @@ -505,10 +494,11 @@ class EnhancedTrackingProtectionTest : TestSetup() { val originHost = "mozilla-mobile.github.io" val currentHost = "localhost" - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(genericWebPage.url) { waitForPageToLoad() - }.openNavigationToolbar { + } + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(testPage) { waitForPageToLoad() }.clickRequestStorageAccessButton { @@ -528,10 +518,11 @@ class EnhancedTrackingProtectionTest : TestSetup() { val originHost = "mozilla-mobile.github.io" val currentHost = "localhost" - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(genericWebPage.url) { waitForPageToLoad() - }.openNavigationToolbar { + } + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(testPage) { waitForPageToLoad() }.clickRequestStorageAccessButton { diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/FirefoxSuggestTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/FirefoxSuggestTest.kt @@ -16,6 +16,7 @@ import org.mozilla.fenix.helpers.HomeActivityTestRule import org.mozilla.fenix.helpers.TestHelper import org.mozilla.fenix.helpers.TestSetup import org.mozilla.fenix.helpers.perf.DetectMemoryLeaksRule +import org.mozilla.fenix.ui.robots.homeScreen import org.mozilla.fenix.ui.robots.navigationToolbar /** @@ -26,7 +27,7 @@ import org.mozilla.fenix.ui.robots.navigationToolbar class FirefoxSuggestTest : TestSetup() { @get:Rule - val activityTestRule = AndroidComposeTestRule( + val composeTestRule = AndroidComposeTestRule( HomeActivityTestRule( skipOnboarding = true, isPocketEnabled = false, @@ -109,11 +110,10 @@ class FirefoxSuggestTest : TestSetup() { @Test fun verifyFirefoxSuggestSponsoredSearchResultsTest() { runWithCondition(TestHelper.appContext.settings().enableFxSuggest) { - navigationToolbar { - }.clickUrlbar { + homeScreen(composeTestRule) { + }.openSearch { typeSearch(searchTerm = sponsoredKeyWord) verifySponsoredSuggestionsResults( - rule = activityTestRule, searchSuggestions = arrayOf( "Firefox Suggest", sponsoredKeyWords.getValue(sponsoredKeyWord)[0], @@ -131,11 +131,10 @@ class FirefoxSuggestTest : TestSetup() { @Test fun verifyFirefoxSuggestSponsoredSearchResultsWithPartialKeywordTest() { runWithCondition(TestHelper.appContext.settings().enableFxSuggest) { - navigationToolbar { - }.clickUrlbar { + homeScreen(composeTestRule) { + }.openSearch { typeSearch(searchTerm = sponsoredKeyWord.dropLast(1)) verifySponsoredSuggestionsResults( - rule = activityTestRule, searchSuggestions = arrayOf( "Firefox Suggest", sponsoredKeyWords.getValue(sponsoredKeyWord)[0], @@ -153,11 +152,10 @@ class FirefoxSuggestTest : TestSetup() { @Test fun openFirefoxSuggestSponsoredSearchResultsTest() { runWithCondition(TestHelper.appContext.settings().enableFxSuggest) { - navigationToolbar { - }.clickUrlbar { + homeScreen(composeTestRule) { + }.openSearch { typeSearch(searchTerm = sponsoredKeyWord) verifySponsoredSuggestionsResults( - rule = activityTestRule, searchSuggestions = arrayOf( "Firefox Suggest", sponsoredKeyWords.getValue(sponsoredKeyWord)[0], @@ -178,12 +176,11 @@ class FirefoxSuggestTest : TestSetup() { @Test fun verifyFirefoxSuggestSponsoredSearchResultsWithEditedKeywordTest() { runWithCondition(TestHelper.appContext.settings().enableFxSuggest) { - navigationToolbar { - }.clickUrlbar { + homeScreen(composeTestRule) { + }.openSearch { typeSearch(searchTerm = sponsoredKeyWord) deleteSearchKeywordCharacters(numberOfDeletionSteps = 1) verifySponsoredSuggestionsResults( - rule = activityTestRule, searchSuggestions = arrayOf( "Firefox Suggest", sponsoredKeyWords.getValue(sponsoredKeyWord)[0], @@ -204,11 +201,10 @@ class FirefoxSuggestTest : TestSetup() { @Test fun verifyFirefoxSuggestNonSponsoredSearchResultsTest() { runWithCondition(TestHelper.appContext.settings().enableFxSuggest) { - navigationToolbar { - }.clickUrlbar { + homeScreen(composeTestRule) { + }.openSearch { typeSearch(searchTerm = nonSponsoredKeyWord) verifySponsoredSuggestionsResults( - rule = activityTestRule, searchSuggestions = arrayOf( "Firefox Suggest", nonSponsoredKeyWords.getValue(nonSponsoredKeyWord)[0], @@ -216,7 +212,6 @@ class FirefoxSuggestTest : TestSetup() { searchTerm = nonSponsoredKeyWord, ) verifySuggestionsAreNotDisplayed( - rule = activityTestRule, searchSuggestions = arrayOf( "Sponsored", ), @@ -231,11 +226,10 @@ class FirefoxSuggestTest : TestSetup() { @Test fun verifyFirefoxSuggestNonSponsoredSearchResultsWithPartialKeywordTest() { runWithCondition(TestHelper.appContext.settings().enableFxSuggest) { - navigationToolbar { - }.clickUrlbar { + homeScreen(composeTestRule) { + }.openSearch { typeSearch(searchTerm = nonSponsoredKeyWord.dropLast(1)) verifySponsoredSuggestionsResults( - rule = activityTestRule, searchSuggestions = arrayOf( "Firefox Suggest", nonSponsoredKeyWords.getValue(nonSponsoredKeyWord)[0], @@ -252,11 +246,10 @@ class FirefoxSuggestTest : TestSetup() { @Test fun openFirefoxSuggestNonSponsoredSearchResultsTest() { runWithCondition(TestHelper.appContext.settings().enableFxSuggest) { - navigationToolbar { - }.clickUrlbar { + homeScreen(composeTestRule) { + }.openSearch { typeSearch(searchTerm = nonSponsoredKeyWord) verifySponsoredSuggestionsResults( - rule = activityTestRule, searchSuggestions = arrayOf( "Firefox Suggest", nonSponsoredKeyWords.getValue(nonSponsoredKeyWord)[0], diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/GlobalPrivacyControlTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/GlobalPrivacyControlTest.kt @@ -24,7 +24,7 @@ class GlobalPrivacyControlTest : TestSetup() { private lateinit var gpcPage: TestAsset @get:Rule(order = 0) - val activityTestRule = + val composeTestRule = AndroidComposeTestRule( HomeActivityIntentTestRule.withDefaultSettingsOverrides( skipOnboarding = true, @@ -43,18 +43,18 @@ class GlobalPrivacyControlTest : TestSetup() { // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2429327 @Test fun testGPCinNormalBrowsing() { - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(gpcPage.url) { verifyPageContent("GPC not enabled.") }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openEnhancedTrackingProtectionSubMenu { scrollToGCPSettings() verifyGPCTextWithSwitchWidget() verifyGPCSwitchEnabled(false) switchGPCToggle() }.goBack { - }.goBackToBrowser { + }.goBackToBrowser(composeTestRule) { verifyPageContent("GPC is enabled.") } } @@ -62,19 +62,21 @@ class GlobalPrivacyControlTest : TestSetup() { // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2429364 @Test fun testGPCinPrivateBrowsing() { - homeScreen { }.togglePrivateBrowsingMode() - navigationToolbar { + homeScreen(composeTestRule) { + }.togglePrivateBrowsingMode() + + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(gpcPage.url) { verifyPageContent("GPC is enabled.") }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openEnhancedTrackingProtectionSubMenu { scrollToGCPSettings() verifyGPCTextWithSwitchWidget() verifyGPCSwitchEnabled(false) switchGPCToggle() }.goBack { - }.goBackToBrowser { + }.goBackToBrowser(composeTestRule) { verifyPageContent("GPC is enabled.") } } diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/HTTPSFirstModeTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/HTTPSFirstModeTest.kt @@ -15,7 +15,7 @@ import org.mozilla.fenix.ui.robots.navigationToolbar class HTTPSFirstModeTest : TestSetup() { @get:Rule - val activityTestRule = + val composeTestRule = AndroidComposeTestRule( HomeActivityIntentTestRule.withDefaultSettingsOverrides(), ) { it.activity } @@ -25,29 +25,30 @@ class HTTPSFirstModeTest : TestSetup() { @Test fun httpsFirstModeImplicitSchemeTest() { - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser("permission.site".toUri()) { verifyPageContent("permission.site") - }.openNavigationToolbar { - verifyUrl("https://permission.site/") + }.openSearch { + verifyTypedToolbarText("https://permission.site/", exists = true) } } @Test fun httpsFirstModeExplicitSchemeTest() { - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser("http://permission.site".toUri()) { verifyPageContent("permission.site") - }.openNavigationToolbar { - verifyUrl("http://permission.site/") + }.openSearch { + verifyTypedToolbarText("http://permission.site/", exists = true) + }.dismissSearchBar { } // Exception should persist - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser("permission.site".toUri()) { verifyPageContent("permission.site") - }.openNavigationToolbar { - verifyUrl("http://permission.site/") + }.openSearch { + verifyTypedToolbarText("http://permission.site/", exists = true) } } } diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/HistoryTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/HistoryTest.kt @@ -8,6 +8,7 @@ import androidx.compose.ui.test.junit4.AndroidComposeTestRule import androidx.test.espresso.Espresso.openActionBarOverflowOrOptionsMenu import androidx.test.espresso.Espresso.pressBack import androidx.test.filters.SdkSuppress +import org.junit.Ignore import org.junit.Rule import org.junit.Test import org.mozilla.fenix.R @@ -15,6 +16,7 @@ import org.mozilla.fenix.customannotations.SkipLeaks import org.mozilla.fenix.customannotations.SmokeTest import org.mozilla.fenix.helpers.AppAndSystemHelper.registerAndCleanupIdlingResources import org.mozilla.fenix.helpers.HomeActivityIntentTestRule +import org.mozilla.fenix.helpers.MockBrowserDataHelper.createHistoryItem import org.mozilla.fenix.helpers.RecyclerViewIdlingResource import org.mozilla.fenix.helpers.TestAssetHelper.getGenericAsset import org.mozilla.fenix.helpers.TestAssetHelper.htmlControlsFormAsset @@ -36,7 +38,7 @@ import org.mozilla.fenix.ui.robots.navigationToolbar */ class HistoryTest : TestSetup() { @get:Rule - val activityTestRule = + val composeTestRule = AndroidComposeTestRule( HomeActivityIntentTestRule( // workaround for toolbar at top position by default @@ -51,10 +53,10 @@ class HistoryTest : TestSetup() { // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/243285 @Test fun verifyEmptyHistoryMenuTest() { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { verifyHistoryButton() - }.openHistory { + }.clickHistoryButton { verifyHistoryMenuView() verifyEmptyHistoryView() } @@ -68,14 +70,14 @@ class HistoryTest : TestSetup() { fun verifyHistoryMenuWithHistoryItemsTest() { val firstWebPage = mockWebServer.getGenericAsset(1) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(firstWebPage.url) { mDevice.waitForIdle() }.openThreeDotMenu { - }.openHistory { + }.clickHistoryButton { verifyHistoryListExists() registerAndCleanupIdlingResources( - RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.history_list), 1), + RecyclerViewIdlingResource(composeTestRule.activity.findViewById(R.id.history_list), 1), ) { verifyHistoryMenuView() verifyVisitedTimeTitle() @@ -91,15 +93,15 @@ class HistoryTest : TestSetup() { fun deleteHistoryItemTest() { val firstWebPage = mockWebServer.getGenericAsset(1) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(firstWebPage.url) { mDevice.waitForIdle() }.openThreeDotMenu { - }.openHistory { + }.clickHistoryButton { verifyHistoryListExists() registerAndCleanupIdlingResources( RecyclerViewIdlingResource( - activityTestRule.activity.findViewById(R.id.history_list), + composeTestRule.activity.findViewById(R.id.history_list), 1, ), ) { @@ -116,14 +118,14 @@ class HistoryTest : TestSetup() { fun deleteAllHistoryTest() { val firstWebPage = mockWebServer.getGenericAsset(1) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(firstWebPage.url) { mDevice.waitForIdle() }.openThreeDotMenu { - }.openHistory { + }.clickHistoryButton { verifyHistoryListExists() registerAndCleanupIdlingResources( - RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.history_list), 1), + RecyclerViewIdlingResource(composeTestRule.activity.findViewById(R.id.history_list), 1), ) { clickDeleteAllHistoryButton() } @@ -140,20 +142,20 @@ class HistoryTest : TestSetup() { fun historyMultiSelectionToolbarItemsTest() { val firstWebPage = mockWebServer.getGenericAsset(1) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(firstWebPage.url) { mDevice.waitForIdle() }.openThreeDotMenu { - }.openHistory { + }.clickHistoryButton { verifyHistoryListExists() registerAndCleanupIdlingResources( - RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.history_list), 1), + RecyclerViewIdlingResource(composeTestRule.activity.findViewById(R.id.history_list), 1), ) { longTapSelectItem(firstWebPage.url) } } - multipleSelectionToolbar { + multipleSelectionToolbar(composeTestRule) { verifyMultiSelectionCheckmark() verifyMultiSelectionCounter(1) verifyShareHistoryButton() @@ -168,26 +170,27 @@ class HistoryTest : TestSetup() { fun openMultipleSelectedHistoryItemsInANewTabTest() { val firstWebPage = mockWebServer.getGenericAsset(1) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(firstWebPage.url) { mDevice.waitForIdle() - }.openTabDrawer(activityTestRule) { + }.openTabDrawer(composeTestRule) { closeTab() } - homeScreen { }.openThreeDotMenu { - }.openHistory { + homeScreen(composeTestRule) { + }.openThreeDotMenu { + }.clickHistoryButton { verifyHistoryListExists() registerAndCleanupIdlingResources( - RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.history_list), 1), + RecyclerViewIdlingResource(composeTestRule.activity.findViewById(R.id.history_list), 1), ) { longTapSelectItem(firstWebPage.url) - openActionBarOverflowOrOptionsMenu(activityTestRule.activity) + openActionBarOverflowOrOptionsMenu(composeTestRule.activity) } } - multipleSelectionToolbar { - }.clickOpenNewTab(activityTestRule) { + multipleSelectionToolbar(composeTestRule) { + }.clickOpenNewTab { verifyNormalTabsList() verifyNormalBrowsingButtonIsSelected() } @@ -199,22 +202,22 @@ class HistoryTest : TestSetup() { fun openMultipleSelectedHistoryItemsInPrivateTabTest() { val firstWebPage = mockWebServer.getGenericAsset(1) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(firstWebPage.url) { mDevice.waitForIdle() }.openThreeDotMenu { - }.openHistory { + }.clickHistoryButton { verifyHistoryListExists() registerAndCleanupIdlingResources( - RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.history_list), 1), + RecyclerViewIdlingResource(composeTestRule.activity.findViewById(R.id.history_list), 1), ) { longTapSelectItem(firstWebPage.url) - openActionBarOverflowOrOptionsMenu(activityTestRule.activity) + openActionBarOverflowOrOptionsMenu(composeTestRule.activity) } } - multipleSelectionToolbar { - }.clickOpenPrivateTab(activityTestRule) { + multipleSelectionToolbar(composeTestRule) { + }.clickOpenPrivateTab { verifyPrivateTabsList() verifyPrivateBrowsingButtonIsSelected() } @@ -226,31 +229,29 @@ class HistoryTest : TestSetup() { val firstWebPage = mockWebServer.getGenericAsset(1) val secondWebPage = mockWebServer.getGenericAsset(2) - navigationToolbar { - }.enterURLAndEnterToBrowser(firstWebPage.url) { - }.openNavigationToolbar { - }.enterURLAndEnterToBrowser(secondWebPage.url) { - mDevice.waitForIdle() - verifyUrl(secondWebPage.url.toString()) + createHistoryItem(firstWebPage.url.toString()) + createHistoryItem(secondWebPage.url.toString()) + + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openHistory { + }.clickHistoryButton { verifyHistoryListExists() registerAndCleanupIdlingResources( - RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.history_list), 2), + RecyclerViewIdlingResource(composeTestRule.activity.findViewById(R.id.history_list), 2), ) { verifyHistoryItemExists(true, firstWebPage.url.toString()) verifyHistoryItemExists(true, secondWebPage.url.toString()) longTapSelectItem(firstWebPage.url) longTapSelectItem(secondWebPage.url) - openActionBarOverflowOrOptionsMenu(activityTestRule.activity) + openActionBarOverflowOrOptionsMenu(composeTestRule.activity) } } - multipleSelectionToolbar { + multipleSelectionToolbar(composeTestRule) { clickMultiSelectionDelete() } - historyMenu { + historyMenu(composeTestRule) { verifyEmptyHistoryView() } } @@ -260,20 +261,20 @@ class HistoryTest : TestSetup() { fun shareMultipleSelectedHistoryItemsTest() { val firstWebPage = mockWebServer.getGenericAsset(1) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(firstWebPage.url) { mDevice.waitForIdle() }.openThreeDotMenu { - }.openHistory { + }.clickHistoryButton { verifyHistoryListExists() registerAndCleanupIdlingResources( - RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.history_list), 1), + RecyclerViewIdlingResource(composeTestRule.activity.findViewById(R.id.history_list), 1), ) { longTapSelectItem(firstWebPage.url) } } - multipleSelectionToolbar { + multipleSelectionToolbar(composeTestRule) { clickShareHistoryButton() verifyShareOverlay() verifyShareTabFavicon() @@ -283,44 +284,43 @@ class HistoryTest : TestSetup() { } // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/1715627 + @Ignore("Disabled after enabling the composable toolbar and main menu: https://bugzilla.mozilla.org/show_bug.cgi?id=2006295") @Test fun verifySearchHistoryViewTest() { val defaultWebPage = mockWebServer.getGenericAsset(1) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(defaultWebPage.url) { }.openThreeDotMenu { - }.openHistory { + }.clickHistoryButton { }.clickSearchButton { - verifySearchView() verifySearchToolbar(true) verifySearchSelectorButton() - verifySearchEngineIcon("history") + verifySearchEngineIcon("History") verifySearchBarPlaceholder("Search history") verifySearchBarPosition(true) tapOutsideToDismissSearchBar() verifySearchToolbar(false) exitMenu() } - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openCustomizeSubMenu { clickTopToolbarToggle() } exitMenu() - browserScreen { + browserScreen(composeTestRule) { }.openThreeDotMenu { - }.openHistory { + }.clickHistoryButton { }.clickSearchButton { - verifySearchView() verifySearchToolbar(true) verifySearchBarPosition(false) pressBack() } - historyMenu { + historyMenu(composeTestRule) { verifyHistoryMenuView() } } @@ -329,12 +329,12 @@ class HistoryTest : TestSetup() { @SdkSuppress(minSdkVersion = 34) @Test fun verifyVoiceSearchInHistoryTest() { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openHistory { + }.clickHistoryButton { }.clickSearchButton { verifySearchToolbar(true) - verifySearchEngineIcon("history") + verifySearchEngineIcon("History") startVoiceSearch() } } @@ -345,23 +345,23 @@ class HistoryTest : TestSetup() { val firstWebPage = mockWebServer.getGenericAsset(1) val secondWebPage = mockWebServer.htmlControlsFormAsset - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(firstWebPage.url) { } - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(secondWebPage.url) { }.openThreeDotMenu { - }.openHistory { + }.clickHistoryButton { }.clickSearchButton { // Search for a valid term typeSearch(firstWebPage.title) - verifySearchSuggestionsAreDisplayed(activityTestRule, firstWebPage.url.toString()) - verifySuggestionsAreNotDisplayed(activityTestRule, secondWebPage.url.toString()) + verifySearchSuggestionsAreDisplayed(firstWebPage.url.toString()) + verifySuggestionsAreNotDisplayed(secondWebPage.url.toString()) clickClearButton() // Search for invalid term typeSearch("Android") - verifySuggestionsAreNotDisplayed(activityTestRule, firstWebPage.url.toString()) - verifySuggestionsAreNotDisplayed(activityTestRule, secondWebPage.url.toString()) + verifySuggestionsAreNotDisplayed(firstWebPage.url.toString()) + verifySuggestionsAreNotDisplayed(secondWebPage.url.toString()) } } @@ -372,19 +372,19 @@ class HistoryTest : TestSetup() { val secondWebPage = mockWebServer.getGenericAsset(2) val thirdWebPage = mockWebServer.getGenericAsset(3) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(firstWebPage.url) { verifyPageContent(firstWebPage.content) } - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(secondWebPage.url) { verifyPageContent(secondWebPage.content) } - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(thirdWebPage.url) { verifyPageContent(thirdWebPage.content) }.openThreeDotMenu { - }.openHistory { + }.clickHistoryButton { verifyHistoryListExists() clickDeleteHistoryButton(firstWebPage.title) verifyHistoryItemExists(false, firstWebPage.title) @@ -393,18 +393,18 @@ class HistoryTest : TestSetup() { }.clickSearchButton { // Search for a valid term typeSearch("generic") - verifySuggestionsAreNotDisplayed(activityTestRule, firstWebPage.url.toString()) - verifySuggestionsAreNotDisplayed(activityTestRule, secondWebPage.url.toString()) - verifySponsoredSuggestionsResults(activityTestRule, thirdWebPage.url.toString(), searchTerm = "generic") + verifySuggestionsAreNotDisplayed(firstWebPage.url.toString()) + verifySuggestionsAreNotDisplayed(secondWebPage.url.toString()) + verifySponsoredSuggestionsResults(thirdWebPage.url.toString(), searchTerm = "generic") pressBack() } - historyMenu { + historyMenu(composeTestRule) { clickDeleteHistoryButton(thirdWebPage.title) verifyHistoryItemExists(false, firstWebPage.title) }.clickSearchButton { // Search for a valid term typeSearch("generic") - verifySuggestionsAreNotDisplayed(activityTestRule, thirdWebPage.url.toString()) + verifySuggestionsAreNotDisplayed(thirdWebPage.url.toString()) } } @@ -416,15 +416,14 @@ class HistoryTest : TestSetup() { fun noHistoryInPrivateBrowsingTest() { val website = mockWebServer.getGenericAsset(1) - homeScreen { + homeScreen(composeTestRule) { }.togglePrivateBrowsingMode() - homeScreen { - }.openNavigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(website.url) { mDevice.waitForIdle() }.openThreeDotMenu { - }.openHistory { + }.clickHistoryButton { verifyEmptyHistoryView() } } @@ -434,10 +433,10 @@ class HistoryTest : TestSetup() { fun openHistoryItemTest() { val defaultWebPage = mockWebServer.getGenericAsset(1) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(defaultWebPage.url) { }.openThreeDotMenu { - }.openHistory { + }.clickHistoryButton { }.openWebsite(defaultWebPage.url) { verifyUrl(defaultWebPage.url.toString()) } diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/HomeScreenTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/HomeScreenTest.kt @@ -27,7 +27,7 @@ import org.mozilla.fenix.ui.robots.navigationToolbar class HomeScreenTest : TestSetup() { @get:Rule(order = 0) - val activityTestRule = + val composeTestRule = AndroidComposeTestRule( HomeActivityIntentTestRule.withDefaultSettingsOverrides(), ) { it.activity } @@ -43,20 +43,19 @@ class HomeScreenTest : TestSetup() { @Test fun homeScreenItemsTest() { // Workaround to make sure the Pocket articles are populated before starting the test. - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { - }.goBack { + }.clickSettingsButton { + }.goBack(composeTestRule) { verifyHomeWordmark() verifyHomePrivateBrowsingButton() - verifyExistingTopSitesTabs(activityTestRule, "Wikipedia") - verifyExistingTopSitesTabs(activityTestRule, "Google") - verifyCollectionsHeader(activityTestRule) - verifyNoCollectionsText(activityTestRule) + verifyExistingTopSitesTabs("Wikipedia") + verifyExistingTopSitesTabs("Google") + verifyCollectionsHeader() + verifyNoCollectionsText() verifyThoughtProvokingStories(true) verifyNavigationToolbar() verifyHomeMenuButton() - verifyTabButton() verifyTabCounter("0") } } @@ -64,11 +63,12 @@ class HomeScreenTest : TestSetup() { // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/244199 @Test fun privateBrowsingHomeScreenItemsTest() { - homeScreen { }.togglePrivateBrowsingMode() + homeScreen(composeTestRule) { + }.togglePrivateBrowsingMode() - homeScreen { + homeScreen(composeTestRule) { verifyPrivateBrowsingHomeScreenItems() - }.openPrivateBrowsingModeLearnMoreLink(activityTestRule) { + }.openPrivateBrowsingModeLearnMoreLink { verifyUrl("common-myths-about-private-browsing") } } @@ -78,7 +78,7 @@ class HomeScreenTest : TestSetup() { @Ignore("disabled - https://bugzilla.mozilla.org/show_bug.cgi?id=1989405") @Test fun verifyJumpBackInSectionTest() { - activityTestRule.activityRule.applySettingsExceptions { + composeTestRule.activityRule.applySettingsExceptions { it.isRecentlyVisitedFeatureEnabled = false it.isPocketEnabled = false } @@ -86,45 +86,45 @@ class HomeScreenTest : TestSetup() { val firstWebPage = mockWebServer.getGenericAsset(4) val secondWebPage = mockWebServer.getGenericAsset(1) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(firstWebPage.url) { verifyPageContent(firstWebPage.content) verifyUrl(firstWebPage.url.toString()) - }.goToHomescreen(activityTestRule) { + }.goToHomescreen { verifyJumpBackInSectionIsDisplayed() - verifyJumpBackInItemTitle(activityTestRule, firstWebPage.title) - verifyJumpBackInItemWithUrl(activityTestRule, firstWebPage.url.toString()) + verifyJumpBackInItemTitle(composeTestRule, firstWebPage.title) + verifyJumpBackInItemWithUrl(composeTestRule, firstWebPage.url.toString()) verifyJumpBackInShowAllButton() - }.clickJumpBackInShowAllButton(activityTestRule) { + }.clickJumpBackInShowAllButton { verifyExistingOpenTabs(firstWebPage.title) }.closeTabDrawer { } - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(secondWebPage.url) { verifyPageContent(secondWebPage.content) verifyUrl(secondWebPage.url.toString()) - }.goToHomescreen(activityTestRule) { + }.goToHomescreen { verifyJumpBackInSectionIsDisplayed() - verifyJumpBackInItemTitle(activityTestRule, secondWebPage.title) - verifyJumpBackInItemWithUrl(activityTestRule, secondWebPage.url.toString()) - }.openTabDrawer(activityTestRule) { + verifyJumpBackInItemTitle(composeTestRule, secondWebPage.title) + verifyJumpBackInItemWithUrl(composeTestRule, secondWebPage.url.toString()) + }.openTabDrawer { closeTabWithTitle(secondWebPage.title) waitUntilSnackbarGone() verifyExistingOpenTabs(firstWebPage.title) }.closeTabDrawer { } - homeScreen { + homeScreen(composeTestRule) { verifyJumpBackInSectionIsDisplayed() - verifyJumpBackInItemTitle(activityTestRule, firstWebPage.title) - verifyJumpBackInItemWithUrl(activityTestRule, firstWebPage.url.toString()) - }.openTabDrawer(activityTestRule) { + verifyJumpBackInItemTitle(composeTestRule, firstWebPage.title) + verifyJumpBackInItemWithUrl(composeTestRule, firstWebPage.url.toString()) + }.openTabDrawer { closeTab() } - homeScreen { - verifyJumpBackInSectionIsNotDisplayed(activityTestRule) + homeScreen(composeTestRule) { + verifyJumpBackInSectionIsNotDisplayed() } } } diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/LoginsTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/LoginsTest.kt @@ -66,9 +66,9 @@ class LoginsTest : TestSetup() { // Tests the Passwords menu items and default values @Test fun loginsAndPasswordsSettingsItemsTest() { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { // Necessary to scroll a little bit for all screen sizes scrollToElementByText("Passwords") }.openLoginsAndPasswordSubMenu { @@ -83,27 +83,27 @@ class LoginsTest : TestSetup() { // For tests after signing in, see SyncIntegration test suite @Test fun verifySavedLoginsListTest() { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { // Necessary to scroll a little bit for all screen sizes scrollToElementByText("Passwords") }.openLoginsAndPasswordSubMenu { verifyDefaultView() - }.openSavedLogins { + }.openSavedLogins(composeTestRule) { verifySecurityPromptForLogins() tapSetupLater() // Verify that logins list is empty - verifyEmptySavedLoginsListView(composeTestRule) + verifyEmptySavedLoginsListView() } } // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2092925 @Test fun verifySyncLoginsOptionsTest() { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { // Necessary to scroll a little bit for all screen sizes scrollToElementByText("Passwords") }.openLoginsAndPasswordSubMenu { @@ -118,9 +118,9 @@ class LoginsTest : TestSetup() { fun saveLoginFromPromptTest() { val saveLoginTest = mockWebServer.saveLoginAsset - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openLoginsAndPasswordSubMenu { }.openSaveLoginsAndPasswordsOptions { verifySaveLoginsOptionsView() @@ -128,20 +128,20 @@ class LoginsTest : TestSetup() { exitMenu() - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(saveLoginTest.url) { clickSubmitLoginButton() verifySaveLoginPromptIsDisplayed() // Click save to save the login - clickPageObject(itemWithText("Save")) + clickPageObject(composeTestRule, itemWithText("Save")) } - browserScreen { + browserScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { scrollToElementByText("Passwords") }.openLoginsAndPasswordSubMenu { verifyDefaultView() - }.openSavedLogins { + }.openSavedLogins(composeTestRule) { verifySecurityPromptForLogins() tapSetupLater() // Verify that the login appears correctly @@ -157,24 +157,24 @@ class LoginsTest : TestSetup() { val userName = "test" val password = "pass" - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(loginPage.toUri()) { - setPageObjectText(itemWithResId("username"), userName) + setPageObjectText(composeTestRule, itemWithResId("username"), userName) waitForAppWindowToBeUpdated() - setPageObjectText(itemWithResId("password"), password) + setPageObjectText(composeTestRule, itemWithResId("password"), password) waitForAppWindowToBeUpdated() - clickPageObject(itemWithResId("submit")) + clickPageObject(composeTestRule, itemWithResId("submit")) verifySaveLoginPromptIsDisplayed() - clickPageObject(itemWithText("Save")) + clickPageObject(composeTestRule, itemWithText("Save")) mDevice.waitForIdle() }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openLoginsAndPasswordSubMenu { - }.openSavedLogins { + }.openSavedLogins(composeTestRule) { verifySecurityPromptForLogins() tapSetupLater() - viewSavedLoginDetails(composeTestRule, userName) - }.goToSavedWebsite(composeTestRule) { + viewSavedLoginDetails(userName) + }.goToSavedWebsite { verifyUrl(originWebsite) } } @@ -184,24 +184,24 @@ class LoginsTest : TestSetup() { fun neverSaveLoginFromPromptTest() { val saveLoginTest = mockWebServer.saveLoginAsset - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(saveLoginTest.url) { clickSubmitLoginButton() // Don't save the login, add to exceptions - clickPageObject(itemWithText("Never save")) + clickPageObject(composeTestRule, itemWithText("Never save")) mDevice.waitForIdle() }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openLoginsAndPasswordSubMenu { verifyDefaultView() - }.openSavedLogins { + }.openSavedLogins(composeTestRule) { verifySecurityPromptForLogins() tapSetupLater() // Verify that the login list is empty - verifyEmptySavedLoginsListView(composeTestRule) - verifyNotSavedLoginFromPrompt(composeTestRule) - }.goBack(composeTestRule) { - }.openLoginExceptions { + verifyEmptySavedLoginsListView() + verifyNotSavedLoginFromPrompt() + }.goBack { + }.openLoginExceptions(composeTestRule) { // Verify localhost was added to exceptions list verifyLocalhostExceptionAdded() } @@ -214,32 +214,33 @@ class LoginsTest : TestSetup() { fun verifyUpdatedLoginIsSavedTest() { val saveLoginTest = mockWebServer.saveLoginAsset - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(saveLoginTest.url) { clickSubmitLoginButton() verifySaveLoginPromptIsDisplayed() // Click Save to save the login - clickPageObject(itemWithText("Save")) - }.openNavigationToolbar { + clickPageObject(composeTestRule, itemWithText("Save")) + } + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(saveLoginTest.url) { enterPassword("test") mDevice.waitForIdle() clickSubmitLoginButton() verifySaveLoginPromptIsDisplayed() // Click Update to change the saved password - clickPageObject(itemWithText("Update")) + clickPageObject(composeTestRule, itemWithText("Update")) }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { scrollToElementByText("Passwords") }.openLoginsAndPasswordSubMenu { - }.openSavedLogins { + }.openSavedLogins(composeTestRule) { verifySecurityPromptForLogins() tapSetupLater() // Verify that the login appears correctly verifySavedLoginsSectionUsername("test@example.com") - viewSavedLoginDetails(composeTestRule, "test@example.com") - revealPassword(composeTestRule) - verifyPasswordSaved(composeTestRule, "test") + viewSavedLoginDetails("test@example.com") + revealPassword() + verifyPasswordSaved("test") } } @@ -253,33 +254,33 @@ class LoginsTest : TestSetup() { val secondUser = "fenix" val secondPass = "pass" - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(loginPage.toUri()) { - setPageObjectText(itemWithResId("username"), firstUser) + setPageObjectText(composeTestRule, itemWithResId("username"), firstUser) waitForAppWindowToBeUpdated() - setPageObjectText(itemWithResId("password"), firstPass) + setPageObjectText(composeTestRule, itemWithResId("password"), firstPass) waitForAppWindowToBeUpdated() - clickPageObject(itemWithResId("submit")) + clickPageObject(composeTestRule, itemWithResId("submit")) verifySaveLoginPromptIsDisplayed() - clickPageObject(itemWithText("Save")) - setPageObjectText(itemWithResId("username"), secondUser) + clickPageObject(composeTestRule, itemWithText("Save")) + setPageObjectText(composeTestRule, itemWithResId("username"), secondUser) waitForAppWindowToBeUpdated() - setPageObjectText(itemWithResId("password"), secondPass) + setPageObjectText(composeTestRule, itemWithResId("password"), secondPass) waitForAppWindowToBeUpdated() - clickPageObject(itemWithResId("submit")) + clickPageObject(composeTestRule, itemWithResId("submit")) verifySaveLoginPromptIsDisplayed() - clickPageObject(itemWithText("Save")) + clickPageObject(composeTestRule, itemWithText("Save")) waitUntilSnackbarGone() } - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(loginPage.toUri()) { - clickPageObject(itemWithResId("username")) + clickPageObject(composeTestRule, itemWithResId("username")) clickSuggestedLoginsButton() - verifySuggestedUserName(composeTestRule, firstUser) - verifySuggestedUserName(composeTestRule, secondUser) - clickSuggestedLogin(composeTestRule, firstUser) - clickPageObject(itemWithResId("togglePassword")) - verifyPrefilledLoginCredentials(composeTestRule, firstUser, firstPass, true) + verifySuggestedUserName(firstUser) + verifySuggestedUserName(secondUser) + clickSuggestedLogin(firstUser) + clickPageObject(composeTestRule, itemWithResId("togglePassword")) + verifyPrefilledLoginCredentials(firstUser, firstPass, true) } } @@ -290,29 +291,29 @@ class LoginsTest : TestSetup() { val loginPage = "https://mozilla-mobile.github.io/testapp/loginForm" val originWebsite = "https://mozilla-mobile.github.io" - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(loginPage.toUri()) { - setPageObjectText(itemWithResId("username"), "mozilla") + setPageObjectText(composeTestRule, itemWithResId("username"), "mozilla") waitForAppWindowToBeUpdated() - setPageObjectText(itemWithResId("password"), "firefox") + setPageObjectText(composeTestRule, itemWithResId("password"), "firefox") waitForAppWindowToBeUpdated() - clickPageObject(itemWithResId("submit")) + clickPageObject(composeTestRule, itemWithResId("submit")) verifySaveLoginPromptIsDisplayed() - clickPageObject(itemWithText("Save")) + clickPageObject(composeTestRule, itemWithText("Save")) mDevice.waitForIdle() }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openLoginsAndPasswordSubMenu { - }.openSavedLogins { + }.openSavedLogins(composeTestRule) { tapSetupLater() - viewSavedLoginDetails(composeTestRule, originWebsite) - clickThreeDotButton(composeTestRule) - clickEditLoginButton(composeTestRule) - setNewPasswordWhileEditingALogin(composeTestRule, "fenix") - saveEditedLogin(composeTestRule) - clickThreeDotButton(composeTestRule) - clickEditLoginButton(composeTestRule) - verifyPasswordWhileEditingALogin(composeTestRule, "fenix") + viewSavedLoginDetails(originWebsite) + clickThreeDotButton() + clickEditLoginButton() + setNewPasswordWhileEditingALogin("fenix") + saveEditedLogin() + clickThreeDotButton() + clickEditLoginButton() + verifyPasswordWhileEditingALogin("fenix") } } @@ -322,40 +323,40 @@ class LoginsTest : TestSetup() { val loginPage = "https://mozilla-mobile.github.io/testapp/v2.0/loginForm.html" val originWebsite = "https://mozilla-mobile.github.io" - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(loginPage.toUri()) { waitForPageToLoad(pageLoadWaitingTime = waitingTimeLong) - setPageObjectText(itemWithResId("username"), "mozilla") + setPageObjectText(composeTestRule, itemWithResId("username"), "mozilla") waitForAppWindowToBeUpdated() - setPageObjectText(itemWithResId("password"), "firefox") + setPageObjectText(composeTestRule, itemWithResId("password"), "firefox") waitForAppWindowToBeUpdated() - clickPageObject(itemWithResId("submit")) + clickPageObject(composeTestRule, itemWithResId("submit")) verifySaveLoginPromptIsDisplayed() - clickPageObject(itemWithText("Save")) + clickPageObject(composeTestRule, itemWithText("Save")) mDevice.waitForIdle() }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openLoginsAndPasswordSubMenu { - }.openSavedLogins { + }.openSavedLogins(composeTestRule) { tapSetupLater() - viewSavedLoginDetails(composeTestRule, originWebsite) - clickThreeDotButton(composeTestRule) - clickEditLoginButton(composeTestRule) - setNewUserNameWhileEditingALogin(composeTestRule, "android") - setNewPasswordWhileEditingALogin(composeTestRule, "fenix") - saveEditedLogin(composeTestRule) - clickGoBackButton(composeTestRule) - }.goBack(composeTestRule) { + viewSavedLoginDetails(originWebsite) + clickThreeDotButton() + clickEditLoginButton() + setNewUserNameWhileEditingALogin("android") + setNewPasswordWhileEditingALogin("fenix") + saveEditedLogin() + clickGoBackButton() + }.goBack { } exitMenu() - browserScreen { + browserScreen(composeTestRule) { }.openThreeDotMenu { - }.refreshPage { + }.clickRefreshButton { waitForPageToLoad(pageLoadWaitingTime = waitingTimeLong) - clickPageObject(itemWithResId("togglePassword")) - verifyPrefilledLoginCredentials(composeTestRule, "android", "fenix", true) + clickPageObject(composeTestRule, itemWithResId("togglePassword")) + verifyPrefilledLoginCredentials("android", "fenix", true) } } @@ -366,29 +367,29 @@ class LoginsTest : TestSetup() { val loginPage = "https://mozilla-mobile.github.io/testapp/loginForm" val originWebsite = "https://mozilla-mobile.github.io" - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(loginPage.toUri()) { - setPageObjectText(itemWithResId("username"), "mozilla") + setPageObjectText(composeTestRule, itemWithResId("username"), "mozilla") waitForAppWindowToBeUpdated() - setPageObjectText(itemWithResId("password"), "firefox") + setPageObjectText(composeTestRule, itemWithResId("password"), "firefox") waitForAppWindowToBeUpdated() - clickPageObject(itemWithResId("submit")) + clickPageObject(composeTestRule, itemWithResId("submit")) verifySaveLoginPromptIsDisplayed() - clickPageObject(itemWithText("Save")) + clickPageObject(composeTestRule, itemWithText("Save")) mDevice.waitForIdle() }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openLoginsAndPasswordSubMenu { - }.openSavedLogins { + }.openSavedLogins(composeTestRule) { tapSetupLater() - viewSavedLoginDetails(composeTestRule, originWebsite) - clickThreeDotButton(composeTestRule) - clickEditLoginButton(composeTestRule) - clickClearUserNameButton(composeTestRule) - verifyUserNameRequiredErrorMessage(composeTestRule) - verifySaveLoginButtonIsEnabled(composeTestRule, false) - clickGoBackButton(composeTestRule) - verifyLoginItemUsername(composeTestRule, "mozilla") + viewSavedLoginDetails(originWebsite) + clickThreeDotButton() + clickEditLoginButton() + clickClearUserNameButton() + verifyUserNameRequiredErrorMessage() + verifySaveLoginButtonIsEnabled(false) + clickGoBackButton() + verifyLoginItemUsername("mozilla") } } @@ -399,30 +400,30 @@ class LoginsTest : TestSetup() { val loginPage = "https://mozilla-mobile.github.io/testapp/loginForm" val originWebsite = "https://mozilla-mobile.github.io" - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(loginPage.toUri()) { - setPageObjectText(itemWithResId("username"), "mozilla") + setPageObjectText(composeTestRule, itemWithResId("username"), "mozilla") waitForAppWindowToBeUpdated() - setPageObjectText(itemWithResId("password"), "firefox") + setPageObjectText(composeTestRule, itemWithResId("password"), "firefox") waitForAppWindowToBeUpdated() - clickPageObject(itemWithResId("submit")) + clickPageObject(composeTestRule, itemWithResId("submit")) verifySaveLoginPromptIsDisplayed() - clickPageObject(itemWithText("Save")) + clickPageObject(composeTestRule, itemWithText("Save")) mDevice.waitForIdle() }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openLoginsAndPasswordSubMenu { - }.openSavedLogins { + }.openSavedLogins(composeTestRule) { tapSetupLater() - viewSavedLoginDetails(composeTestRule, originWebsite) - clickThreeDotButton(composeTestRule) - clickEditLoginButton(composeTestRule) - clickClearPasswordButton(composeTestRule) - verifyPasswordRequiredErrorMessage(composeTestRule) - verifySaveLoginButtonIsEnabled(composeTestRule, false) - clickGoBackButton(composeTestRule) - revealPassword(composeTestRule) - verifyPasswordSaved(composeTestRule, "firefox") + viewSavedLoginDetails(originWebsite) + clickThreeDotButton() + clickEditLoginButton() + clickClearPasswordButton() + verifyPasswordRequiredErrorMessage() + verifySaveLoginButtonIsEnabled(false) + clickGoBackButton() + revealPassword() + verifyPasswordSaved("firefox") } } @@ -433,30 +434,30 @@ class LoginsTest : TestSetup() { val loginPage = "https://mozilla-mobile.github.io/testapp/loginForm" val originWebsite = "https://mozilla-mobile.github.io" - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(loginPage.toUri()) { - setPageObjectText(itemWithResId("username"), "mozilla") + setPageObjectText(composeTestRule, itemWithResId("username"), "mozilla") waitForAppWindowToBeUpdated() - setPageObjectText(itemWithResId("password"), "firefox") + setPageObjectText(composeTestRule, itemWithResId("password"), "firefox") waitForAppWindowToBeUpdated() - clickPageObject(itemWithResId("submit")) + clickPageObject(composeTestRule, itemWithResId("submit")) verifySaveLoginPromptIsDisplayed() - clickPageObject(itemWithText("Save")) + clickPageObject(composeTestRule, itemWithText("Save")) mDevice.waitForIdle() }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openLoginsAndPasswordSubMenu { - }.openSavedLogins { + }.openSavedLogins(composeTestRule) { tapSetupLater() - viewSavedLoginDetails(composeTestRule, originWebsite) - clickThreeDotButton(composeTestRule) - clickEditLoginButton(composeTestRule) - setNewUserNameWhileEditingALogin(composeTestRule, "android") - setNewPasswordWhileEditingALogin(composeTestRule, "fenix") - clickGoBackButton(composeTestRule) - verifyLoginItemUsername(composeTestRule, "mozilla") - revealPassword(composeTestRule) - verifyPasswordSaved(composeTestRule, "firefox") + viewSavedLoginDetails(originWebsite) + clickThreeDotButton() + clickEditLoginButton() + setNewUserNameWhileEditingALogin("android") + setNewPasswordWhileEditingALogin("fenix") + clickGoBackButton() + verifyLoginItemUsername("mozilla") + revealPassword() + verifyPasswordSaved("firefox") } } @@ -465,27 +466,27 @@ class LoginsTest : TestSetup() { fun verifyDeleteLoginButtonTest() { val loginPage = mockWebServer.saveLoginAsset - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(loginPage.url) { clickSubmitLoginButton() - clickPageObject(itemWithText("Save")) + clickPageObject(composeTestRule, itemWithText("Save")) mDevice.waitForIdle() }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openLoginsAndPasswordSubMenu { - }.openSavedLogins { + }.openSavedLogins(composeTestRule) { tapSetupLater() - viewSavedLoginDetails(composeTestRule, "test@example.com") - clickThreeDotButton(composeTestRule) - clickDeleteLoginButton(composeTestRule) - verifyLoginDeletionPrompt(composeTestRule) - clickCancelDeleteLogin(composeTestRule) - verifyLoginItemUsername(composeTestRule, "test@example.com") - viewSavedLoginDetails(composeTestRule, "test@example.com") - clickThreeDotButton(composeTestRule) - clickDeleteLoginButton(composeTestRule) - verifyLoginDeletionPrompt(composeTestRule) - clickConfirmDeleteLogin(composeTestRule) + viewSavedLoginDetails("test@example.com") + clickThreeDotButton() + clickDeleteLoginButton() + verifyLoginDeletionPrompt() + clickCancelDeleteLogin() + verifyLoginItemUsername("test@example.com") + viewSavedLoginDetails("test@example.com") + clickThreeDotButton() + clickDeleteLoginButton() + verifyLoginDeletionPrompt() + clickConfirmDeleteLogin() // The account remains displayed, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1812431 // verifyNotSavedLoginFromPrompt() } @@ -498,9 +499,9 @@ class LoginsTest : TestSetup() { fun verifyNeverSaveLoginOptionTest() { val loginPage = mockWebServer.saveLoginAsset - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openLoginsAndPasswordSubMenu { }.openSaveLoginsAndPasswordsOptions { clickNeverSaveOption() @@ -509,7 +510,7 @@ class LoginsTest : TestSetup() { exitMenu() - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(loginPage.url) { clickSubmitLoginButton() verifySaveLoginPromptIsNotDisplayed() @@ -522,33 +523,33 @@ class LoginsTest : TestSetup() { fun verifyAutofillToggleTest() { val loginPage = "https://mozilla-mobile.github.io/testapp/v2.0/loginForm.html" - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(loginPage.toUri()) { waitForPageToLoad(pageLoadWaitingTime = waitingTimeLong) - setPageObjectText(itemWithResId("username"), "mozilla") + setPageObjectText(composeTestRule, itemWithResId("username"), "mozilla") waitForAppWindowToBeUpdated() - setPageObjectText(itemWithResId("password"), "firefox") + setPageObjectText(composeTestRule, itemWithResId("password"), "firefox") waitForAppWindowToBeUpdated() - clickPageObject(itemWithResId("submit")) + clickPageObject(composeTestRule, itemWithResId("submit")) waitForPageToLoad(pageLoadWaitingTime = waitingTimeLong) verifySaveLoginPromptIsDisplayed() - clickPageObject(itemWithText("Save")) + clickPageObject(composeTestRule, itemWithText("Save")) }.openTabDrawer(composeTestRule) { closeTab() } - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(loginPage.toUri()) { waitForPageToLoad(pageLoadWaitingTime = waitingTimeLong) - clickPageObject(itemWithResId("togglePassword")) - verifyPrefilledLoginCredentials(composeTestRule, "mozilla", "firefox", true) + clickPageObject(composeTestRule, itemWithResId("togglePassword")) + verifyPrefilledLoginCredentials("mozilla", "firefox", true) }.openTabDrawer(composeTestRule) { closeTab() } - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openLoginsAndPasswordSubMenu { verifyAutofillInFirefoxToggle(true) clickAutofillInFirefoxOption() @@ -558,9 +559,9 @@ class LoginsTest : TestSetup() { exitMenu() - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(loginPage.toUri()) { - verifyPrefilledLoginCredentials(composeTestRule, "mozilla", "firefox", false) + verifyPrefilledLoginCredentials("mozilla", "firefox", false) } } @@ -571,32 +572,32 @@ class LoginsTest : TestSetup() { val loginPage = "https://mozilla-mobile.github.io/testapp/v2.0/loginForm.html" val originWebsite = "https://mozilla-mobile.github.io" - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(loginPage.toUri()) { - setPageObjectText(itemWithResId("username"), "mozilla") + setPageObjectText(composeTestRule, itemWithResId("username"), "mozilla") waitForAppWindowToBeUpdated() - setPageObjectText(itemWithResId("password"), "firefox") + setPageObjectText(composeTestRule, itemWithResId("password"), "firefox") waitForAppWindowToBeUpdated() - clickPageObject(itemWithResId("submit")) + clickPageObject(composeTestRule, itemWithResId("submit")) verifySaveLoginPromptIsDisplayed() - clickPageObject(itemWithText("Save")) + clickPageObject(composeTestRule, itemWithText("Save")) waitForAppWindowToBeUpdated() - clickPageObject(itemWithResId("togglePassword")) - setPageObjectText(itemWithResId("username"), "mozilla") + clickPageObject(composeTestRule, itemWithResId("togglePassword")) + setPageObjectText(composeTestRule, itemWithResId("username"), "mozilla") waitForAppWindowToBeUpdated() - setPageObjectText(itemWithResId("password"), "fenix") + setPageObjectText(composeTestRule, itemWithResId("password"), "fenix") waitForAppWindowToBeUpdated() - clickPageObject(itemWithResId("submit")) + clickPageObject(composeTestRule, itemWithResId("submit")) verifySaveLoginPromptIsDisplayed() - clickPageObject(itemWithText("Not now")) + clickPageObject(composeTestRule, itemWithText("Not now")) }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openLoginsAndPasswordSubMenu { - }.openSavedLogins { + }.openSavedLogins(composeTestRule) { tapSetupLater() - viewSavedLoginDetails(composeTestRule, originWebsite) - revealPassword(composeTestRule) - verifyPasswordSaved(composeTestRule, "firefox") + viewSavedLoginDetails(originWebsite) + revealPassword() + verifyPasswordSaved("firefox") } } @@ -608,43 +609,44 @@ class LoginsTest : TestSetup() { val secondLoginPage = "https://mozilla-mobile.github.io/testapp/v2.0/loginForm.html" val originWebsite = "https://mozilla-mobile.github.io" - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(firstLoginPage.url) { clickSubmitLoginButton() verifySaveLoginPromptIsDisplayed() - clickPageObject(itemWithText("Save")) - }.openNavigationToolbar { + clickPageObject(composeTestRule, itemWithText("Save")) + } + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(secondLoginPage.toUri()) { - setPageObjectText(itemWithResId("username"), "android") - setPageObjectText(itemWithResId("password"), "firefox") - clickPageObject(itemWithResId("submit")) + setPageObjectText(composeTestRule, itemWithResId("username"), "android") + setPageObjectText(composeTestRule, itemWithResId("password"), "firefox") + clickPageObject(composeTestRule, itemWithResId("submit")) verifySaveLoginPromptIsDisplayed() - clickPageObject(itemWithText("Save")) + clickPageObject(composeTestRule, itemWithText("Save")) }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openLoginsAndPasswordSubMenu { - }.openSavedLogins { + }.openSavedLogins(composeTestRule) { tapSetupLater() - clickSearchLoginButton(composeTestRule) - searchLogin(composeTestRule, "ANDROID") - viewSavedLoginDetails(composeTestRule, originWebsite) - verifyLoginItemUsername(composeTestRule, "android") - revealPassword(composeTestRule) - verifyPasswordSaved(composeTestRule, "firefox") - clickGoBackButton(composeTestRule) - clickSearchLoginButton(composeTestRule) - searchLogin(composeTestRule, "android") - viewSavedLoginDetails(composeTestRule, originWebsite) - verifyLoginItemUsername(composeTestRule, "android") - revealPassword(composeTestRule) - verifyPasswordSaved(composeTestRule, "firefox") - clickGoBackButton(composeTestRule) - clickSearchLoginButton(composeTestRule) - searchLogin(composeTestRule, "AnDrOiD") - viewSavedLoginDetails(composeTestRule, originWebsite) - verifyLoginItemUsername(composeTestRule, "android") - revealPassword(composeTestRule) - verifyPasswordSaved(composeTestRule, "firefox") + clickSearchLoginButton() + searchLogin("ANDROID") + viewSavedLoginDetails(originWebsite) + verifyLoginItemUsername("android") + revealPassword() + verifyPasswordSaved("firefox") + clickGoBackButton() + clickSearchLoginButton() + searchLogin("android") + viewSavedLoginDetails(originWebsite) + verifyLoginItemUsername("android") + revealPassword() + verifyPasswordSaved("firefox") + clickGoBackButton() + clickSearchLoginButton() + searchLogin("AnDrOiD") + viewSavedLoginDetails(originWebsite) + verifyLoginItemUsername("android") + revealPassword() + verifyPasswordSaved("firefox") } } @@ -656,43 +658,44 @@ class LoginsTest : TestSetup() { val secondLoginPage = "https://mozilla-mobile.github.io/testapp/v2.0/loginForm.html" val originWebsite = "https://mozilla-mobile.github.io" - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(firstLoginPage.url) { clickSubmitLoginButton() verifySaveLoginPromptIsDisplayed() - clickPageObject(itemWithText("Save")) - }.openNavigationToolbar { + clickPageObject(composeTestRule, itemWithText("Save")) + } + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(secondLoginPage.toUri()) { - setPageObjectText(itemWithResId("username"), "android") - setPageObjectText(itemWithResId("password"), "firefox") - clickPageObject(itemWithResId("submit")) + setPageObjectText(composeTestRule, itemWithResId("username"), "android") + setPageObjectText(composeTestRule, itemWithResId("password"), "firefox") + clickPageObject(composeTestRule, itemWithResId("submit")) verifySaveLoginPromptIsDisplayed() - clickPageObject(itemWithText("Save")) + clickPageObject(composeTestRule, itemWithText("Save")) }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openLoginsAndPasswordSubMenu { - }.openSavedLogins { + }.openSavedLogins(composeTestRule) { tapSetupLater() - clickSearchLoginButton(composeTestRule) - searchLogin(composeTestRule, "MOZILLA") - viewSavedLoginDetails(composeTestRule, originWebsite) - verifyLoginItemUsername(composeTestRule, "android") - revealPassword(composeTestRule) - verifyPasswordSaved(composeTestRule, "firefox") - clickGoBackButton(composeTestRule) - clickSearchLoginButton(composeTestRule) - searchLogin(composeTestRule, "mozilla") - viewSavedLoginDetails(composeTestRule, originWebsite) - verifyLoginItemUsername(composeTestRule, "android") - revealPassword(composeTestRule) - verifyPasswordSaved(composeTestRule, "firefox") - clickGoBackButton(composeTestRule) - clickSearchLoginButton(composeTestRule) - searchLogin(composeTestRule, "MoZiLlA") - viewSavedLoginDetails(composeTestRule, originWebsite) - verifyLoginItemUsername(composeTestRule, "android") - revealPassword(composeTestRule) - verifyPasswordSaved(composeTestRule, "firefox") + clickSearchLoginButton() + searchLogin("MOZILLA") + viewSavedLoginDetails(originWebsite) + verifyLoginItemUsername("android") + revealPassword() + verifyPasswordSaved("firefox") + clickGoBackButton() + clickSearchLoginButton() + searchLogin("mozilla") + viewSavedLoginDetails(originWebsite) + verifyLoginItemUsername("android") + revealPassword() + verifyPasswordSaved("firefox") + clickGoBackButton() + clickSearchLoginButton() + searchLogin("MoZiLlA") + viewSavedLoginDetails(originWebsite) + verifyLoginItemUsername("android") + revealPassword() + verifyPasswordSaved("firefox") } } @@ -702,41 +705,42 @@ class LoginsTest : TestSetup() { val firstLoginPage = mockWebServer.saveLoginAsset val secondLoginPage = "https://mozilla-mobile.github.io/testapp/v2.0/loginForm.html" - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(firstLoginPage.url) { clickSubmitLoginButton() verifySaveLoginPromptIsDisplayed() - clickPageObject(itemWithText("Save")) - }.openNavigationToolbar { + clickPageObject(composeTestRule, itemWithText("Save")) + } + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(secondLoginPage.toUri()) { - setPageObjectText(itemWithResId("username"), "mozilla") - setPageObjectText(itemWithResId("password"), "firefox") - clickPageObject(itemWithResId("submit")) + setPageObjectText(composeTestRule, itemWithResId("username"), "mozilla") + setPageObjectText(composeTestRule, itemWithResId("password"), "firefox") + clickPageObject(composeTestRule, itemWithResId("submit")) verifySaveLoginPromptIsDisplayed() - clickPageObject(itemWithText("Save")) + clickPageObject(composeTestRule, itemWithText("Save")) }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openLoginsAndPasswordSubMenu { - }.openSavedLogins { + }.openSavedLogins(composeTestRule) { tapSetupLater() - clickSortPasswordsButton(composeTestRule) - verifyLoginsSortingOptions(composeTestRule) - clickLastUsedSortingOption(composeTestRule) + clickSortPasswordsButton() + verifyLoginsSortingOptions() + clickLastUsedSortingOption() verifySortedLogin(1, "https://mozilla-mobile.github.io") verifySortedLogin(2, "${firstLoginPage.url.scheme}://${firstLoginPage.url.authority}") - }.goBack(composeTestRule) { - }.openSavedLogins { + }.goBack { + }.openSavedLogins(composeTestRule) { verifySortedLogin(1, "https://mozilla-mobile.github.io") verifySortedLogin(2, "${firstLoginPage.url.scheme}://${firstLoginPage.url.authority}") } restartApp(composeTestRule.activityRule) - browserScreen { + browserScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openLoginsAndPasswordSubMenu { - }.openSavedLogins { + }.openSavedLogins(composeTestRule) { verifySortedLogin(1, "https://mozilla-mobile.github.io") verifySortedLogin(2, "${firstLoginPage.url.scheme}://${firstLoginPage.url.authority}") } @@ -748,39 +752,40 @@ class LoginsTest : TestSetup() { val firstLoginPage = mockWebServer.saveLoginAsset val secondLoginPage = "https://mozilla-mobile.github.io/testapp/v2.0/loginForm.html" - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(firstLoginPage.url) { clickSubmitLoginButton() verifySaveLoginPromptIsDisplayed() - clickPageObject(itemWithText("Save")) - }.openNavigationToolbar { + clickPageObject(composeTestRule, itemWithText("Save")) + } + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(secondLoginPage.toUri()) { - setPageObjectText(itemWithResId("username"), "mozilla") - setPageObjectText(itemWithResId("password"), "firefox") - clickPageObject(itemWithResId("submit")) + setPageObjectText(composeTestRule, itemWithResId("username"), "mozilla") + setPageObjectText(composeTestRule, itemWithResId("password"), "firefox") + clickPageObject(composeTestRule, itemWithResId("submit")) verifySaveLoginPromptIsDisplayed() - clickPageObject(itemWithText("Save")) + clickPageObject(composeTestRule, itemWithText("Save")) mDevice.waitForIdle() }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openLoginsAndPasswordSubMenu { - }.openSavedLogins { + }.openSavedLogins(composeTestRule) { tapSetupLater() verifySortedLogin(1, "${firstLoginPage.url.scheme}://${firstLoginPage.url.authority}") verifySortedLogin(2, "https://mozilla-mobile.github.io") - }.goBack(composeTestRule) { - }.openSavedLogins { + }.goBack { + }.openSavedLogins(composeTestRule) { verifySortedLogin(1, "${firstLoginPage.url.scheme}://${firstLoginPage.url.authority}") verifySortedLogin(2, "https://mozilla-mobile.github.io") } restartApp(composeTestRule.activityRule) - browserScreen { + browserScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openLoginsAndPasswordSubMenu { - }.openSavedLogins { + }.openSavedLogins(composeTestRule) { verifySortedLogin(1, "${firstLoginPage.url.scheme}://${firstLoginPage.url.authority}") verifySortedLogin(2, "https://mozilla-mobile.github.io") } @@ -791,39 +796,39 @@ class LoginsTest : TestSetup() { fun verifyAddLoginManuallyTest() { val loginPage = "https://mozilla-mobile.github.io/testapp/v2.0/loginForm.html" - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openLoginsAndPasswordSubMenu { - }.openSavedLogins { + }.openSavedLogins(composeTestRule) { tapSetupLater() clickAddLoginButton() - verifyAddNewLoginView(composeTestRule) - enterSiteCredentialWhileAddingALogin(composeTestRule, "mozilla") - verifyHostnameErrorMessage(composeTestRule) - enterSiteCredentialWhileAddingALogin(composeTestRule, loginPage) - verifyHostnameClearButton(composeTestRule) - setUserNameWhileAddingANewLogin(composeTestRule, "mozilla") - setNewPasswordWhileAddingANewLogin(composeTestRule, "firefox") - clickClearPasswordButton(composeTestRule) - verifyPasswordErrorMessage(composeTestRule) - setNewPasswordWhileAddingANewLogin(composeTestRule, "firefox") - verifyPasswordClearButton(composeTestRule) - saveNewLogin(composeTestRule) - clickGoBackButton(composeTestRule) - }.goBack(composeTestRule) { + verifyAddNewLoginView() + enterSiteCredentialWhileAddingALogin("mozilla") + verifyHostnameErrorMessage() + enterSiteCredentialWhileAddingALogin(loginPage) + verifyHostnameClearButton() + setUserNameWhileAddingANewLogin("mozilla") + setNewPasswordWhileAddingANewLogin("firefox") + clickClearPasswordButton() + verifyPasswordErrorMessage() + setNewPasswordWhileAddingANewLogin("firefox") + verifyPasswordClearButton() + saveNewLogin() + clickGoBackButton() + }.goBack { } exitMenu() - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(loginPage.toUri()) { - clickPageObject(itemWithResId("username")) + clickPageObject(composeTestRule, itemWithResId("username")) clickSuggestedLoginsButton() - verifySuggestedUserName(composeTestRule, "mozilla") - clickSuggestedLogin(composeTestRule, "mozilla") - clickPageObject(itemWithResId("togglePassword")) - verifyPrefilledLoginCredentials(composeTestRule, "mozilla", "firefox", true) + verifySuggestedUserName("mozilla") + clickSuggestedLogin("mozilla") + clickPageObject(composeTestRule, itemWithResId("togglePassword")) + verifyPrefilledLoginCredentials("mozilla", "firefox", true) } } @@ -834,22 +839,22 @@ class LoginsTest : TestSetup() { fun verifyCopyLoginCredentialsToClipboardTest() { val firstLoginPage = mockWebServer.saveLoginAsset - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(firstLoginPage.url) { clickSubmitLoginButton() verifySaveLoginPromptIsDisplayed() - clickPageObject(itemWithText("Save")) + clickPageObject(composeTestRule, itemWithText("Save")) }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openLoginsAndPasswordSubMenu { - }.openSavedLogins { + }.openSavedLogins(composeTestRule) { tapSetupLater() - viewSavedLoginDetails(composeTestRule, "test@example.com") - clickCopyUserNameButton(composeTestRule) - verifyCopyUserNameLoginCredentialsSnackBar(composeTestRule) - waitUntilCopyLoginCredentialsSnackBarIsGone(composeTestRule) - clickCopyPasswordButton(composeTestRule) - verifyCopyPasswordLoginCredentialsSnackBar(composeTestRule) + viewSavedLoginDetails("test@example.com") + clickCopyUserNameButton() + verifyCopyUserNameLoginCredentialsSnackBar() + waitUntilCopyLoginCredentialsSnackBarIsGone() + clickCopyPasswordButton() + verifyCopyPasswordLoginCredentialsSnackBar() } } } diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/MainMenuTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/MainMenuTest.kt @@ -2,528 +2,1393 @@ * 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("DEPRECATION") + package org.mozilla.fenix.ui import androidx.compose.ui.test.junit4.AndroidComposeTestRule import androidx.core.net.toUri +import androidx.test.rule.ActivityTestRule +import org.junit.Ignore import org.junit.Rule import org.junit.Test +import org.mozilla.fenix.IntentReceiverActivity +import org.mozilla.fenix.R import org.mozilla.fenix.customannotations.SmokeTest +import org.mozilla.fenix.helpers.AppAndSystemHelper.assertExternalAppOpens import org.mozilla.fenix.helpers.AppAndSystemHelper.assertNativeAppOpens import org.mozilla.fenix.helpers.AppAndSystemHelper.assertYoutubeAppOpens import org.mozilla.fenix.helpers.AppAndSystemHelper.clickSystemHomeScreenShortcutAddButton +import org.mozilla.fenix.helpers.Constants.PackageName.GOOGLE_DOCS import org.mozilla.fenix.helpers.Constants.PackageName.PRINT_SPOOLER -import org.mozilla.fenix.helpers.DataGenerationHelper.generateRandomString +import org.mozilla.fenix.helpers.DataGenerationHelper.createCustomTabIntent +import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource import org.mozilla.fenix.helpers.HomeActivityIntentTestRule import org.mozilla.fenix.helpers.MatcherHelper +import org.mozilla.fenix.helpers.MatcherHelper.itemContainingText +import org.mozilla.fenix.helpers.MatcherHelper.itemWithResIdAndText +import org.mozilla.fenix.helpers.MockBrowserDataHelper +import org.mozilla.fenix.helpers.TestAssetHelper.firstForeignWebPageAsset import org.mozilla.fenix.helpers.TestAssetHelper.getGenericAsset +import org.mozilla.fenix.helpers.TestAssetHelper.pdfFormAsset import org.mozilla.fenix.helpers.TestAssetHelper.refreshAsset -import org.mozilla.fenix.helpers.TestHelper.clickSnackbarButton +import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime +import org.mozilla.fenix.helpers.TestAssetHelper.waitingTimeLong +import org.mozilla.fenix.helpers.TestAssetHelper.waitingTimeVeryShort import org.mozilla.fenix.helpers.TestHelper.closeApp import org.mozilla.fenix.helpers.TestHelper.exitMenu import org.mozilla.fenix.helpers.TestHelper.mDevice import org.mozilla.fenix.helpers.TestHelper.restartApp import org.mozilla.fenix.helpers.TestHelper.verifySnackBarText +import org.mozilla.fenix.helpers.TestHelper.waitForAppWindowToBeUpdated +import org.mozilla.fenix.helpers.TestHelper.waitUntilSnackbarGone import org.mozilla.fenix.helpers.TestSetup import org.mozilla.fenix.helpers.perf.DetectMemoryLeaksRule import org.mozilla.fenix.nimbus.FxNimbus import org.mozilla.fenix.nimbus.Translations import org.mozilla.fenix.ui.robots.browserScreen -import org.mozilla.fenix.ui.robots.clickContextMenuItem import org.mozilla.fenix.ui.robots.clickPageObject +import org.mozilla.fenix.ui.robots.customTabScreen import org.mozilla.fenix.ui.robots.homeScreen -import org.mozilla.fenix.ui.robots.longClickPageObject import org.mozilla.fenix.ui.robots.navigationToolbar class MainMenuTest : TestSetup() { - - val activityTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides() + @get:Rule + val composeTestRule = + AndroidComposeTestRule( + HomeActivityIntentTestRule( + skipOnboarding = true, + isMenuRedesignCFREnabled = false, + isPageLoadTranslationsPromptEnabled = false, + ), + ) { it.activity } @get:Rule - val composeTestRule = AndroidComposeTestRule(activityTestRule) { it.activity } + val intentReceiverActivityTestRule = ActivityTestRule( + IntentReceiverActivity::class.java, + true, + false, + ) @get:Rule val memoryLeaksRule = DetectMemoryLeaksRule() - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/233849 + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080168 + @SmokeTest @Test - fun verifyTabMainMenuItemsTest() { - FxNimbus.features.translations.withInitializer { _, _ -> - Translations( - mainFlowBrowserMenuEnabled = true, - ) + fun verifyTheHomepageRedesignedMenuItemsTest() { + homeScreen(composeTestRule) { + }.openThreeDotMenu { + verifyHomeMainMenuItems() } + } - val defaultWebPage = mockWebServer.getGenericAsset(1) + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080124 + @SmokeTest + @Test + fun verifyTheWebpageRedesignedMenuItemsTest() { + val testPage = mockWebServer.getGenericAsset(1) - navigationToolbar { - }.enterURLAndEnterToBrowser(defaultWebPage.url) { + navigationToolbar(composeTestRule) { + }.enterURLAndEnterToBrowser(testPage.url) { + }.openThreeDotMenu { + verifyPageMainMenuItems() + } + } + + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080133 + @SmokeTest + @Test + fun verifySwitchToDesktopSiteIsDisabledOnPDFsTest() { + val pdfPage = mockWebServer.pdfFormAsset + + navigationToolbar(composeTestRule) { + }.enterURLAndEnterToBrowser(pdfPage.url) { waitForPageToLoad() + verifyPageContent(pdfPage.content) }.openThreeDotMenu { - verifyPageThreeDotMainMenuItems(isRequestDesktopSiteEnabled = false) + verifySwitchToDesktopSiteButtonIsEnabled(isEnabled = false) } } - // Verifies the list of items in the homescreen's 3 dot main menu - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/233848 + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080130 @SmokeTest @Test - fun homeMainMenuItemsTest() { - homeScreen { + fun verifyTheFindInPageMenuItemTest() { + val testPage = mockWebServer.getGenericAsset(3) + + navigationToolbar(composeTestRule) { + }.enterURLAndEnterToBrowser(testPage.url) { + mDevice.waitForIdle() }.openThreeDotMenu { - verifyHomeThreeDotMainMenuItems() - }.openBookmarksMenu(composeTestRule) { - verifyEmptyBookmarksMenuView() - }.goBackToHomeScreen { + }.clickFindInPageButton { + verifyFindInPageNextButton() + verifyFindInPagePrevButton() + verifyFindInPageCloseButton() + enterFindInPageQuery("a") + verifyFindInPageResult("1/3") + clickFindInPageNextButton() + verifyFindInPageResult("2/3") + clickFindInPageNextButton() + verifyFindInPageResult("3/3") + clickFindInPagePrevButton() + verifyFindInPageResult("2/3") + clickFindInPagePrevButton() + verifyFindInPageResult("1/3") + }.closeFindInPageWithCloseButton(composeTestRule) { + verifyFindInPageBar(false) }.openThreeDotMenu { - }.openHistory { + }.clickFindInPageButton { + enterFindInPageQuery("3") + verifyFindInPageResult("1/1") + }.closeFindInPageWithBackButton(composeTestRule) { + verifyFindInPageBar(false) + } + } + + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080136 + @SmokeTest + @Test + fun verifyTheHistoryMenuItemTest() { + val testPage = mockWebServer.getGenericAsset(1) + + navigationToolbar(composeTestRule) { + }.enterURLAndEnterToBrowser(testPage.url) { + }.openThreeDotMenu { + }.clickHistoryButton { verifyHistoryMenuView() }.goBack { + verifyPageContent(testPage.content) + } + } + + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080138 + @SmokeTest + @Test + fun verifyTheDownloadsMenuItemTest() { + val testPage = mockWebServer.getGenericAsset(1) + + navigationToolbar(composeTestRule) { + }.enterURLAndEnterToBrowser(testPage.url) { }.openThreeDotMenu { - }.openDownloadsManager { - verifyEmptyDownloadsList(composeTestRule) - }.goBackToHomeScreen(composeTestRule) { + }.clickDownloadsButton { + verifyEmptyDownloadsList() + exitMenu() + }.exitDownloadsManagerToBrowser { + verifyPageContent(testPage.content) + } + } + + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080139 + @SmokeTest + @Test + fun verifyThePasswordsMenuItemTest() { + val testPage = mockWebServer.getGenericAsset(1) + + navigationToolbar(composeTestRule) { + }.enterURLAndEnterToBrowser(testPage.url) { }.openThreeDotMenu { - }.openPasswords { + }.clickPasswordsButton { verifySecurityPromptForLogins() tapSetupLater() - verifyEmptySavedLoginsListView(composeTestRule) - }.goBack(composeTestRule) { + verifyEmptySavedLoginsListView() + }.goBack { } exitMenu() + browserScreen(composeTestRule) { + verifyPageContent(testPage.content) + } + } - homeScreen { - }.openThreeDotMenu { - }.openAddonsManagerMenu { - verifyAddonsListIsDisplayed(true) - }.goBackToHomeScreen { + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080095 + // Verifies the main menu of a custom tab with a custom menu item + @SmokeTest + @Test + fun verifyTheCustomTabsMainMenuItemsTest() { + val customMenuItem = "TestMenuItem" + val customTabPage = mockWebServer.getGenericAsset(1) + + intentReceiverActivityTestRule.launchActivity( + createCustomTabIntent( + customTabPage.url.toString(), + customMenuItem, + ), + ) + + customTabScreen(composeTestRule) { + verifyCustomTabCloseButton() + }.openMainMenu { + verifyCustomTabsMainMenuItems(customMenuItem, true) + } + } + + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080100 + // The test opens a link in a custom tab then sends it to the browser + @SmokeTest + @Test + fun verifyOpenInFirefoxMainMenuTest() { + val customTabPage = mockWebServer.getGenericAsset(1) + + intentReceiverActivityTestRule.launchActivity( + createCustomTabIntent( + customTabPage.url.toString(), + ), + ) + + customTabScreen(composeTestRule) { + verifyCustomTabCloseButton() + }.openMainMenu { + }.clickOpenInBrowserButtonFromRedesignedToolbar { + verifyPageContent(customTabPage.content) + verifyTabCounter("1") + } + } + + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080151 + @SmokeTest + @Test + fun verifyRecommendedExtensionsListWhileNoExtensionIsInstalledTest() { + val genericURL = mockWebServer.getGenericAsset(1) + + navigationToolbar(composeTestRule) { + }.enterURLAndEnterToBrowser(genericURL.url) { + verifyPageContent(genericURL.content) }.openThreeDotMenu { - }.openSyncSignIn { - verifyTurnOnSyncMenu() - }.goBack {} - homeScreen { + verifyTryRecommendedExtensionButton() + }.clickExtensionsButton { + verifyRecommendedAddonsViewFromRedesignedMainMenu(composeTestRule) + } + } + + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080160 + @SmokeTest + @Test + fun verifyTheExtensionsMenuListAfterRemovingAnExtensionTest() { + var recommendedExtensionTitle = "" + val genericURL = mockWebServer.getGenericAsset(1) + + navigationToolbar(composeTestRule) { + }.enterURLAndEnterToBrowser(genericURL.url) { + verifyPageContent(genericURL.content) }.openThreeDotMenu { - }.openHelp { - verifyHelpUrl() - }.goToHomescreen(composeTestRule) { + verifyTryRecommendedExtensionButton() + }.clickExtensionsButton { + recommendedExtensionTitle = installRecommendedAddon(composeTestRule) + verifyAddonPermissionPrompt(recommendedExtensionTitle) + acceptPermissionToInstallAddon() + verifyAddonInstallCompletedPrompt( + recommendedExtensionTitle, + composeTestRule.activityRule, + ) + closeAddonInstallCompletePrompt() + } + + navigationToolbar(composeTestRule) { + }.enterURLAndEnterToBrowser(genericURL.url) { }.openThreeDotMenu { - }.openCustomizeHome { - verifyHomePageView() + }.clickExtensionsButton { + clickManageExtensionsButtonFromRedesignedMainMenu(composeTestRule) + }.openDetailedMenuForAddon(recommendedExtensionTitle) { + }.removeAddon(composeTestRule.activityRule) { }.goBackToHomeScreen { + } + browserScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { - verifySettingsView() + verifyTryRecommendedExtensionButton() } } - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2284134 + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080163 + @SmokeTest @Test - fun openNewTabTest() { - val defaultWebPage = mockWebServer.getGenericAsset(1) + fun verifyTheManageExtensionsItemTest() { + var recommendedExtensionTitle = "" + val genericURL = mockWebServer.getGenericAsset(1) - navigationToolbar { - }.enterURLAndEnterToBrowser(defaultWebPage.url) { + navigationToolbar(composeTestRule) { + }.enterURLAndEnterToBrowser(genericURL.url) { + verifyPageContent(genericURL.content) }.openThreeDotMenu { - }.clickNewTabButton { - verifySearchView() - }.submitQuery("test") { - verifyTabCounter("2") + verifyTryRecommendedExtensionButton() + }.clickExtensionsButton { + recommendedExtensionTitle = installRecommendedAddon(composeTestRule) + verifyAddonPermissionPrompt(recommendedExtensionTitle) + acceptPermissionToInstallAddon() + verifyAddonInstallCompletedPrompt( + recommendedExtensionTitle, + composeTestRule.activityRule, + ) + closeAddonInstallCompletePrompt() + } + browserScreen(composeTestRule) { + waitForPageToLoad() + }.openThreeDotMenu { + waitForAppWindowToBeUpdated() + }.clickExtensionsButton { + clickManageExtensionsButtonFromRedesignedMainMenu(composeTestRule) + verifyAddonsListIsDisplayed(shouldBeDisplayed = true) + verifyAddonIsInstalled(recommendedExtensionTitle) + verifyEnabledTitleDisplayed() } } - // Device or AVD requires a Google Services Android OS installation with Play Store installed - // Verifies the Open in app button when an app is installed - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/387756 + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080129 + @Ignore("Failing, see https://bugzilla.mozilla.org/show_bug.cgi?id=1968653") @SmokeTest @Test - fun openInAppFunctionalityTest() { - val youtubeURL = "vnd.youtube://".toUri() + fun verifyTheBookmarkPageMenuOptionTest() { + val testPage = mockWebServer.getGenericAsset(1) - navigationToolbar { - }.enterURLAndEnterToBrowser(youtubeURL) { - verifyNotificationDotOnMainMenu() + navigationToolbar(composeTestRule) { + }.enterURLAndEnterToBrowser(testPage.url) { }.openThreeDotMenu { - }.clickOpenInApp { - assertYoutubeAppOpens() + clickSaveButton() + }.clickBookmarkThisPageButton { + }.openThreeDotMenu { + clickSaveButton() + }.clickEditBookmarkButton { + verifyEditBookmarksView() + clickDeleteBookmarkButtonInEditMode() + } + browserScreen(composeTestRule) { + }.openThreeDotMenu { + clickSaveButton() + verifyBookmarkThisPageButton() } } - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2284323 + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080113 + @SmokeTest @Test - fun openSignInTest() { - val defaultWebPage = mockWebServer.getGenericAsset(1) + fun verifyTheAddToShortcutsSubMenuOptionTest() { + val testPage = mockWebServer.getGenericAsset(1) - navigationToolbar { - }.enterURLAndEnterToBrowser(defaultWebPage.url) { - mDevice.waitForIdle() + navigationToolbar(composeTestRule) { + }.enterURLAndEnterToBrowser(testPage.url) { + verifyPageContent(testPage.content) }.openThreeDotMenu { - }.openSyncSignIn { - verifyTurnOnSyncMenu() + clickTheMoreButton() + }.clickAddToShortcutsButton { + verifySnackBarText(getStringResource(R.string.snackbar_added_to_shortcuts)) + }.goToHomescreen { + verifyExistingTopSitesTabs(testPage.title) + }.openTopSiteTabWithTitle(testPage.title) { + }.openThreeDotMenu { + clickTheMoreButton() + }.clickRemoveFromShortcutsButton { + composeTestRule.waitForIdle() + }.goToHomescreen { + verifyNotExistingTopSiteItem(testPage.title) } } - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/243840 + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080114 + @SmokeTest @Test - fun findInPageTest() { - val defaultWebPage = mockWebServer.getGenericAsset(3) + fun verifyTheAddToHomeScreenSubMenuOptionTest() { + val testPage = mockWebServer.getGenericAsset(1) - navigationToolbar { - }.enterURLAndEnterToBrowser(defaultWebPage.url) { - mDevice.waitForIdle() + navigationToolbar(composeTestRule) { + }.enterURLAndEnterToBrowser(testPage.url) { }.openThreeDotMenu { - verifyThreeDotMenuExists() - verifyFindInPageButton() - }.openFindInPage { - verifyFindInPageNextButton() - verifyFindInPagePrevButton() - verifyFindInPageCloseButton() - enterFindInPageQuery("a") - verifyFindInPageResult("1/3") - clickFindInPageNextButton() - verifyFindInPageResult("2/3") - clickFindInPageNextButton() - verifyFindInPageResult("3/3") - clickFindInPagePrevButton() - verifyFindInPageResult("2/3") - clickFindInPagePrevButton() - verifyFindInPageResult("1/3") - }.closeFindInPageWithCloseButton { - verifyFindInPageBar(false) + clickTheMoreButton() + }.clickAddToHomeScreenButton { + clickCancelShortcutButton() + } + browserScreen(composeTestRule) { }.openThreeDotMenu { - }.openFindInPage { - enterFindInPageQuery("3") - verifyFindInPageResult("1/1") - }.closeFindInPageWithBackButton { - verifyFindInPageBar(false) + clickTheMoreButton() + }.clickAddToHomeScreenButton { + clickAddShortcutButton() + clickSystemHomeScreenShortcutAddButton() + }.openHomeScreenShortcut(testPage.title) { + verifyPageContent(testPage.content) } } - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2283303 + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080115 + @SmokeTest @Test - fun switchDesktopSiteModeOnOffTest() { - val defaultWebPage = mockWebServer.getGenericAsset(1) + fun verifyTheSaveToCollectionSubMenuOptionTest() { + val collectionTitle = "First Collection" + val firstTestPage = mockWebServer.getGenericAsset(1) + val secondTestPage = mockWebServer.getGenericAsset(2) - navigationToolbar { - }.enterURLAndEnterToBrowser(defaultWebPage.url) { - }.openThreeDotMenu { - }.switchDesktopSiteMode { - }.openThreeDotMenu { - verifyDesktopSiteModeEnabled(true) - }.switchDesktopSiteMode { + composeTestRule.activityRule.applySettingsExceptions { + // Disabling these features to have better visibility of the Collections view + it.isRecentlyVisitedFeatureEnabled = false + it.isRecentTabsFeatureEnabled = false + } + + MockBrowserDataHelper + .createCollection( + Pair(firstTestPage.url.toString(), firstTestPage.title), + title = collectionTitle, + ) + + navigationToolbar(composeTestRule) { + }.enterURLAndEnterToBrowser(secondTestPage.url) { }.openThreeDotMenu { - verifyDesktopSiteModeEnabled(false) + clickTheMoreButton() + }.clickSaveToCollectionButton { + }.selectExistingCollection(collectionTitle) { + verifySnackBarText("Tab saved") + }.goToHomescreen { + }.expandCollection(collectionTitle) { + verifyTabSavedInCollection(firstTestPage.title) + verifyTabSavedInCollection(secondTestPage.title) } } - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/1314137 + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080118 + @Ignore("Failing, see https://bugzilla.mozilla.org/show_bug.cgi?id=1968653") + @SmokeTest @Test - fun setDesktopSiteBeforePageLoadTest() { - val webPage = mockWebServer.getGenericAsset(4) + fun verifyTheSaveAsPDFSubMenuOptionTest() { + val testPage = mockWebServer.getGenericAsset(1) - navigationToolbar { - }.enterURLAndEnterToBrowser(webPage.url) { + navigationToolbar(composeTestRule) { + }.enterURLAndEnterToBrowser(testPage.url) { }.openThreeDotMenu { - }.switchDesktopSiteMode { - }.openThreeDotMenu { - verifyDesktopSiteModeEnabled(true) - }.closeBrowserMenuToBrowser { - clickPageObject(MatcherHelper.itemContainingText("Link 1")) + clickSaveButton() + }.clickSaveAsPDFButton { + verifyDownloadPrompt(testPage.title + ".pdf") + }.clickDownload { + }.clickOpen("application/pdf") { + assertExternalAppOpens(GOOGLE_DOCS) + } + } + + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080111 + @SmokeTest + @Test + fun verifyTheTranslatePageSubMenuOptionTest() { + val testPage = mockWebServer.firstForeignWebPageAsset + + navigationToolbar(composeTestRule) { + }.enterURLAndEnterToBrowser(testPage.url) { }.openThreeDotMenu { - verifyDesktopSiteModeEnabled(true) - }.closeBrowserMenuToBrowser { - }.openNavigationToolbar { - }.enterURLAndEnterToBrowser(webPage.url) { + clickTheMoreButton() + }.clickTranslateButton { + verifyTranslationSheetIsDisplayed(isDisplayed = true) + }.clickTranslateButton { }.openThreeDotMenu { - verifyDesktopSiteModeEnabled(true) - }.closeBrowserMenuToBrowser { - longClickPageObject(MatcherHelper.itemWithText("Link 2")) - clickContextMenuItem("Open link in new tab") - clickSnackbarButton(composeTestRule, "SWITCH") + clickTheMoreButton() + }.clickTranslatedButton { + verifyTranslationSheetIsDisplayed(isDisplayed = true) + }.clickShowOriginalButton { + verifyPageContent(testPage.content) }.openThreeDotMenu { - verifyDesktopSiteModeEnabled(false) + clickTheMoreButton() + verifyTranslatePageButton() } } - // Verifies the Add to home screen option in a tab's 3 dot menu - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/410724 + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080128 @SmokeTest @Test - fun addPageShortcutToHomeScreenTest() { - val website = mockWebServer.getGenericAsset(1) - val shortcutTitle = generateRandomString(5) + fun verifyTheShareButtonTest() { + val testPage = mockWebServer.getGenericAsset(1) - homeScreen { - }.openNavigationToolbar { - }.enterURLAndEnterToBrowser(website.url) { + navigationToolbar(composeTestRule) { + }.enterURLAndEnterToBrowser(testPage.url) { + verifyPageContent(testPage.content) }.openThreeDotMenu { - expandMenu() - }.openAddToHomeScreen { - clickCancelShortcutButton() + }.clickShareButton { + verifyShareTabLayout() + verifySharingWithSelectedApp( + appName = "Gmail", + content = testPage.url.toString(), + subject = testPage.title, + ) } + } - browserScreen { + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080117 + @SmokeTest + @Test + fun verifyTheOpenInAppSubMenuOptionIsEnabledTest() { + val youtubeURL = "vnd.youtube://".toUri() + + navigationToolbar(composeTestRule) { + }.enterURLAndEnterToBrowser(youtubeURL) { + waitForPageToLoad(waitingTime) }.openThreeDotMenu { - expandMenu() - }.openAddToHomeScreen { - verifyShortcutTextFieldTitle("Test_Page_1") - addShortcutName(shortcutTitle) - clickAddShortcutButton() - clickSystemHomeScreenShortcutAddButton() - }.openHomeScreenShortcut(shortcutTitle) { - verifyUrl(website.url.toString()) - verifyTabCounter("1") + clickTheMoreButton() + verifyOpenInAppButtonIsEnabled(appName = "YouTube", isEnabled = true) + clickOpenInAppButton(appName = "YouTube") + assertYoutubeAppOpens() } } - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/329893 + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080131 @SmokeTest @Test - fun mainMenuShareButtonTest() { + fun verifyDesktopSiteModeOnOffIsEnabledTest() { val defaultWebPage = mockWebServer.getGenericAsset(1) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(defaultWebPage.url) { }.openThreeDotMenu { - }.clickShareButton { - verifyShareTabLayout() + verifySwitchToDesktopSiteButton() + verifyDesktopSiteButtonState(isEnabled = false) + clickSwitchToDesktopSiteButton() + } + browserScreen(composeTestRule) { + waitForPageToLoad(pageLoadWaitingTime = waitingTimeLong) + }.openThreeDotMenu { + verifyDesktopSiteButtonState(isEnabled = true) + clickSwitchToDesktopSiteButton() + } + browserScreen(composeTestRule) { + waitForPageToLoad(pageLoadWaitingTime = waitingTimeLong) + }.openThreeDotMenu { + verifyDesktopSiteButtonState(isEnabled = false) } } - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/233604 + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080119 + @SmokeTest @Test - fun navigateBackAndForwardTest() { + fun verifyThePrintSubMenuOptionTest() { val defaultWebPage = mockWebServer.getGenericAsset(1) - val nextWebPage = mockWebServer.getGenericAsset(2) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(defaultWebPage.url) { mDevice.waitForIdle() - }.openNavigationToolbar { - }.enterURLAndEnterToBrowser(nextWebPage.url) { - verifyUrl(nextWebPage.url.toString()) }.openThreeDotMenu { - }.goToPreviousPage { - mDevice.waitForIdle() - verifyUrl(defaultWebPage.url.toString()) + clickTheMoreButton() + clickPrintContentButton() + assertNativeAppOpens(composeTestRule, PRINT_SPOOLER) + } + } + + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080156 + @SmokeTest + @Test + fun verifyTheExtensionInstallationTest() { + var recommendedExtensionTitle = "" + val genericURL = mockWebServer.getGenericAsset(1) + + navigationToolbar(composeTestRule) { + }.enterURLAndEnterToBrowser(genericURL.url) { + verifyPageContent(genericURL.content) }.openThreeDotMenu { - }.goForward { - verifyUrl(nextWebPage.url.toString()) + verifyTryRecommendedExtensionButton() + }.clickExtensionsButton { + recommendedExtensionTitle = installRecommendedAddon(composeTestRule) + acceptPermissionToInstallAddon() + verifyAddonInstallCompletedPrompt( + recommendedExtensionTitle, + composeTestRule.activityRule, + ) + closeAddonInstallCompletePrompt() + } + browserScreen(composeTestRule) { + }.openThreeDotMenu { + verifyExtensionsButtonWithInstalledExtension(recommendedExtensionTitle) + }.clickExtensionsButton { + verifyDiscoverMoreExtensionsButton(composeTestRule, isDisplayed = false) + verifyManageExtensionsButtonFromRedesignedMainMenu(composeTestRule, isDisplayed = true) + verifyInstalledExtension(composeTestRule, recommendedExtensionTitle) } } - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2195819 + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080181 @SmokeTest @Test - fun refreshPageButtonTest() { - val refreshWebPage = mockWebServer.refreshAsset + fun verifyTheHomePageSettingsMenuItemTest() { + homeScreen(composeTestRule) { + }.openThreeDotMenu { + }.clickSettingsButton { + verifySettingsToolbar() + }.goBack(composeTestRule) { + verifyHomeWordmark() + } + } - navigationToolbar { - }.enterURLAndEnterToBrowser(refreshWebPage.url) { - mDevice.waitForIdle() + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080121 + @Ignore("Disabled after enabling the composable toolbar and main menu: https://bugzilla.mozilla.org/show_bug.cgi?id=2006295") + @Test + fun verifyTheBrowserViewMainMenuCFRTest() { + val genericURL = mockWebServer.getGenericAsset(1) + + composeTestRule.activityRule.applySettingsExceptions { + it.isMenuRedesignCFREnabled = true + } + navigationToolbar(composeTestRule) { + }.enterURLAndEnterToBrowser(genericURL.url) { }.openThreeDotMenu { - verifyThreeDotMenuExists() - }.refreshPage { - verifyPageContent("REFRESHED") + verifyMainMenuCFR() } } - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2265657 + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080898 @Test - fun forceRefreshPageTest() { - val refreshWebPage = mockWebServer.refreshAsset + fun verifyTheFindInPageOptionInPDFsTest() { + val testPage = mockWebServer.getGenericAsset(3) - navigationToolbar { - }.enterURLAndEnterToBrowser(refreshWebPage.url) { - mDevice.waitForIdle() + navigationToolbar(composeTestRule) { + }.enterURLAndEnterToBrowser(testPage.url) { + clickPageObject(composeTestRule, MatcherHelper.itemWithText("PDF form file")) + clickPageObject(composeTestRule, itemWithResIdAndText("android:id/button2", "Cancel")) }.openThreeDotMenu { - verifyThreeDotMenuExists() - }.forceRefreshPage { - verifyPageContent("REFRESHED") + }.clickFindInPageButton { + verifyFindInPageNextButton() + verifyFindInPagePrevButton() + verifyFindInPageCloseButton() + enterFindInPageQuery("l") + verifyFindInPageResult("1/2") + clickFindInPageNextButton() + verifyFindInPageResult("2/2") + clickFindInPagePrevButton() + verifyFindInPageResult("1/2") + }.closeFindInPageWithCloseButton(composeTestRule) { + verifyFindInPageBar(false) + }.openThreeDotMenu { + }.clickFindInPageButton { + enterFindInPageQuery("p") + verifyFindInPageResult("1/1") + }.closeFindInPageWithBackButton(composeTestRule) { + verifyFindInPageBar(false) } } - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2282411 + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080145 @Test - fun printWebPageFromMainMenuTest() { - val defaultWebPage = mockWebServer.getGenericAsset(1) + fun verifyTheQuitFirefoxMenuItemTest() { + val genericURL = mockWebServer.getGenericAsset(1) - navigationToolbar { - }.enterURLAndEnterToBrowser(defaultWebPage.url) { - mDevice.waitForIdle() + homeScreen(composeTestRule) { + }.openThreeDotMenu { + }.clickSettingsButton { + }.openSettingsSubMenuDeleteBrowsingDataOnQuit { + verifyDeleteBrowsingOnQuitEnabled(false) + clickDeleteBrowsingOnQuitButtonSwitch() + verifyDeleteBrowsingOnQuitEnabled(true) + }.goBack { + verifySettingsOptionSummary("Delete browsing data on quit", "On") + }.goBack(composeTestRule) { + } + navigationToolbar(composeTestRule) { + }.enterURLAndEnterToBrowser(genericURL.url) { + }.openThreeDotMenu { + clickTheQuitFirefoxButton() + restartApp(composeTestRule.activityRule) + } + homeScreen(composeTestRule) { + verifyHomeWordmark() + } + } + + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080103 + @Test + fun verifyTheDesktopSiteMenuItemInACustomTabTest() { + val customTabPage = mockWebServer.getGenericAsset(1) + + intentReceiverActivityTestRule.launchActivity( + createCustomTabIntent( + customTabPage.url.toString(), + ), + ) + + customTabScreen(composeTestRule) { + }.openMainMenu { + verifySwitchToDesktopSiteButton() + verifyDesktopSiteButtonState(isEnabled = false) + clickSwitchToDesktopSiteButton() + }.openMainMenu { + verifyDesktopSiteButtonState(isEnabled = true) + clickSwitchToDesktopSiteButton() + }.openMainMenu { + verifyDesktopSiteButtonState(isEnabled = false) + } + } + + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080101 + @SmokeTest + @Test + fun verifyTheFindInPageMenuItemInACustomTabTest() { + val customTabPage = mockWebServer.getGenericAsset(3) + + intentReceiverActivityTestRule.launchActivity( + createCustomTabIntent( + customTabPage.url.toString(), + ), + ) + + customTabScreen(composeTestRule) { + }.openMainMenu { + }.clickFindInPageButton { + verifyFindInPageNextButton() + verifyFindInPagePrevButton() + verifyFindInPageCloseButton() + enterFindInPageQuery("a") + verifyFindInPageResult("1/3") + clickFindInPageNextButton() + verifyFindInPageResult("2/3") + clickFindInPageNextButton() + verifyFindInPageResult("3/3") + clickFindInPagePrevButton() + verifyFindInPageResult("2/3") + clickFindInPagePrevButton() + verifyFindInPageResult("1/3") + }.closeFindInPageWithCloseButton(composeTestRule) { + verifyFindInPageBar(false) }.openThreeDotMenu { - }.clickPrintButton { - assertNativeAppOpens(PRINT_SPOOLER) + }.clickFindInPageButton { + enterFindInPageQuery("3") + verifyFindInPageResult("1/1") + }.closeFindInPageWithBackButton(composeTestRule) { + verifyFindInPageBar(false) } } - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2282408 + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080107 @Test - fun printWebPageFromShareMenuTest() { + fun verifyTheClosingBehaviourWhenTappingOutsideTheCustomTabMainMenuTest() { + val customMenuItem = "TestMenuItem" + val customTabPage = mockWebServer.getGenericAsset(1) + + intentReceiverActivityTestRule.launchActivity( + createCustomTabIntent( + customTabPage.url.toString(), + ), + ) + + customTabScreen(composeTestRule) { + }.openMainMenu { + }.clickOutsideTheMainMenu { + } + customTabScreen(composeTestRule) { + verifyCustomTabsMainMenuItems( + customMenuItem, + false, + waitingTimeVeryShort, + ) + } + } + + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080162 + @SmokeTest + @Test + fun verifyTheExtensionMenuListWhileExtensionsAreDisabledTest() { + var recommendedExtensionTitle = "" + val genericURL = mockWebServer.getGenericAsset(1) + + navigationToolbar(composeTestRule) { + }.enterURLAndEnterToBrowser(genericURL.url) { + verifyPageContent(genericURL.content) + }.openThreeDotMenu { + verifyTryRecommendedExtensionButton() + }.clickExtensionsButton { + recommendedExtensionTitle = installRecommendedAddon(composeTestRule) + acceptPermissionToInstallAddon() + verifyAddonInstallCompletedPrompt( + recommendedExtensionTitle, + composeTestRule.activityRule, + ) + closeAddonInstallCompletePrompt() + } + browserScreen(composeTestRule) { + }.openThreeDotMenu { + verifyExtensionsButtonWithInstalledExtension(recommendedExtensionTitle) + }.clickExtensionsButton { + clickManageExtensionsButtonFromRedesignedMainMenu(composeTestRule) + }.openDetailedMenuForAddon(recommendedExtensionTitle) { + disableExtension() + waitUntilSnackbarGone() + }.goBack { + }.goBackToBrowser { + }.openThreeDotMenu { + verifyNoExtensionsEnabledButton() + } + } + + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080153 + @Test + fun verifyTheDiscoverMoreExtensionsSubMenuItemTest() { + val genericURL = mockWebServer.getGenericAsset(1) + + navigationToolbar(composeTestRule) { + }.enterURLAndEnterToBrowser(genericURL.url) { + verifyPageContent(genericURL.content) + }.openThreeDotMenu { + verifyTryRecommendedExtensionButton() + }.clickExtensionsButton { + }.clickDiscoverMoreExtensionsButton(composeTestRule) { + verifyUrl("addons.mozilla.org") + } + } + + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080112 + @SmokeTest + @Test + fun verifyTheReportBrokenSiteSubMenuOptionTest() { val defaultWebPage = mockWebServer.getGenericAsset(1) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(defaultWebPage.url) { - mDevice.waitForIdle() }.openThreeDotMenu { - }.clickShareButton { - }.clickPrintButton { - assertNativeAppOpens(PRINT_SPOOLER) + clickTheMoreButton() + }.clickReportBrokenSiteButton { + verifyWebCompatReporterViewItems(websiteURL = defaultWebPage.url.toString()) } } - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2937924 + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2939173 @Test fun verifyTheWhatIsBrokenErrorMessageTest() { val defaultWebPage = mockWebServer.getGenericAsset(1) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(defaultWebPage.url) { }.openThreeDotMenu { - }.openReportBrokenSite { - verifyWebCompatReporterViewItems(composeTestRule, defaultWebPage.url.toString()) + clickTheMoreButton() + }.clickReportBrokenSiteButton { + verifyWebCompatReporterViewItems(defaultWebPage.url.toString()) verifyWhatIsBrokenField(composeTestRule) - verifySendButtonIsEnabled(composeTestRule, isEnabled = false) + verifySendButtonIsEnabled(isEnabled = false) clickChooseReasonField(composeTestRule) clickSiteDoesNotLoadReason(composeTestRule) verifyChooseReasonErrorMessageIsNotDisplayed(composeTestRule) - verifySendButtonIsEnabled(composeTestRule, isEnabled = true) + verifySendButtonIsEnabled(isEnabled = true) } } - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2937926 + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2939175 @Test - fun verifyThatTheBrokenSiteFormCanBeCanceledTest() { + fun verifyThatTheBrokenSiteFormSubmissionCanBeCanceledTest() { val defaultWebPage = mockWebServer.getGenericAsset(1) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(defaultWebPage.url) { }.openThreeDotMenu { - }.openReportBrokenSite { - verifyWebCompatReporterViewItems(composeTestRule, defaultWebPage.url.toString()) + clickTheMoreButton() + }.clickReportBrokenSiteButton { + verifyWebCompatReporterViewItems(defaultWebPage.url.toString()) clickChooseReasonField(composeTestRule) clickSiteDoesNotLoadReason(composeTestRule) clickBrokenSiteFormCancelButton(composeTestRule) }.openThreeDotMenu { - }.openReportBrokenSite { + clickTheMoreButton() + }.clickReportBrokenSiteButton { verifyWhatIsBrokenField(composeTestRule) } } - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2937927 + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2939176 + @Ignore("Failing, see https://bugzilla.mozilla.org/show_bug.cgi?id=1968653") @Test - fun verifyTheBrokenSiteFormSubmissionTest() { + fun verifyTheBrokenSiteFormSubmissionWithOptionalFieldsTest() { val defaultWebPage = mockWebServer.getGenericAsset(1) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(defaultWebPage.url) { }.openThreeDotMenu { - }.openReportBrokenSite { - verifyWebCompatReporterViewItems(composeTestRule, defaultWebPage.url.toString()) + clickTheToolsButton() + }.clickReportBrokenSiteButton { + verifyWebCompatReporterViewItems(defaultWebPage.url.toString()) clickChooseReasonField(composeTestRule) clickSiteDoesNotLoadReason(composeTestRule) - describeBrokenSiteProblem(composeTestRule, problemDescription = "Prolonged page loading time") + describeBrokenSiteProblem(problemDescription = "Prolonged page loading time") clickBrokenSiteFormSendButton(composeTestRule) } - browserScreen { + browserScreen(composeTestRule) { verifySnackBarText("Report sent") }.openThreeDotMenu { - }.openReportBrokenSite { + clickTheToolsButton() + }.clickReportBrokenSiteButton { verifyWhatIsBrokenField(composeTestRule) - verifyBrokenSiteProblem(composeTestRule, problemDescription = "Prolonged page loading time", isDisplayed = false) + verifyBrokenSiteProblem( + problemDescription = "Prolonged page loading time", + isDisplayed = false, + ) } } - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2937930 + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2939179 @Test fun verifyThatTheBrokenSiteFormInfoPersistsTest() { val defaultWebPage = mockWebServer.getGenericAsset(1) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(defaultWebPage.url) { }.openThreeDotMenu { - }.openReportBrokenSite { - verifyWebCompatReporterViewItems(composeTestRule, defaultWebPage.url.toString()) + clickTheMoreButton() + }.clickReportBrokenSiteButton { + verifyWebCompatReporterViewItems(defaultWebPage.url.toString()) clickChooseReasonField(composeTestRule) clickSiteDoesNotLoadReason(composeTestRule) - describeBrokenSiteProblem(composeTestRule, problemDescription = "Prolonged page loading time") + describeBrokenSiteProblem(problemDescription = "Prolonged page loading time") }.closeWebCompatReporter { }.openThreeDotMenu { - }.openReportBrokenSite { - verifyBrokenSiteProblem(composeTestRule, problemDescription = "Prolonged page loading time", isDisplayed = true) + clickTheMoreButton() + }.clickReportBrokenSiteButton { + verifyBrokenSiteProblem( + problemDescription = "Prolonged page loading time", + isDisplayed = true, + ) } } - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2937931 + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2939180 @Test fun verifyTheBrokenSiteFormIsEmptyWithoutSubmittingThePreviousOneTest() { val firstWebPage = mockWebServer.getGenericAsset(1) val secondWebPage = mockWebServer.getGenericAsset(2) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(firstWebPage.url) { }.openThreeDotMenu { - }.openReportBrokenSite { - verifyWebCompatReporterViewItems(composeTestRule, firstWebPage.url.toString()) + clickTheMoreButton() + }.clickReportBrokenSiteButton { + verifyWebCompatReporterViewItems(firstWebPage.url.toString()) clickChooseReasonField(composeTestRule) clickSiteDoesNotLoadReason(composeTestRule) - describeBrokenSiteProblem(composeTestRule, problemDescription = "Prolonged page loading time") + describeBrokenSiteProblem( + problemDescription = "Prolonged page loading time", + ) }.closeWebCompatReporter { }.openTabDrawer(composeTestRule) { }.openNewTab { }.submitQuery(secondWebPage.url.toString()) { }.openThreeDotMenu { - }.openReportBrokenSite { + clickTheMoreButton() + }.clickReportBrokenSiteButton { verifyWhatIsBrokenField(composeTestRule) - verifyBrokenSiteProblem(composeTestRule, problemDescription = "Prolonged page loading time", isDisplayed = false) + verifyBrokenSiteProblem( + problemDescription = "Prolonged page loading time", + isDisplayed = false, + ) } } - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2937932 + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2939181 @Test fun verifyThatTheBrokenSiteFormInfoIsErasedWhenKillingTheAppTest() { val defaultWebPage = mockWebServer.getGenericAsset(1) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(defaultWebPage.url) { }.openThreeDotMenu { - }.openReportBrokenSite { - verifyWebCompatReporterViewItems(composeTestRule, defaultWebPage.url.toString()) + clickTheMoreButton() + }.clickReportBrokenSiteButton { + verifyWebCompatReporterViewItems(defaultWebPage.url.toString()) clickChooseReasonField(composeTestRule) clickSiteDoesNotLoadReason(composeTestRule) - describeBrokenSiteProblem(composeTestRule, problemDescription = "Prolonged page loading time") + describeBrokenSiteProblem(problemDescription = "Prolonged page loading time") } closeApp(composeTestRule.activityRule) restartApp(composeTestRule.activityRule) - browserScreen { + browserScreen(composeTestRule) { }.openThreeDotMenu { - }.openReportBrokenSite { + clickTheMoreButton() + }.clickReportBrokenSiteButton { verifyWhatIsBrokenField(composeTestRule) - verifyBrokenSiteProblem(composeTestRule, problemDescription = "Prolonged page loading time", isDisplayed = false) + verifyBrokenSiteProblem( + problemDescription = "Prolonged page loading time", + isDisplayed = false, + ) } } - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2937933 + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2939182 @Test fun verifyReportBrokenSiteFormNotDisplayedWhenTelemetryIsDisabledTest() { val defaultWebPage = mockWebServer.getGenericAsset(1) - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openSettingsSubMenuDataCollection { clickUsageAndTechnicalDataToggle(composeTestRule) verifyUsageAndTechnicalDataToggle(composeTestRule, isChecked = false) } - exitMenu() - - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(defaultWebPage.url) { }.openThreeDotMenu { - }.openReportBrokenSite { + clickTheMoreButton() + }.clickReportBrokenSiteButton { + waitForAppWindowToBeUpdated() verifyUrl("webcompat.com/issues/new") } } + + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080172 + @SmokeTest + @Test + fun verifyTheExtensionsMenuOptionTest() { + homeScreen(composeTestRule) { + }.openThreeDotMenu { + }.clickExtensionsButton { + verifyAddonsListIsDisplayed(true) + }.goBackToHomeScreen { + verifyHomeComponent() + } + } + + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080173 + @Test + fun verifyTheHistoryMenuOptionTest() { + homeScreen(composeTestRule) { + }.openThreeDotMenu { + }.clickHistoryButton { + verifyEmptyHistoryView() + }.goBackToHomeScreen { + verifyHomeComponent() + } + } + + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080174 + @Test + fun verifyTheBookmarksMenuOptionTest() { + homeScreen(composeTestRule) { + }.openThreeDotMenu { + }.clickBookmarksButton { + verifyEmptyBookmarksMenuView() + }.goBackToHomeScreen { + verifyHomeComponent() + } + } + + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080175 + @Test + fun verifyTheDownloadsMenuOptionTest() { + homeScreen(composeTestRule) { + }.openThreeDotMenu { + }.clickDownloadsButton { + verifyEmptyDownloadsList() + }.goBackToHomeScreen { + verifyHomeComponent() + } + } + + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080176 + @Test + fun verifyThePasswordsMenuOptionTest() { + homeScreen(composeTestRule) { + }.openThreeDotMenu { + }.clickPasswordsButton { + verifySecurityPromptForLogins() + tapSetupLater() + verifyEmptySavedLoginsListView() + }.goBack { + } + + exitMenu() + + homeScreen(composeTestRule) { + verifyHomeComponent() + } + } + + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080177 + @Test + fun verifyTheSignInMenuOptionTest() { + homeScreen(composeTestRule) { + }.openThreeDotMenu { + }.clickSignInToSyncButton { + verifyTurnOnSyncMenu() + }.goBackToHomeScreen { + verifyHomeComponent() + } + } + + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080182 + @Test + fun verifyTheQuitMenuOptionTest() { + homeScreen(composeTestRule) { + }.openThreeDotMenu { + }.clickSettingsButton { + }.openSettingsSubMenuDeleteBrowsingDataOnQuit { + verifyDeleteBrowsingOnQuitEnabled(false) + clickDeleteBrowsingOnQuitButtonSwitch() + verifyDeleteBrowsingOnQuitEnabled(true) + }.goBack { + verifySettingsOptionSummary("Delete browsing data on quit", "On") + }.goBack(composeTestRule) { + }.openThreeDotMenu { + clickTheQuitFirefoxButton() + restartApp(composeTestRule.activityRule) + } + homeScreen(composeTestRule) { + verifyHomeComponent() + } + } + + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080125 + @SmokeTest + @Test + fun verifyTheMainMenuBackButtonTest() { + val firstWebPage = mockWebServer.getGenericAsset(1) + val nextWebPage = mockWebServer.getGenericAsset(2) + + navigationToolbar(composeTestRule) { + }.enterURLAndEnterToBrowser(firstWebPage.url) { + } + navigationToolbar(composeTestRule) { + }.enterURLAndEnterToBrowser(nextWebPage.url) { + verifyUrl(nextWebPage.url.toString()) + }.openThreeDotMenu { + }.clickPreviousPageButton { + waitForAppWindowToBeUpdated() + verifyUrl(firstWebPage.url.toString()) + } + } + + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080126 + @SmokeTest + @Test + fun verifyTheMainMenuForwardButtonTest() { + val firstWebPage = mockWebServer.getGenericAsset(1) + val nextWebPage = mockWebServer.getGenericAsset(2) + + navigationToolbar(composeTestRule) { + }.enterURLAndEnterToBrowser(firstWebPage.url) { + } + navigationToolbar(composeTestRule) { + }.enterURLAndEnterToBrowser(nextWebPage.url) { + verifyUrl(nextWebPage.url.toString()) + }.openThreeDotMenu { + }.clickPreviousPageButton { + mDevice.waitForIdle() + verifyUrl(firstWebPage.url.toString()) + }.openThreeDotMenu { + }.clickForwardButton { + waitForAppWindowToBeUpdated() + verifyUrl(nextWebPage.url.toString()) + } + } + + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080127 + @Test + fun verifyTheRefreshButtonTest() { + val refreshWebPage = mockWebServer.refreshAsset + + navigationToolbar(composeTestRule) { + }.enterURLAndEnterToBrowser(refreshWebPage.url) { + verifyPageContent("DEFAULT") + }.openThreeDotMenu { + }.clickRefreshButton { + verifyPageContent("REFRESHED") + } + } + + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080134 + @SmokeTest + @Test + fun verifyTheExtensionsMainMenuListTest() { + val testPage = mockWebServer.getGenericAsset(1) + + navigationToolbar(composeTestRule) { + }.enterURLAndEnterToBrowser(testPage.url) { + }.openThreeDotMenu { + verifyTryRecommendedExtensionButton() + }.clickExtensionsChevronFromMainMenu { + verifyRecommendedAddonsViewFromRedesignedMainMenu(composeTestRule) + clickCollapseExtensionsChevronFromMainMenu(composeTestRule) + verifyExtensionsMainMenuOptionIsCollapsed(composeTestRule, areExtensionsInstalled = false) + } + } + + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080135 + @Test + fun verifyTheMoreMainMenuListTest() { + val firstTestPage = mockWebServer.firstForeignWebPageAsset + + navigationToolbar(composeTestRule) { + }.enterURLAndEnterToBrowser(firstTestPage.url) { + }.openThreeDotMenu { + clickMoreOptionChevron() + verifyMoreMainMenuItems() + } + } + + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080137 + @SmokeTest + @Test + fun verifyTheBookmarksMainMenuItemTest() { + val testPage = mockWebServer.getGenericAsset(1) + + navigationToolbar(composeTestRule) { + }.enterURLAndEnterToBrowser(testPage.url) { + }.openThreeDotMenu { + }.clickBookmarksButton { + verifyEmptyBookmarksMenuView() + }.goBackToBrowserScreen { + verifyPageContent(testPage.content) + } + } + + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080140 + @Test + fun verifyTheSignInMainMenuItemTest() { + val testPage = mockWebServer.getGenericAsset(1) + + navigationToolbar(composeTestRule) { + }.enterURLAndEnterToBrowser(testPage.url) { + }.openThreeDotMenu { + }.clickSignInToSyncButton { + verifyTurnOnSyncMenu() + }.goBack { + verifyPageContent(testPage.content) + } + } + + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080144 + @Test + fun verifyTheSettingsMainMenuItemTest() { + val testPage = mockWebServer.getGenericAsset(1) + + navigationToolbar(composeTestRule) { + }.enterURLAndEnterToBrowser(testPage.url) { + }.openThreeDotMenu { + }.clickSettingsButton { + verifySettingsView() + }.goBackToBrowser(composeTestRule) { + verifyPageContent(testPage.content) + } + } + + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080096 + @SmokeTest + @Test + fun verifyTheMainMenuBackButtonFromCustomTabTest() { + val customMenuItem = "TestMenuItem" + val customTabPage = mockWebServer.getGenericAsset(4) + + intentReceiverActivityTestRule.launchActivity( + createCustomTabIntent( + customTabPage.url.toString(), + customMenuItem, + ), + ) + + customTabScreen(composeTestRule) { + clickPageObject(composeTestRule, itemContainingText("Link 1")) + }.openMainMenu { + }.clickBackButtonFromMenu { + waitForPageToLoad(waitingTime) + } + + browserScreen(composeTestRule) { + verifyPageContent(customTabPage.content) + } + } + + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080097 + @SmokeTest + @Test + fun verifyTheMainMenuForwardButtonFromCustomTabTest() { + val customMenuItem = "TestMenuItem" + val firstCustomTabPage = mockWebServer.getGenericAsset(4) + val secondCustomTabPage = mockWebServer.getGenericAsset(1) + + intentReceiverActivityTestRule.launchActivity( + createCustomTabIntent( + firstCustomTabPage.url.toString(), + customMenuItem, + ), + ) + + customTabScreen(composeTestRule) { + clickPageObject(composeTestRule, itemContainingText("Link 1")) + }.openMainMenu { + }.clickBackButtonFromMenu { + waitForPageToLoad(waitingTime) + verifyPageContent(firstCustomTabPage.content) + } + + customTabScreen(composeTestRule) { + }.openMainMenu { + }.clickForwardButtonFromMenu { + waitForPageToLoad(waitingTime) + verifyPageContent(secondCustomTabPage.content) + } + } + + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080098 + @Test + fun verifyTheMainMenuRefreshButtonFromCustomTabTest() { + val customMenuItem = "TestMenuItem" + val customTabPage = mockWebServer.refreshAsset + + intentReceiverActivityTestRule.launchActivity( + createCustomTabIntent( + customTabPage.url.toString(), + customMenuItem, + ), + ) + + browserScreen(composeTestRule) { + verifyPageContent("DEFAULT") + } + customTabScreen(composeTestRule) { + }.openMainMenu { + }.clickRefreshButton { + verifyPageContent("REFRESHED") + } + } + + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080099 + @Test + fun verifyTheMainMenuShareButtonFromCustomTabTest() { + val customMenuItem = "TestMenuItem" + val customTabPage = mockWebServer.getGenericAsset(1) + + intentReceiverActivityTestRule.launchActivity( + createCustomTabIntent( + customTabPage.url.toString(), + customMenuItem, + ), + ) + + customTabScreen(composeTestRule) { + }.openMainMenu { + }.clickShareButtonFromRedesignedMenu { + verifyShareTabLayout() + } + } + + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080102 + @Test + fun verifySwitchToDesktopSiteIsDisabledOnPDFsFromCustomTabTest() { + val customMenuItem = "TestMenuItem" + val customTabPDF = mockWebServer.pdfFormAsset + + intentReceiverActivityTestRule.launchActivity( + createCustomTabIntent( + customTabPDF.url.toString(), + customMenuItem, + ), + ) + + browserScreen(composeTestRule) { + verifyPageContent(customTabPDF.content) + } + + customTabScreen(composeTestRule) { + }.openMainMenu { + verifySwitchToDesktopSiteButton() + verifyDesktopSiteButtonState(isEnabled = false) + } + } + + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080110 + @SmokeTest + @Test + fun verifyTheMoreMainMenuSubListTest() { + val firstTestPage = mockWebServer.firstForeignWebPageAsset + + navigationToolbar(composeTestRule) { + }.enterURLAndEnterToBrowser(firstTestPage.url) { + }.openThreeDotMenu { + clickTheMoreButton() + verifyMoreMainMenuItems() + } + } } diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/MainMenuTestCompose.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/MainMenuTestCompose.kt @@ -1,1407 +0,0 @@ -/* 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/. */ - -@file:Suppress("DEPRECATION") - -package org.mozilla.fenix.ui - -import androidx.compose.ui.test.junit4.AndroidComposeTestRule -import androidx.core.net.toUri -import androidx.test.rule.ActivityTestRule -import org.junit.Ignore -import org.junit.Rule -import org.junit.Test -import org.mozilla.fenix.IntentReceiverActivity -import org.mozilla.fenix.R -import org.mozilla.fenix.customannotations.SmokeTest -import org.mozilla.fenix.helpers.AppAndSystemHelper.assertExternalAppOpens -import org.mozilla.fenix.helpers.AppAndSystemHelper.assertNativeAppOpens -import org.mozilla.fenix.helpers.AppAndSystemHelper.assertYoutubeAppOpens -import org.mozilla.fenix.helpers.AppAndSystemHelper.clickSystemHomeScreenShortcutAddButton -import org.mozilla.fenix.helpers.Constants.PackageName.GOOGLE_DOCS -import org.mozilla.fenix.helpers.Constants.PackageName.PRINT_SPOOLER -import org.mozilla.fenix.helpers.DataGenerationHelper.createCustomTabIntent -import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource -import org.mozilla.fenix.helpers.HomeActivityIntentTestRule -import org.mozilla.fenix.helpers.MatcherHelper -import org.mozilla.fenix.helpers.MatcherHelper.itemContainingText -import org.mozilla.fenix.helpers.MatcherHelper.itemWithResIdAndText -import org.mozilla.fenix.helpers.MockBrowserDataHelper -import org.mozilla.fenix.helpers.TestAssetHelper.firstForeignWebPageAsset -import org.mozilla.fenix.helpers.TestAssetHelper.getGenericAsset -import org.mozilla.fenix.helpers.TestAssetHelper.pdfFormAsset -import org.mozilla.fenix.helpers.TestAssetHelper.refreshAsset -import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime -import org.mozilla.fenix.helpers.TestAssetHelper.waitingTimeLong -import org.mozilla.fenix.helpers.TestAssetHelper.waitingTimeVeryShort -import org.mozilla.fenix.helpers.TestHelper.closeApp -import org.mozilla.fenix.helpers.TestHelper.exitMenu -import org.mozilla.fenix.helpers.TestHelper.mDevice -import org.mozilla.fenix.helpers.TestHelper.restartApp -import org.mozilla.fenix.helpers.TestHelper.verifySnackBarText -import org.mozilla.fenix.helpers.TestHelper.waitForAppWindowToBeUpdated -import org.mozilla.fenix.helpers.TestHelper.waitUntilSnackbarGone -import org.mozilla.fenix.helpers.TestSetup -import org.mozilla.fenix.helpers.perf.DetectMemoryLeaksRule -import org.mozilla.fenix.ui.robots.browserScreen -import org.mozilla.fenix.ui.robots.clickPageObject -import org.mozilla.fenix.ui.robots.customTabScreen -import org.mozilla.fenix.ui.robots.homeScreen -import org.mozilla.fenix.ui.robots.navigationToolbar - -class MainMenuTestCompose : TestSetup() { - @get:Rule - val composeTestRule = - AndroidComposeTestRule( - HomeActivityIntentTestRule( - skipOnboarding = true, - isMenuRedesignEnabled = true, - isMenuRedesignCFREnabled = false, - isPageLoadTranslationsPromptEnabled = false, - ), - ) { it.activity } - - @get:Rule - val intentReceiverActivityTestRule = ActivityTestRule( - IntentReceiverActivity::class.java, - true, - false, - ) - - @get:Rule - val memoryLeaksRule = DetectMemoryLeaksRule() - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080168 - @SmokeTest - @Test - fun verifyTheHomepageRedesignedMenuItemsTest() { - homeScreen { - }.openThreeDotMenu(composeTestRule) { - verifyHomeMainMenuItems() - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080124 - @SmokeTest - @Test - fun verifyTheWebpageRedesignedMenuItemsTest() { - val testPage = mockWebServer.getGenericAsset(1) - - navigationToolbar { - }.enterURLAndEnterToBrowser(testPage.url) { - }.openThreeDotMenu(composeTestRule) { - verifyPageMainMenuItems() - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080133 - @SmokeTest - @Test - fun verifySwitchToDesktopSiteIsDisabledOnPDFsTest() { - val pdfPage = mockWebServer.pdfFormAsset - - navigationToolbar { - }.enterURLAndEnterToBrowser(pdfPage.url) { - waitForPageToLoad() - verifyPageContent(pdfPage.content) - }.openThreeDotMenu(composeTestRule) { - verifySwitchToDesktopSiteButtonIsEnabled(isEnabled = false) - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080130 - @SmokeTest - @Test - fun verifyTheFindInPageMenuItemTest() { - val testPage = mockWebServer.getGenericAsset(3) - - navigationToolbar { - }.enterURLAndEnterToBrowser(testPage.url) { - mDevice.waitForIdle() - }.openThreeDotMenu(composeTestRule) { - }.clickFindInPageButton { - verifyFindInPageNextButton() - verifyFindInPagePrevButton() - verifyFindInPageCloseButton() - enterFindInPageQuery("a") - verifyFindInPageResult("1/3") - clickFindInPageNextButton() - verifyFindInPageResult("2/3") - clickFindInPageNextButton() - verifyFindInPageResult("3/3") - clickFindInPagePrevButton() - verifyFindInPageResult("2/3") - clickFindInPagePrevButton() - verifyFindInPageResult("1/3") - }.closeFindInPageWithCloseButton { - verifyFindInPageBar(false) - }.openThreeDotMenu(composeTestRule) { - }.clickFindInPageButton { - enterFindInPageQuery("3") - verifyFindInPageResult("1/1") - }.closeFindInPageWithBackButton { - verifyFindInPageBar(false) - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080136 - @SmokeTest - @Test - fun verifyTheHistoryMenuItemTest() { - val testPage = mockWebServer.getGenericAsset(1) - - navigationToolbar { - }.enterURLAndEnterToBrowser(testPage.url) { - }.openThreeDotMenu(composeTestRule) { - }.openHistory { - verifyHistoryMenuView() - }.goBack { - verifyPageContent(testPage.content) - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080138 - @SmokeTest - @Test - fun verifyTheDownloadsMenuItemTest() { - val testPage = mockWebServer.getGenericAsset(1) - - navigationToolbar { - }.enterURLAndEnterToBrowser(testPage.url) { - }.openThreeDotMenu(composeTestRule) { - }.openDownloads { - verifyEmptyDownloadsList(composeTestRule) - exitMenu() - }.exitDownloadsManagerToBrowser(composeTestRule) { - verifyPageContent(testPage.content) - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080139 - @SmokeTest - @Test - fun verifyThePasswordsMenuItemTest() { - val testPage = mockWebServer.getGenericAsset(1) - - navigationToolbar { - }.enterURLAndEnterToBrowser(testPage.url) { - }.openThreeDotMenu(composeTestRule) { - }.openPasswords { - verifySecurityPromptForLogins() - tapSetupLater() - verifyEmptySavedLoginsListView(composeTestRule) - }.goBack(composeTestRule) { - } - - exitMenu() - browserScreen { - verifyPageContent(testPage.content) - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080095 - // Verifies the main menu of a custom tab with a custom menu item - @SmokeTest - @Test - fun verifyTheCustomTabsMainMenuItemsTest() { - val customMenuItem = "TestMenuItem" - val customTabPage = mockWebServer.getGenericAsset(1) - - intentReceiverActivityTestRule.launchActivity( - createCustomTabIntent( - customTabPage.url.toString(), - customMenuItem, - ), - ) - - customTabScreen { - verifyCustomTabCloseButton() - }.openMainMenuFromRedesignedToolbar { - verifyRedesignedCustomTabsMainMenuItemsExist(customMenuItem, true) - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080100 - // The test opens a link in a custom tab then sends it to the browser - @SmokeTest - @Test - fun verifyOpenInFirefoxMainMenuTest() { - val customTabPage = mockWebServer.getGenericAsset(1) - - intentReceiverActivityTestRule.launchActivity( - createCustomTabIntent( - customTabPage.url.toString(), - ), - ) - - customTabScreen { - verifyCustomTabCloseButton() - }.openMainMenuFromRedesignedToolbar { - }.clickOpenInBrowserButtonFromRedesignedToolbar(composeTestRule) { - verifyPageContent(customTabPage.content) - verifyTabCounter("1") - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080151 - @SmokeTest - @Test - fun verifyRecommendedExtensionsListWhileNoExtensionIsInstalledTest() { - val genericURL = mockWebServer.getGenericAsset(1) - - navigationToolbar { - }.enterURLAndEnterToBrowser(genericURL.url) { - verifyPageContent(genericURL.content) - }.openThreeDotMenu(composeTestRule) { - verifyTryRecommendedExtensionButton() - }.openExtensionsFromMainMenu { - verifyRecommendedAddonsViewFromRedesignedMainMenu(composeTestRule) - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080160 - @SmokeTest - @Test - fun verifyTheExtensionsMenuListAfterRemovingAnExtensionTest() { - var recommendedExtensionTitle = "" - val genericURL = mockWebServer.getGenericAsset(1) - - navigationToolbar { - }.enterURLAndEnterToBrowser(genericURL.url) { - verifyPageContent(genericURL.content) - }.openThreeDotMenu(composeTestRule) { - verifyTryRecommendedExtensionButton() - }.openExtensionsFromMainMenu { - recommendedExtensionTitle = installRecommendedAddon(composeTestRule) - verifyAddonPermissionPrompt(recommendedExtensionTitle) - acceptPermissionToInstallAddon() - verifyAddonInstallCompletedPrompt( - recommendedExtensionTitle, - composeTestRule.activityRule, - ) - closeAddonInstallCompletePrompt() - } - - navigationToolbar { - }.enterURLAndEnterToBrowser(genericURL.url) { - }.openThreeDotMenu(composeTestRule) { - }.openExtensionsFromMainMenu { - clickManageExtensionsButtonFromRedesignedMainMenu(composeTestRule) - }.openDetailedMenuForAddon(recommendedExtensionTitle) { - }.removeAddon(composeTestRule.activityRule) { - }.goBackToHomeScreen { - } - browserScreen { - }.openThreeDotMenu(composeTestRule) { - verifyTryRecommendedExtensionButton() - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080163 - @SmokeTest - @Test - fun verifyTheManageExtensionsItemTest() { - var recommendedExtensionTitle = "" - val genericURL = mockWebServer.getGenericAsset(1) - - navigationToolbar { - }.enterURLAndEnterToBrowser(genericURL.url) { - verifyPageContent(genericURL.content) - }.openThreeDotMenu(composeTestRule) { - verifyTryRecommendedExtensionButton() - }.openExtensionsFromMainMenu { - recommendedExtensionTitle = installRecommendedAddon(composeTestRule) - verifyAddonPermissionPrompt(recommendedExtensionTitle) - acceptPermissionToInstallAddon() - verifyAddonInstallCompletedPrompt( - recommendedExtensionTitle, - composeTestRule.activityRule, - ) - closeAddonInstallCompletePrompt() - } - browserScreen { - waitForPageToLoad() - }.openThreeDotMenu(composeTestRule) { - waitForAppWindowToBeUpdated() - }.openExtensionsFromMainMenu { - clickManageExtensionsButtonFromRedesignedMainMenu(composeTestRule) - verifyAddonsListIsDisplayed(shouldBeDisplayed = true) - verifyAddonIsInstalled(recommendedExtensionTitle) - verifyEnabledTitleDisplayed() - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080129 - @Ignore("Failing, see https://bugzilla.mozilla.org/show_bug.cgi?id=1968653") - @SmokeTest - @Test - fun verifyTheBookmarkPageMenuOptionTest() { - val testPage = mockWebServer.getGenericAsset(1) - - navigationToolbar { - }.enterURLAndEnterToBrowser(testPage.url) { - }.openThreeDotMenu(composeTestRule) { - clickSaveButton() - }.clickBookmarkThisPageButton { - }.openThreeDotMenu(composeTestRule) { - clickSaveButton() - }.clickEditBookmarkButton(composeTestRule) { - verifyEditBookmarksView() - clickDeleteBookmarkButtonInEditMode() - } - browserScreen { - }.openThreeDotMenu(composeTestRule) { - clickSaveButton() - verifyBookmarkThisPageButton() - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080113 - @SmokeTest - @Test - fun verifyTheAddToShortcutsSubMenuOptionTest() { - val testPage = mockWebServer.getGenericAsset(1) - - navigationToolbar { - }.enterURLAndEnterToBrowser(testPage.url) { - verifyPageContent(testPage.content) - }.openThreeDotMenu(composeTestRule) { - openMoreMenu() - }.clickAddToShortcutsButton { - verifySnackBarText(getStringResource(R.string.snackbar_added_to_shortcuts)) - }.goToHomescreen(composeTestRule) { - verifyExistingTopSitesTabs(composeTestRule, testPage.title) - }.openTopSiteTabWithTitle(composeTestRule, testPage.title) { - }.openThreeDotMenu(composeTestRule) { - openMoreMenu() - }.clickRemoveFromShortcutsButton { - composeTestRule.waitForIdle() - }.goToHomescreen(composeTestRule) { - verifyNotExistingTopSiteItem(composeTestRule, testPage.title) - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080114 - @SmokeTest - @Test - fun verifyTheAddToHomeScreenSubMenuOptionTest() { - val testPage = mockWebServer.getGenericAsset(1) - - navigationToolbar { - }.enterURLAndEnterToBrowser(testPage.url) { - }.openThreeDotMenu(composeTestRule) { - openMoreMenu() - }.clickAddToHomeScreenButton { - clickCancelShortcutButton() - } - browserScreen { - }.openThreeDotMenu(composeTestRule) { - openMoreMenu() - }.clickAddToHomeScreenButton { - clickAddShortcutButton() - clickSystemHomeScreenShortcutAddButton() - }.openHomeScreenShortcut(testPage.title) { - verifyPageContent(testPage.content) - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080115 - @SmokeTest - @Test - fun verifyTheSaveToCollectionSubMenuOptionTest() { - val collectionTitle = "First Collection" - val firstTestPage = mockWebServer.getGenericAsset(1) - val secondTestPage = mockWebServer.getGenericAsset(2) - - composeTestRule.activityRule.applySettingsExceptions { - // Disabling these features to have better visibility of the Collections view - it.isRecentlyVisitedFeatureEnabled = false - it.isRecentTabsFeatureEnabled = false - } - - MockBrowserDataHelper - .createCollection( - Pair(firstTestPage.url.toString(), firstTestPage.title), - title = collectionTitle, - ) - - navigationToolbar { - }.enterURLAndEnterToBrowser(secondTestPage.url) { - }.openThreeDotMenu(composeTestRule) { - openMoreMenu() - }.clickSaveToCollectionButton { - }.selectExistingCollection(collectionTitle) { - verifySnackBarText("Tab saved") - }.goToHomescreen(composeTestRule) { - }.expandCollection(composeTestRule, collectionTitle) { - verifyTabSavedInCollection(composeTestRule, firstTestPage.title) - verifyTabSavedInCollection(composeTestRule, secondTestPage.title) - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080118 - @Ignore("Failing, see https://bugzilla.mozilla.org/show_bug.cgi?id=1968653") - @SmokeTest - @Test - fun verifyTheSaveAsPDFSubMenuOptionTest() { - val testPage = mockWebServer.getGenericAsset(1) - - navigationToolbar { - }.enterURLAndEnterToBrowser(testPage.url) { - }.openThreeDotMenu(composeTestRule) { - clickSaveButton() - }.clickSaveAsPDFButton { - verifyDownloadPrompt(testPage.title + ".pdf") - }.clickDownload { - }.clickOpen("application/pdf") { - assertExternalAppOpens(GOOGLE_DOCS) - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080111 - @SmokeTest - @Test - fun verifyTheTranslatePageSubMenuOptionTest() { - val testPage = mockWebServer.firstForeignWebPageAsset - - navigationToolbar { - }.enterURL(testPage.url) { - }.openThreeDotMenu(composeTestRule) { - openMoreMenu() - }.clickTranslateButton { - verifyTranslationSheetIsDisplayed(isDisplayed = true) - }.clickTranslateButton { - }.openThreeDotMenu(composeTestRule) { - openMoreMenu() - }.clickTranslatedButton { - verifyTranslationSheetIsDisplayed(isDisplayed = true) - }.clickShowOriginalButton { - verifyPageContent(testPage.content) - }.openThreeDotMenu(composeTestRule) { - openMoreMenu() - verifyTranslatePageButton() - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080128 - @SmokeTest - @Test - fun verifyTheShareButtonTest() { - val testPage = mockWebServer.getGenericAsset(1) - - navigationToolbar { - }.enterURLAndEnterToBrowser(testPage.url) { - verifyPageContent(testPage.content) - }.openThreeDotMenu(composeTestRule) { - }.clickShareButton { - verifyShareTabLayout() - verifySharingWithSelectedApp( - appName = "Gmail", - content = testPage.url.toString(), - subject = testPage.title, - ) - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080117 - @SmokeTest - @Test - fun verifyTheOpenInAppSubMenuOptionIsEnabledTest() { - val youtubeURL = "vnd.youtube://".toUri() - - navigationToolbar { - }.enterURLAndEnterToBrowser(youtubeURL) { - waitForPageToLoad(waitingTime) - }.openThreeDotMenu(composeTestRule) { - openMoreMenu() - verifyOpenInAppButtonIsEnabled(appName = "YouTube", isEnabled = true) - clickOpenInAppButton(appName = "YouTube") - assertYoutubeAppOpens() - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080131 - @SmokeTest - @Test - fun verifyDesktopSiteModeOnOffIsEnabledTest() { - val defaultWebPage = mockWebServer.getGenericAsset(1) - - navigationToolbar { - }.enterURLAndEnterToBrowser(defaultWebPage.url) { - }.openThreeDotMenu(composeTestRule) { - verifySwitchToDesktopSiteButton() - verifyDesktopSiteButtonState(isEnabled = false) - clickSwitchToDesktopSiteButton() - } - browserScreen { - waitForPageToLoad(pageLoadWaitingTime = waitingTimeLong) - }.openThreeDotMenu(composeTestRule) { - verifyDesktopSiteButtonState(isEnabled = true) - clickSwitchToDesktopSiteButton() - } - browserScreen { - waitForPageToLoad(pageLoadWaitingTime = waitingTimeLong) - }.openThreeDotMenu(composeTestRule) { - verifyDesktopSiteButtonState(isEnabled = false) - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080119 - @SmokeTest - @Test - fun verifyThePrintSubMenuOptionTest() { - val defaultWebPage = mockWebServer.getGenericAsset(1) - - navigationToolbar { - }.enterURLAndEnterToBrowser(defaultWebPage.url) { - mDevice.waitForIdle() - }.openThreeDotMenu(composeTestRule) { - openMoreMenu() - clickPrintContentButton() - assertNativeAppOpens(PRINT_SPOOLER) - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080156 - @Ignore("Failing, see: https://bugzilla.mozilla.org/show_bug.cgi?id=2005535") - @SmokeTest - @Test - fun verifyTheExtensionInstallationTest() { - var recommendedExtensionTitle = "" - val genericURL = mockWebServer.getGenericAsset(1) - - navigationToolbar { - }.enterURLAndEnterToBrowser(genericURL.url) { - verifyPageContent(genericURL.content) - }.openThreeDotMenu(composeTestRule) { - verifyTryRecommendedExtensionButton() - }.openExtensionsFromMainMenu { - recommendedExtensionTitle = installRecommendedAddon(composeTestRule) - acceptPermissionToInstallAddon() - verifyAddonInstallCompletedPrompt( - recommendedExtensionTitle, - composeTestRule.activityRule, - ) - closeAddonInstallCompletePrompt() - } - browserScreen { - }.openThreeDotMenu(composeTestRule) { - verifyExtensionsButtonWithInstalledExtension(recommendedExtensionTitle) - }.openExtensionsFromMainMenu { - verifyDiscoverMoreExtensionsButton(composeTestRule, isDisplayed = false) - verifyManageExtensionsButtonFromRedesignedMainMenu(composeTestRule, isDisplayed = true) - verifyInstalledExtension(composeTestRule, recommendedExtensionTitle) - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080181 - @SmokeTest - @Test - fun verifyTheHomePageSettingsMenuItemTest() { - homeScreen { - }.openThreeDotMenu(composeTestRule) { - }.openSettings { - verifySettingsToolbar() - }.goBack { - verifyHomeWordmark() - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080121 - @Test - fun verifyTheBrowserViewMainMenuCFRTest() { - val genericURL = mockWebServer.getGenericAsset(1) - - composeTestRule.activityRule.applySettingsExceptions { - it.isMenuRedesignCFREnabled = true - } - navigationToolbar { - }.enterURLAndEnterToBrowser(genericURL.url) { - }.openThreeDotMenu(composeTestRule) { - verifyMainMenuCFR() - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080898 - @Test - fun verifyTheFindInPageOptionInPDFsTest() { - val testPage = mockWebServer.getGenericAsset(3) - - navigationToolbar { - }.enterURLAndEnterToBrowser(testPage.url) { - clickPageObject(MatcherHelper.itemWithText("PDF form file")) - clickPageObject(itemWithResIdAndText("android:id/button2", "Cancel")) - }.openThreeDotMenu(composeTestRule) { - }.clickFindInPageButton { - verifyFindInPageNextButton() - verifyFindInPagePrevButton() - verifyFindInPageCloseButton() - enterFindInPageQuery("l") - verifyFindInPageResult("1/2") - clickFindInPageNextButton() - verifyFindInPageResult("2/2") - clickFindInPagePrevButton() - verifyFindInPageResult("1/2") - }.closeFindInPageWithCloseButton { - verifyFindInPageBar(false) - }.openThreeDotMenu(composeTestRule) { - }.clickFindInPageButton { - enterFindInPageQuery("p") - verifyFindInPageResult("1/1") - }.closeFindInPageWithBackButton { - verifyFindInPageBar(false) - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080145 - @Test - fun verifyTheQuitFirefoxMenuItemTest() { - val genericURL = mockWebServer.getGenericAsset(1) - - homeScreen { - }.openThreeDotMenu(composeTestRule) { - }.openSettings { - }.openSettingsSubMenuDeleteBrowsingDataOnQuit { - verifyDeleteBrowsingOnQuitEnabled(false) - clickDeleteBrowsingOnQuitButtonSwitch() - verifyDeleteBrowsingOnQuitEnabled(true) - }.goBack { - verifySettingsOptionSummary("Delete browsing data on quit", "On") - }.goBack { - } - navigationToolbar { - }.enterURLAndEnterToBrowser(genericURL.url) { - }.openThreeDotMenu(composeTestRule) { - clickQuitFirefoxButton() - restartApp(composeTestRule.activityRule) - } - homeScreen { - verifyHomeWordmark() - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080103 - @Test - fun verifyTheDesktopSiteMenuItemInACustomTabTest() { - val customTabPage = mockWebServer.getGenericAsset(1) - - intentReceiverActivityTestRule.launchActivity( - createCustomTabIntent( - customTabPage.url.toString(), - ), - ) - - customTabScreen { - }.openMainMenuFromRedesignedToolbar { - verifySwitchToDesktopSiteButton(composeTestRule) - verifyDesktopSiteButtonState(composeTestRule, isEnabled = false) - clickSwitchToDesktopSiteButton(composeTestRule) - }.openMainMenuFromRedesignedToolbar { - verifyDesktopSiteButtonState(composeTestRule, isEnabled = true) - clickSwitchToDesktopSiteButton(composeTestRule) - }.openMainMenuFromRedesignedToolbar { - verifyDesktopSiteButtonState(composeTestRule, isEnabled = false) - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080101 - @SmokeTest - @Test - fun verifyTheFindInPageMenuItemInACustomTabTest() { - val customTabPage = mockWebServer.getGenericAsset(3) - - intentReceiverActivityTestRule.launchActivity( - createCustomTabIntent( - customTabPage.url.toString(), - ), - ) - - customTabScreen { - }.openMainMenuFromRedesignedToolbar { - }.clickFindInPageButton(composeTestRule) { - verifyFindInPageNextButton() - verifyFindInPagePrevButton() - verifyFindInPageCloseButton() - enterFindInPageQuery("a") - verifyFindInPageResult("1/3") - clickFindInPageNextButton() - verifyFindInPageResult("2/3") - clickFindInPageNextButton() - verifyFindInPageResult("3/3") - clickFindInPagePrevButton() - verifyFindInPageResult("2/3") - clickFindInPagePrevButton() - verifyFindInPageResult("1/3") - }.closeFindInPageWithCloseButton { - verifyFindInPageBar(false) - }.openThreeDotMenu(composeTestRule) { - }.clickFindInPageButton { - enterFindInPageQuery("3") - verifyFindInPageResult("1/1") - }.closeFindInPageWithBackButton { - verifyFindInPageBar(false) - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080107 - @Test - fun verifyTheClosingBehaviourWhenTappingOutsideTheCustomTabMainMenuTest() { - val customMenuItem = "TestMenuItem" - val customTabPage = mockWebServer.getGenericAsset(1) - - intentReceiverActivityTestRule.launchActivity( - createCustomTabIntent( - customTabPage.url.toString(), - ), - ) - - customTabScreen { - }.openMainMenuFromRedesignedToolbar { - }.clickOutsideTheMainMenu { - } - customTabScreen { - verifyRedesignedCustomTabsMainMenuItemsExist( - customMenuItem, - false, - waitingTimeVeryShort, - ) - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080162 - @Ignore("Failing, see: https://bugzilla.mozilla.org/show_bug.cgi?id=2002573") - @SmokeTest - @Test - fun verifyTheExtensionMenuListWhileExtensionsAreDisabledTest() { - var recommendedExtensionTitle = "" - val genericURL = mockWebServer.getGenericAsset(1) - - navigationToolbar { - }.enterURLAndEnterToBrowser(genericURL.url) { - verifyPageContent(genericURL.content) - }.openThreeDotMenu(composeTestRule) { - verifyTryRecommendedExtensionButton() - }.openExtensionsFromMainMenu { - recommendedExtensionTitle = installRecommendedAddon(composeTestRule) - acceptPermissionToInstallAddon() - verifyAddonInstallCompletedPrompt( - recommendedExtensionTitle, - composeTestRule.activityRule, - ) - closeAddonInstallCompletePrompt() - } - browserScreen { - }.openThreeDotMenu(composeTestRule) { - verifyExtensionsButtonWithInstalledExtension(recommendedExtensionTitle) - }.openExtensionsFromMainMenu { - clickManageExtensionsButtonFromRedesignedMainMenu(composeTestRule) - }.openDetailedMenuForAddon(recommendedExtensionTitle) { - disableExtension() - waitUntilSnackbarGone() - }.goBack { - }.goBackToBrowser { - }.openThreeDotMenu(composeTestRule) { - verifyNoExtensionsEnabledButton() - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080153 - @Test - fun verifyTheDiscoverMoreExtensionsSubMenuItemTest() { - val genericURL = mockWebServer.getGenericAsset(1) - - navigationToolbar { - }.enterURLAndEnterToBrowser(genericURL.url) { - verifyPageContent(genericURL.content) - }.openThreeDotMenu(composeTestRule) { - verifyTryRecommendedExtensionButton() - }.openExtensionsFromMainMenu { - }.clickDiscoverMoreExtensionsButton(composeTestRule) { - verifyUrl("addons.mozilla.org/en-US/android") - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080112 - @SmokeTest - @Test - fun verifyTheReportBrokenSiteSubMenuOptionTest() { - val defaultWebPage = mockWebServer.getGenericAsset(1) - - navigationToolbar { - }.enterURLAndEnterToBrowser(defaultWebPage.url) { - }.openThreeDotMenu(composeTestRule) { - openMoreMenu() - }.clickReportBrokenSiteButton { - verifyWebCompatReporterViewItems( - composeTestRule, - websiteURL = defaultWebPage.url.toString(), - ) - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2939173 - @Test - fun verifyTheWhatIsBrokenErrorMessageTest() { - val defaultWebPage = mockWebServer.getGenericAsset(1) - - navigationToolbar { - }.enterURLAndEnterToBrowser(defaultWebPage.url) { - }.openThreeDotMenu(composeTestRule) { - openMoreMenu() - }.openReportBrokenSite { - verifyWebCompatReporterViewItems(composeTestRule, defaultWebPage.url.toString()) - verifyWhatIsBrokenField(composeTestRule) - verifySendButtonIsEnabled(composeTestRule, isEnabled = false) - clickChooseReasonField(composeTestRule) - clickSiteDoesNotLoadReason(composeTestRule) - verifyChooseReasonErrorMessageIsNotDisplayed(composeTestRule) - verifySendButtonIsEnabled(composeTestRule, isEnabled = true) - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2939175 - @Test - fun verifyThatTheBrokenSiteFormSubmissionCanBeCanceledTest() { - val defaultWebPage = mockWebServer.getGenericAsset(1) - - navigationToolbar { - }.enterURLAndEnterToBrowser(defaultWebPage.url) { - }.openThreeDotMenu(composeTestRule) { - openMoreMenu() - }.openReportBrokenSite { - verifyWebCompatReporterViewItems(composeTestRule, defaultWebPage.url.toString()) - clickChooseReasonField(composeTestRule) - clickSiteDoesNotLoadReason(composeTestRule) - clickBrokenSiteFormCancelButton(composeTestRule) - }.openThreeDotMenu(composeTestRule) { - openMoreMenu() - }.openReportBrokenSite { - verifyWhatIsBrokenField(composeTestRule) - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2939176 - @Ignore("Failing, see https://bugzilla.mozilla.org/show_bug.cgi?id=1968653") - @Test - fun verifyTheBrokenSiteFormSubmissionWithOptionalFieldsTest() { - val defaultWebPage = mockWebServer.getGenericAsset(1) - - navigationToolbar { - }.enterURLAndEnterToBrowser(defaultWebPage.url) { - }.openThreeDotMenu(composeTestRule) { - openToolsMenu() - }.openReportBrokenSite { - verifyWebCompatReporterViewItems(composeTestRule, defaultWebPage.url.toString()) - clickChooseReasonField(composeTestRule) - clickSiteDoesNotLoadReason(composeTestRule) - describeBrokenSiteProblem( - composeTestRule, - problemDescription = "Prolonged page loading time", - ) - clickBrokenSiteFormSendButton(composeTestRule) - } - browserScreen { - verifySnackBarText("Report sent") - }.openThreeDotMenu(composeTestRule) { - openToolsMenu() - }.openReportBrokenSite { - verifyWhatIsBrokenField(composeTestRule) - verifyBrokenSiteProblem( - composeTestRule, - problemDescription = "Prolonged page loading time", - isDisplayed = false, - ) - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2939179 - @Test - fun verifyThatTheBrokenSiteFormInfoPersistsTest() { - val defaultWebPage = mockWebServer.getGenericAsset(1) - - navigationToolbar { - }.enterURLAndEnterToBrowser(defaultWebPage.url) { - }.openThreeDotMenu(composeTestRule) { - openMoreMenu() - }.openReportBrokenSite { - verifyWebCompatReporterViewItems(composeTestRule, defaultWebPage.url.toString()) - clickChooseReasonField(composeTestRule) - clickSiteDoesNotLoadReason(composeTestRule) - describeBrokenSiteProblem( - composeTestRule, - problemDescription = "Prolonged page loading time", - ) - }.closeWebCompatReporter { - }.openThreeDotMenu(composeTestRule) { - openMoreMenu() - }.openReportBrokenSite { - verifyBrokenSiteProblem( - composeTestRule, - problemDescription = "Prolonged page loading time", - isDisplayed = true, - ) - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2939180 - @Test - fun verifyTheBrokenSiteFormIsEmptyWithoutSubmittingThePreviousOneTest() { - val firstWebPage = mockWebServer.getGenericAsset(1) - val secondWebPage = mockWebServer.getGenericAsset(2) - - navigationToolbar { - }.enterURLAndEnterToBrowser(firstWebPage.url) { - }.openThreeDotMenu(composeTestRule) { - openMoreMenu() - }.openReportBrokenSite { - verifyWebCompatReporterViewItems(composeTestRule, firstWebPage.url.toString()) - clickChooseReasonField(composeTestRule) - clickSiteDoesNotLoadReason(composeTestRule) - describeBrokenSiteProblem( - composeTestRule, - problemDescription = "Prolonged page loading time", - ) - }.closeWebCompatReporter { - }.openTabDrawer(composeTestRule) { - }.openNewTab { - }.submitQuery(secondWebPage.url.toString()) { - }.openThreeDotMenu(composeTestRule) { - openMoreMenu() - }.openReportBrokenSite { - verifyWhatIsBrokenField(composeTestRule) - verifyBrokenSiteProblem( - composeTestRule, - problemDescription = "Prolonged page loading time", - isDisplayed = false, - ) - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2939181 - @Test - fun verifyThatTheBrokenSiteFormInfoIsErasedWhenKillingTheAppTest() { - val defaultWebPage = mockWebServer.getGenericAsset(1) - - navigationToolbar { - }.enterURLAndEnterToBrowser(defaultWebPage.url) { - }.openThreeDotMenu(composeTestRule) { - openMoreMenu() - }.openReportBrokenSite { - verifyWebCompatReporterViewItems(composeTestRule, defaultWebPage.url.toString()) - clickChooseReasonField(composeTestRule) - clickSiteDoesNotLoadReason(composeTestRule) - describeBrokenSiteProblem( - composeTestRule, - problemDescription = "Prolonged page loading time", - ) - } - closeApp(composeTestRule.activityRule) - restartApp(composeTestRule.activityRule) - - browserScreen { - }.openThreeDotMenu(composeTestRule) { - openMoreMenu() - }.openReportBrokenSite { - verifyWhatIsBrokenField(composeTestRule) - verifyBrokenSiteProblem( - composeTestRule, - problemDescription = "Prolonged page loading time", - isDisplayed = false, - ) - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2939182 - @Test - fun verifyReportBrokenSiteFormNotDisplayedWhenTelemetryIsDisabledTest() { - val defaultWebPage = mockWebServer.getGenericAsset(1) - - homeScreen { - }.openThreeDotMenu(composeTestRule) { - }.openSettings { - }.openSettingsSubMenuDataCollection { - clickUsageAndTechnicalDataToggle(composeTestRule) - verifyUsageAndTechnicalDataToggle(composeTestRule, isChecked = false) - } - exitMenu() - navigationToolbar { - }.enterURLAndEnterToBrowser(defaultWebPage.url) { - }.openThreeDotMenu(composeTestRule) { - openMoreMenu() - }.openReportBrokenSite { - verifyUrl("webcompat.com/issues/new") - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080172 - @SmokeTest - @Test - fun verifyTheExtensionsMenuOptionTest() { - homeScreen { - }.openThreeDotMenu(composeTestRule) { - }.openExtensionsFromMainMenu { - verifyAddonsListIsDisplayed(true) - }.goBackToHomeScreen { - verifyHomeComponent(composeTestRule) - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080173 - @Test - fun verifyTheHistoryMenuOptionTest() { - homeScreen { - }.openThreeDotMenu(composeTestRule) { - }.openHistory { - verifyEmptyHistoryView() - }.goBackToHomeScreen { - verifyHomeComponent(composeTestRule) - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080174 - @Test - fun verifyTheBookmarksMenuOptionTest() { - homeScreen { - }.openThreeDotMenu(composeTestRule) { - }.openBookmarks(composeTestRule) { - verifyEmptyBookmarksMenuView() - }.goBackToHomeScreen { - verifyHomeComponent(composeTestRule) - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080175 - @Test - fun verifyTheDownloadsMenuOptionTest() { - homeScreen { - }.openThreeDotMenu(composeTestRule) { - }.openDownloads { - verifyEmptyDownloadsList(composeTestRule) - }.goBackToHomeScreen(composeTestRule) { - verifyHomeComponent(composeTestRule) - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080176 - @Test - fun verifyThePasswordsMenuOptionTest() { - homeScreen { - }.openThreeDotMenu(composeTestRule) { - }.openPasswords { - verifySecurityPromptForLogins() - tapSetupLater() - verifyEmptySavedLoginsListView(composeTestRule) - }.goBack(composeTestRule) { - } - - exitMenu() - - homeScreen { - verifyHomeComponent(composeTestRule) - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080177 - @Test - fun verifyTheSignInMenuOptionTest() { - homeScreen { - }.openThreeDotMenu(composeTestRule) { - }.clickSignInMainMenuButton(composeTestRule) { - verifyTurnOnSyncMenu() - }.goBackToHomeScreen { - verifyHomeComponent(composeTestRule) - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080182 - @Test - fun verifyTheQuitMenuOptionTest() { - homeScreen { - }.openThreeDotMenu(composeTestRule) { - }.openSettings { - }.openSettingsSubMenuDeleteBrowsingDataOnQuit { - verifyDeleteBrowsingOnQuitEnabled(false) - clickDeleteBrowsingOnQuitButtonSwitch() - verifyDeleteBrowsingOnQuitEnabled(true) - }.goBack { - verifySettingsOptionSummary("Delete browsing data on quit", "On") - }.goBack { - }.openThreeDotMenu(composeTestRule) { - clickQuitFirefoxButton() - restartApp(composeTestRule.activityRule) - } - homeScreen { - verifyHomeComponent(composeTestRule) - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080125 - @SmokeTest - @Test - fun verifyTheMainMenuBackButtonTest() { - val firstWebPage = mockWebServer.getGenericAsset(1) - val nextWebPage = mockWebServer.getGenericAsset(2) - - navigationToolbar { - }.enterURLAndEnterToBrowser(firstWebPage.url) { - }.openNavigationToolbar { - }.enterURLAndEnterToBrowser(nextWebPage.url) { - verifyUrl(nextWebPage.url.toString()) - }.openThreeDotMenu(composeTestRule) { - }.goToPreviousPage { - mDevice.waitForIdle() - verifyUrl(firstWebPage.url.toString()) - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080126 - @SmokeTest - @Test - fun verifyTheMainMenuForwardButtonTest() { - val firstWebPage = mockWebServer.getGenericAsset(1) - val nextWebPage = mockWebServer.getGenericAsset(2) - - navigationToolbar { - }.enterURLAndEnterToBrowser(firstWebPage.url) { - }.openNavigationToolbar { - }.enterURLAndEnterToBrowser(nextWebPage.url) { - verifyUrl(nextWebPage.url.toString()) - }.openThreeDotMenu(composeTestRule) { - }.goToPreviousPage { - mDevice.waitForIdle() - verifyUrl(firstWebPage.url.toString()) - }.openThreeDotMenu(composeTestRule) { - }.goForward { - verifyUrl(nextWebPage.url.toString()) - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080127 - @Test - fun verifyTheRefreshButtonTest() { - val refreshWebPage = mockWebServer.refreshAsset - - navigationToolbar { - }.enterURLAndEnterToBrowser(refreshWebPage.url) { - verifyPageContent("DEFAULT") - }.openThreeDotMenu(composeTestRule) { - }.clickRefreshButton { - verifyPageContent("REFRESHED") - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080134 - @SmokeTest - @Test - fun verifyTheExtensionsMainMenuListTest() { - val testPage = mockWebServer.getGenericAsset(1) - - navigationToolbar { - }.enterURLAndEnterToBrowser(testPage.url) { - }.openThreeDotMenu(composeTestRule) { - verifyTryRecommendedExtensionButton() - }.clickExtensionsChevronFromMainMenu { - verifyRecommendedAddonsViewFromRedesignedMainMenu(composeTestRule) - clickCollapseExtensionsChevronFromMainMenu(composeTestRule) - verifyExtensionsMainMenuOptionIsCollapsed(composeTestRule, areExtensionsInstalled = false) - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080135 - @Test - fun verifyTheMoreMainMenuListTest() { - val firstTestPage = mockWebServer.firstForeignWebPageAsset - - navigationToolbar { - }.enterURLAndEnterToBrowser(firstTestPage.url) { - }.openThreeDotMenu(composeTestRule) { - clickMoreOptionChevron() - verifyMoreMainMenuItems() - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080137 - @SmokeTest - @Test - fun verifyTheBookmarksMainMenuItemTest() { - val testPage = mockWebServer.getGenericAsset(1) - - navigationToolbar { - }.enterURLAndEnterToBrowser(testPage.url) { - }.openThreeDotMenu(composeTestRule) { - }.openBookmarks(composeTestRule) { - verifyEmptyBookmarksMenuView() - }.goBackToBrowserScreen { - verifyPageContent(testPage.content) - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080140 - @Test - fun verifyTheSignInMainMenuItemTest() { - val testPage = mockWebServer.getGenericAsset(1) - - navigationToolbar { - }.enterURLAndEnterToBrowser(testPage.url) { - }.openThreeDotMenu(composeTestRule) { - }.clickSignInMainMenuButton(composeTestRule) { - verifyTurnOnSyncMenu() - }.goBack { - verifyPageContent(testPage.content) - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080144 - @Test - fun verifyTheSettingsMainMenuItemTest() { - val testPage = mockWebServer.getGenericAsset(1) - - navigationToolbar { - }.enterURLAndEnterToBrowser(testPage.url) { - }.openThreeDotMenu(composeTestRule) { - }.openSettings { - verifySettingsView() - }.goBackToBrowser { - verifyPageContent(testPage.content) - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080096 - @SmokeTest - @Test - fun verifyTheMainMenuBackButtonFromCustomTabTest() { - val customMenuItem = "TestMenuItem" - val customTabPage = mockWebServer.getGenericAsset(4) - - intentReceiverActivityTestRule.launchActivity( - createCustomTabIntent( - customTabPage.url.toString(), - customMenuItem, - ), - ) - - customTabScreen { - clickPageObject(itemContainingText("Link 1")) - }.openMainMenuFromRedesignedToolbar { - }.clickBackButtonFromMenu(composeTestRule) { - waitForPageToLoad(waitingTime) - } - - browserScreen { - verifyPageContent(customTabPage.content) - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080097 - @SmokeTest - @Test - fun verifyTheMainMenuForwardButtonFromCustomTabTest() { - val customMenuItem = "TestMenuItem" - val firstCustomTabPage = mockWebServer.getGenericAsset(4) - val secondCustomTabPage = mockWebServer.getGenericAsset(1) - - intentReceiverActivityTestRule.launchActivity( - createCustomTabIntent( - firstCustomTabPage.url.toString(), - customMenuItem, - ), - ) - - customTabScreen { - clickPageObject(itemContainingText("Link 1")) - }.openMainMenuFromRedesignedToolbar { - }.clickBackButtonFromMenu(composeTestRule) { - waitForPageToLoad(waitingTime) - verifyPageContent(firstCustomTabPage.content) - } - - customTabScreen { - }.openMainMenuFromRedesignedToolbar { - }.clickForwardButtonFromMenu(composeTestRule) { - waitForPageToLoad(waitingTime) - verifyPageContent(secondCustomTabPage.content) - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080098 - @Test - fun verifyTheMainMenuRefreshButtonFromCustomTabTest() { - val customMenuItem = "TestMenuItem" - val customTabPage = mockWebServer.refreshAsset - - intentReceiverActivityTestRule.launchActivity( - createCustomTabIntent( - customTabPage.url.toString(), - customMenuItem, - ), - ) - - browserScreen { - verifyPageContent("DEFAULT") - } - customTabScreen { - }.openMainMenuFromRedesignedToolbar { - }.clickRefreshButton(composeTestRule) { - verifyPageContent("REFRESHED") - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080099 - @Test - fun verifyTheMainMenuShareButtonFromCustomTabTest() { - val customMenuItem = "TestMenuItem" - val customTabPage = mockWebServer.getGenericAsset(1) - - intentReceiverActivityTestRule.launchActivity( - createCustomTabIntent( - customTabPage.url.toString(), - customMenuItem, - ), - ) - - customTabScreen { - }.openMainMenuFromRedesignedToolbar { - }.clickShareButtonFromRedesignedMenu(composeTestRule) { - verifyShareTabLayout() - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080102 - @Test - fun verifySwitchToDesktopSiteIsDisabledOnPDFsFromCustomTabTest() { - val customMenuItem = "TestMenuItem" - val customTabPDF = mockWebServer.pdfFormAsset - - intentReceiverActivityTestRule.launchActivity( - createCustomTabIntent( - customTabPDF.url.toString(), - customMenuItem, - ), - ) - - browserScreen { - verifyPageContent(customTabPDF.content) - } - - customTabScreen { - }.openMainMenuFromRedesignedToolbar { - verifySwitchToDesktopSiteButton(composeTestRule) - verifyDesktopSiteButtonState(composeTestRule, isEnabled = false) - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3080110 - @SmokeTest - @Test - fun verifyTheMoreMainMenuSubListTest() { - val firstTestPage = mockWebServer.firstForeignWebPageAsset - - navigationToolbar { - }.enterURLAndEnterToBrowser(firstTestPage.url) { - }.openThreeDotMenu(composeTestRule) { - openMoreMenu() - verifyMoreMainMenuItems() - } - } -} diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/MediaNotificationTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/MediaNotificationTest.kt @@ -50,10 +50,10 @@ class MediaNotificationTest : TestSetup() { fun verifyVideoPlaybackSystemNotificationTest() { val videoTestPage = mockWebServer.videoPageAsset - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(videoTestPage.url) { mDevice.waitForIdle() - clickPageObject(MatcherHelper.itemWithText("Play")) + clickPageObject(composeTestRule, MatcherHelper.itemWithText("Play")) assertPlaybackState(browserStore, MediaSession.PlaybackState.PLAYING) }.openNotificationShade { verifySystemNotificationExists(videoTestPage.title) @@ -63,7 +63,7 @@ class MediaNotificationTest : TestSetup() { mDevice.pressBack() - browserScreen { + browserScreen(composeTestRule) { assertPlaybackState(browserStore, MediaSession.PlaybackState.PAUSED) }.openTabDrawer(composeTestRule) { closeTab() @@ -85,10 +85,10 @@ class MediaNotificationTest : TestSetup() { fun verifyAudioPlaybackSystemNotificationTest() { val audioTestPage = mockWebServer.audioPageAsset - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(audioTestPage.url) { mDevice.waitForIdle() - clickPageObject(MatcherHelper.itemWithText("Play")) + clickPageObject(composeTestRule, MatcherHelper.itemWithText("Play")) assertPlaybackState(browserStore, MediaSession.PlaybackState.PLAYING) }.openNotificationShade { verifySystemNotificationExists(audioTestPage.title) @@ -98,7 +98,7 @@ class MediaNotificationTest : TestSetup() { mDevice.pressBack() - browserScreen { + browserScreen(composeTestRule) { assertPlaybackState(browserStore, MediaSession.PlaybackState.PAUSED) }.openTabDrawer(composeTestRule) { closeTab() @@ -119,13 +119,13 @@ class MediaNotificationTest : TestSetup() { fun mediaSystemNotificationInPrivateModeTest() { val audioTestPage = mockWebServer.audioPageAsset - homeScreen { - }.openTabDrawer(composeTestRule) { + homeScreen(composeTestRule) { + }.openTabDrawer { }.toggleToPrivateTabs { }.openNewTab { }.submitQuery(audioTestPage.url.toString()) { mDevice.waitForIdle() - clickPageObject(MatcherHelper.itemWithText("Play")) + clickPageObject(composeTestRule, MatcherHelper.itemWithText("Play")) assertPlaybackState(browserStore, MediaSession.PlaybackState.PLAYING) }.openNotificationShade { verifySystemNotificationExists("A site is playing media") @@ -135,7 +135,7 @@ class MediaNotificationTest : TestSetup() { mDevice.pressBack() - browserScreen { + browserScreen(composeTestRule) { assertPlaybackState(browserStore, MediaSession.PlaybackState.PAUSED) }.openTabDrawer(composeTestRule) { closeTab() @@ -150,6 +150,7 @@ class MediaNotificationTest : TestSetup() { // close notification shade before and go back to regular mode before the next test mDevice.pressBack() - homeScreen { }.togglePrivateBrowsingMode() + homeScreen(composeTestRule) { + }.togglePrivateBrowsingMode() } } diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/MicrosurveyTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/MicrosurveyTest.kt @@ -4,6 +4,7 @@ package org.mozilla.fenix.ui import androidx.compose.ui.test.junit4.AndroidComposeTestRule +import org.junit.Ignore import org.junit.Rule import org.junit.Test import org.mozilla.fenix.R @@ -36,15 +37,15 @@ class MicrosurveyTest : TestSetup() { fun activationOfThePrintMicrosurveyTest() { val testPage = mockWebServer.getGenericAsset(1) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(testPage.url) { }.openThreeDotMenu { }.clickShareButton { - }.clickPrintButton { + }.clickPrintButton(composeTestRule) { mDevice.waitForIdle() mDevice.pressBack() } - surveyScreen { + surveyScreen(composeTestRule) { verifyThePrintSurveyPrompt(composeTestRule = composeTestRule, exists = true) } } @@ -56,43 +57,45 @@ class MicrosurveyTest : TestSetup() { val testPage1 = mockWebServer.getGenericAsset(1) val testPage2 = mockWebServer.getGenericAsset(2) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(testPage1.url) { }.openThreeDotMenu { }.clickShareButton { - }.clickPrintButton { + }.clickPrintButton(composeTestRule) { mDevice.waitForIdle() mDevice.pressBack() } - surveyScreen { + surveyScreen(composeTestRule) { clickContinueSurveyButton(composeTestRule) verifyPleaseCompleteTheSurveyHeader(composeTestRule) selectAnswer("Very satisfied", composeTestRule) }.collapseSurveyByTappingBackButton { - }.openNavigationToolbar { + } + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(testPage2.url) { mDevice.waitForIdle() - surveyScreen { + surveyScreen(composeTestRule) { verifyTheSurveyTitle(getStringResource(R.string.microsurvey_prompt_printing_title), composeTestRule, true) } } } // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2809361 + @Ignore("Disabled after enabling the composable toolbar and main menu: https://bugzilla.mozilla.org/show_bug.cgi?id=2006295") @SmokeTest @Test fun verifyTheSurveyConfirmationSheetTest() { val testPage = mockWebServer.getGenericAsset(1) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(testPage.url) { }.openThreeDotMenu { }.clickShareButton { - }.clickPrintButton { + }.clickPrintButton(composeTestRule) { mDevice.waitForIdle() mDevice.pressBack() } - surveyScreen { + surveyScreen(composeTestRule) { clickContinueSurveyButton(composeTestRule) expandSurveySheet(composeTestRule) selectAnswer("Very satisfied", composeTestRule) @@ -102,25 +105,26 @@ class MicrosurveyTest : TestSetup() { } // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2809344 + @Ignore("Disabled after enabling the composable toolbar and main menu: https://bugzilla.mozilla.org/show_bug.cgi?id=2006295") @Test fun dismissTheSurveyPromptTest() { val testPage = mockWebServer.getGenericAsset(1) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(testPage.url) { }.openThreeDotMenu { }.clickShareButton { - }.clickPrintButton { + }.clickPrintButton(composeTestRule) { mDevice.waitForIdle() mDevice.pressBack() } - surveyScreen { + surveyScreen(composeTestRule) { verifyThePrintSurveyPrompt(composeTestRule = composeTestRule, exists = true) clickOutsideTheSurveyPrompt() verifyThePrintSurveyPrompt(composeTestRule = composeTestRule, exists = true) }.clickHomeScreenSurveyCloseButton { } - surveyScreen { + surveyScreen(composeTestRule) { verifyThePrintSurveyPrompt(composeTestRule = composeTestRule, exists = false) } } diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/NavigationToolbarTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/NavigationToolbarTest.kt @@ -2,24 +2,67 @@ * 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("DEPRECATION") + package org.mozilla.fenix.ui +import android.content.Context +import android.content.res.Configuration +import android.hardware.camera2.CameraManager import androidx.compose.ui.test.junit4.AndroidComposeTestRule import androidx.core.net.toUri +import androidx.test.espresso.Espresso +import androidx.test.filters.SdkSuppress +import androidx.test.rule.ActivityTestRule +import mozilla.components.concept.engine.utils.EngineReleaseChannel +import okhttp3.mockwebserver.MockWebServer +import org.junit.After +import org.junit.Assume +import org.junit.Before import org.junit.Rule import org.junit.Test +import org.mozilla.fenix.FenixApplication +import org.mozilla.fenix.IntentReceiverActivity +import org.mozilla.fenix.R import org.mozilla.fenix.customannotations.SkipLeaks import org.mozilla.fenix.customannotations.SmokeTest +import org.mozilla.fenix.ext.components +import org.mozilla.fenix.ext.settings import org.mozilla.fenix.helpers.AppAndSystemHelper.enableOrDisableBackGestureNavigationOnDevice +import org.mozilla.fenix.helpers.AppAndSystemHelper.grantSystemPermission import org.mozilla.fenix.helpers.AppAndSystemHelper.runWithAppLocaleChanged +import org.mozilla.fenix.helpers.AppAndSystemHelper.runWithCondition +import org.mozilla.fenix.helpers.AppAndSystemHelper.verifyKeyboardVisibility +import org.mozilla.fenix.helpers.DataGenerationHelper.createCustomTabIntent +import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource +import org.mozilla.fenix.helpers.HomeActivityIntentTestRule import org.mozilla.fenix.helpers.HomeActivityTestRule +import org.mozilla.fenix.helpers.MatcherHelper.itemWithText +import org.mozilla.fenix.helpers.MockBrowserDataHelper.createBookmarkItem +import org.mozilla.fenix.helpers.MockBrowserDataHelper.createHistoryItem +import org.mozilla.fenix.helpers.MockBrowserDataHelper.generateBookmarkFolder +import org.mozilla.fenix.helpers.MockBrowserDataHelper.setCustomSearchEngine +import org.mozilla.fenix.helpers.SearchDispatcher import org.mozilla.fenix.helpers.TestAssetHelper.getGenericAsset +import org.mozilla.fenix.helpers.TestAssetHelper.htmlControlsFormAsset +import org.mozilla.fenix.helpers.TestAssetHelper.loremIpsumAsset import org.mozilla.fenix.helpers.TestAssetHelper.waitingTimeLong +import org.mozilla.fenix.helpers.TestHelper +import org.mozilla.fenix.helpers.TestHelper.clickSnackbarButton +import org.mozilla.fenix.helpers.TestHelper.exitMenu import org.mozilla.fenix.helpers.TestHelper.mDevice +import org.mozilla.fenix.helpers.TestHelper.verifyDarkThemeApplied +import org.mozilla.fenix.helpers.TestHelper.verifyLightThemeApplied import org.mozilla.fenix.helpers.TestSetup import org.mozilla.fenix.helpers.perf.DetectMemoryLeaksRule +import org.mozilla.fenix.nimbus.FxNimbus +import org.mozilla.fenix.ui.robots.checkTextSizeOnWebsite +import org.mozilla.fenix.ui.robots.clickContextMenuItem +import org.mozilla.fenix.ui.robots.customTabScreen import org.mozilla.fenix.ui.robots.homeScreen +import org.mozilla.fenix.ui.robots.longClickPageObject import org.mozilla.fenix.ui.robots.navigationToolbar +import org.mozilla.fenix.ui.robots.searchScreen import java.util.Locale /** @@ -33,143 +76,922 @@ import java.util.Locale */ class NavigationToolbarTest : TestSetup() { + private val customTabActionButton = "CustomActionButton" + + private lateinit var searchMockServer: MockWebServer + + private val bookmarkFolderName = "My Folder" + + private val queryString: String = "firefox" + + private val defaultSearchEngineList = + listOf( + "Bing", + "DuckDuckGo", + "Google", + ) + + private val generalEnginesList = listOf("DuckDuckGo", "Google", "Bing") + private val topicEnginesList = listOf("Wikipedia (en)") + + private val firefoxSuggestHeader = getStringResource(R.string.firefox_suggest_header) + + private fun getUiTheme(): Boolean { + val mode = + composeTestRule.activity.resources?.configuration?.uiMode?.and(Configuration.UI_MODE_NIGHT_MASK) + + return when (mode) { + Configuration.UI_MODE_NIGHT_YES -> true // dark theme is set + Configuration.UI_MODE_NIGHT_NO -> false // dark theme is not set, using light theme + else -> false // default option is light theme + } + } + @get:Rule val composeTestRule = AndroidComposeTestRule( - HomeActivityTestRule.withDefaultSettingsOverrides(), + HomeActivityIntentTestRule( + isPWAsPromptEnabled = false, + isWallpaperOnboardingEnabled = false, + isOpenInAppBannerEnabled = false, + isMicrosurveyEnabled = false, + isTermsOfServiceAccepted = true, + ), ) { it.activity } @get:Rule + val intentReceiverActivityTestRule = ActivityTestRule( + IntentReceiverActivity::class.java, + true, + false, + ) + + @get:Rule val memoryLeaksRule = DetectMemoryLeaksRule() - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/987326 - // Swipes the nav bar left/right to switch between tabs + @Before + override fun setUp() { + super.setUp() + searchMockServer = MockWebServer().apply { + dispatcher = SearchDispatcher() + start() + } + } + + @After + override fun tearDown() { + super.tearDown() + searchMockServer.shutdown() + } + + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3135074 + @SmokeTest + @Test + fun verifySecurePageSecuritySubMenuTest() { + runWithCondition( + composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.BETA && + composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.RELEASE, + ) { + val defaultWebPage = "https://mozilla-mobile.github.io/testapp/loginForm" + val defaultWebPageTitle = "Login_form" + + navigationToolbar(composeTestRule) { + }.enterURLAndEnterToBrowser( + defaultWebPage.toUri(), + ) { + verifyPageContent("Login Form") + }.openSiteSecuritySheet { + verifyQuickActionSheet(defaultWebPage, true) + openSecureConnectionSubMenu(true) + verifySecureConnectionSubMenu(defaultWebPageTitle, defaultWebPage, true) + } + } + } + + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3135075 + @SmokeTest + @Test + fun verifyInsecurePageSecuritySubMenuTest() { + runWithCondition( + composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.BETA && + composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.RELEASE, + ) { + val defaultWebPage = mockWebServer.getGenericAsset(1) + + navigationToolbar(composeTestRule) { + }.enterURLAndEnterToBrowser(defaultWebPage.url) { + verifyPageContent(defaultWebPage.content) + }.openSiteSecuritySheet { + verifyQuickActionSheet(defaultWebPage.url.toString(), false) + openSecureConnectionSubMenu(false) + verifySecureConnectionSubMenu( + defaultWebPage.title, + defaultWebPage.url.toString(), + false, + ) + } + } + } + + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3135076 @SmokeTest @Test @SkipLeaks - fun swipeToSwitchTabTest() { - val firstWebPage = mockWebServer.getGenericAsset(1) - val secondWebPage = mockWebServer.getGenericAsset(2) + fun verifyClearCookiesFromQuickSettingsTest() { + runWithCondition( + composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.BETA && + composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.RELEASE, + ) { + val loginPage = "https://mozilla-mobile.github.io/testapp/loginForm" + val originWebsite = "mozilla-mobile.github.io" + + navigationToolbar(composeTestRule) { + }.enterURLAndEnterToBrowser(loginPage.toUri()) { + waitForPageToLoad(waitingTimeLong) + }.openSiteSecuritySheet { + clickQuickActionSheetClearSiteData() + verifyClearSiteDataPrompt(originWebsite) + } + } + } + + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3135005 + @SmokeTest + @Test + fun verifyFontSizingChangeTest() { + runWithCondition( + composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.BETA && + composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.RELEASE, + ) { + // Goes through the settings and changes the default text on a webpage, then verifies if the text has changed. + val fenixApp = composeTestRule.activity.applicationContext as FenixApplication + val webpage = mockWebServer.loremIpsumAsset.url + + // This value will represent the text size percentage the webpage will scale to. The default value is 100%. + val textSizePercentage = 180 + + homeScreen(composeTestRule) { + }.openThreeDotMenu { + }.clickSettingsButton { + }.openAccessibilitySubMenu { + clickFontSizingSwitch() + verifyEnabledMenuItems() + changeTextSizeSlider(textSizePercentage) + verifyTextSizePercentage(textSizePercentage) + }.goBack { + }.goBack(composeTestRule) { + } + navigationToolbar(composeTestRule) { + }.enterURLAndEnterToBrowser(webpage) { + checkTextSizeOnWebsite(textSizePercentage, fenixApp.components) + }.openThreeDotMenu { + }.clickSettingsButton { + }.openAccessibilitySubMenu { + clickFontSizingSwitch() + verifyMenuItemsAreDisabled() + } + } + } + + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3135034 + @SmokeTest + @Test + fun verifySearchForBookmarkedItemsTest() { + runWithCondition( + composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.BETA && + composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.RELEASE, + ) { + val firstWebPage = mockWebServer.getGenericAsset(1) + val secondWebPage = mockWebServer.htmlControlsFormAsset + + val newFolder = generateBookmarkFolder(title = bookmarkFolderName, position = null) + createBookmarkItem(firstWebPage.url.toString(), firstWebPage.title, null, newFolder) + createBookmarkItem(secondWebPage.url.toString(), secondWebPage.title, null) + + homeScreen(composeTestRule) { + }.openThreeDotMenu { + }.clickBookmarksButton { + }.clickSearchButton { + // Search for a valid term + typeSearch(firstWebPage.title) + verifySearchSuggestionsAreDisplayed(firstWebPage.url.toString()) + verifySuggestionsAreNotDisplayed(secondWebPage.url.toString()) + // Search for invalid term + typeSearch("Android") + verifySuggestionsAreNotDisplayed(firstWebPage.url.toString()) + verifySuggestionsAreNotDisplayed(secondWebPage.url.toString()) + } + } + } + + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3135037 + @SmokeTest + @Test + fun verifyTheCustomTabsMainMenuItemsTest() { + runWithCondition( + composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.BETA && + composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.RELEASE, + ) { + val customMenuItem = "TestMenuItem" + val customTabPage = mockWebServer.getGenericAsset(1) + + intentReceiverActivityTestRule.launchActivity( + createCustomTabIntent( + customTabPage.url.toString(), + customMenuItem, + ), + ) + + customTabScreen(composeTestRule) { + verifyCustomTabCloseButton() + }.openMainMenu { + verifyCustomTabsMainMenuItems(customMenuItem, true) + } + } + } + + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3135106 + @SmokeTest + @Test + fun verifyShowSearchSuggestionsToggleTest() { + runWithCondition( + composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.BETA && + composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.RELEASE, + ) { + homeScreen(composeTestRule) { + }.openSearch { + // The Google related suggestions aren't always displayed on cold run + // Bugzilla ticket: https://bugzilla.mozilla.org/show_bug.cgi?id=1813587 + clickSearchSelectorButton() + selectTemporarySearchMethod("DuckDuckGo") + typeSearch("mozilla ") + verifySearchSuggestionsAreDisplayed("mozilla firefox") + }.dismissSearchBar { + }.openThreeDotMenu { + }.clickSettingsButton { + }.openSearchSubMenu { + toggleShowSearchSuggestions() + }.goBack { + }.goBack(composeTestRule) { + }.openSearch { + // The Google related suggestions aren't always displayed on cold run + // Bugzilla ticket: https://bugzilla.mozilla.org/show_bug.cgi?id=1813587 + clickSearchSelectorButton() + selectTemporarySearchMethod("DuckDuckGo") + typeSearch("mozilla") + verifySuggestionsAreNotDisplayed() + } + } + } + + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3135025 + @SmokeTest + @Test + fun verifyTheDefaultSearchEngineCanBeChangedTest() { + runWithCondition( + composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.BETA && + composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.RELEASE, + ) { + // Goes through the settings and changes the default search engine, then verifies it has changed. + defaultSearchEngineList.forEach { + homeScreen(composeTestRule) { + }.openThreeDotMenu { + }.clickSettingsButton { + }.openSearchSubMenu { + openDefaultSearchEngineMenu() + changeDefaultSearchEngine(it) + exitMenu() + } + searchScreen(composeTestRule) { + verifySearchEngineIcon(name = it) + } + } + } + } + + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3135009 + @SmokeTest + @Test + fun scanQRCodeToOpenAWebpageTest() { + runWithCondition( + composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.BETA && + composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.RELEASE, + ) { + val cameraManager = + TestHelper.appContext.getSystemService(Context.CAMERA_SERVICE) as CameraManager + Assume.assumeTrue(cameraManager.cameraIdList.isNotEmpty()) + + homeScreen(composeTestRule) { + }.openSearch { + clickScanButton() + grantSystemPermission() + verifyScannerOpen() + } + } + } + + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3135051 + @SmokeTest + @Test + fun verifyHistorySearchWithBrowsingHistoryTest() { + runWithCondition( + composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.BETA && + composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.RELEASE, + ) { + val firstPageUrl = searchMockServer.getGenericAsset(1) + val secondPageUrl = searchMockServer.getGenericAsset(2) + + createHistoryItem(firstPageUrl.url.toString()) + createHistoryItem(secondPageUrl.url.toString()) + + homeScreen(composeTestRule) { + }.openSearch { + clickSearchSelectorButton() + selectTemporarySearchMethod(searchEngineName = "History") + typeSearch(searchTerm = "Mozilla") + verifySuggestionsAreNotDisplayed("Mozilla") + clickClearButton() + typeSearch(searchTerm = "generic") + // verifyTypedToolbarText("generic", exists = true) + verifySearchSuggestionsAreDisplayed( + searchSuggestions = arrayOf( + firstPageUrl.url.toString(), + secondPageUrl.url.toString(), + ), + ) + }.clickSearchSuggestion(firstPageUrl.url.toString()) { + verifyUrl(firstPageUrl.url.toString()) + } + } + } + + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3135109 + // Verifies a temporary change of search engine from the Search shortcut menu + @SmokeTest + @Test + fun searchEnginesCanBeChangedTemporarilyFromSearchSelectorMenuTest() { + runWithCondition( + composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.BETA && + composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.RELEASE, + ) { + (generalEnginesList + topicEnginesList).forEach { + homeScreen(composeTestRule) { + }.openSearch { + clickSearchSelectorButton() + verifySearchShortcutList(it, isSearchEngineDisplayed = true) + selectTemporarySearchMethod(it) + verifySearchEngineIcon(it) + }.submitQuery("mozilla ") { + verifyUrl("mozilla") + }.goToHomescreen { + } + } + } + } + + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3135027 + @SmokeTest + @Test + fun searchHistoryNotRememberedInPrivateBrowsingTest() { + runWithCondition( + composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.BETA && + composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.RELEASE, + ) { + TestHelper.appContext.settings().shouldShowSearchSuggestionsInPrivate = true - // Disable the back gesture from the edge of the screen on the device. - enableOrDisableBackGestureNavigationOnDevice(backGestureNavigationEnabled = false) + val firstPageUrl = searchMockServer.getGenericAsset(1) + val searchEngineName = "TestSearchEngine" - navigationToolbar { - }.enterURLAndEnterToBrowser(firstWebPage.url) { - }.openTabDrawer(composeTestRule) { - }.openNewTab { - }.submitQuery(secondWebPage.url.toString()) { - swipeNavBarRight(secondWebPage.url.toString()) - verifyUrl(firstWebPage.url.toString()) - swipeNavBarLeft(firstWebPage.url.toString()) - verifyUrl(secondWebPage.url.toString()) + setCustomSearchEngine(searchMockServer, searchEngineName) + createBookmarkItem(firstPageUrl.url.toString(), firstPageUrl.title, 1u) + + homeScreen(composeTestRule) { + }.openSearch { + }.submitQuery("test page 1") { + }.goToHomescreen { + togglePrivateBrowsingModeOnOff() + }.openSearch { + }.submitQuery("test page 2") { + }.openSearch { + typeSearch(searchTerm = "test page") + verifyTheSuggestionsHeader(firefoxSuggestHeader) + verifyTheSuggestionsHeader("TestSearchEngine search") + verifySearchSuggestionsAreDisplayed( + searchSuggestions = arrayOf( + "test page 1", + firstPageUrl.url.toString(), + ), + ) + // 2 search engine suggestions and 2 browser suggestions (1 history, 1 bookmark) + verifySearchSuggestionsCount( + numberOfSuggestions = 4, + searchTerm = "test page", + ) + verifySuggestionsAreNotDisplayed( + searchSuggestions = arrayOf( + "test page 2", + ), + ) + } } } - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/987327 + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3135012 + @SmokeTest + @Test + fun searchResultsOpenedInNewTabsGenerateSearchGroupsTest() { + runWithCondition( + composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.BETA && + composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.RELEASE, + ) { + val firstPageUrl = searchMockServer.getGenericAsset(1).url + val secondPageUrl = searchMockServer.getGenericAsset(2).url + val searchEngineName = "TestSearchEngine" + // setting our custom mockWebServer search URL + setCustomSearchEngine(searchMockServer, searchEngineName) + + // Performs a search and opens 2 dummy search results links to create a search group + homeScreen(composeTestRule) { + }.openSearch { + }.submitQuery(queryString) { + longClickPageObject(composeTestRule, itemWithText("Link 1")) + clickContextMenuItem("Open link in new tab") + clickSnackbarButton(composeTestRule, "SWITCH") + verifyUrl(firstPageUrl.toString()) + Espresso.pressBack() + longClickPageObject(composeTestRule, itemWithText("Link 2")) + clickContextMenuItem("Open link in new tab") + clickSnackbarButton(composeTestRule, "SWITCH") + verifyUrl(secondPageUrl.toString()) + }.goToHomescreen { + verifyRecentlyVisitedSearchGroupDisplayed( + shouldBeDisplayed = true, + searchTerm = queryString, + groupSize = 3, + ) + } + } + } + + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3135013 + @SmokeTest + @Test + fun searchGroupIsNotGeneratedForLinksOpenedInPrivateTabsTest() { + runWithCondition( + composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.BETA && + composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.RELEASE, + ) { + // setting our custom mockWebServer search URL + val searchEngineName = "TestSearchEngine" + setCustomSearchEngine(searchMockServer, searchEngineName) + + // Performs a search and opens 2 dummy search results links to create a search group + homeScreen(composeTestRule) { + }.openSearch { + }.submitQuery(queryString) { + longClickPageObject(composeTestRule, itemWithText("Link 1")) + clickContextMenuItem("Open link in private tab") + longClickPageObject(composeTestRule, itemWithText("Link 2")) + clickContextMenuItem("Open link in private tab") + }.openTabDrawer(composeTestRule) { + }.toggleToPrivateTabs { + }.openPrivateTab(0) { + }.openTabDrawer(composeTestRule) { + }.openPrivateTab(1) { + }.goToHomescreen(isPrivateModeEnabled = true) { + togglePrivateBrowsingModeOnOff() + verifyRecentlyVisitedSearchGroupDisplayed( + shouldBeDisplayed = false, + searchTerm = queryString, + groupSize = 3, + ) + }.openThreeDotMenu { + }.clickHistoryButton { + verifyHistoryItemExists(shouldExist = false, item = "3 sites") + } + } + } + + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3135071 + // Swipes the nav bar left/right to switch between tabs + @SmokeTest @Test @SkipLeaks - fun swipeToSwitchTabInRTLTest() { - val firstWebPage = mockWebServer.getGenericAsset(1) - val secondWebPage = mockWebServer.getGenericAsset(2) - val arabicLocale = Locale.Builder().setLanguage("ar").setRegion("AR").build() + fun swipeToSwitchTabTest() { + runWithCondition( + composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.BETA && + composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.RELEASE, + ) { + val firstWebPage = mockWebServer.getGenericAsset(1) + val secondWebPage = mockWebServer.getGenericAsset(2) - // Disable the back gesture from the edge of the screen on the device. - enableOrDisableBackGestureNavigationOnDevice(backGestureNavigationEnabled = false) + // Disable the back gesture from the edge of the screen on the device. + enableOrDisableBackGestureNavigationOnDevice(backGestureNavigationEnabled = false) - runWithAppLocaleChanged(arabicLocale, composeTestRule.activityRule) { - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(firstWebPage.url) { }.openTabDrawer(composeTestRule) { }.openNewTab { }.submitQuery(secondWebPage.url.toString()) { - swipeNavBarLeft(secondWebPage.url.toString()) + swipeNavBarRight(secondWebPage.url.toString()) verifyUrl(firstWebPage.url.toString()) - swipeNavBarRight(firstWebPage.url.toString()) + swipeNavBarLeft(firstWebPage.url.toString()) verifyUrl(secondWebPage.url.toString()) } } } - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2265279 - @SmokeTest + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3135000 @Test - fun verifySecurePageSecuritySubMenuTest() { - val defaultWebPage = "https://mozilla-mobile.github.io/testapp/loginForm" - val defaultWebPageTitle = "Login_form" + fun changeThemeOfTheAppTest() { + runWithCondition( + composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.BETA && + composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.RELEASE, + ) { + homeScreen(composeTestRule) { + }.openThreeDotMenu { + }.clickSettingsButton { + }.openCustomizeSubMenu { + verifyThemes() + selectDarkMode() + verifyDarkThemeApplied(getUiTheme()) + selectLightMode() + verifyLightThemeApplied(getUiTheme()) + } + } + } - navigationToolbar { - }.enterURLAndEnterToBrowser(defaultWebPage.toUri()) { - verifyPageContent("Login Form") - }.openSiteSecuritySheet { - verifyQuickActionSheet(defaultWebPage, true) - openSecureConnectionSubMenu(true) - verifySecureConnectionSubMenu(defaultWebPageTitle, defaultWebPage, true) + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3135001 + @Test + fun setToolbarPositionTest() { + runWithCondition( + composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.BETA && + composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.RELEASE, + ) { + homeScreen(composeTestRule) { + }.openThreeDotMenu { + }.clickSettingsButton { + }.openCustomizeSubMenu { + verifyAddressBarPositionPreference("Top") + clickBottomToolbarToggle() + verifyAddressBarPositionPreference("Bottom") + }.goBack { + }.goBack(composeTestRule) { + verifyToolbarPosition(bottomPosition = true) + }.openThreeDotMenu { + }.clickSettingsButton { + }.openCustomizeSubMenu { + clickTopToolbarToggle() + verifyAddressBarPositionPreference("Top") + exitMenu() + } + homeScreen(composeTestRule) { + verifyToolbarPosition(bottomPosition = false) + } } } - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2265280 - @SmokeTest + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3135099 @Test - fun verifyInsecurePageSecuritySubMenuTest() { - val defaultWebPage = mockWebServer.getGenericAsset(1) + fun verifyEnabledUrlAutocompleteToggleTest() { + runWithCondition( + composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.BETA && + composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.RELEASE, + ) { + // Currently part of an experiment https://bugzilla.mozilla.org/show_bug.cgi?id=1842106 + // Check if "Top domain" suggestions for the address bar's autocomplete are enabled + if (FxNimbus.features.suggestShippedDomains.value().enabled) { + // If true it will use the hardcoded list of "top domain" suggestions for the address bar's autocomplete suggestions + homeScreen(composeTestRule) { + }.openSearch { + typeSearch("mo") + verifyTypedToolbarText("monster.com", exists = true) + typeSearch("moz") + verifyTypedToolbarText("mozilla.org", exists = true) + } + } else { + // The suggestions for the address bar's autocomplete will take use of the user's local browsing history and bookmarks + createHistoryItem("https://github.com/mozilla-mobile/fenix") + createBookmarkItem( + "https://github.com/mozilla-mobile/focus-android", + "focus-android", + 1u, + ) - navigationToolbar { - }.enterURLAndEnterToBrowser(defaultWebPage.url) { - verifyPageContent(defaultWebPage.content) - }.openSiteSecuritySheet { - verifyQuickActionSheet(defaultWebPage.url.toString(), false) - openSecureConnectionSubMenu(false) - verifySecureConnectionSubMenu(defaultWebPage.title, defaultWebPage.url.toString(), false) + homeScreen(composeTestRule) { + }.openSearch { + typeSearch("moz") + // "Top domain" suggestions from the address bar's autocomplete are disabled, "moz" shouldn't autocomplete to mozilla.org + verifyTypedToolbarText("mozilla.org", exists = false) + // The address bar's autocomplete should take use of the browsing history + // Autocomplete with the history items url + typeSearch("github.com/mozilla-mobile/f") + verifyTypedToolbarText( + "github.com/mozilla-mobile/fenix", + exists = true, + ) + // The address bar's autocomplete should also take use of the saved bookmarks + // Autocomplete with the bookmarked items url + typeSearch("github.com/mozilla-mobile/fo") + verifyTypedToolbarText( + "github.com/mozilla-mobile/focus-android", + exists = true, + ) + // It should not autocomplete with links that are not part of browsing history or bookmarks + typeSearch("github.com/mozilla-mobile/fi") + verifyTypedToolbarText( + "github.com/mozilla-mobile/firefox-android", + exists = false, + ) + } + } } } - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/1661318 - @SmokeTest + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3135102 @Test - @SkipLeaks - fun verifyClearCookiesFromQuickSettingsTest() { - val loginPage = "https://mozilla-mobile.github.io/testapp/loginForm" - val originWebsite = "mozilla-mobile.github.io" + fun disableSearchBrowsingHistorySuggestionsToggleTest() { + runWithCondition( + composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.BETA && + composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.RELEASE, + ) { + val websiteURL = mockWebServer.getGenericAsset(1).url.toString() + + createHistoryItem(websiteURL) + + homeScreen(composeTestRule) { + }.openThreeDotMenu { + }.clickSettingsButton { + }.openSearchSubMenu { + switchSearchHistoryToggle() + exitMenu() + } - navigationToolbar { - }.enterURLAndEnterToBrowser(loginPage.toUri()) { - waitForPageToLoad(waitingTimeLong) - }.openSiteSecuritySheet { - clickQuickActionSheetClearSiteData() - verifyClearSiteDataPrompt(originWebsite) + homeScreen(composeTestRule) { + }.openSearch { + typeSearch("test") + verifySuggestionsAreNotDisplayed( + "Firefox Suggest", + websiteURL, + ) + } } } - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/1360555 - @SmokeTest + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3135103 @Test - fun goToHomeScreenTest() { - val genericURL = mockWebServer.getGenericAsset(1) + fun disableSearchBookmarksToggleTest() { + runWithCondition( + composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.BETA && + composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.RELEASE, + ) { + val website = mockWebServer.getGenericAsset(1) - navigationToolbar { - }.enterURLAndEnterToBrowser(genericURL.url) { - mDevice.waitForIdle() - }.goToHomescreen(composeTestRule) { - verifyHomeScreen() + createBookmarkItem(website.url.toString(), website.title, 1u) + + homeScreen(composeTestRule) { + }.openThreeDotMenu { + }.clickSettingsButton { + }.openSearchSubMenu { + switchSearchBookmarksToggle() + // We want to avoid confusion between history and bookmarks searches, + // so we'll disable this too. + switchSearchHistoryToggle() + exitMenu() + } + + homeScreen(composeTestRule) { + }.openSearch { + typeSearch("test") + verifySuggestionsAreNotDisplayed( + "Firefox Suggest", + website.title, + ) + } } } - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2256552 - @SmokeTest + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3135105 + @SdkSuppress(minSdkVersion = 34) @Test - fun goToHomeScreenInPrivateModeTest() { - val genericURL = mockWebServer.getGenericAsset(1) + fun verifyShowVoiceSearchToggleTest() { + runWithCondition( + composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.BETA && + composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.RELEASE, + ) { + homeScreen(composeTestRule) { + }.openSearch { + verifyVoiceSearchButton(isDisplayed = true) + startVoiceSearch() + closeVoiceSearchDialog() + }.dismissSearchBar { + }.openThreeDotMenu { + }.clickSettingsButton { + }.openSearchSubMenu { + toggleVoiceSearch() + exitMenu() + } + homeScreen(composeTestRule) { + }.openSearch { + verifyVoiceSearchButton(isDisplayed = false) + } + } + } - homeScreen { - togglePrivateBrowsingModeOnOff(composeTestRule = composeTestRule) + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3135107 + @Test + fun doNotAllowSearchSuggestionsInPrivateBrowsingTest() { + runWithCondition( + composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.BETA && + composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.RELEASE, + ) { + homeScreen(composeTestRule) { + togglePrivateBrowsingModeOnOff() + }.openSearch { + typeSearch("mozilla") + verifyAllowSuggestionsInPrivateModeDialog() + denySuggestionsInPrivateMode() + verifySuggestionsAreNotDisplayed("mozilla firefox") + } } + } + + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3135006 + @Test + fun verifyClearSearchButtonTest() { + runWithCondition( + composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.BETA && + composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.RELEASE, + ) { + homeScreen(composeTestRule) { + }.openSearch { + typeSearch(queryString) + clickClearButton() + verifySearchBarPlaceholder("Search or enter address") + } + } + } + + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3135044 + @Test + fun verifySearchForHistoryItemsTest() { + runWithCondition( + composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.BETA && + composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.RELEASE, + ) { + val firstWebPage = mockWebServer.getGenericAsset(1) + val secondWebPage = mockWebServer.htmlControlsFormAsset - navigationToolbar { - }.enterURLAndEnterToBrowser(genericURL.url) { - mDevice.waitForIdle() - }.goToHomescreen(composeTestRule) { - verifyHomeScreen() + navigationToolbar(composeTestRule) { + }.enterURLAndEnterToBrowser(firstWebPage.url) { + } + navigationToolbar(composeTestRule) { + }.enterURLAndEnterToBrowser(secondWebPage.url) { + }.openThreeDotMenu { + }.clickHistoryButton { + }.clickSearchButton { + // Search for a valid term + typeSearch(firstWebPage.title) + verifySearchSuggestionsAreDisplayed(firstWebPage.url.toString()) + verifySuggestionsAreNotDisplayed(secondWebPage.url.toString()) + clickClearButton() + // Search for invalid term + typeSearch("Android") + verifySuggestionsAreNotDisplayed(firstWebPage.url.toString()) + verifySuggestionsAreNotDisplayed(secondWebPage.url.toString()) + } + } + } + + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3135049 + @Test + fun verifyHistorySearchWithoutBrowsingHistoryTest() { + runWithCondition( + composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.BETA && + composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.RELEASE, + ) { + homeScreen(composeTestRule) { + }.openSearch { + clickSearchSelectorButton() + selectTemporarySearchMethod("History") + typeSearch(searchTerm = "Mozilla") + verifySuggestionsAreNotDisplayed("Mozilla") + clickClearButton() + verifySearchBarPlaceholder("Search history") + } + } + } + + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3135015 + @SdkSuppress(minSdkVersion = 34) + @Test + fun verifySearchBarItemsTest() { + runWithCondition( + composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.BETA && + composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.RELEASE, + ) { + navigationToolbar(composeTestRule) { + verifyDefaultSearchEngine("Google") + verifySearchBarPlaceholder() + }.clickURLBar { + verifyKeyboardVisibility(isExpectedToBeVisible = true) + verifyScanButton(isDisplayed = true) + verifyVoiceSearchButton(isDisplayed = true) + verifySearchBarPlaceholder("Search or enter address") + typeSearch("mozilla ") + verifyScanButton(isDisplayed = false) + verifyVoiceSearchButton(isDisplayed = true) + } + } + } + + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3135016 + @Test + fun verifySearchSelectorMenuItemsTest() { + runWithCondition( + composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.BETA && + composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.RELEASE, + ) { + homeScreen(composeTestRule) { + }.openSearch { + clickSearchSelectorButton() + verifySearchShortcutList( + *generalEnginesList.toTypedArray(), + *topicEnginesList.toTypedArray(), + "Bookmarks", + "Tabs", + "History", + "Search settings", + isSearchEngineDisplayed = true, + ) + } + } + } + + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3135021 + @SdkSuppress(minSdkVersion = 34) + @Test + fun verifyTabsSearchItemsTest() { + runWithCondition( + composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.BETA && + composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.RELEASE, + ) { + searchScreen(composeTestRule) { + clickSearchSelectorButton() + selectTemporarySearchMethod("Tabs") + verifyVoiceSearchButton(isDisplayed = true) + verifySearchBarPlaceholder("Search tabs") + verifyScanButton(isDisplayed = false) + } + } + } + + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3135048 + @SdkSuppress(minSdkVersion = 34) + @Test + fun verifyHistorySearchItemsTest() { + runWithCondition( + composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.BETA && + composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.RELEASE, + ) { + searchScreen(composeTestRule) { + clickSearchSelectorButton() + selectTemporarySearchMethod("History") + verifyVoiceSearchButton(isDisplayed = true) + verifySearchBarPlaceholder("Search history") + verifyScanButton(isDisplayed = false) + } + } + } + + // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3135036 + @Test + fun verifyCustomTabViewItemsTest() { + runWithCondition( + composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.BETA && + composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.RELEASE, + ) { + val customTabPage = mockWebServer.getGenericAsset(1) + + intentReceiverActivityTestRule.launchActivity( + createCustomTabIntent( + pageUrl = customTabPage.url.toString(), + customActionButtonDescription = customTabActionButton, + ), + ) + + customTabScreen(composeTestRule) { + verifyCustomTabCloseButton() + verifyCustomTabsSiteInfoButton() + verifyCustomTabToolbarTitle(customTabPage.title) + verifyCustomTabUrl(customTabPage.url.toString()) + verifyCustomTabActionButton(customTabActionButton) + verifyMainMenuButton() + clickCustomTabCloseButton() + } + homeScreen(composeTestRule) { + verifyHomeScreenAppBarItems() + } } } } diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/NavigationToolbarTestCompose.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/NavigationToolbarTestCompose.kt @@ -1,1003 +0,0 @@ -/* 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/. */ - -@file:Suppress("DEPRECATION") - -package org.mozilla.fenix.ui - -import android.content.Context -import android.content.res.Configuration -import android.hardware.camera2.CameraManager -import androidx.compose.ui.test.junit4.AndroidComposeTestRule -import androidx.core.net.toUri -import androidx.test.espresso.Espresso -import androidx.test.filters.SdkSuppress -import androidx.test.rule.ActivityTestRule -import mozilla.components.concept.engine.utils.EngineReleaseChannel -import okhttp3.mockwebserver.MockWebServer -import org.junit.After -import org.junit.Assume -import org.junit.Before -import org.junit.Rule -import org.junit.Test -import org.mozilla.fenix.FenixApplication -import org.mozilla.fenix.IntentReceiverActivity -import org.mozilla.fenix.R -import org.mozilla.fenix.customannotations.SkipLeaks -import org.mozilla.fenix.customannotations.SmokeTest -import org.mozilla.fenix.ext.components -import org.mozilla.fenix.ext.settings -import org.mozilla.fenix.helpers.AppAndSystemHelper.enableOrDisableBackGestureNavigationOnDevice -import org.mozilla.fenix.helpers.AppAndSystemHelper.grantSystemPermission -import org.mozilla.fenix.helpers.AppAndSystemHelper.runWithCondition -import org.mozilla.fenix.helpers.AppAndSystemHelper.verifyKeyboardVisibility -import org.mozilla.fenix.helpers.DataGenerationHelper.createCustomTabIntent -import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource -import org.mozilla.fenix.helpers.HomeActivityIntentTestRule -import org.mozilla.fenix.helpers.MatcherHelper.itemWithText -import org.mozilla.fenix.helpers.MockBrowserDataHelper.createBookmarkItem -import org.mozilla.fenix.helpers.MockBrowserDataHelper.createHistoryItem -import org.mozilla.fenix.helpers.MockBrowserDataHelper.generateBookmarkFolder -import org.mozilla.fenix.helpers.MockBrowserDataHelper.setCustomSearchEngine -import org.mozilla.fenix.helpers.SearchDispatcher -import org.mozilla.fenix.helpers.TestAssetHelper.getGenericAsset -import org.mozilla.fenix.helpers.TestAssetHelper.htmlControlsFormAsset -import org.mozilla.fenix.helpers.TestAssetHelper.loremIpsumAsset -import org.mozilla.fenix.helpers.TestAssetHelper.waitingTimeLong -import org.mozilla.fenix.helpers.TestHelper -import org.mozilla.fenix.helpers.TestHelper.clickSnackbarButton -import org.mozilla.fenix.helpers.TestHelper.exitMenu -import org.mozilla.fenix.helpers.TestHelper.verifyDarkThemeApplied -import org.mozilla.fenix.helpers.TestHelper.verifyLightThemeApplied -import org.mozilla.fenix.helpers.TestSetup -import org.mozilla.fenix.helpers.perf.DetectMemoryLeaksRule -import org.mozilla.fenix.nimbus.FxNimbus -import org.mozilla.fenix.ui.robots.checkTextSizeOnWebsite -import org.mozilla.fenix.ui.robots.clickContextMenuItem -import org.mozilla.fenix.ui.robots.customTabScreen -import org.mozilla.fenix.ui.robots.homeScreen -import org.mozilla.fenix.ui.robots.longClickPageObject -import org.mozilla.fenix.ui.robots.navigationToolbar -import org.mozilla.fenix.ui.robots.searchScreen - -class NavigationToolbarTestCompose : TestSetup() { - private val customTabActionButton = "CustomActionButton" - - private lateinit var searchMockServer: MockWebServer - - private val bookmarkFolderName = "My Folder" - - private val queryString: String = "firefox" - - private val defaultSearchEngineList = - listOf( - "Bing", - "DuckDuckGo", - "Google", - ) - - private val generalEnginesList = listOf("DuckDuckGo", "Google", "Bing") - private val topicEnginesList = listOf("Wikipedia (en)") - - private val firefoxSuggestHeader = getStringResource(R.string.firefox_suggest_header) - - private fun getUiTheme(): Boolean { - val mode = - composeTestRule.activity.resources?.configuration?.uiMode?.and(Configuration.UI_MODE_NIGHT_MASK) - - return when (mode) { - Configuration.UI_MODE_NIGHT_YES -> true // dark theme is set - Configuration.UI_MODE_NIGHT_NO -> false // dark theme is not set, using light theme - else -> false // default option is light theme - } - } - - @get:Rule - val composeTestRule = - AndroidComposeTestRule( - HomeActivityIntentTestRule( - isComposableToolbarEnabled = true, - isMenuRedesignEnabled = true, - isPWAsPromptEnabled = false, - isWallpaperOnboardingEnabled = false, - isOpenInAppBannerEnabled = false, - isMicrosurveyEnabled = false, - isTermsOfServiceAccepted = true, - ), - ) { it.activity } - - @get:Rule - val intentReceiverActivityTestRule = ActivityTestRule( - IntentReceiverActivity::class.java, - true, - false, - ) - - @get:Rule - val memoryLeaksRule = DetectMemoryLeaksRule() - - @Before - override fun setUp() { - super.setUp() - searchMockServer = MockWebServer().apply { - dispatcher = SearchDispatcher() - start() - } - } - - @After - override fun tearDown() { - super.tearDown() - searchMockServer.shutdown() - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3135074 - @SmokeTest - @Test - fun verifySecurePageSecuritySubMenuTest() { - runWithCondition( - composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.BETA && - composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.RELEASE, - ) { - val defaultWebPage = "https://mozilla-mobile.github.io/testapp/loginForm" - val defaultWebPageTitle = "Login_form" - - navigationToolbar { - }.enterURLAndEnterToBrowserWithComposableToolbar( - composeTestRule, - defaultWebPage.toUri(), - ) { - verifyPageContent("Login Form") - }.openSiteSecuritySheetWithComposableToolbar(composeTestRule) { - verifyQuickActionSheet(defaultWebPage, true) - openSecureConnectionSubMenu(true) - verifySecureConnectionSubMenu(defaultWebPageTitle, defaultWebPage, true) - } - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3135075 - @SmokeTest - @Test - fun verifyInsecurePageSecuritySubMenuTest() { - runWithCondition( - composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.BETA && - composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.RELEASE, - ) { - val defaultWebPage = mockWebServer.getGenericAsset(1) - - navigationToolbar { - }.enterURLAndEnterToBrowserWithComposableToolbar(composeTestRule, defaultWebPage.url) { - verifyPageContent(defaultWebPage.content) - }.openSiteSecuritySheetWithComposableToolbar(composeTestRule) { - verifyQuickActionSheet(defaultWebPage.url.toString(), false) - openSecureConnectionSubMenu(false) - verifySecureConnectionSubMenu( - defaultWebPage.title, - defaultWebPage.url.toString(), - false, - ) - } - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3135076 - @SmokeTest - @Test - @SkipLeaks - fun verifyClearCookiesFromQuickSettingsTest() { - runWithCondition( - composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.BETA && - composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.RELEASE, - ) { - val loginPage = "https://mozilla-mobile.github.io/testapp/loginForm" - val originWebsite = "mozilla-mobile.github.io" - - navigationToolbar { - }.enterURLAndEnterToBrowserWithComposableToolbar(composeTestRule, loginPage.toUri()) { - waitForPageToLoad(waitingTimeLong) - }.openSiteSecuritySheetWithComposableToolbar(composeTestRule) { - clickQuickActionSheetClearSiteData() - verifyClearSiteDataPrompt(originWebsite) - } - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3135005 - @SmokeTest - @Test - fun verifyFontSizingChangeTest() { - runWithCondition( - composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.BETA && - composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.RELEASE, - ) { - // Goes through the settings and changes the default text on a webpage, then verifies if the text has changed. - val fenixApp = composeTestRule.activity.applicationContext as FenixApplication - val webpage = mockWebServer.loremIpsumAsset.url - - // This value will represent the text size percentage the webpage will scale to. The default value is 100%. - val textSizePercentage = 180 - - homeScreen { - }.openThreeDotMenuWithComposableToolbar(composeTestRule) { - }.openSettings { - }.openAccessibilitySubMenu { - clickFontSizingSwitch() - verifyEnabledMenuItems() - changeTextSizeSlider(textSizePercentage) - verifyTextSizePercentage(textSizePercentage) - }.goBack { - }.goBack { - } - navigationToolbar { - }.enterURLAndEnterToBrowserWithComposableToolbar(composeTestRule, webpage) { - checkTextSizeOnWebsite(textSizePercentage, fenixApp.components) - }.openThreeDotMenuWithComposableToolbar(composeTestRule) { - }.openSettings { - }.openAccessibilitySubMenu { - clickFontSizingSwitch() - verifyMenuItemsAreDisabled() - } - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3135034 - @SmokeTest - @Test - fun verifySearchForBookmarkedItemsTest() { - runWithCondition( - composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.BETA && - composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.RELEASE, - ) { - val firstWebPage = mockWebServer.getGenericAsset(1) - val secondWebPage = mockWebServer.htmlControlsFormAsset - - val newFolder = generateBookmarkFolder(title = bookmarkFolderName, position = null) - createBookmarkItem(firstWebPage.url.toString(), firstWebPage.title, null, newFolder) - createBookmarkItem(secondWebPage.url.toString(), secondWebPage.title, null) - - homeScreen { - }.openThreeDotMenuWithComposableToolbar(composeTestRule) { - }.openBookmarks(composeTestRule) { - }.clickSearchButton { - // Search for a valid term - typeSearchWithComposableToolbar(composeTestRule, firstWebPage.title) - verifySearchSuggestionsAreDisplayed(composeTestRule, firstWebPage.url.toString()) - verifySuggestionsAreNotDisplayed(composeTestRule, secondWebPage.url.toString()) - // Search for invalid term - typeSearchWithComposableToolbar(composeTestRule, "Android") - verifySuggestionsAreNotDisplayed(composeTestRule, firstWebPage.url.toString()) - verifySuggestionsAreNotDisplayed(composeTestRule, secondWebPage.url.toString()) - } - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3135037 - @SmokeTest - @Test - fun verifyTheCustomTabsMainMenuItemsTest() { - runWithCondition( - composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.BETA && - composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.RELEASE, - ) { - val customMenuItem = "TestMenuItem" - val customTabPage = mockWebServer.getGenericAsset(1) - - intentReceiverActivityTestRule.launchActivity( - createCustomTabIntent( - customTabPage.url.toString(), - customMenuItem, - ), - ) - - customTabScreen { - verifyCustomTabCloseButtonWithComposableToolbar(composeTestRule) - }.openMainMenuWithComposableToolbar(composeTestRule) { - verifyRedesignedCustomTabsMainMenuItemsExist(customMenuItem, true) - } - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3135106 - @SmokeTest - @Test - fun verifyShowSearchSuggestionsToggleTest() { - runWithCondition( - composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.BETA && - composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.RELEASE, - ) { - homeScreen { - }.openSearchWithComposableToolbar(composeTestRule) { - // The Google related suggestions aren't always displayed on cold run - // Bugzilla ticket: https://bugzilla.mozilla.org/show_bug.cgi?id=1813587 - clickSearchSelectorButtonWithComposableToolbar(composeTestRule) - selectTemporarySearchMethodWithComposableToolbar(composeTestRule, "DuckDuckGo") - typeSearchWithComposableToolbar(composeTestRule, "mozilla ") - verifySearchSuggestionsAreDisplayed(composeTestRule, "mozilla firefox") - }.dismissSearchBar { - }.openThreeDotMenuWithComposableToolbar(composeTestRule) { - }.openSettings { - }.openSearchSubMenu { - toggleShowSearchSuggestions() - }.goBack { - }.goBack { - }.openSearchWithComposableToolbar(composeTestRule) { - // The Google related suggestions aren't always displayed on cold run - // Bugzilla ticket: https://bugzilla.mozilla.org/show_bug.cgi?id=1813587 - clickSearchSelectorButtonWithComposableToolbar(composeTestRule) - selectTemporarySearchMethodWithComposableToolbar(composeTestRule, "DuckDuckGo") - typeSearchWithComposableToolbar(composeTestRule, "mozilla") - verifySuggestionsWithComposableToolbarAreNotDisplayed(composeTestRule) - } - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3135025 - @SmokeTest - @Test - fun verifyTheDefaultSearchEngineCanBeChangedTest() { - runWithCondition( - composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.BETA && - composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.RELEASE, - ) { - // Goes through the settings and changes the default search engine, then verifies it has changed. - defaultSearchEngineList.forEach { - homeScreen { - }.openThreeDotMenuWithComposableToolbar(composeTestRule) { - }.openSettings { - }.openSearchSubMenu { - openDefaultSearchEngineMenu() - changeDefaultSearchEngine(it) - exitMenu() - } - searchScreen { - verifySearchEngineIconWithComposableToolbar( - composeTestRule = composeTestRule, - name = it, - ) - } - } - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3135009 - @SmokeTest - @Test - fun scanQRCodeToOpenAWebpageTest() { - runWithCondition( - composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.BETA && - composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.RELEASE, - ) { - val cameraManager = - TestHelper.appContext.getSystemService(Context.CAMERA_SERVICE) as CameraManager - Assume.assumeTrue(cameraManager.cameraIdList.isNotEmpty()) - - homeScreen { - }.openSearchWithComposableToolbar(composeTestRule) { - clickScanButtonWithComposableToolbar(composeTestRule) - grantSystemPermission() - verifyScannerOpen() - } - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3135051 - @SmokeTest - @Test - fun verifyHistorySearchWithBrowsingHistoryTest() { - runWithCondition( - composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.BETA && - composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.RELEASE, - ) { - val firstPageUrl = searchMockServer.getGenericAsset(1) - val secondPageUrl = searchMockServer.getGenericAsset(2) - - createHistoryItem(firstPageUrl.url.toString()) - createHistoryItem(secondPageUrl.url.toString()) - - homeScreen { - }.openSearchWithComposableToolbar(composeTestRule) { - clickSearchSelectorButtonWithComposableToolbar(composeTestRule) - selectTemporarySearchMethodWithComposableToolbar( - composeTestRule, - searchEngineName = "History", - ) - typeSearchWithComposableToolbar(composeTestRule, searchTerm = "Mozilla") - verifySuggestionsAreNotDisplayed(rule = composeTestRule, "Mozilla") - clickClearButtonWithComposableToolbar(composeTestRule) - typeSearchWithComposableToolbar(composeTestRule, searchTerm = "generic") - // verifyTypedToolbarText("generic", exists = true) - verifySearchSuggestionsAreDisplayed( - rule = composeTestRule, - searchSuggestions = arrayOf( - firstPageUrl.url.toString(), - secondPageUrl.url.toString(), - ), - ) - }.clickSearchSuggestion(firstPageUrl.url.toString()) { - verifyUrlWithComposableToolbar(composeTestRule, firstPageUrl.url.toString()) - } - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3135109 - // Verifies a temporary change of search engine from the Search shortcut menu - @SmokeTest - @Test - fun searchEnginesCanBeChangedTemporarilyFromSearchSelectorMenuTest() { - runWithCondition( - composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.BETA && - composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.RELEASE, - ) { - (generalEnginesList + topicEnginesList).forEach { - homeScreen { - }.openSearchWithComposableToolbar(composeTestRule) { - clickSearchSelectorButtonWithComposableToolbar(composeTestRule) - verifySearchShortcutListWithComposableToolbar(composeTestRule, it) - selectTemporarySearchMethodWithComposableToolbar(composeTestRule, it) - verifySearchEngineIconWithComposableToolbar(composeTestRule, it) - }.submitQueryWithComposableToolbar(composeTestRule, "mozilla ") { - verifyUrlWithComposableToolbar(composeTestRule, "mozilla") - }.goToHomescreenWithComposableToolbar(composeTestRule) { - } - } - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3135027 - @SmokeTest - @Test - fun searchHistoryNotRememberedInPrivateBrowsingTest() { - runWithCondition( - composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.BETA && - composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.RELEASE, - ) { - TestHelper.appContext.settings().shouldShowSearchSuggestionsInPrivate = true - - val firstPageUrl = searchMockServer.getGenericAsset(1) - val searchEngineName = "TestSearchEngine" - - setCustomSearchEngine(searchMockServer, searchEngineName) - createBookmarkItem(firstPageUrl.url.toString(), firstPageUrl.title, 1u) - - homeScreen { - }.openSearchWithComposableToolbar(composeTestRule) { - }.submitQueryWithComposableToolbar(composeTestRule, "test page 1") { - }.goToHomescreenWithComposableToolbar(composeTestRule) { - togglePrivateBrowsingModeOnOff(composeTestRule) - }.openSearchWithComposableToolbar(composeTestRule) { - }.submitQueryWithComposableToolbar(composeTestRule, "test page 2") { - }.openSearchWithComposableToolbar(composeTestRule) { - typeSearchWithComposableToolbar(composeTestRule, searchTerm = "test page") - verifyTheSuggestionsHeader(composeTestRule, firefoxSuggestHeader) - verifyTheSuggestionsHeader(composeTestRule, "TestSearchEngine search") - verifySearchSuggestionsAreDisplayed( - rule = composeTestRule, - searchSuggestions = arrayOf( - "test page 1", - firstPageUrl.url.toString(), - ), - ) - // 2 search engine suggestions and 2 browser suggestions (1 history, 1 bookmark) - verifySearchSuggestionsCount( - composeTestRule, - numberOfSuggestions = 4, - searchTerm = "test page", - ) - verifySuggestionsAreNotDisplayed( - composeTestRule, - searchSuggestions = arrayOf( - "test page 2", - ), - ) - } - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3135012 - @SmokeTest - @Test - fun searchResultsOpenedInNewTabsGenerateSearchGroupsTest() { - runWithCondition( - composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.BETA && - composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.RELEASE, - ) { - val firstPageUrl = searchMockServer.getGenericAsset(1).url - val secondPageUrl = searchMockServer.getGenericAsset(2).url - val searchEngineName = "TestSearchEngine" - // setting our custom mockWebServer search URL - setCustomSearchEngine(searchMockServer, searchEngineName) - - // Performs a search and opens 2 dummy search results links to create a search group - homeScreen { - }.openSearchWithComposableToolbar(composeTestRule) { - }.submitQueryWithComposableToolbar(composeTestRule, queryString) { - longClickPageObject(itemWithText("Link 1")) - clickContextMenuItem("Open link in new tab") - clickSnackbarButton(composeTestRule, "SWITCH") - verifyUrlWithComposableToolbar(composeTestRule, firstPageUrl.toString()) - Espresso.pressBack() - longClickPageObject(itemWithText("Link 2")) - clickContextMenuItem("Open link in new tab") - clickSnackbarButton(composeTestRule, "SWITCH") - verifyUrlWithComposableToolbar(composeTestRule, secondPageUrl.toString()) - }.goToHomescreenWithComposableToolbar(composeTestRule) { - verifyRecentlyVisitedSearchGroupDisplayed( - composeTestRule, - shouldBeDisplayed = true, - searchTerm = queryString, - groupSize = 3, - ) - } - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3135013 - @SmokeTest - @Test - fun searchGroupIsNotGeneratedForLinksOpenedInPrivateTabsTest() { - runWithCondition( - composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.BETA && - composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.RELEASE, - ) { - // setting our custom mockWebServer search URL - val searchEngineName = "TestSearchEngine" - setCustomSearchEngine(searchMockServer, searchEngineName) - - // Performs a search and opens 2 dummy search results links to create a search group - homeScreen { - }.openSearchWithComposableToolbar(composeTestRule) { - }.submitQueryWithComposableToolbar(composeTestRule, queryString) { - longClickPageObject(itemWithText("Link 1")) - clickContextMenuItem("Open link in private tab") - longClickPageObject(itemWithText("Link 2")) - clickContextMenuItem("Open link in private tab") - }.openTabDrawerWithComposableToolbar(composeTestRule) { - }.toggleToPrivateTabs { - }.openPrivateTab(0) { - }.openTabDrawerWithComposableToolbar(composeTestRule) { - }.openPrivateTab(1) { - }.goToHomescreenWithComposableToolbar(composeTestRule, isPrivateModeEnabled = true) { - togglePrivateBrowsingModeOnOff(composeTestRule = composeTestRule) - verifyRecentlyVisitedSearchGroupDisplayed( - composeTestRule, - shouldBeDisplayed = false, - searchTerm = queryString, - groupSize = 3, - ) - }.openThreeDotMenuWithComposableToolbar(composeTestRule) { - }.openHistory { - verifyHistoryItemExists(shouldExist = false, item = "3 sites") - } - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3135071 - // Swipes the nav bar left/right to switch between tabs - @SmokeTest - @Test - @SkipLeaks - fun swipeToSwitchTabTest() { - runWithCondition( - composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.BETA && - composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.RELEASE, - ) { - val firstWebPage = mockWebServer.getGenericAsset(1) - val secondWebPage = mockWebServer.getGenericAsset(2) - - // Disable the back gesture from the edge of the screen on the device. - enableOrDisableBackGestureNavigationOnDevice(backGestureNavigationEnabled = false) - - navigationToolbar { - }.enterURLAndEnterToBrowserWithComposableToolbar(composeTestRule, firstWebPage.url) { - }.openTabDrawerWithComposableToolbar(composeTestRule) { - }.openNewTab { - }.submitQueryWithComposableToolbar(composeTestRule, secondWebPage.url.toString()) { - swipeNavBarRightWithComposableToolbar(composeTestRule, secondWebPage.url.toString()) - verifyUrlWithComposableToolbar(composeTestRule, firstWebPage.url.toString()) - swipeNavBarLeftWithComposableToolbar(composeTestRule, firstWebPage.url.toString()) - verifyUrlWithComposableToolbar(composeTestRule, secondWebPage.url.toString()) - } - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3135000 - @Test - fun changeThemeOfTheAppTest() { - runWithCondition( - composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.BETA && - composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.RELEASE, - ) { - homeScreen { - }.openThreeDotMenuWithComposableToolbar(composeTestRule) { - }.openSettings { - }.openCustomizeSubMenu { - verifyThemes() - selectDarkMode() - verifyDarkThemeApplied(getUiTheme()) - selectLightMode() - verifyLightThemeApplied(getUiTheme()) - } - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3135001 - @Test - fun setToolbarPositionTest() { - runWithCondition( - composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.BETA && - composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.RELEASE, - ) { - homeScreen { - }.openThreeDotMenuWithComposableToolbar(composeTestRule) { - }.openSettings { - }.openCustomizeSubMenu { - verifyAddressBarPositionPreference("Top") - clickBottomToolbarToggle() - verifyAddressBarPositionPreference("Bottom") - }.goBack { - }.goBack { - verifyComposableToolbarPosition(bottomPosition = true) - }.openThreeDotMenuWithComposableToolbar(composeTestRule) { - }.openSettings { - }.openCustomizeSubMenu { - clickTopToolbarToggle() - verifyAddressBarPositionPreference("Top") - exitMenu() - } - homeScreen { - verifyComposableToolbarPosition(bottomPosition = false) - } - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3135099 - @Test - fun verifyEnabledUrlAutocompleteToggleTest() { - runWithCondition( - composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.BETA && - composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.RELEASE, - ) { - // Currently part of an experiment https://bugzilla.mozilla.org/show_bug.cgi?id=1842106 - // Check if "Top domain" suggestions for the address bar's autocomplete are enabled - if (FxNimbus.features.suggestShippedDomains.value().enabled) { - // If true it will use the hardcoded list of "top domain" suggestions for the address bar's autocomplete suggestions - homeScreen { - }.openSearchWithComposableToolbar(composeTestRule) { - typeSearchWithComposableToolbar(composeTestRule, "mo") - verifyTypedToolbarTextWithComposableToolbar(composeTestRule, "monster.com", exists = true) - typeSearchWithComposableToolbar(composeTestRule, "moz") - verifyTypedToolbarTextWithComposableToolbar(composeTestRule, "mozilla.org", exists = true) - } - } else { - // The suggestions for the address bar's autocomplete will take use of the user's local browsing history and bookmarks - createHistoryItem("https://github.com/mozilla-mobile/fenix") - createBookmarkItem( - "https://github.com/mozilla-mobile/focus-android", - "focus-android", - 1u, - ) - - homeScreen { - }.openSearchWithComposableToolbar(composeTestRule) { - typeSearchWithComposableToolbar(composeTestRule, "moz") - // "Top domain" suggestions from the address bar's autocomplete are disabled, "moz" shouldn't autocomplete to mozilla.org - verifyTypedToolbarTextWithComposableToolbar(composeTestRule, "mozilla.org", exists = false) - // The address bar's autocomplete should take use of the browsing history - // Autocomplete with the history items url - typeSearchWithComposableToolbar(composeTestRule, "github.com/mozilla-mobile/f") - verifyTypedToolbarTextWithComposableToolbar( - composeTestRule, - "github.com/mozilla-mobile/fenix", - exists = true, - ) - // The address bar's autocomplete should also take use of the saved bookmarks - // Autocomplete with the bookmarked items url - typeSearchWithComposableToolbar(composeTestRule, "github.com/mozilla-mobile/fo") - verifyTypedToolbarTextWithComposableToolbar( - composeTestRule, - "github.com/mozilla-mobile/focus-android", - exists = true, - ) - // It should not autocomplete with links that are not part of browsing history or bookmarks - typeSearchWithComposableToolbar(composeTestRule, "github.com/mozilla-mobile/fi") - verifyTypedToolbarTextWithComposableToolbar( - composeTestRule, - "github.com/mozilla-mobile/firefox-android", - exists = false, - ) - } - } - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3135102 - @Test - fun disableSearchBrowsingHistorySuggestionsToggleTest() { - runWithCondition( - composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.BETA && - composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.RELEASE, - ) { - val websiteURL = mockWebServer.getGenericAsset(1).url.toString() - - createHistoryItem(websiteURL) - - homeScreen { - }.openThreeDotMenuWithComposableToolbar(composeTestRule) { - }.openSettings { - }.openSearchSubMenu { - switchSearchHistoryToggle() - exitMenu() - } - - homeScreen { - }.openSearchWithComposableToolbar(composeTestRule) { - typeSearchWithComposableToolbar(composeTestRule, "test") - verifySuggestionsAreNotDisplayed( - composeTestRule, - "Firefox Suggest", - websiteURL, - ) - } - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3135103 - @Test - fun disableSearchBookmarksToggleTest() { - runWithCondition( - composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.BETA && - composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.RELEASE, - ) { - val website = mockWebServer.getGenericAsset(1) - - createBookmarkItem(website.url.toString(), website.title, 1u) - - homeScreen { - }.openThreeDotMenuWithComposableToolbar(composeTestRule) { - }.openSettings { - }.openSearchSubMenu { - switchSearchBookmarksToggle() - // We want to avoid confusion between history and bookmarks searches, - // so we'll disable this too. - switchSearchHistoryToggle() - exitMenu() - } - - homeScreen { - }.openSearchWithComposableToolbar(composeTestRule) { - typeSearchWithComposableToolbar(composeTestRule, "test") - verifySuggestionsAreNotDisplayed( - composeTestRule, - "Firefox Suggest", - website.title, - ) - } - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3135105 - @SdkSuppress(minSdkVersion = 34) - @Test - fun verifyShowVoiceSearchToggleTest() { - runWithCondition( - composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.BETA && - composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.RELEASE, - ) { - homeScreen { - }.openSearchWithComposableToolbar(composeTestRule) { - verifyVoiceSearchButtonWithComposableToolbar(composeTestRule, isDisplayed = true) - startVoiceSearchWithComposableToolbar(composeTestRule) - closeVoiceSearchDialog() - }.dismissSearchBar { - }.openThreeDotMenuWithComposableToolbar(composeTestRule) { - }.openSettings { - }.openSearchSubMenu { - toggleVoiceSearch() - exitMenu() - } - homeScreen { - }.openSearchWithComposableToolbar(composeTestRule) { - verifyVoiceSearchButtonWithComposableToolbar(composeTestRule, isDisplayed = false) - } - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3135107 - @Test - fun doNotAllowSearchSuggestionsInPrivateBrowsingTest() { - runWithCondition( - composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.BETA && - composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.RELEASE, - ) { - homeScreen { - togglePrivateBrowsingModeOnOff(composeTestRule = composeTestRule) - }.openSearchWithComposableToolbar(composeTestRule) { - typeSearchWithComposableToolbar(composeTestRule, "mozilla") - verifyAllowSuggestionsInPrivateModeDialogWithComposableToolbar(composeTestRule) - denySuggestionsInPrivateMode() - verifySuggestionsAreNotDisplayed(composeTestRule, "mozilla firefox") - } - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3135006 - @Test - fun verifyClearSearchButtonTest() { - runWithCondition( - composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.BETA && - composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.RELEASE, - ) { - homeScreen { - }.openSearchWithComposableToolbar(composeTestRule) { - typeSearchWithComposableToolbar(composeTestRule, queryString) - clickClearButtonWithComposableToolbar(composeTestRule) - verifySearchBarPlaceholderWithComposableToolbar(composeTestRule, "Search or enter address") - } - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3135044 - @Test - fun verifySearchForHistoryItemsTest() { - runWithCondition( - composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.BETA && - composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.RELEASE, - ) { - val firstWebPage = mockWebServer.getGenericAsset(1) - val secondWebPage = mockWebServer.htmlControlsFormAsset - - navigationToolbar { - }.enterURLAndEnterToBrowserWithComposableToolbar(composeTestRule, firstWebPage.url) { - } - navigationToolbar { - }.enterURLAndEnterToBrowserWithComposableToolbar(composeTestRule, secondWebPage.url) { - }.openThreeDotMenuWithComposableToolbar(composeTestRule) { - }.openHistory { - }.clickSearchButton { - // Search for a valid term - typeSearchWithComposableToolbar(composeTestRule, firstWebPage.title) - verifySearchSuggestionsAreDisplayed(composeTestRule, firstWebPage.url.toString()) - verifySuggestionsAreNotDisplayed(composeTestRule, secondWebPage.url.toString()) - clickClearButtonWithComposableToolbar(composeTestRule) - // Search for invalid term - typeSearchWithComposableToolbar(composeTestRule, "Android") - verifySuggestionsAreNotDisplayed(composeTestRule, firstWebPage.url.toString()) - verifySuggestionsAreNotDisplayed(composeTestRule, secondWebPage.url.toString()) - } - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3135049 - @Test - fun verifyHistorySearchWithoutBrowsingHistoryTest() { - runWithCondition( - composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.BETA && - composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.RELEASE, - ) { - homeScreen { - }.openSearchWithComposableToolbar(composeTestRule) { - clickSearchSelectorButtonWithComposableToolbar(composeTestRule) - selectTemporarySearchMethodWithComposableToolbar(composeTestRule, "History") - typeSearchWithComposableToolbar(composeTestRule, searchTerm = "Mozilla") - verifySuggestionsAreNotDisplayed(rule = composeTestRule, "Mozilla") - clickClearButtonWithComposableToolbar(composeTestRule) - verifySearchBarPlaceholderWithComposableToolbar(composeTestRule, "Search history") - } - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3135015 - @SdkSuppress(minSdkVersion = 34) - @Test - fun verifySearchBarItemsTest() { - runWithCondition( - composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.BETA && - composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.RELEASE, - ) { - navigationToolbar { - verifyDefaultSearchEngineWithComposableToolbar(composeTestRule, "Google") - verifySearchBarPlaceholderWithComposableToolbar(composeTestRule) - }.clickURLBarWithComposableToolbar(composeTestRule) { - verifyKeyboardVisibility(isExpectedToBeVisible = true) - verifyScanButtonWithComposableToolbar(composeTestRule, isDisplayed = true) - verifyVoiceSearchButtonVisibility(enabled = true) - verifySearchBarPlaceholderWithComposableToolbar(composeTestRule, "Search or enter address") - typeSearchWithComposableToolbar(composeTestRule, "mozilla ") - verifyScanButtonWithComposableToolbar(composeTestRule, isDisplayed = false) - verifyVoiceSearchButtonVisibility(enabled = true) - } - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3135016 - @Test - fun verifySearchSelectorMenuItemsTest() { - runWithCondition( - composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.BETA && - composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.RELEASE, - ) { - homeScreen { - }.openSearchWithComposableToolbar(composeTestRule) { - clickSearchSelectorButtonWithComposableToolbar(composeTestRule) - verifySearchShortcutListWithComposableToolbar( - composeTestRule = composeTestRule, - *generalEnginesList.toTypedArray(), - *topicEnginesList.toTypedArray(), - "Bookmarks", - "Tabs", - "History", - "Search settings", - ) - } - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3135021 - @SdkSuppress(minSdkVersion = 34) - @Test - fun verifyTabsSearchItemsTest() { - runWithCondition( - composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.BETA && - composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.RELEASE, - ) { - searchScreen { - clickSearchSelectorButtonWithComposableToolbar(composeTestRule) - selectTemporarySearchMethodWithComposableToolbar(composeTestRule, "Tabs") - verifyVoiceSearchButtonWithComposableToolbar(composeTestRule, isDisplayed = true) - verifySearchBarPlaceholderWithComposableToolbar(composeTestRule, "Search tabs") - verifyScanButtonWithComposableToolbar(composeTestRule, isDisplayed = false) - } - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3135048 - @SdkSuppress(minSdkVersion = 34) - @Test - fun verifyHistorySearchItemsTest() { - runWithCondition( - composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.BETA && - composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.RELEASE, - ) { - searchScreen { - clickSearchSelectorButtonWithComposableToolbar(composeTestRule) - selectTemporarySearchMethodWithComposableToolbar(composeTestRule, "History") - verifyVoiceSearchButtonWithComposableToolbar(composeTestRule, isDisplayed = true) - verifySearchBarPlaceholderWithComposableToolbar(composeTestRule, "Search history") - verifyScanButtonWithComposableToolbar(composeTestRule, isDisplayed = false) - } - } - } - - // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3135036 - @Test - fun verifyCustomTabViewItemsTest() { - runWithCondition( - composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.BETA && - composeTestRule.activity.components.core.engine.version.releaseChannel !== EngineReleaseChannel.RELEASE, - ) { - val customTabPage = mockWebServer.getGenericAsset(1) - - intentReceiverActivityTestRule.launchActivity( - createCustomTabIntent( - pageUrl = customTabPage.url.toString(), - customActionButtonDescription = customTabActionButton, - ), - ) - - customTabScreen { - verifyCustomTabCloseButtonWithComposableToolbar(composeTestRule) - verifyCustomTabsSiteInfoButtonWithComposableToolbar(composeTestRule) - verifyCustomTabToolbarTitleWithComposableToolbar(composeTestRule, customTabPage.title) - verifyCustomTabUrlWithComposableToolbar(composeTestRule, customTabPage.url.toString()) - verifyCustomTabActionButtonWithComposableToolbar(composeTestRule, customTabActionButton) - verifyMainMenuComposeButtonWithComposableToolbar(composeTestRule) - clickCustomTabCloseButtonWithComposableToolbar(composeTestRule) - } - homeScreen { - verifyHomeScreenAppBarItems() - } - } - } -} diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/NimbusEventTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/NimbusEventTest.kt @@ -9,6 +9,7 @@ import io.mockk.mockk import mozilla.components.concept.sync.AuthType import mozilla.components.service.fxa.FirefoxAccount import org.junit.Assert.assertTrue +import org.junit.Ignore import org.junit.Rule import org.junit.Test import org.mozilla.fenix.components.TelemetryAccountObserver diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/NimbusMessagingHomescreenTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/NimbusMessagingHomescreenTest.kt @@ -5,11 +5,13 @@ package org.mozilla.fenix.ui import android.content.Intent +import androidx.compose.ui.test.junit4.AndroidComposeTestRule import mozilla.components.service.nimbus.messaging.FxNimbusMessaging import mozilla.components.service.nimbus.messaging.MessageData import mozilla.components.service.nimbus.messaging.Messaging import mozilla.components.service.nimbus.messaging.StyleData import org.junit.Before +import org.junit.Ignore import org.junit.Rule import org.junit.Test import org.mozilla.experiments.nimbus.Res @@ -27,7 +29,6 @@ import org.mozilla.fenix.ui.robots.homeScreen * * Verifies a message can be displayed with all of the correct components **/ - class NimbusMessagingHomescreenTest : TestSetup() { private var messageButtonLabel = "CLICK ME" private var messageText = "Some Nimbus Messaging text" @@ -46,6 +47,9 @@ class NimbusMessagingHomescreenTest : TestSetup() { @JvmField val retryTestRule = RetryTestRule(3) + val composeTestRule = + AndroidComposeTestRule(HomeActivityIntentTestRule.withDefaultSettingsOverrides()) { it.activity } + @Before override fun setUp() { super.setUp() @@ -97,7 +101,7 @@ class NimbusMessagingHomescreenTest : TestSetup() { @Test fun testNimbusMessageIsDisplayed() { // Checks the home screen card message is displayed correctly - homeScreen { + homeScreen(composeTestRule) { verifyNimbusMessageCard(messageTitle, messageText, messageButtonLabel) } } diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/NimbusMessagingMessageTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/NimbusMessagingMessageTest.kt @@ -13,6 +13,7 @@ import org.junit.Assert.assertFalse import org.junit.Assert.assertTrue import org.junit.Assert.fail import org.junit.Before +import org.junit.Ignore import org.junit.Rule import org.junit.Test import org.mozilla.fenix.ext.components diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/NimbusMessagingNotificationTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/NimbusMessagingNotificationTest.kt @@ -6,11 +6,13 @@ package org.mozilla.fenix.ui import android.content.Context import android.os.Build +import androidx.compose.ui.test.junit4.AndroidComposeTestRule import androidx.test.rule.GrantPermissionRule import androidx.test.rule.GrantPermissionRule.grant import mozilla.components.service.nimbus.messaging.FxNimbusMessaging import org.json.JSONObject import org.junit.Before +import org.junit.Ignore import org.junit.Rule import org.junit.Test import org.mozilla.experiments.nimbus.HardcodedNimbusFeatures @@ -29,8 +31,10 @@ class NimbusMessagingNotificationTest : TestSetup() { private lateinit var hardcodedNimbus: HardcodedNimbusFeatures @get:Rule - val activityTestRule = - HomeActivityIntentTestRule.withDefaultSettingsOverrides(skipOnboarding = true) + val composeTestRule = + AndroidComposeTestRule( + HomeActivityIntentTestRule.withDefaultSettingsOverrides(skipOnboarding = true), + ) { it.activity } @get:Rule val grantPermissionRule: GrantPermissionRule = @@ -77,9 +81,9 @@ class NimbusMessagingNotificationTest : TestSetup() { // hardcodedNimbus by the time its re-scheduled. // Because the scheduling happens for a second time, the work request needs to replace the // existing one. - activityTestRule.finishActivity() + composeTestRule.activityRule.finishActivity() hardcodedNimbus.connectWith(FxNimbus) - activityTestRule.launchActivity(null) + composeTestRule.activityRule.launchActivity(null) mDevice.openNotification() notificationShade { diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/NimbusMessagingSurveyTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/NimbusMessagingSurveyTest.kt @@ -6,9 +6,11 @@ package org.mozilla.fenix.ui import android.content.Context import android.content.pm.ActivityInfo +import androidx.compose.ui.test.junit4.AndroidComposeTestRule import org.json.JSONObject import org.junit.Assert.assertNotEquals import org.junit.Before +import org.junit.Ignore import org.junit.Rule import org.junit.Test import org.mozilla.experiments.nimbus.HardcodedNimbusFeatures @@ -32,13 +34,8 @@ class NimbusMessagingSurveyTest : TestSetup() { private lateinit var hardcodedNimbus: HardcodedNimbusFeatures @get:Rule - val activityTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides( - skipOnboarding = true, - ) - - @Rule - @JvmField - val retryTestRule = RetryTestRule(2) + val composeTestRule = + AndroidComposeTestRule(HomeActivityIntentTestRule.withDefaultSettingsOverrides(skipOnboarding = true)) { it.activity } @Before override fun setUp() { @@ -86,26 +83,26 @@ class NimbusMessagingSurveyTest : TestSetup() { ), ) } - activityTestRule.finishActivity() + composeTestRule.activityRule.finishActivity() hardcodedNimbus.connectWith(FxNimbus) - activityTestRule.launchActivity(null) + composeTestRule.activityRule.launchActivity(null) } // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2809390 @Test fun checkSurveyNavigatesCorrectly() { - surveyScreen { - verifySurveyButton() + surveyScreen(composeTestRule) { + verifySurveyButton(composeTestRule) }.clickSurveyButton { - assertNotEquals("", getCurrentUrl()) + verifyUrl("example.com") } } // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2809389 @Test fun checkSurveyNoThanksNavigatesCorrectly() { - surveyScreen { - verifySurveyNoThanksButton() + surveyScreen(composeTestRule) { + verifySurveyNoThanksButton(composeTestRule) }.clickNoThanksSurveyButton { verifyTabCounter("0") } @@ -114,10 +111,10 @@ class NimbusMessagingSurveyTest : TestSetup() { // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2809388 @Test fun checkSurveyLandscapeLooksCorrect() { - activityTestRule.activity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE - surveyScreen { - verifySurveyNoThanksButton() - verifySurveyButton() + composeTestRule.activity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE + surveyScreen(composeTestRule) { + verifySurveyNoThanksButton(composeTestRule) + verifySurveyButton(composeTestRule) }.clickNoThanksSurveyButton { verifyTabCounter("0") } diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/NimbusMessagingTriggerTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/NimbusMessagingTriggerTest.kt @@ -8,6 +8,7 @@ import mozilla.components.service.nimbus.messaging.FxNimbusMessaging import mozilla.components.service.nimbus.messaging.Messaging import org.junit.Assert import org.junit.Before +import org.junit.Ignore import org.junit.Rule import org.junit.Test import org.mozilla.experiments.nimbus.NimbusInterface diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/NoNetworkAccessStartupTests.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/NoNetworkAccessStartupTests.kt @@ -42,7 +42,7 @@ class NoNetworkAccessStartupTests : TestSetup() { composeTestRule.activityRule.launchActivity(null) - homeScreen { + homeScreen(composeTestRule) { verifyHomeScreen() } } @@ -56,13 +56,13 @@ class NoNetworkAccessStartupTests : TestSetup() { composeTestRule.activityRule.launchActivity(null) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(url.toUri()) {} setNetworkEnabled(false) - browserScreen { - }.goToHomescreen(composeTestRule) { + browserScreen(composeTestRule) { + }.goToHomescreen { verifyHomeScreen() } } @@ -75,14 +75,14 @@ class NoNetworkAccessStartupTests : TestSetup() { composeTestRule.activityRule.launchActivity(null) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(url.toUri()) {} setNetworkEnabled(false) - browserScreen { + browserScreen(composeTestRule) { }.openThreeDotMenu { - }.refreshPage { } + }.clickRefreshButton { } } // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2240721 @@ -95,12 +95,12 @@ class NoNetworkAccessStartupTests : TestSetup() { composeTestRule.activityRule.launchActivity(null) - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openTurnOnSyncMenu { tapOnUseEmailToSignIn() - browserScreen { + browserScreen(composeTestRule) { verifyUrl("firefox.com") } } diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/OnboardingTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/OnboardingTest.kt @@ -17,7 +17,7 @@ import org.mozilla.fenix.ui.robots.homeScreen class OnboardingTest : TestSetup() { @get:Rule - val activityTestRule = + val composeTestRule = AndroidComposeTestRule( HomeActivityIntentTestRule.withDefaultSettingsOverrides(launchActivity = false), ) { it.activity } @@ -31,9 +31,9 @@ class OnboardingTest : TestSetup() { // Run UI test only on devices with Android version lower than 10 // because on Android 10 and above, the default browser dialog is shown and the first onboarding card is skipped runWithCondition(Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) { - runWithLauncherIntent(activityTestRule) { - homeScreen { - verifyFirstOnboardingCard(activityTestRule) + runWithLauncherIntent(composeTestRule) { + homeScreen(composeTestRule) { + verifyFirstOnboardingCard() } } } @@ -45,15 +45,15 @@ class OnboardingTest : TestSetup() { // Run UI test only on devices with Android version lower than 10 // because on Android 10 and above, the default browser dialog is shown and the first onboarding card is skipped runWithCondition(Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) { - runWithLauncherIntent(activityTestRule) { - homeScreen { - clickDefaultCardNotNowOnboardingButton(activityTestRule) - verifySecondOnboardingCard(activityTestRule) + runWithLauncherIntent(composeTestRule) { + homeScreen(composeTestRule) { + clickDefaultCardNotNowOnboardingButton() + verifySecondOnboardingCard() swipeSecondOnboardingCardToRight() - }.clickSetAsDefaultBrowserOnboardingButton(activityTestRule) { + }.clickSetAsDefaultBrowserOnboardingButton { verifyAndroidDefaultAppsMenuAppears() - }.goBackToOnboardingScreen { - verifySecondOnboardingCard(activityTestRule) + }.goBackToOnboardingScreen(composeTestRule) { + verifySecondOnboardingCard() } } } @@ -62,15 +62,15 @@ class OnboardingTest : TestSetup() { // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2122343 @Test fun verifySecondOnboardingCardItemsTest() { - runWithLauncherIntent(activityTestRule) { - homeScreen { + runWithLauncherIntent(composeTestRule) { + homeScreen(composeTestRule) { // Check if the device is running on Android version lower than 10 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) { // If true, click the "Not Now" button from the first onboarding card - clickDefaultCardNotNowOnboardingButton(activityTestRule) + clickDefaultCardNotNowOnboardingButton() } dismissSetAsDefaultBrowserOnboardingDialog() - verifySecondOnboardingCard(activityTestRule) + verifySecondOnboardingCard() } } } @@ -79,18 +79,18 @@ class OnboardingTest : TestSetup() { @SmokeTest @Test fun verifyThirdOnboardingCardSignInFunctionalityTest() { - runWithLauncherIntent(activityTestRule) { - homeScreen { + runWithLauncherIntent(composeTestRule) { + homeScreen(composeTestRule) { // Check if the device is running on Android version lower than 10 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) { // If true, click the "Not Now" button from the first onboarding card - clickDefaultCardNotNowOnboardingButton(activityTestRule) + clickDefaultCardNotNowOnboardingButton() } dismissSetAsDefaultBrowserOnboardingDialog() - verifySecondOnboardingCard(activityTestRule) - clickAddSearchWidgetNotNowOnboardingButton(activityTestRule) - verifyThirdOnboardingCard(activityTestRule) - }.clickSignInOnboardingButton(activityTestRule) { + verifySecondOnboardingCard() + clickAddSearchWidgetNotNowOnboardingButton() + verifyThirdOnboardingCard() + }.clickSignInOnboardingButton { verifyTurnOnSyncMenu() } } @@ -101,8 +101,8 @@ class OnboardingTest : TestSetup() { @SmokeTest @Test fun verifySetAsDefaultBrowserDialogWhileFirefoxIsNotSetAsDefaultBrowserTest() { - runWithLauncherIntent(activityTestRule) { - homeScreen { + runWithLauncherIntent(composeTestRule) { + homeScreen(composeTestRule) { verifySetAsDefaultBrowserDialogWhileFirefoxIsNotSetAsDefaultBrowser() } } diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/PDFViewerTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/PDFViewerTest.kt @@ -50,10 +50,10 @@ class PDFViewerTest : TestSetup() { fun verifyPDFFileIsOpenedInTheSameTabTest() { val genericURL = mockWebServer.getGenericAsset(3) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(genericURL.url) { - clickPageObject(itemContainingText("PDF form file")) - clickPageObject(itemWithResIdAndText("android:id/button2", "Cancel")) + clickPageObject(composeTestRule, itemContainingText("PDF form file")) + clickPageObject(composeTestRule, itemWithResIdAndText("android:id/button2", "Cancel")) verifyPageContent("Washington Crossing the Delaware") verifyTabCounter("1") } @@ -66,10 +66,10 @@ class PDFViewerTest : TestSetup() { val genericURL = mockWebServer.getGenericAsset(3) val downloadFile = "pdfForm.pdf" - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(genericURL.url) { - clickPageObject(itemWithText("PDF form file")) - clickPageObject(itemWithResIdAndText("android:id/button2", "Cancel")) + clickPageObject(composeTestRule, itemWithText("PDF form file")) + clickPageObject(composeTestRule, itemWithResIdAndText("android:id/button2", "Cancel")) }.clickDownloadPDFButton { verifyDownloadCompleteSnackbar(fileName = downloadFile) clickSnackbarButton(composeTestRule = composeTestRule, "OPEN") @@ -82,14 +82,12 @@ class PDFViewerTest : TestSetup() { fun pdfFindInPageTest() { val genericURL = mockWebServer.getGenericAsset(3) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(genericURL.url) { - clickPageObject(MatcherHelper.itemWithText("PDF form file")) - clickPageObject(itemWithResIdAndText("android:id/button2", "Cancel")) + clickPageObject(composeTestRule, itemWithText("PDF form file")) + clickPageObject(composeTestRule, itemWithResIdAndText("android:id/button2", "Cancel")) }.openThreeDotMenu { - verifyThreeDotMenuExists() - verifyFindInPageButton() - }.openFindInPage { + }.clickFindInPageButton { verifyFindInPageNextButton() verifyFindInPagePrevButton() verifyFindInPageCloseButton() @@ -99,13 +97,13 @@ class PDFViewerTest : TestSetup() { verifyFindInPageResult("2/2") clickFindInPagePrevButton() verifyFindInPageResult("1/2") - }.closeFindInPageWithCloseButton { + }.closeFindInPageWithCloseButton(composeTestRule) { verifyFindInPageBar(false) }.openThreeDotMenu { - }.openFindInPage { + }.clickFindInPageButton { enterFindInPageQuery("p") verifyFindInPageResult("1/1") - }.closeFindInPageWithBackButton { + }.closeFindInPageWithBackButton(composeTestRule) { verifyFindInPageBar(false) } } @@ -113,14 +111,14 @@ class PDFViewerTest : TestSetup() { // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2284297 @Test fun addPDFToHomeScreenTest() { - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(downloadTestPage.toUri()) { - clickPageObject(MatcherHelper.itemContainingText(pdfFileName)) + clickPageObject(composeTestRule, itemContainingText(pdfFileName)) verifyUrl(pdfFileURL) verifyPageContent(pdfFileContent) }.openThreeDotMenu { - expandMenu() - }.openAddToHomeScreen { + clickTheMoreButton() + }.clickAddToHomeScreenButton { verifyShortcutTextFieldTitle(pdfFileName) clickAddShortcutButton() clickSystemHomeScreenShortcutAddButton() @@ -136,14 +134,14 @@ class PDFViewerTest : TestSetup() { val genericURL = mockWebServer.getGenericAsset(3) val downloadFile = "pdfForm.pdf" - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(genericURL.url) { - clickPageObject(itemWithText("PDF form file")) - clickPageObject(itemWithResIdAndText("android:id/button2", "Cancel")) + clickPageObject(composeTestRule, itemWithText("PDF form file")) + clickPageObject(composeTestRule, itemWithResIdAndText("android:id/button2", "Cancel")) verifyTabCounter("1") }.openThreeDotMenu { - expandMenu() - }.openAddToHomeScreen { + clickTheMoreButton() + }.clickAddToHomeScreenButton { verifyShortcutTextFieldTitle("Untitled document") addShortcutName("pdfForm") clickAddShortcutButton() @@ -154,16 +152,16 @@ class PDFViewerTest : TestSetup() { verifyDownloadCompleteSnackbar(fileName = downloadFile) clickSnackbarButton(composeTestRule = composeTestRule, "OPEN") } - browserScreen { + browserScreen(composeTestRule) { selectToAlwaysOpenDownloadedFileWithApp(appName = appName) verifyUrl("content://media/external_primary/downloads/") verifyTabCounter("2") } - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(genericURL.url) { - clickPageObject(itemWithText("PDF form file")) - clickPageObject(itemWithResIdAndText("android:id/button2", "Cancel")) + clickPageObject(composeTestRule, itemWithText("PDF form file")) + clickPageObject(composeTestRule, itemWithResIdAndText("android:id/button2", "Cancel")) }.clickDownloadPDFButton { } @@ -173,14 +171,14 @@ class PDFViewerTest : TestSetup() { expandMultipleDownloadNotification("pdfForm(1).pdf") clickNotification("pdfForm(1).pdf") } - browserScreen { + browserScreen(composeTestRule) { verifyUrl("content://media/external_primary/downloads/") verifyTabCounter("3") }.openThreeDotMenu { - }.openDownloadsManager { - clickDownloadedItem(composeTestRule, "pdfForm.pdf") + }.clickDownloadsButton { + clickDownloadedItem("pdfForm.pdf") } - browserScreen { + browserScreen(composeTestRule) { verifyTabCounter("4") verifyUrl("content://media/external_primary/downloads/") } diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/PocketTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/PocketTest.kt @@ -21,7 +21,7 @@ import org.mozilla.fenix.ui.robots.homeScreen class PocketTest : TestSetup() { @get:Rule(order = 0) - val activityTestRule = + val composeTestRule = AndroidComposeTestRule( HomeActivityTestRule( isRecentTabsFeatureEnabled = false, @@ -42,10 +42,10 @@ class PocketTest : TestSetup() { // Workaround to make sure the Pocket articles are populated before starting the tests. for (i in 1..RETRY_COUNT) { try { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { - }.goBack { + }.clickSettingsButton { + }.goBack(composeTestRule) { verifyThoughtProvokingStories(true) } @@ -64,16 +64,17 @@ class PocketTest : TestSetup() { @Test fun verifyPocketSectionTest() { runWithCondition(isNetworkConnected()) { - homeScreen { + homeScreen(composeTestRule) { verifyThoughtProvokingStories(true) - verifyPocketRecommendedStoriesItems(activityTestRule) + verifyPocketRecommendedStoriesItems() // Sponsored Pocket stories are only advertised for a limited time. // See also known issue https://bugzilla.mozilla.org/show_bug.cgi?id=1828629 // verifyPocketSponsoredStoriesItems(2, 8) }.openThreeDotMenu { - }.openCustomizeHome { + }.clickSettingsButton { + }.openHomepageSubMenu { clickPocketButton() - }.goBackToHomeScreen { + }.goBackToHomeScreen(composeTestRule) { verifyThoughtProvokingStories(false) } } @@ -83,7 +84,7 @@ class PocketTest : TestSetup() { @Test fun openPocketStoryItemTest() { runWithCondition(isNetworkConnected()) { - homeScreen { + homeScreen(composeTestRule) { verifyThoughtProvokingStories(true) }.clickPocketStoryItem(1) { verifyUrl(Constants.STORIES_UTM_PARAM) diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/PromptTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/PromptTest.kt @@ -1,6 +1,7 @@ package org.mozilla.fenix.ui import androidx.compose.ui.test.junit4.AndroidComposeTestRule +import androidx.test.espresso.Espresso.closeSoftKeyboard import org.junit.Rule import org.junit.Test import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource @@ -9,6 +10,7 @@ import org.mozilla.fenix.helpers.MatcherHelper import org.mozilla.fenix.helpers.MatcherHelper.itemContainingText import org.mozilla.fenix.helpers.TestAssetHelper.getGenericAsset import org.mozilla.fenix.helpers.TestAssetHelper.promptAsset +import org.mozilla.fenix.helpers.TestHelper.waitForAppWindowToBeUpdated import org.mozilla.fenix.helpers.TestSetup import org.mozilla.fenix.helpers.perf.DetectMemoryLeaksRule import org.mozilla.fenix.ui.robots.clickPageObject @@ -37,13 +39,15 @@ class PromptTest : TestSetup() { val defaultWebPage = mockWebServer.getGenericAsset(1) val promptWebPage = mockWebServer.promptAsset - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(promptWebPage.url) { - clickPageObject(MatcherHelper.itemWithResId("nameInput")) + clickPageObject(composeTestRule, MatcherHelper.itemWithResId("nameInput")) } - navigationToolbar { - }.enterURL(defaultWebPage.url) { + navigationToolbar(composeTestRule) { + closeSoftKeyboard() + waitForAppWindowToBeUpdated() + }.enterURLAndEnterToBrowser(defaultWebPage.url) { verifyBeforeUnloadPromptExists() } } diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/PwaTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/PwaTest.kt @@ -4,12 +4,14 @@ package org.mozilla.fenix.ui +import androidx.compose.ui.test.junit4.AndroidComposeTestRule import androidx.core.net.toUri import org.junit.Rule import org.junit.Test import org.mozilla.fenix.customannotations.SmokeTest import org.mozilla.fenix.helpers.AppAndSystemHelper.clickSystemHomeScreenShortcutAddButton import org.mozilla.fenix.helpers.HomeActivityIntentTestRule +import org.mozilla.fenix.helpers.HomeActivityTestRule import org.mozilla.fenix.helpers.MatcherHelper.itemContainingText import org.mozilla.fenix.helpers.TestHelper.mDevice import org.mozilla.fenix.helpers.TestSetup @@ -29,7 +31,10 @@ class PwaTest : TestSetup() { private val shortcutTitle = "TEST_APP" @get:Rule - val activityTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides() + val composeTestRule = + AndroidComposeTestRule( + HomeActivityTestRule.withDefaultSettingsOverrides(), + ) { it.activity } @get:Rule val memoryLeaksRule = DetectMemoryLeaksRule() @@ -39,17 +44,18 @@ class PwaTest : TestSetup() { fun externalLinkPWATest() { val externalLinkURL = "https://mozilla-mobile.github.io/testapp/downloads" - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(externalLinksPWAPage.toUri()) { verifyPageContent("Misc Link Types") }.openThreeDotMenu { - }.clickAddAppToHomeScreen { + clickTheMoreButton() + }.clickAddAppToHomeScreenButton { clickSystemHomeScreenShortcutAddButton() }.openHomeScreenShortcut(shortcutTitle) { - clickPageObject(itemContainingText("External link")) + clickPageObject(composeTestRule, itemContainingText("External link")) } - customTabScreen { + customTabScreen(composeTestRule) { verifyCustomTabToolbarTitle(externalLinkURL) } } @@ -57,11 +63,12 @@ class PwaTest : TestSetup() { // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/845694 @Test fun appLikeExperiencePWATest() { - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(externalLinksPWAPage.toUri()) { verifyPageContent("Misc Link Types") }.openThreeDotMenu { - }.clickAddAppToHomeScreen { + clickTheMoreButton() + }.clickAddAppToHomeScreenButton { clickSystemHomeScreenShortcutAddButton() }.openHomeScreenShortcut(shortcutTitle) { } @@ -78,13 +85,14 @@ class PwaTest : TestSetup() { fun installPWAFromTheMainMenuTest() { val pwaPage = "https://mozilla-mobile.github.io/testapp/loginForm" - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(pwaPage.toUri()) { waitForPageToLoad() verifyUrl("mozilla-mobile.github.io/testapp/loginForm") verifyPageContent("Login Form") }.openThreeDotMenu { - }.clickAddAppToHomeScreen { + clickTheMoreButton() + }.clickAddAppToHomeScreenButton { clickSystemHomeScreenShortcutAddButton() }.openHomeScreenShortcut("TEST_APP") { mDevice.waitForIdle() diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ReaderViewTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/ReaderViewTest.kt @@ -5,12 +5,12 @@ package org.mozilla.fenix.ui import android.view.View +import androidx.compose.ui.test.junit4.AndroidComposeTestRule import org.junit.Rule import org.junit.Test import org.mozilla.fenix.customannotations.SmokeTest import org.mozilla.fenix.helpers.AppAndSystemHelper.registerAndCleanupIdlingResources -import org.mozilla.fenix.helpers.HomeActivityIntentTestRule -import org.mozilla.fenix.helpers.RetryTestRule +import org.mozilla.fenix.helpers.HomeActivityTestRule import org.mozilla.fenix.helpers.TestAssetHelper.getGenericAsset import org.mozilla.fenix.helpers.TestAssetHelper.loremIpsumAsset import org.mozilla.fenix.helpers.TestHelper.mDevice @@ -34,15 +34,14 @@ class ReaderViewTest : TestSetup() { private val estimatedReadingTime = "1 - 2 minutes" @get:Rule - val activityIntentTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides() + val composeTestRule = + AndroidComposeTestRule( + HomeActivityTestRule.withDefaultSettingsOverrides(), + ) { it.activity } @get:Rule val memoryLeaksRule = DetectMemoryLeaksRule() - @Rule - @JvmField - val retryTestRule = RetryTestRule(3) - /** * Verify that Reader View capable pages * @@ -55,24 +54,16 @@ class ReaderViewTest : TestSetup() { val readerViewPage = mockWebServer.loremIpsumAsset val genericPage = mockWebServer.getGenericAsset(1) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(readerViewPage.url) { - mDevice.waitForIdle() } - registerAndCleanupIdlingResources( - ViewVisibilityIdlingResource( - activityIntentTestRule.activity.findViewById(toolbarR.id.mozac_browser_toolbar_page_actions), - View.VISIBLE, - ), - ) {} - - navigationToolbar { - verifyReaderViewDetected(true) + navigationToolbar(composeTestRule) { + verifyReaderViewToolbarButton(true) }.enterURLAndEnterToBrowser(genericPage.url) { } - navigationToolbar { - verifyReaderViewDetected(false) + navigationToolbar(composeTestRule) { + verifyReaderViewToolbarButton(false) } } @@ -82,29 +73,21 @@ class ReaderViewTest : TestSetup() { fun verifyReaderModeControlsTest() { val readerViewPage = mockWebServer.loremIpsumAsset - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(readerViewPage.url) { - mDevice.waitForIdle() + waitForPageToLoad() } - registerAndCleanupIdlingResources( - ViewVisibilityIdlingResource( - activityIntentTestRule.activity.findViewById(toolbarR.id.mozac_browser_toolbar_page_actions), - View.VISIBLE, - ), - ) {} - - navigationToolbar { - verifyReaderViewDetected(true) - toggleReaderView() - mDevice.waitForIdle() + navigationToolbar(composeTestRule) { + verifyReaderViewToolbarButton(true) + clickReaderViewToolbarButton(isReaderViewEnabled = false) } - browserScreen { + browserScreen(composeTestRule) { verifyPageContent(estimatedReadingTime) }.openThreeDotMenu { - verifyReaderViewAppearance(true) - }.openReaderViewAppearance { + verifyCustomizeReaderViewButton(true) + }.clickCustomizeReaderViewButton { verifyAppearanceFontGroup(true) verifyAppearanceFontSansSerif(true) verifyAppearanceFontSerif(true) @@ -137,14 +120,15 @@ class ReaderViewTest : TestSetup() { verifyAppearanceColorSchemeChange("SEPIA") }.toggleColorSchemeChangeLight { verifyAppearanceColorSchemeChange("LIGHT") - }.closeAppearanceMenu { + }.closeReaderViewControlMenu(composeTestRule) { + } + navigationToolbar(composeTestRule) { + clickReaderViewToolbarButton(isReaderViewEnabled = true) + verifyReaderViewToolbarButton(true) } - navigationToolbar { - toggleReaderView() - mDevice.waitForIdle() - verifyReaderViewDetected(true) + browserScreen(composeTestRule) { }.openThreeDotMenu { - verifyReaderViewAppearance(false) + verifyCustomizeReaderViewButton(false) } } } diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/RecentlyClosedTabsTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/RecentlyClosedTabsTest.kt @@ -30,7 +30,7 @@ import org.mozilla.fenix.ui.robots.navigationToolbar */ class RecentlyClosedTabsTest : TestSetup() { @get:Rule - val activityTestRule = AndroidComposeTestRule( + val composeTestRule = AndroidComposeTestRule( HomeActivityIntentTestRule.withDefaultSettingsOverrides(), ) { it.activity } @@ -45,26 +45,25 @@ class RecentlyClosedTabsTest : TestSetup() { fun openRecentlyClosedItemTest() { val website = mockWebServer.getGenericAsset(1) - homeScreen { - }.openNavigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(website.url) { mDevice.waitForIdle() - }.openTabDrawer(activityTestRule) { + }.openTabDrawer(composeTestRule) { closeTab() } - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openHistory { + }.clickHistoryButton { }.openRecentlyClosedTabs { waitForListToExist() registerAndCleanupIdlingResources( - RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.recently_closed_list), 1), + RecyclerViewIdlingResource(composeTestRule.activity.findViewById(R.id.recently_closed_list), 1), ) { verifyRecentlyClosedTabsMenuView() verifyRecentlyClosedTabsPageTitle("Test_Page_1") verifyRecentlyClosedTabsUrl(website.url) } - }.clickRecentlyClosedItem("Test_Page_1") { + }.clickRecentlyClosedItem(composeTestRule, "Test_Page_1") { verifyUrl(website.url.toString()) } } @@ -77,20 +76,19 @@ class RecentlyClosedTabsTest : TestSetup() { fun deleteRecentlyClosedTabsItemTest() { val website = mockWebServer.getGenericAsset(1) - homeScreen { - }.openNavigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(website.url) { mDevice.waitForIdle() - }.openTabDrawer(activityTestRule) { + }.openTabDrawer(composeTestRule) { closeTab() } - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openHistory { + }.clickHistoryButton { }.openRecentlyClosedTabs { waitForListToExist() registerAndCleanupIdlingResources( - RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.recently_closed_list), 1), + RecyclerViewIdlingResource(composeTestRule.activity.findViewById(R.id.recently_closed_list), 1), ) { verifyRecentlyClosedTabsMenuView() } @@ -106,29 +104,29 @@ class RecentlyClosedTabsTest : TestSetup() { val firstPage = mockWebServer.getGenericAsset(1) val secondPage = mockWebServer.getGenericAsset(2) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(firstPage.url) { waitForPageToLoad() - }.openTabDrawer(activityTestRule) { + }.openTabDrawer(composeTestRule) { }.openNewTab { }.submitQuery(secondPage.url.toString()) { waitForPageToLoad() - }.openTabDrawer(activityTestRule) { + }.openTabDrawer(composeTestRule) { }.openThreeDotMenu { }.closeAllTabs { }.openThreeDotMenu { - }.openHistory { + }.clickHistoryButton { }.openRecentlyClosedTabs { waitForListToExist() longTapSelectItem(firstPage.url) longTapSelectItem(secondPage.url) - openActionBarOverflowOrOptionsMenu(activityTestRule.activity) - }.clickOpenInNewTab(activityTestRule) { + openActionBarOverflowOrOptionsMenu(composeTestRule.activity) + }.clickOpenInNewTab(composeTestRule) { // URL verification to be removed once https://bugzilla.mozilla.org/show_bug.cgi?id=1839179 is fixed. - browserScreen { + browserScreen(composeTestRule) { verifyPageContent(secondPage.content) verifyUrl(secondPage.url.toString()) - }.openTabDrawer(activityTestRule) { + }.openTabDrawer(composeTestRule) { verifyNormalBrowsingButtonIsSelected(true) verifyExistingOpenTabs(firstPage.title, secondPage.title) } @@ -142,29 +140,29 @@ class RecentlyClosedTabsTest : TestSetup() { val firstPage = mockWebServer.getGenericAsset(1) val secondPage = mockWebServer.getGenericAsset(2) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(firstPage.url) { waitForPageToLoad() - }.openTabDrawer(activityTestRule) { + }.openTabDrawer(composeTestRule) { }.openNewTab { }.submitQuery(secondPage.url.toString()) { waitForPageToLoad() - }.openTabDrawer(activityTestRule) { + }.openTabDrawer(composeTestRule) { }.openThreeDotMenu { }.closeAllTabs { }.openThreeDotMenu { - }.openHistory { + }.clickHistoryButton { }.openRecentlyClosedTabs { waitForListToExist() longTapSelectItem(firstPage.url) longTapSelectItem(secondPage.url) - openActionBarOverflowOrOptionsMenu(activityTestRule.activity) - }.clickOpenInPrivateTab(activityTestRule) { + openActionBarOverflowOrOptionsMenu(composeTestRule.activity) + }.clickOpenInPrivateTab(composeTestRule) { // URL verification to be removed once https://bugzilla.mozilla.org/show_bug.cgi?id=1839179 is fixed. - browserScreen { + browserScreen(composeTestRule) { verifyPageContent(secondPage.content) verifyUrl(secondPage.url.toString()) - }.openTabDrawer(activityTestRule) { + }.openTabDrawer(composeTestRule) { verifyPrivateBrowsingButtonIsSelected(true) verifyExistingOpenTabs(firstPage.title, secondPage.title) } @@ -181,18 +179,18 @@ class RecentlyClosedTabsTest : TestSetup() { val sharingApp = "Gmail" val urlString = "${firstPage.url}\n\n${secondPage.url}" - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(firstPage.url) { waitForPageToLoad() - }.openTabDrawer(activityTestRule) { + }.openTabDrawer(composeTestRule) { }.openNewTab { }.submitQuery(secondPage.url.toString()) { waitForPageToLoad() - }.openTabDrawer(activityTestRule) { + }.openTabDrawer(composeTestRule) { }.openThreeDotMenu { }.closeAllTabs { }.openThreeDotMenu { - }.openHistory { + }.clickHistoryButton { }.openRecentlyClosedTabs { waitForListToExist() longTapSelectItem(firstPage.url) @@ -211,19 +209,21 @@ class RecentlyClosedTabsTest : TestSetup() { val firstPage = mockWebServer.getGenericAsset(1) val secondPage = mockWebServer.getGenericAsset(2) - homeScreen {}.togglePrivateBrowsingMode() - navigationToolbar { + homeScreen(composeTestRule) { + }.togglePrivateBrowsingMode() + + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(firstPage.url) { waitForPageToLoad() - }.openTabDrawer(activityTestRule) { + }.openTabDrawer(composeTestRule) { }.openNewTab { }.submitQuery(secondPage.url.toString()) { waitForPageToLoad() - }.openTabDrawer(activityTestRule) { + }.openTabDrawer(composeTestRule) { }.openThreeDotMenu { }.closeAllTabs { }.openThreeDotMenu { - }.openHistory { + }.clickHistoryButton { }.openRecentlyClosedTabs { verifyEmptyRecentlyClosedTabsList() } @@ -237,21 +237,21 @@ class RecentlyClosedTabsTest : TestSetup() { val firstPage = mockWebServer.getGenericAsset(1) val secondPage = mockWebServer.getGenericAsset(2) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(firstPage.url) { waitForPageToLoad() - }.openTabDrawer(activityTestRule) { + }.openTabDrawer(composeTestRule) { }.openNewTab { }.submitQuery(secondPage.url.toString()) { waitForPageToLoad() - }.openTabDrawer(activityTestRule) { + }.openTabDrawer(composeTestRule) { }.openThreeDotMenu { }.closeAllTabs { }.openThreeDotMenu { - }.openHistory { + }.clickHistoryButton { }.openRecentlyClosedTabs { waitForListToExist() - }.goBackToHistoryMenu { + }.goBackToHistoryMenu(composeTestRule) { clickDeleteAllHistoryButton() selectEverythingOption() confirmDeleteAllHistory() diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SearchTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SearchTest.kt @@ -74,7 +74,7 @@ class SearchTest : TestSetup() { private val firefoxSuggestHeader = getStringResource(R.string.firefox_suggest_header) @get:Rule - val activityTestRule = AndroidComposeTestRule( + val composeTestRule = AndroidComposeTestRule( HomeActivityTestRule( skipOnboarding = true, isPocketEnabled = false, @@ -109,36 +109,36 @@ class SearchTest : TestSetup() { @SdkSuppress(minSdkVersion = 34) @Test fun verifySearchBarItemsTest() { - navigationToolbar { + navigationToolbar(composeTestRule) { verifyDefaultSearchEngine("Google") - verifySearchBarPlaceholder("Search or enter address") - }.clickUrlbar { + verifySearchBarPlaceholder() + }.clickURLBar { verifyKeyboardVisibility(isExpectedToBeVisible = true) - verifyScanButtonVisibility(visible = true) - verifyVoiceSearchButtonVisibility(enabled = true) + verifyScanButton(isDisplayed = true) + verifyVoiceSearchButton(isDisplayed = true) verifySearchBarPlaceholder("Search or enter address") typeSearch("mozilla ") waitForAppWindowToBeUpdated() - verifyScanButtonVisibility(visible = false) - verifyVoiceSearchButtonVisibility(enabled = true) + verifyScanButton(isDisplayed = false) + verifyVoiceSearchButton(isDisplayed = true) } } // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2154190 @Test fun verifySearchSelectorMenuItemsTest() { - homeScreen { + homeScreen(composeTestRule) { }.openSearch { - verifySearchView() verifySearchToolbar(isDisplayed = true) clickSearchSelectorButton() - verifySearchShortcutListContains( + verifySearchShortcutList( *generalEnginesList.toTypedArray(), *topicEnginesList.toTypedArray(), "Bookmarks", "Tabs", "History", "Search settings", + isSearchEngineDisplayed = true, ) } } @@ -147,7 +147,7 @@ class SearchTest : TestSetup() { @Test fun verifySearchPlaceholderForGeneralDefaultSearchEnginesTest() { generalEnginesList.forEach { - homeScreen { + homeScreen(composeTestRule) { }.openSearch { clickSearchSelectorButton() }.clickSearchEngineSettings { @@ -155,8 +155,8 @@ class SearchTest : TestSetup() { changeDefaultSearchEngine(it) exitMenu() } - navigationToolbar { - verifySearchBarPlaceholder("Search or enter address") + navigationToolbar(composeTestRule) { + verifySearchBarPlaceholder() } } } @@ -167,7 +167,7 @@ class SearchTest : TestSetup() { val generalEnginesList = listOf("DuckDuckGo", "Bing") generalEnginesList.forEach { - homeScreen { + homeScreen(composeTestRule) { }.openSearch { clickSearchSelectorButton() selectTemporarySearchMethod(it) @@ -180,7 +180,7 @@ class SearchTest : TestSetup() { @Test fun verifySearchPlaceholderForTopicSpecificSearchEnginesTest() { topicEnginesList.forEach { - homeScreen { + homeScreen(composeTestRule) { }.openSearch { clickSearchSelectorButton() selectTemporarySearchMethod(it) @@ -190,26 +190,26 @@ class SearchTest : TestSetup() { } // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/1059459 + @Ignore("Disabled after enabling the composable toolbar and main menu: https://bugzilla.mozilla.org/show_bug.cgi?id=2006295") @SmokeTest @Test fun verifyQRScanningCameraAccessDialogTest() { val cameraManager = TestHelper.appContext.getSystemService(Context.CAMERA_SERVICE) as CameraManager Assume.assumeTrue(cameraManager.cameraIdList.isNotEmpty()) - homeScreen { + homeScreen(composeTestRule) { }.openSearch { waitForAppWindowToBeUpdated() - verifySearchView() clickScanButton() denyPermission() clickScanButton() clickDismissPermissionRequiredDialog() } - homeScreen { + homeScreen(composeTestRule) { }.openSearch { clickScanButton() clickGoToPermissionsSettings() - assertNativeAppOpens(Constants.PackageName.ANDROID_SETTINGS) + assertNativeAppOpens(composeTestRule, Constants.PackageName.ANDROID_SETTINGS) } } @@ -220,7 +220,7 @@ class SearchTest : TestSetup() { val cameraManager = TestHelper.appContext.getSystemService(Context.CAMERA_SERVICE) as CameraManager Assume.assumeTrue(cameraManager.cameraIdList.isNotEmpty()) - homeScreen { + homeScreen(composeTestRule) { }.openSearch { clickScanButton() grantSystemPermission() @@ -232,20 +232,20 @@ class SearchTest : TestSetup() { @Test fun verifyScanButtonAvailableOnlyForGeneralSearchEnginesTest() { generalEnginesList.forEach { - homeScreen { + homeScreen(composeTestRule) { }.openSearch { clickSearchSelectorButton() selectTemporarySearchMethod(it) - verifyScanButtonVisibility(visible = true) + verifyScanButton(isDisplayed = true) }.dismissSearchBar {} } topicEnginesList.forEach { - homeScreen { + homeScreen(composeTestRule) { }.openSearch { clickSearchSelectorButton() selectTemporarySearchMethod(it) - verifyScanButtonVisibility(visible = false) + verifyScanButton(isDisplayed = false) }.dismissSearchBar {} } } @@ -256,22 +256,22 @@ class SearchTest : TestSetup() { @Test fun searchEnginesCanBeChangedTemporarilyFromSearchSelectorMenuTest() { (generalEnginesList + topicEnginesList).forEach { - homeScreen { + homeScreen(composeTestRule) { }.openSearch { clickSearchSelectorButton() - verifySearchShortcutListContains(it) + verifySearchShortcutList(it, isSearchEngineDisplayed = true) selectTemporarySearchMethod(it) verifySearchEngineIcon(it) }.submitQuery("mozilla ") { verifyUrl("mozilla") - }.goToHomescreen(activityTestRule) {} + }.goToHomescreen {} } } // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/233589 @Test fun defaultSearchEnginesCanBeSetFromSearchSelectorMenuTest() { - searchScreen { + searchScreen(composeTestRule) { clickSearchSelectorButton() }.clickSearchEngineSettings { verifyToolbarText("Search") @@ -279,7 +279,7 @@ class SearchTest : TestSetup() { changeDefaultSearchEngine("DuckDuckGo") exitMenu() } - homeScreen { + homeScreen(composeTestRule) { }.openSearch { }.submitQuery(queryString) { verifyUrl(queryString) @@ -289,7 +289,7 @@ class SearchTest : TestSetup() { // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/522918 @Test fun verifyClearSearchButtonTest() { - homeScreen { + homeScreen(composeTestRule) { }.openSearch { typeSearch(queryString) clickClearButton() @@ -308,22 +308,22 @@ class SearchTest : TestSetup() { setCustomSearchEngine(searchMockServer, searchEngineName) // Performs a search and opens 2 dummy search results links to create a search group - homeScreen { + homeScreen(composeTestRule) { }.openSearch { }.submitQuery(queryString) { - longClickPageObject(MatcherHelper.itemWithText("Link 1")) + longClickPageObject(composeTestRule, MatcherHelper.itemWithText("Link 1")) clickContextMenuItem("Open link in new tab") - clickSnackbarButton(activityTestRule, "SWITCH") + clickSnackbarButton(composeTestRule, "SWITCH") verifyUrl(firstPageUrl.toString()) Espresso.pressBack() - longClickPageObject(MatcherHelper.itemWithText("Link 2")) + longClickPageObject(composeTestRule, MatcherHelper.itemWithText("Link 2")) clickContextMenuItem("Open link in new tab") - clickSnackbarButton(activityTestRule, "SWITCH") + clickSnackbarButton(composeTestRule, "SWITCH") verifyUrl(secondPageUrl.toString()) - }.openTabDrawer(activityTestRule) { + }.openTabDrawer(composeTestRule) { }.openThreeDotMenu { }.closeAllTabs { - verifyRecentlyVisitedSearchGroupDisplayed(activityTestRule, shouldBeDisplayed = true, searchTerm = queryString, groupSize = 3) + verifyRecentlyVisitedSearchGroupDisplayed(shouldBeDisplayed = true, searchTerm = queryString, groupSize = 3) } } @@ -340,33 +340,33 @@ class SearchTest : TestSetup() { setCustomSearchEngine(searchMockServer, searchEngineName) // Performs a search and opens 2 dummy search results links to create a search group - homeScreen { + homeScreen(composeTestRule) { }.openSearch { }.submitQuery(queryString) { - longClickPageObject(MatcherHelper.itemWithText("Link 1")) + longClickPageObject(composeTestRule, MatcherHelper.itemWithText("Link 1")) clickContextMenuItem("Open link in new tab") - clickSnackbarButton(activityTestRule, "SWITCH") + clickSnackbarButton(composeTestRule, "SWITCH") verifyUrl(firstPageUrl.toString()) Espresso.pressBack() - longClickPageObject(MatcherHelper.itemWithText("Link 1")) + longClickPageObject(composeTestRule, MatcherHelper.itemWithText("Link 1")) clickContextMenuItem("Open link in new tab") - clickSnackbarButton(activityTestRule, "SWITCH") + clickSnackbarButton(composeTestRule, "SWITCH") verifyUrl(firstPageUrl.toString()) Espresso.pressBack() - longClickPageObject(MatcherHelper.itemWithText("Link 2")) + longClickPageObject(composeTestRule, MatcherHelper.itemWithText("Link 2")) clickContextMenuItem("Open link in new tab") - clickSnackbarButton(activityTestRule, "SWITCH") + clickSnackbarButton(composeTestRule, "SWITCH") verifyUrl(secondPageUrl.toString()) Espresso.pressBack() - longClickPageObject(MatcherHelper.itemWithText("Link 1")) + longClickPageObject(composeTestRule, MatcherHelper.itemWithText("Link 1")) clickContextMenuItem("Open link in new tab") - clickSnackbarButton(activityTestRule, "SWITCH") + clickSnackbarButton(composeTestRule, "SWITCH") verifyUrl(firstPageUrl.toString()) - }.openTabDrawer(activityTestRule) { + }.openTabDrawer(composeTestRule) { }.openThreeDotMenu { }.closeAllTabs { - verifyRecentlyVisitedSearchGroupDisplayed(activityTestRule, shouldBeDisplayed = true, searchTerm = queryString, groupSize = 3) - }.openRecentlyVisitedSearchGroupHistoryList(activityTestRule, queryString) { + verifyRecentlyVisitedSearchGroupDisplayed(shouldBeDisplayed = true, searchTerm = queryString, groupSize = 3) + }.openRecentlyVisitedSearchGroupHistoryList(queryString) { verifyTestPageUrl(firstPageUrl) verifyTestPageUrl(secondPageUrl) verifyTestPageUrl(originPageUrl) @@ -382,18 +382,18 @@ class SearchTest : TestSetup() { setCustomSearchEngine(searchMockServer, searchEngineName) // Performs a search and opens 2 dummy search results links to create a search group - homeScreen { + homeScreen(composeTestRule) { }.openSearch { }.submitQuery(queryString) { - clickPageObject(MatcherHelper.itemContainingText("Link 1")) + clickPageObject(composeTestRule, MatcherHelper.itemContainingText("Link 1")) waitForPageToLoad() Espresso.pressBack() - clickPageObject(MatcherHelper.itemContainingText("Link 2")) + clickPageObject(composeTestRule, MatcherHelper.itemContainingText("Link 2")) waitForPageToLoad() - }.openTabDrawer(activityTestRule) { + }.openTabDrawer(composeTestRule) { }.openThreeDotMenu { }.closeAllTabs { - verifyRecentlyVisitedSearchGroupDisplayed(activityTestRule, shouldBeDisplayed = true, searchTerm = queryString, groupSize = 3) + verifyRecentlyVisitedSearchGroupDisplayed(shouldBeDisplayed = true, searchTerm = queryString, groupSize = 3) } } @@ -407,25 +407,25 @@ class SearchTest : TestSetup() { setCustomSearchEngine(searchMockServer, searchEngineName) // Performs a search and opens 2 dummy search results links to create a search group - homeScreen { + homeScreen(composeTestRule) { }.openSearch { }.submitQuery(queryString) { - longClickPageObject(MatcherHelper.itemWithText("Link 1")) + longClickPageObject(composeTestRule, MatcherHelper.itemWithText("Link 1")) clickContextMenuItem("Open link in private tab") - longClickPageObject(MatcherHelper.itemWithText("Link 2")) + longClickPageObject(composeTestRule, MatcherHelper.itemWithText("Link 2")) clickContextMenuItem("Open link in private tab") - }.openTabDrawer(activityTestRule) { + }.openTabDrawer(composeTestRule) { }.toggleToPrivateTabs { }.openPrivateTab(0) { - }.openTabDrawer(activityTestRule) { + }.openTabDrawer(composeTestRule) { }.openPrivateTab(1) { - }.openTabDrawer(activityTestRule) { + }.openTabDrawer(composeTestRule) { }.openThreeDotMenu { }.closeAllTabs { - togglePrivateBrowsingModeOnOff(composeTestRule = activityTestRule) - verifyRecentlyVisitedSearchGroupDisplayed(activityTestRule, shouldBeDisplayed = false, searchTerm = queryString, groupSize = 3) + togglePrivateBrowsingModeOnOff() + verifyRecentlyVisitedSearchGroupDisplayed(shouldBeDisplayed = false, searchTerm = queryString, groupSize = 3) }.openThreeDotMenu { - }.openHistory { + }.clickHistoryButton { verifyHistoryItemExists(shouldExist = false, item = "3 sites") } } @@ -442,36 +442,36 @@ class SearchTest : TestSetup() { setCustomSearchEngine(searchMockServer, searchEngineName) // Performs a search and opens 2 dummy search results links to create a search group - homeScreen { + homeScreen(composeTestRule) { }.openSearch { }.submitQuery(queryString) { - longClickPageObject(MatcherHelper.itemWithText("Link 1")) + longClickPageObject(composeTestRule, MatcherHelper.itemWithText("Link 1")) clickContextMenuItem("Open link in new tab") - clickSnackbarButton(activityTestRule, "SWITCH") + clickSnackbarButton(composeTestRule, "SWITCH") verifyUrl(firstPageUrl.toString()) TestHelper.mDevice.pressBack() - longClickPageObject(MatcherHelper.itemWithText("Link 2")) + longClickPageObject(composeTestRule, MatcherHelper.itemWithText("Link 2")) clickContextMenuItem("Open link in new tab") - clickSnackbarButton(activityTestRule, "SWITCH") + clickSnackbarButton(composeTestRule, "SWITCH") verifyUrl(secondPageUrl.toString()) - }.openTabDrawer(activityTestRule) { + }.openTabDrawer(composeTestRule) { }.openThreeDotMenu { }.closeAllTabs { - verifyRecentlyVisitedSearchGroupDisplayed(activityTestRule, shouldBeDisplayed = true, searchTerm = queryString, groupSize = 3) - }.openRecentlyVisitedSearchGroupHistoryList(activityTestRule, queryString) { + verifyRecentlyVisitedSearchGroupDisplayed(shouldBeDisplayed = true, searchTerm = queryString, groupSize = 3) + }.openRecentlyVisitedSearchGroupHistoryList(queryString) { clickDeleteHistoryButton(firstPageUrl.toString()) longTapSelectItem(secondPageUrl) - multipleSelectionToolbar { - openActionBarOverflowOrOptionsMenu(activityTestRule.activity) + multipleSelectionToolbar(composeTestRule) { + openActionBarOverflowOrOptionsMenu(composeTestRule.activity) clickMultiSelectionDelete() waitUntilSnackbarGone() } exitMenu() } - homeScreen { + homeScreen(composeTestRule) { waitForAppWindowToBeUpdated() // checking that the group is removed when only 1 item is left - verifyRecentlyVisitedSearchGroupDisplayed(activityTestRule, shouldBeDisplayed = false, searchTerm = queryString, groupSize = 1) + verifyRecentlyVisitedSearchGroupDisplayed(shouldBeDisplayed = false, searchTerm = queryString, groupSize = 1) } } @@ -486,32 +486,32 @@ class SearchTest : TestSetup() { setCustomSearchEngine(searchMockServer, searchEngineName) // Performs a search and opens 2 dummy search results links to create a search group - homeScreen { + homeScreen(composeTestRule) { }.openSearch { }.submitQuery(queryString) { - longClickPageObject(MatcherHelper.itemWithText("Link 1")) + longClickPageObject(composeTestRule, MatcherHelper.itemWithText("Link 1")) clickContextMenuItem("Open link in new tab") - clickSnackbarButton(activityTestRule, "SWITCH") + clickSnackbarButton(composeTestRule, "SWITCH") verifyUrl(firstPageUrl.toString()) TestHelper.mDevice.pressBack() - longClickPageObject(MatcherHelper.itemWithText("Link 2")) + longClickPageObject(composeTestRule, MatcherHelper.itemWithText("Link 2")) clickContextMenuItem("Open link in new tab") - clickSnackbarButton(activityTestRule, "SWITCH") + clickSnackbarButton(composeTestRule, "SWITCH") verifyUrl(secondPageUrl.toString()) - }.openTabDrawer(activityTestRule) { + }.openTabDrawer(composeTestRule) { }.openThreeDotMenu { }.closeAllTabs { - verifyRecentlyVisitedSearchGroupDisplayed(activityTestRule, shouldBeDisplayed = true, searchTerm = queryString, groupSize = 3) - }.openRecentlyVisitedSearchGroupHistoryList(activityTestRule, queryString) { + verifyRecentlyVisitedSearchGroupDisplayed(shouldBeDisplayed = true, searchTerm = queryString, groupSize = 3) + }.openRecentlyVisitedSearchGroupHistoryList(queryString) { clickDeleteAllHistoryButton() confirmDeleteAllHistory() verifySnackBarText(expectedText = "Group deleted") verifyHistoryItemExists(shouldExist = false, firstPageUrl.toString()) }.goBack {} - homeScreen { - verifyRecentlyVisitedSearchGroupDisplayed(activityTestRule, shouldBeDisplayed = false, queryString, groupSize = 3) + homeScreen(composeTestRule) { + verifyRecentlyVisitedSearchGroupDisplayed(shouldBeDisplayed = false, queryString, groupSize = 3) }.openThreeDotMenu { - }.openHistory { + }.clickHistoryButton { verifySearchGroupDisplayed(shouldBeDisplayed = false, queryString, groupSize = 3) verifyEmptyHistoryView() } @@ -529,40 +529,40 @@ class SearchTest : TestSetup() { setCustomSearchEngine(searchMockServer, searchEngineName) // Performs a search and opens 2 dummy search results links to create a search group - homeScreen { + homeScreen(composeTestRule) { }.openSearch { }.submitQuery(queryString) { - longClickPageObject(MatcherHelper.itemWithText("Link 1")) + longClickPageObject(composeTestRule, MatcherHelper.itemWithText("Link 1")) clickContextMenuItem("Open link in new tab") - clickSnackbarButton(activityTestRule, "SWITCH") + clickSnackbarButton(composeTestRule, "SWITCH") verifyUrl(firstPageUrl.toString()) TestHelper.mDevice.pressBack() - longClickPageObject(MatcherHelper.itemWithText("Link 2")) + longClickPageObject(composeTestRule, MatcherHelper.itemWithText("Link 2")) clickContextMenuItem("Open link in new tab") - clickSnackbarButton(activityTestRule, "SWITCH") + clickSnackbarButton(composeTestRule, "SWITCH") verifyUrl(secondPageUrl.toString()) waitForPageToLoad() - }.openTabDrawer(activityTestRule) { + }.openTabDrawer(composeTestRule) { }.openThreeDotMenu { }.closeAllTabs { - verifyRecentlyVisitedSearchGroupDisplayed(activityTestRule, shouldBeDisplayed = true, searchTerm = queryString, groupSize = 3) - }.openRecentlyVisitedSearchGroupHistoryList(activityTestRule, queryString) { + verifyRecentlyVisitedSearchGroupDisplayed(shouldBeDisplayed = true, searchTerm = queryString, groupSize = 3) + }.openRecentlyVisitedSearchGroupHistoryList(queryString) { }.openWebsiteFromSearchGroup(firstPageUrl) { verifyUrl(firstPageUrl.toString()) - }.goToHomescreen(activityTestRule) { - }.openRecentlyVisitedSearchGroupHistoryList(activityTestRule, queryString) { - TestHelper.longTapSelectItem(firstPageUrl) - TestHelper.longTapSelectItem(secondPageUrl) - Espresso.openActionBarOverflowOrOptionsMenu(activityTestRule.activity) + }.goToHomescreen { + }.openRecentlyVisitedSearchGroupHistoryList(queryString) { + longTapSelectItem(firstPageUrl) + longTapSelectItem(secondPageUrl) + openActionBarOverflowOrOptionsMenu(composeTestRule.activity) } - multipleSelectionToolbar { - }.clickOpenNewTab(activityTestRule) { + multipleSelectionToolbar(composeTestRule) { + }.clickOpenNewTab { verifyNormalBrowsingButtonIsSelected() }.closeTabDrawer {} - Espresso.openActionBarOverflowOrOptionsMenu(activityTestRule.activity) - multipleSelectionToolbar { - }.clickOpenPrivateTab(activityTestRule) { + Espresso.openActionBarOverflowOrOptionsMenu(composeTestRule.activity) + multipleSelectionToolbar(composeTestRule) { + }.clickOpenPrivateTab { verifyPrivateBrowsingButtonIsSelected() } } @@ -578,27 +578,27 @@ class SearchTest : TestSetup() { setCustomSearchEngine(searchMockServer, searchEngineName) // Performs a search and opens 2 dummy search results links to create a search group - homeScreen { + homeScreen(composeTestRule) { }.openSearch { }.submitQuery(queryString) { - longClickPageObject(MatcherHelper.itemWithText("Link 1")) + longClickPageObject(composeTestRule, MatcherHelper.itemWithText("Link 1")) clickContextMenuItem("Open link in new tab") - clickSnackbarButton(activityTestRule, "SWITCH") + clickSnackbarButton(composeTestRule, "SWITCH") verifyUrl(firstPageUrl.toString()) TestHelper.mDevice.pressBack() - longClickPageObject(MatcherHelper.itemWithText("Link 2")) + longClickPageObject(composeTestRule, MatcherHelper.itemWithText("Link 2")) clickContextMenuItem("Open link in new tab") - clickSnackbarButton(activityTestRule, "SWITCH") + clickSnackbarButton(composeTestRule, "SWITCH") verifyUrl(secondPageUrl.toString()) - }.openTabDrawer(activityTestRule) { + }.openTabDrawer(composeTestRule) { }.openThreeDotMenu { }.closeAllTabs { - verifyRecentlyVisitedSearchGroupDisplayed(activityTestRule, shouldBeDisplayed = true, searchTerm = queryString, groupSize = 3) - }.openRecentlyVisitedSearchGroupHistoryList(activityTestRule, queryString) { + verifyRecentlyVisitedSearchGroupDisplayed(shouldBeDisplayed = true, searchTerm = queryString, groupSize = 3) + }.openRecentlyVisitedSearchGroupHistoryList(queryString) { TestHelper.longTapSelectItem(firstPageUrl) } - multipleSelectionToolbar { + multipleSelectionToolbar(composeTestRule) { clickShareHistoryButton() verifyShareOverlay() verifyShareTabFavicon() @@ -612,12 +612,12 @@ class SearchTest : TestSetup() { @Test @SkipLeaks fun defaultSearchCodeGoogleUS() { - homeScreen { + homeScreen(composeTestRule) { }.openSearch { }.submitQuery(queryString) { verifyPageContent("google") }.openThreeDotMenu { - }.openHistory { + }.clickHistoryButton { // Full URL no longer visible in the nav bar, so we'll check the history record // A search group is sometimes created when searching with Google (probably redirects) try { @@ -633,20 +633,20 @@ class SearchTest : TestSetup() { // Default search code for Bing-US @Test fun defaultSearchCodeBingUS() { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openSearchSubMenu { openDefaultSearchEngineMenu() changeDefaultSearchEngine("Bing") exitMenu() } - homeScreen { + homeScreen(composeTestRule) { }.openSearch { }.submitQuery(queryString) { waitForPageToLoad() }.openThreeDotMenu { - }.openHistory { + }.clickHistoryButton { // Full URL no longer visible in the nav bar, so we'll check the history record // A search group is sometimes created when searching with Bing (probably redirects) try { @@ -663,20 +663,20 @@ class SearchTest : TestSetup() { @Test @SkipLeaks fun defaultSearchCodeDuckDuckGoUS() { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openSearchSubMenu { openDefaultSearchEngineMenu() changeDefaultSearchEngine("DuckDuckGo") exitMenu() } - homeScreen { + homeScreen(composeTestRule) { }.openSearch { }.submitQuery(queryString) { verifyPageContent("duckduckgo") }.openThreeDotMenu { - }.openHistory { + }.clickHistoryButton { // Full URL no longer visible in the nav bar, so we'll check the history record // A search group is sometimes created when searching with DuckDuckGo try { @@ -698,12 +698,11 @@ class SearchTest : TestSetup() { createTabItem(firstPage.url.toString()) createBookmarkItem(secondPage.url.toString(), secondPage.title, 1u) - homeScreen { + homeScreen(composeTestRule) { }.openSearch { typeSearch("generic") - verifyTheSuggestionsHeader(activityTestRule, firefoxSuggestHeader) + verifyTheSuggestionsHeader(firefoxSuggestHeader) verifySearchSuggestionsAreDisplayed( - activityTestRule, searchSuggestions = arrayOf( firstPage.url.toString(), secondPage.url.toString(), @@ -722,17 +721,16 @@ class SearchTest : TestSetup() { MockBrowserDataHelper.createHistoryItem(firstPageUrl.url.toString()) MockBrowserDataHelper.createHistoryItem(secondPageUrl.url.toString()) - navigationToolbar { - }.clickUrlbar { + navigationToolbar(composeTestRule) { + }.clickURLBar { clickSearchSelectorButton() selectTemporarySearchMethod(searchEngineName = "History") typeSearch(searchTerm = "Mozilla") - verifySuggestionsAreNotDisplayed(rule = activityTestRule, "Mozilla") + verifySuggestionsAreNotDisplayed("Mozilla") clickClearButton() typeSearch(searchTerm = "generic") verifyTypedToolbarText("generic", exists = true) verifySearchSuggestionsAreDisplayed( - rule = activityTestRule, searchSuggestions = arrayOf( firstPageUrl.url.toString(), secondPageUrl.url.toString(), @@ -747,26 +745,25 @@ class SearchTest : TestSetup() { @SdkSuppress(minSdkVersion = 34) @Test fun verifyTabsSearchItemsTest() { - navigationToolbar { - }.clickUrlbar { + navigationToolbar(composeTestRule) { + }.clickURLBar { clickSearchSelectorButton() selectTemporarySearchMethod("Tabs") - verifyKeyboardVisibility(isExpectedToBeVisible = true) - verifyScanButtonVisibility(visible = false) - verifyVoiceSearchButtonVisibility(enabled = true) - verifySearchBarPlaceholder(text = "Search tabs") + verifyScanButton(isDisplayed = false) + verifyVoiceSearchButton(isDisplayed = true) + verifySearchBarPlaceholder(searchHint = "Search tabs") } } // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2154198 @Test fun verifyTabsSearchWithoutOpenTabsTest() { - navigationToolbar { - }.clickUrlbar { + navigationToolbar(composeTestRule) { + }.clickURLBar { clickSearchSelectorButton() selectTemporarySearchMethod(searchEngineName = "Tabs") typeSearch(searchTerm = "Mozilla") - verifySuggestionsAreNotDisplayed(rule = activityTestRule, "Mozilla") + verifySuggestionsAreNotDisplayed("Mozilla") clickClearButton() verifySearchBarPlaceholder("Search tabs") } @@ -782,18 +779,17 @@ class SearchTest : TestSetup() { createTabItem(firstPageUrl.url.toString()) createTabItem(secondPageUrl.url.toString()) - navigationToolbar { - }.clickUrlbar { + navigationToolbar(composeTestRule) { + }.clickURLBar { clickSearchSelectorButton() selectTemporarySearchMethod(searchEngineName = "Tabs") typeSearch(searchTerm = "Mozilla") - verifySuggestionsAreNotDisplayed(rule = activityTestRule, "Mozilla") + verifySuggestionsAreNotDisplayed("Mozilla") clickClearButton() typeSearch(searchTerm = "generic") verifyTypedToolbarText("generic", exists = true) - verifyTheSuggestionsHeader(activityTestRule, firefoxSuggestHeader) + verifyTheSuggestionsHeader(firefoxSuggestHeader) verifySearchSuggestionsAreDisplayed( - rule = activityTestRule, searchSuggestions = arrayOf( firstPageUrl.url.toString(), secondPageUrl.url.toString(), @@ -801,7 +797,7 @@ class SearchTest : TestSetup() { ) }.clickSearchSuggestion(firstPageUrl.url.toString()) { verifyTabCounter("2") - }.openTabDrawer(activityTestRule) { + }.openTabDrawer(composeTestRule) { verifyOpenTabsOrder(position = 1, title = firstPageUrl.url.toString()) verifyOpenTabsOrder(position = 2, title = secondPageUrl.url.toString()) } @@ -811,24 +807,24 @@ class SearchTest : TestSetup() { @SdkSuppress(minSdkVersion = 34) @Test fun verifyBookmarksSearchItemsTest() { - navigationToolbar { + navigationToolbar(composeTestRule) { }.clickSearchSelectorButton { selectTemporarySearchMethod("Bookmarks") verifySearchBarPlaceholder("Search bookmarks") verifyKeyboardVisibility(isExpectedToBeVisible = true) - verifyScanButtonVisibility(visible = false) - verifyVoiceSearchButtonVisibility(enabled = true) + verifyScanButton(isDisplayed = false) + verifyVoiceSearchButton(isDisplayed = true) } } // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2154204 @Test fun verifyBookmarkSearchWithNoBookmarksTest() { - navigationToolbar { + navigationToolbar(composeTestRule) { }.clickSearchSelectorButton { selectTemporarySearchMethod("Bookmarks") typeSearch("test") - verifySuggestionsAreNotDisplayed(activityTestRule, "test") + verifySuggestionsAreNotDisplayed("test") } } @@ -838,13 +834,12 @@ class SearchTest : TestSetup() { createBookmarkItem(url = "https://bookmarktest1.com", title = "Test1", position = 1u) createBookmarkItem(url = "https://bookmarktest2.com", title = "Test2", position = 2u) - navigationToolbar { + navigationToolbar(composeTestRule) { }.clickSearchSelectorButton { selectTemporarySearchMethod("Bookmarks") typeSearch("test") - verifyTheSuggestionsHeader(activityTestRule, firefoxSuggestHeader) + verifyTheSuggestionsHeader(firefoxSuggestHeader) verifySearchSuggestionsAreDisplayed( - rule = activityTestRule, searchSuggestions = arrayOf( "Test1", "https://bookmarktest1.com/", @@ -855,7 +850,7 @@ class SearchTest : TestSetup() { }.dismissSearchBar { }.openSearch { typeSearch("mozilla ") - verifySuggestionsAreNotDisplayed(activityTestRule, "Test1", "Test2") + verifySuggestionsAreNotDisplayed("Test1", "Test2") } } @@ -863,26 +858,25 @@ class SearchTest : TestSetup() { @SdkSuppress(minSdkVersion = 34) @Test fun verifyHistorySearchItemsTest() { - navigationToolbar { - }.clickUrlbar { + navigationToolbar(composeTestRule) { + }.clickURLBar { clickSearchSelectorButton() selectTemporarySearchMethod("History") - verifyKeyboardVisibility(isExpectedToBeVisible = true) - verifyScanButtonVisibility(visible = false) - verifyVoiceSearchButtonVisibility(enabled = true) - verifySearchBarPlaceholder(text = "Search history") + verifyScanButton(isDisplayed = false) + verifyVoiceSearchButton(isDisplayed = true) + verifySearchBarPlaceholder(searchHint = "Search history") } } // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2154213 @Test fun verifyHistorySearchWithoutBrowsingHistoryTest() { - navigationToolbar { - }.clickUrlbar { + navigationToolbar(composeTestRule) { + }.clickURLBar { clickSearchSelectorButton() selectTemporarySearchMethod(searchEngineName = "History") typeSearch(searchTerm = "Mozilla") - verifySuggestionsAreNotDisplayed(rule = activityTestRule, "Mozilla") + verifySuggestionsAreNotDisplayed("Mozilla") clickClearButton() verifySearchBarPlaceholder("Search history") } @@ -900,33 +894,29 @@ class SearchTest : TestSetup() { setCustomSearchEngine(searchMockServer, searchEngineName) createBookmarkItem(firstPageUrl.url.toString(), firstPageUrl.title, 1u) - homeScreen { - }.openNavigationToolbar { - }.clickUrlbar { + navigationToolbar(composeTestRule) { + }.clickURLBar { }.submitQuery("test page 1") { - }.goToHomescreen(activityTestRule) { + }.goToHomescreen { }.togglePrivateBrowsingMode() - homeScreen { - }.openNavigationToolbar { - }.clickUrlbar { + navigationToolbar(composeTestRule) { + }.clickURLBar { }.submitQuery("test page 2") { }.openNavigationToolbar { - }.clickUrlbar { + }.clickURLBar { typeSearch(searchTerm = "test page") - verifyTheSuggestionsHeader(activityTestRule, firefoxSuggestHeader) - verifyTheSuggestionsHeader(activityTestRule, "TestSearchEngine search") + verifyTheSuggestionsHeader(firefoxSuggestHeader) + verifyTheSuggestionsHeader("TestSearchEngine search") verifySearchSuggestionsAreDisplayed( - rule = activityTestRule, searchSuggestions = arrayOf( "test page 1", firstPageUrl.url.toString(), ), ) // 2 search engine suggestions and 2 browser suggestions (1 history, 1 bookmark) - verifySearchSuggestionsCount(activityTestRule, numberOfSuggestions = 4, searchTerm = "test page") + verifySearchSuggestionsCount(numberOfSuggestions = 4, searchTerm = "test page") verifySuggestionsAreNotDisplayed( - activityTestRule, searchSuggestions = arrayOf( "test page 2", ), @@ -936,20 +926,22 @@ class SearchTest : TestSetup() { // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/1232631 // Expected for app language set to Arabic + @SkipLeaks(reasons = ["https://bugzilla.mozilla.org/show_bug.cgi?id=2006674"]) @Test fun verifySearchEnginesFunctionalityUsingRTLLocaleTest() { val arabicLocale = Locale.Builder().setLanguage("ar").setRegion("AR").build() - AppAndSystemHelper.runWithAppLocaleChanged(arabicLocale, activityTestRule.activityRule) { - homeScreen { + AppAndSystemHelper.runWithAppLocaleChanged(arabicLocale, composeTestRule.activityRule) { + homeScreen(composeTestRule) { }.openSearch { - verifyTranslatedFocusedNavigationToolbar("ابحث أو أدخِل عنوانا") + verifyTranslatedNavigationToolbarHint("ابحث أو أدخِل عنوانا") clickSearchSelectorButton() - verifySearchShortcutListContains( + verifySearchShortcutList( "Google", "Bing", "DuckDuckGo", "ويكيبيديا (ar)", + isSearchEngineDisplayed = true, ) selectTemporarySearchMethod("ويكيبيديا (ar)") }.submitQuery("firefox") { diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsAboutTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsAboutTest.kt @@ -4,15 +4,16 @@ package org.mozilla.fenix.ui +import androidx.compose.ui.test.junit4.AndroidComposeTestRule import androidx.test.uiautomator.UiSelector import org.junit.Rule import org.junit.Test import org.mozilla.fenix.Config -import org.mozilla.fenix.ReleaseChannel import org.mozilla.fenix.helpers.AppAndSystemHelper.runWithCondition import org.mozilla.fenix.helpers.HomeActivityIntentTestRule -import org.mozilla.fenix.helpers.RetryTestRule +import org.mozilla.fenix.helpers.HomeActivityTestRule import org.mozilla.fenix.helpers.TestHelper.mDevice +import org.mozilla.fenix.helpers.TestHelper.waitForAppWindowToBeUpdated import org.mozilla.fenix.helpers.TestSetup import org.mozilla.fenix.helpers.perf.DetectMemoryLeaksRule import org.mozilla.fenix.ui.robots.clickRateButtonGooglePlay @@ -25,22 +26,21 @@ import org.mozilla.fenix.ui.robots.homeScreen class SettingsAboutTest : TestSetup() { @get:Rule - val activityIntentTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides() + val composeTestRule = + AndroidComposeTestRule( + HomeActivityIntentTestRule.withDefaultSettingsOverrides(), + ) { it.activity } @get:Rule val memoryLeaksRule = DetectMemoryLeaksRule() - @Rule - @JvmField - val retryTestRule = RetryTestRule(3) - // Walks through the About settings menu to ensure all items are present // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2092700 @Test fun verifyAboutSettingsItemsTest() { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { verifyAboutHeading() verifyRateOnGooglePlay() verifyAboutFirefoxPreview() @@ -50,11 +50,11 @@ class SettingsAboutTest : TestSetup() { // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/246966 @Test fun verifyRateOnGooglePlayButtonTest() { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { clickRateButtonGooglePlay() - verifyGooglePlayRedirect() + verifyGooglePlayRedirect(composeTestRule) // press back to return to the app, or accept ToS if still visible mDevice.pressBack() dismissGooglePlayToS() @@ -64,9 +64,9 @@ class SettingsAboutTest : TestSetup() { @Test fun verifyLibrariesListInReleaseBuildsTest() { runWithCondition(Config.channel.isReleased) { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openAboutFirefoxPreview { verifyLibrariesUsedLink() verifyTheLibrariesListNotEmpty() @@ -77,9 +77,9 @@ class SettingsAboutTest : TestSetup() { // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3132639 @Test fun verifyAboutFirefoxMenuAppDetailsItemTest() { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openAboutFirefoxPreview { verifyAboutToolbar() verifyAboutFirefoxPreviewInfo() @@ -89,33 +89,33 @@ class SettingsAboutTest : TestSetup() { // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3132640 @Test fun verifyAboutFirefoxMenuWhatsNewInFirefoxItemTest() { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openAboutFirefoxPreview { verifyAboutToolbar() - verifyWhatIsNewInFirefoxLink() + verifyWhatIsNewInFirefoxLink(composeTestRule) } } // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3132641 @Test fun verifyAboutFirefoxMenuSupportItemTest() { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openAboutFirefoxPreview { verifyAboutToolbar() - verifySupportLink() + verifySupportLink(composeTestRule) } } // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3132642 @Test fun verifyAboutFirefoxMenuCrashesItemTest() { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openAboutFirefoxPreview { verifyAboutToolbar() verifyCrashesLink() @@ -125,45 +125,45 @@ class SettingsAboutTest : TestSetup() { // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3132643 @Test fun verifyAboutFirefoxMenuPrivacyNoticeItemTest() { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openAboutFirefoxPreview { verifyAboutToolbar() - verifyPrivacyNoticeLink() + verifyPrivacyNoticeLink(composeTestRule) } } // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3132644 @Test fun verifyAboutFirefoxMenuKnowYourRightsItemTest() { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openAboutFirefoxPreview { verifyAboutToolbar() - verifyKnowYourRightsLink() + verifyKnowYourRightsLink(composeTestRule) } } // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3132645 @Test fun verifyAboutFirefoxMenuLicensingInformationItemTest() { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openAboutFirefoxPreview { verifyAboutToolbar() - verifyLicensingInformationLink() + verifyLicensingInformationLink(composeTestRule) } } // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3132646 @Test fun verifyAboutFirefoxMenuLibrariesThatWeUseItemTest() { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openAboutFirefoxPreview { verifyAboutToolbar() verifyLibrariesUsedLink() diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsAddonsTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsAddonsTest.kt @@ -12,7 +12,6 @@ import org.mozilla.fenix.R import org.mozilla.fenix.customannotations.SmokeTest import org.mozilla.fenix.ext.settings import org.mozilla.fenix.helpers.AppAndSystemHelper.registerAndCleanupIdlingResources -import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource import org.mozilla.fenix.helpers.HomeActivityIntentTestRule import org.mozilla.fenix.helpers.RecyclerViewIdlingResource import org.mozilla.fenix.helpers.TestAssetHelper.enhancedTrackingProtectionAsset @@ -29,7 +28,7 @@ import org.mozilla.fenix.ui.robots.navigationToolbar */ class SettingsAddonsTest : TestSetup() { @get:Rule - val activityTestRule = + val composeTestRule = AndroidComposeTestRule( HomeActivityIntentTestRule.withDefaultSettingsOverrides(), ) { it.activity } @@ -41,14 +40,14 @@ class SettingsAddonsTest : TestSetup() { // Walks through settings add-ons menu to ensure all items are present @Test fun verifyAddonsListItemsTest() { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { verifyAdvancedHeading() verifyAddons() - }.openAddonsManagerMenu { + }.openAddonsManagerMenu(composeTestRule) { registerAndCleanupIdlingResources( - RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.add_ons_list), 1), + RecyclerViewIdlingResource(composeTestRule.activity.findViewById(R.id.add_ons_list), 1), ) { verifyAddonsItems() } @@ -61,12 +60,12 @@ class SettingsAddonsTest : TestSetup() { fun installAddonFromMainMenuTest() { val addonName = "AdGuard AdBlocker" - homeScreen {} + homeScreen(composeTestRule) {} .openThreeDotMenu {} - .openAddonsManagerMenu { + .clickExtensionsButton { registerAndCleanupIdlingResources( RecyclerViewIdlingResource( - activityTestRule.activity.findViewById(R.id.add_ons_list), + composeTestRule.activity.findViewById(R.id.add_ons_list), 1, ), ) { @@ -78,7 +77,7 @@ class SettingsAddonsTest : TestSetup() { cancelInstallAddon() clickInstallAddon(addonName) acceptPermissionToInstallAddon() - verifyAddonInstallCompletedPrompt(addonName, activityTestRule.activityRule) + verifyAddonInstallCompletedPrompt(addonName, composeTestRule.activityRule) closeAddonInstallCompletePrompt() verifyAddonIsInstalled(addonName) verifyEnabledTitleDisplayed() @@ -91,14 +90,14 @@ class SettingsAddonsTest : TestSetup() { fun verifyAddonsCanBeUninstalledTest() { val addonName = "uBlock Origin" - addonsMenu { - installAddon(addonName, activityTestRule.activityRule) + addonsMenu(composeTestRule) { + installAddon(addonName, composeTestRule.activityRule) closeAddonInstallCompletePrompt() }.openDetailedMenuForAddon(addonName) { - }.removeAddon(activityTestRule.activityRule) { + }.removeAddon(composeTestRule.activityRule) { }.goBackToHomeScreen { }.openThreeDotMenu { - }.openAddonsManagerMenu { + }.clickExtensionsButton { verifyAddonCanBeInstalled(addonName) } } @@ -111,28 +110,30 @@ class SettingsAddonsTest : TestSetup() { @Test fun noCrashWithAddonInstalledTest() { // setting ETP to Strict mode to test it works with add-ons - activityTestRule.activity.settings().setStrictETP() + composeTestRule.activity.settings().setStrictETP() val uBlockAddon = "uBlock Origin" val darkReaderAddon = "Dark Reader" val trackingProtectionPage = mockWebServer.enhancedTrackingProtectionAsset - addonsMenu { - installAddon(uBlockAddon, activityTestRule.activityRule) + addonsMenu(composeTestRule) { + installAddon(uBlockAddon, composeTestRule.activityRule) closeAddonInstallCompletePrompt() - installAddon(darkReaderAddon, activityTestRule.activityRule) + // installAddon(darkReaderAddon, composeTestRule.activityRule) + clickInstallAddon(darkReaderAddon) + verifyAddonPermissionPrompt(darkReaderAddon) + acceptPermissionToInstallAddon() + verifyAddonInstallCompletedPrompt(darkReaderAddon, composeTestRule.activityRule) closeAddonInstallCompletePrompt() }.goBackToHomeScreen { - }.openNavigationToolbar { + } + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(trackingProtectionPage.url) { verifyUrl(trackingProtectionPage.url.toString()) - }.goToHomescreen(activityTestRule) { - }.openTopSiteTabWithTitle( - activityTestRule, - "Wikipedia", - ) { + }.goToHomescreen { + }.openTopSiteTabWithTitle("Wikipedia") { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { verifySettingsView() } } @@ -145,18 +146,16 @@ class SettingsAddonsTest : TestSetup() { val addonName = "uBlock Origin" val webPage = "https://mozilla-mobile.github.io/testapp/" - addonsMenu { - installAddonInPrivateMode(addonName, activityTestRule.activityRule) + addonsMenu(composeTestRule) { + installAddonInPrivateMode(addonName, composeTestRule.activityRule) closeAddonInstallCompletePrompt() }.goBackToHomeScreen { } - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(webPage.toUri()) { verifyPageContent("Lets test!") }.openThreeDotMenu { - openAddonsSubList() - verifyAddonAvailableInMainMenu(addonName) - verifyTrackersBlockedByUblock() + verifyExtensionsButtonWithInstalledExtension(addonName) } } @@ -166,17 +165,16 @@ class SettingsAddonsTest : TestSetup() { val addonName = "uBlock Origin" val webPage = "https://mozilla-mobile.github.io/testapp/" - addonsMenu { - installAddon(addonName, activityTestRule.activityRule) + addonsMenu(composeTestRule) { + installAddon(addonName, composeTestRule.activityRule) closeAddonInstallCompletePrompt() }.goBackToHomeScreen { } - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(webPage.toUri()) { verifyPageContent("Lets test!") }.openThreeDotMenu { - openAddonsSubList() - verifyTrackersBlockedByUblock() + verifyExtensionsButtonWithInstalledExtension(addonName) } } } diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsAdvancedTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsAdvancedTest.kt @@ -4,6 +4,7 @@ package org.mozilla.fenix.ui +import androidx.compose.ui.test.junit4.AndroidComposeTestRule import androidx.core.net.toUri import org.junit.Before import org.junit.Rule @@ -38,7 +39,10 @@ class SettingsAdvancedTest : TestSetup() { private val playStoreUrl = "play.google.com" @get:Rule - val activityIntentTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides() + val composeTestRule = + AndroidComposeTestRule( + HomeActivityIntentTestRule.withDefaultSettingsOverrides(), + ) { it.activity } @get:Rule val memoryLeaksRule = DetectMemoryLeaksRule() @@ -56,9 +60,9 @@ class SettingsAdvancedTest : TestSetup() { @Test fun verifyAdvancedSettingsSectionItemsTest() { // ADVANCED - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { verifySettingsToolbar() verifyAdvancedHeading() verifyAddons() @@ -79,15 +83,15 @@ class SettingsAdvancedTest : TestSetup() { @SmokeTest @Test fun askBeforeOpeningOpenLinkInAppTest() { - activityIntentTestRule.applySettingsExceptions { + composeTestRule.activityRule.applySettingsExceptions { it.openLinksInExternalApp = OpenLinksInApp.ASK } exitMenu() - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(externalLinksPage.url) { - clickPageObject(playStoreLink) + clickPageObject(composeTestRule, playStoreLink) verifyUrl(playStoreUrl) } } @@ -96,13 +100,13 @@ class SettingsAdvancedTest : TestSetup() { // Assumes Youtube is installed and enabled @Test fun privateBrowsingAskBeforeOpeningOpenLinkInAppTest() { - activityIntentTestRule.applySettingsExceptions { + composeTestRule.activityRule.applySettingsExceptions { it.openLinksInExternalApp = OpenLinksInApp.ASK } - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(externalLinksPage.url) { - clickPageObject(playStoreLink) + clickPageObject(composeTestRule, playStoreLink) verifyUrl(playStoreUrl) } } @@ -112,15 +116,15 @@ class SettingsAdvancedTest : TestSetup() { @SmokeTest @Test fun askBeforeOpeningLinkInAppCancelTest() { - activityIntentTestRule.applySettingsExceptions { + composeTestRule.activityRule.applySettingsExceptions { it.openLinksInExternalApp = OpenLinksInApp.ASK } - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(externalLinksPage.url) { - clickPageObject(youTubeSchemaLink) + clickPageObject(composeTestRule, youTubeSchemaLink) verifyOpenLinkInAnotherAppPrompt(appName = "YouTube") - clickPageObject(itemWithResIdAndText("android:id/button2", "Cancel")) + clickPageObject(composeTestRule, itemWithResIdAndText("android:id/button2", "Cancel")) verifyUrl(externalLinksPage.url.toString()) } } @@ -130,16 +134,16 @@ class SettingsAdvancedTest : TestSetup() { @SmokeTest @Test fun askBeforeOpeningLinkInAppOpenTest() { - activityIntentTestRule.applySettingsExceptions { + composeTestRule.activityRule.applySettingsExceptions { it.openLinksInExternalApp = OpenLinksInApp.ASK } - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(externalLinksPage.url) { - clickPageObject(youTubeSchemaLink) + clickPageObject(composeTestRule, youTubeSchemaLink) verifyOpenLinkInAnotherAppPrompt(appName = "YouTube") waitForAppWindowToBeUpdated() - clickPageObject(itemWithResIdAndText("android:id/button1", "Open")) + clickPageObject(composeTestRule, itemWithResIdAndText("android:id/button1", "Open")) mDevice.waitForIdle() assertYoutubeAppOpens() } @@ -150,22 +154,22 @@ class SettingsAdvancedTest : TestSetup() { @Test fun privateBrowsingAskBeforeOpeningLinkInAppCancelTest() { TestHelper.appContext.settings().shouldShowCookieBannersCFR = false - activityIntentTestRule.applySettingsExceptions { + composeTestRule.activityRule.applySettingsExceptions { it.openLinksInExternalApp = OpenLinksInApp.ASK } - homeScreen { + homeScreen(composeTestRule) { }.togglePrivateBrowsingMode() - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(externalLinksPage.url) { - clickPageObject(youTubeSchemaLink) + clickPageObject(composeTestRule, youTubeSchemaLink) verifyPrivateBrowsingOpenLinkInAnotherAppPrompt( appName = "YouTube", url = "youtube", pageObject = youTubeSchemaLink, ) - clickPageObject(itemWithResIdAndText("android:id/button2", "Cancel")) + clickPageObject(composeTestRule, itemWithResIdAndText("android:id/button2", "Cancel")) verifyUrl(externalLinksPage.url.toString()) } } @@ -174,25 +178,25 @@ class SettingsAdvancedTest : TestSetup() { // Assumes Youtube is installed and enabled @Test fun privateBrowsingAskBeforeOpeningLinkInAppOpenTest() { - activityIntentTestRule.applySettingsExceptions { + composeTestRule.activityRule.applySettingsExceptions { it.openLinksInExternalApp = OpenLinksInApp.ASK } - homeScreen { + homeScreen(composeTestRule) { }.togglePrivateBrowsingMode() exitMenu() - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(externalLinksPage.url) { - clickPageObject(youTubeSchemaLink) + clickPageObject(composeTestRule, youTubeSchemaLink) verifyPrivateBrowsingOpenLinkInAnotherAppPrompt( appName = "YouTube", url = "youtube", pageObject = youTubeSchemaLink, ) waitForAppWindowToBeUpdated() - clickPageObject(itemWithResIdAndText("android:id/button1", "Open")) + clickPageObject(composeTestRule, itemWithResIdAndText("android:id/button1", "Open")) mDevice.waitForIdle() assertYoutubeAppOpens() } @@ -202,13 +206,13 @@ class SettingsAdvancedTest : TestSetup() { // Assumes Youtube is installed and enabled @Test fun alwaysOpenLinkInAppTest() { - activityIntentTestRule.applySettingsExceptions { + composeTestRule.activityRule.applySettingsExceptions { it.openLinksInExternalApp = OpenLinksInApp.ALWAYS } - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(externalLinksPage.url) { - clickPageObject(youTubeSchemaLink) + clickPageObject(composeTestRule, youTubeSchemaLink) mDevice.waitForIdle() assertYoutubeAppOpens() } @@ -217,12 +221,12 @@ class SettingsAdvancedTest : TestSetup() { // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/1058617 @Test fun dismissOpenLinksInAppCFRTest() { - activityIntentTestRule.applySettingsExceptions { + composeTestRule.activityRule.applySettingsExceptions { it.isOpenInAppBannerEnabled = true it.openLinksInExternalApp = OpenLinksInApp.NEVER } - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser("https://m.youtube.com/".toUri()) { verifyPageContent("youtube") verifyOpenLinksInAppsCFRExists(true) @@ -234,12 +238,12 @@ class SettingsAdvancedTest : TestSetup() { // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2288331 @Test fun goToSettingsFromOpenLinksInAppCFRTest() { - activityIntentTestRule.applySettingsExceptions { + composeTestRule.activityRule.applySettingsExceptions { it.isOpenInAppBannerEnabled = true it.openLinksInExternalApp = OpenLinksInApp.NEVER } - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser("https://m.youtube.com/".toUri()) { verifyPageContent("youtube") verifyOpenLinksInAppsCFRExists(true) diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsCustomizeTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsCustomizeTest.kt @@ -17,7 +17,6 @@ import org.mozilla.fenix.helpers.TestHelper.exitMenu import org.mozilla.fenix.helpers.TestHelper.restartApp import org.mozilla.fenix.helpers.TestHelper.verifyDarkThemeApplied import org.mozilla.fenix.helpers.TestHelper.verifyLightThemeApplied -import org.mozilla.fenix.helpers.TestHelper.waitForAppWindowToBeUpdated import org.mozilla.fenix.helpers.TestSetup import org.mozilla.fenix.helpers.perf.DetectMemoryLeaksRule import org.mozilla.fenix.ui.robots.homeScreen @@ -48,9 +47,9 @@ class SettingsCustomizeTest : TestSetup() { @Test fun changeThemeOfTheAppTest() { // Goes through the settings and changes the default search engine, then verifies it changes. - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openCustomizeSubMenu { verifyThemes() selectDarkMode() @@ -63,25 +62,25 @@ class SettingsCustomizeTest : TestSetup() { // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/466571 @Test fun setToolbarPositionTest() { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openCustomizeSubMenu { verifyAddressBarPositionPreference("Bottom") clickTopToolbarToggle() verifyAddressBarPositionPreference("Top") }.goBack { - }.goBack { - verifyAddressBarPosition(bottomPosition = false) + }.goBack(composeTestRule) { + verifyToolbarPosition(bottomPosition = false) }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openCustomizeSubMenu { clickBottomToolbarToggle() verifyAddressBarPositionPreference("Bottom") exitMenu() } - homeScreen { - verifyAddressBarPosition(bottomPosition = true) + homeScreen(composeTestRule) { + verifyToolbarPosition(bottomPosition = true) } } @@ -95,16 +94,16 @@ class SettingsCustomizeTest : TestSetup() { // Disable the back gesture from the edge of the screen on the device. enableOrDisableBackGestureNavigationOnDevice(backGestureNavigationEnabled = false) - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openCustomizeSubMenu { verifySwipeToolbarGesturePrefState(true) clickSwipeToolbarToSwitchTabToggle() verifySwipeToolbarGesturePrefState(false) exitMenu() } - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(firstWebPage.url) { }.openTabDrawer(composeTestRule) { }.openNewTab { @@ -119,9 +118,9 @@ class SettingsCustomizeTest : TestSetup() { // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/1992289 @Test fun pullToRefreshPreferenceTest() { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openCustomizeSubMenu { verifyPullToRefreshGesturePrefState(isEnabled = true) clickPullToRefreshToggle() @@ -133,9 +132,9 @@ class SettingsCustomizeTest : TestSetup() { @SmokeTest @Test fun verifyTheDefaultAppIconSettingTest() { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openCustomizeSubMenu { verifyAppIconOption(composeTestRule, "Default") } @@ -145,9 +144,9 @@ class SettingsCustomizeTest : TestSetup() { @SmokeTest @Test fun verifyTheAppIconSelectionPageTest() { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openCustomizeSubMenu { clickTheAppIconOption(composeTestRule) verifyAppIconSettingItems(composeTestRule) @@ -158,9 +157,9 @@ class SettingsCustomizeTest : TestSetup() { @SmokeTest @Test fun verifyTheChangeAppIconButtonTest() { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openCustomizeSubMenu { verifyAppIconOption(composeTestRule, "Default") clickTheAppIconOption(composeTestRule) @@ -169,9 +168,9 @@ class SettingsCustomizeTest : TestSetup() { clickTheChangeIconDialogButton(composeTestRule) restartApp(composeTestRule.activityRule) } - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openCustomizeSubMenu { verifyAppIconOption(composeTestRule, "Dark") } diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsDeleteBrowsingDataOnQuitTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsDeleteBrowsingDataOnQuitTest.kt @@ -12,12 +12,11 @@ import androidx.test.rule.GrantPermissionRule import org.junit.Ignore import org.junit.Rule import org.junit.Test -import org.mozilla.fenix.R import org.mozilla.fenix.customannotations.SmokeTest import org.mozilla.fenix.helpers.AppAndSystemHelper.setNetworkEnabled -import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource import org.mozilla.fenix.helpers.HomeActivityIntentTestRule import org.mozilla.fenix.helpers.MatcherHelper +import org.mozilla.fenix.helpers.MatcherHelper.itemWithText import org.mozilla.fenix.helpers.TestAssetHelper.getGenericAsset import org.mozilla.fenix.helpers.TestAssetHelper.storageCheckPageAsset import org.mozilla.fenix.helpers.TestAssetHelper.storageWritePageAsset @@ -58,9 +57,9 @@ class SettingsDeleteBrowsingDataOnQuitTest : TestSetup() { // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/416048 @Test fun deleteBrowsingDataOnQuitSettingTest() { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openSettingsSubMenuDeleteBrowsingDataOnQuit { verifyNavigationToolBarHeader() verifyDeleteBrowsingOnQuitEnabled(false) @@ -72,12 +71,12 @@ class SettingsDeleteBrowsingDataOnQuitTest : TestSetup() { verifyAllTheCheckBoxesChecked(true) }.goBack { verifySettingsOptionSummary("Delete browsing data on quit", "On") - }.goBack { + }.goBack(composeTestRule) { }.openThreeDotMenu { verifyQuitButtonExists() pressBack() } - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser("test".toUri()) { }.openThreeDotMenu { verifyQuitButtonExists() @@ -89,22 +88,22 @@ class SettingsDeleteBrowsingDataOnQuitTest : TestSetup() { fun deleteOpenTabsOnQuitTest() { val testPage = mockWebServer.getGenericAsset(1) - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openSettingsSubMenuDeleteBrowsingDataOnQuit { clickDeleteBrowsingOnQuitButtonSwitch() exitMenu() } - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(testPage.url) { - }.goToHomescreen(composeTestRule) { + }.goToHomescreen { }.openThreeDotMenu { - clickQuit() + clickTheQuitFirefoxButton() restartApp(composeTestRule.activityRule) } - homeScreen { - }.openTabDrawer(composeTestRule) { + homeScreen(composeTestRule) { + }.openTabDrawer { verifyNoOpenTabsInNormalBrowsing() } } @@ -114,24 +113,24 @@ class SettingsDeleteBrowsingDataOnQuitTest : TestSetup() { fun deleteBrowsingHistoryOnQuitTest() { val genericPage = mockWebServer.getGenericAsset(1) - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openSettingsSubMenuDeleteBrowsingDataOnQuit { clickDeleteBrowsingOnQuitButtonSwitch() exitMenu() } - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(genericPage.url) { - }.goToHomescreen(composeTestRule) { + }.goToHomescreen { }.openThreeDotMenu { - clickQuit() + clickTheQuitFirefoxButton() restartApp(composeTestRule.activityRule) } - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openHistory { + }.clickHistoryButton { verifyEmptyHistoryView() exitMenu() } @@ -143,28 +142,29 @@ class SettingsDeleteBrowsingDataOnQuitTest : TestSetup() { val storageWritePage = mockWebServer.storageWritePageAsset val storageCheckPage = mockWebServer.storageCheckPageAsset - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openSettingsSubMenuDeleteBrowsingDataOnQuit { clickDeleteBrowsingOnQuitButtonSwitch() exitMenu() } - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(storageWritePage.url) { - clickPageObject(MatcherHelper.itemWithText("Set cookies")) + clickPageObject(composeTestRule, itemWithText("Set cookies")) verifyPageContent("Values written to storage") - }.goToHomescreen(composeTestRule) { + }.goToHomescreen { }.openThreeDotMenu { - clickQuit() + clickTheQuitFirefoxButton() restartApp(composeTestRule.activityRule) } - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(storageCheckPage.url) { verifyPageContent("Session storage empty") verifyPageContent("Local storage empty") - }.openNavigationToolbar { + } + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(storageWritePage.url) { verifyPageContent("No cookies set") } @@ -176,28 +176,28 @@ class SettingsDeleteBrowsingDataOnQuitTest : TestSetup() { fun deleteDownloadsOnQuitTest() { val downloadTestPage = "https://storage.googleapis.com/mobile_test_assets/test_app/downloads.html" - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openSettingsSubMenuDeleteBrowsingDataOnQuit { clickDeleteBrowsingOnQuitButtonSwitch() exitMenu() } - downloadRobot { + downloadRobot(composeTestRule) { openPageAndDownloadFile(url = downloadTestPage.toUri(), downloadFile = "smallZip.zip") verifyDownloadCompleteSnackbar(fileName = "smallZip.zip") } - browserScreen { - }.goToHomescreen(composeTestRule) { + browserScreen(composeTestRule) { + }.goToHomescreen { }.openThreeDotMenu { - clickQuit() + clickTheQuitFirefoxButton() mDevice.waitForIdle() } restartApp(composeTestRule.activityRule) - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openDownloadsManager { - verifyEmptyDownloadsList(composeTestRule) + }.clickDownloadsButton { + verifyEmptyDownloadsList() } } @@ -208,14 +208,14 @@ class SettingsDeleteBrowsingDataOnQuitTest : TestSetup() { val testPage = "https://mozilla-mobile.github.io/testapp/permissions" val testPageHost = "mozilla-mobile.github.io" - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openSettingsSubMenuDeleteBrowsingDataOnQuit { clickDeleteBrowsingOnQuitButtonSwitch() exitMenu() } - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(testPage.toUri()) { verifyPageContent("Open microphone") }.clickStartMicrophoneButton { @@ -223,13 +223,13 @@ class SettingsDeleteBrowsingDataOnQuitTest : TestSetup() { selectRememberPermissionDecision() }.clickPagePermissionButton(false) { verifyPageContent("Microphone not allowed") - }.goToHomescreen(composeTestRule) { + }.goToHomescreen { }.openThreeDotMenu { - clickQuit() + clickTheQuitFirefoxButton() mDevice.waitForIdle() } restartApp(composeTestRule.activityRule) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(testPage.toUri()) { verifyPageContent("Open microphone") }.clickStartMicrophoneButton { @@ -241,26 +241,26 @@ class SettingsDeleteBrowsingDataOnQuitTest : TestSetup() { @Ignore("Failing, see https://bugzilla.mozilla.org/show_bug.cgi?id=1987355") @Test fun deleteCachedFilesOnQuitTest() { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openSettingsSubMenuDeleteBrowsingDataOnQuit { clickDeleteBrowsingOnQuitButtonSwitch() exitMenu() } - homeScreen { - verifyExistingTopSitesTabs(composeTestRule, "Wikipedia") - }.openTopSiteTabWithTitle(composeTestRule, "Wikipedia") { + homeScreen(composeTestRule) { + verifyExistingTopSitesTabs("Wikipedia") + }.openTopSiteTabWithTitle("Wikipedia") { verifyUrl("wikipedia.org") - }.goToHomescreen(composeTestRule) { + }.goToHomescreen { }.openThreeDotMenu { - clickQuit() + clickTheQuitFirefoxButton() mDevice.waitForIdle() } // disabling wifi to prevent downloads in the background setNetworkEnabled(enabled = false) restartApp(composeTestRule.activityRule) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser("about:cache".toUri()) { verifyNetworkCacheIsEmpty("memory") verifyNetworkCacheIsEmpty("disk") diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsDeleteBrowsingDataTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsDeleteBrowsingDataTest.kt @@ -9,11 +9,9 @@ import androidx.test.filters.SdkSuppress import org.junit.Ignore import org.junit.Rule import org.junit.Test -import org.mozilla.fenix.R import org.mozilla.fenix.customannotations.SkipLeaks import org.mozilla.fenix.customannotations.SmokeTest import org.mozilla.fenix.helpers.AppAndSystemHelper.setNetworkEnabled -import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource import org.mozilla.fenix.helpers.HomeActivityIntentTestRule import org.mozilla.fenix.helpers.MatcherHelper.itemWithResId import org.mozilla.fenix.helpers.TestAssetHelper.getGenericAsset @@ -50,9 +48,9 @@ class SettingsDeleteBrowsingDataTest : TestSetup() { // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/937561 @Test fun deleteBrowsingDataOptionStatesTest() { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openSettingsSubMenuDeleteBrowsingData { verifyAllCheckBoxesAreChecked() switchBrowsingHistoryCheckBox() @@ -67,9 +65,9 @@ class SettingsDeleteBrowsingDataTest : TestSetup() { restartApp(composeTestRule.activityRule) - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openSettingsSubMenuDeleteBrowsingData { verifyOpenTabsCheckBox(true) verifyBrowsingHistoryDetails(false) @@ -93,9 +91,9 @@ class SettingsDeleteBrowsingDataTest : TestSetup() { restartApp(composeTestRule.activityRule) - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openSettingsSubMenuDeleteBrowsingData { verifyOpenTabsCheckBox(false) verifyBrowsingHistoryDetails(true) @@ -109,9 +107,9 @@ class SettingsDeleteBrowsingDataTest : TestSetup() { // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/517811 @Test fun deleteOpenTabsBrowsingDataWithNoOpenTabsTest() { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openSettingsSubMenuDeleteBrowsingData { verifyAllCheckBoxesAreChecked() selectOnlyOpenTabsCheckBox() @@ -130,11 +128,11 @@ class SettingsDeleteBrowsingDataTest : TestSetup() { fun deleteOpenTabsBrowsingDataTest() { val defaultWebPage = mockWebServer.getGenericAsset(1) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(defaultWebPage.url) { mDevice.waitForIdle() }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openSettingsSubMenuDeleteBrowsingData { verifyAllCheckBoxesAreChecked() selectOnlyOpenTabsCheckBox() @@ -151,8 +149,8 @@ class SettingsDeleteBrowsingDataTest : TestSetup() { }.openSettingsSubMenuDeleteBrowsingData { verifyOpenTabsDetails("0") }.goBack { - }.goBack { - }.openTabDrawer(composeTestRule) { + }.goBack(composeTestRule) { + }.openTabDrawer { verifyNoOpenTabsInNormalBrowsing() } } @@ -163,10 +161,10 @@ class SettingsDeleteBrowsingDataTest : TestSetup() { fun deleteBrowsingHistoryTest() { val genericPage = mockWebServer.getGenericAsset(1).url - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(genericPage) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openSettingsSubMenuDeleteBrowsingData { verifyBrowsingHistoryDetails("1") selectOnlyBrowsingHistoryCheckBox() @@ -180,9 +178,9 @@ class SettingsDeleteBrowsingDataTest : TestSetup() { verifyBrowsingHistoryDetails("0") exitMenu() } - navigationToolbar { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openHistory { + }.clickHistoryButton { verifyEmptyHistoryView() mDevice.pressBack() } @@ -198,19 +196,21 @@ class SettingsDeleteBrowsingDataTest : TestSetup() { val storageCheckPage = mockWebServer.storageCheckPageAsset.url // Browsing a generic page to allow GV to load on a fresh run - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(genericPage.url) { - }.openNavigationToolbar { + } + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(storageWritePage) { verifyPageContent("No cookies set") - clickPageObject(itemWithResId("setCookies")) + clickPageObject(composeTestRule, itemWithResId("setCookies")) verifyPageContent("user=android") - }.openNavigationToolbar { + } + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(storageCheckPage) { verifyPageContent("Session storage has value") verifyPageContent("Local storage has value") }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openSettingsSubMenuDeleteBrowsingData { selectOnlyCookiesCheckBox() clickDeleteBrowsingDataButton() @@ -222,11 +222,12 @@ class SettingsDeleteBrowsingDataTest : TestSetup() { confirmDeletionAndAssertSnackbar() exitMenu() } - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(storageCheckPage) { verifyPageContent("Session storage empty") verifyPageContent("Local storage empty") - }.openNavigationToolbar { + } + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(storageWritePage) { verifyPageContent("No cookies set") } @@ -238,9 +239,9 @@ class SettingsDeleteBrowsingDataTest : TestSetup() { @SmokeTest @Test fun deleteCachedFilesTest() { - homeScreen { - verifyExistingTopSitesTabs(composeTestRule, "Wikipedia") - }.openTopSiteTabWithTitle(composeTestRule, "Wikipedia") { + homeScreen(composeTestRule) { + verifyExistingTopSitesTabs("Wikipedia") + }.openTopSiteTabWithTitle("Wikipedia") { verifyUrl("wikipedia.org") }.openTabDrawer(composeTestRule) { }.openNewTab { @@ -248,7 +249,7 @@ class SettingsDeleteBrowsingDataTest : TestSetup() { // disabling wifi to prevent downloads in the background setNetworkEnabled(enabled = false) }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openSettingsSubMenuDeleteBrowsingData { selectOnlyCachedFilesCheckBox() clickDeleteBrowsingDataButton() @@ -256,9 +257,9 @@ class SettingsDeleteBrowsingDataTest : TestSetup() { confirmDeletionAndAssertSnackbar() exitMenu() } - browserScreen { + browserScreen(composeTestRule) { }.openThreeDotMenu { - }.refreshPage { + }.clickRefreshButton { verifyNetworkCacheIsEmpty("memory") verifyNetworkCacheIsEmpty("disk") } diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsGeneralTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsGeneralTest.kt @@ -4,6 +4,7 @@ package org.mozilla.fenix.ui +import androidx.compose.ui.test.junit4.AndroidComposeTestRule import androidx.core.net.toUri import androidx.core.os.LocaleListCompat import org.junit.Rule @@ -35,7 +36,10 @@ import org.mozilla.fenix.ui.util.ROMANIAN_LANGUAGE_HEADER */ class SettingsGeneralTest : TestSetup() { @get:Rule - val activityIntentTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides() + val composeTestRule = + AndroidComposeTestRule( + HomeActivityIntentTestRule.withDefaultSettingsOverrides(), + ) { it.activity } @get:Rule val memoryLeaksRule = DetectMemoryLeaksRule() @@ -43,9 +47,9 @@ class SettingsGeneralTest : TestSetup() { // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2092697 @Test fun verifyGeneralSettingsItemsTest() { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { verifySettingsToolbar() verifyGeneralHeading() verifySearchButton() @@ -69,27 +73,28 @@ class SettingsGeneralTest : TestSetup() { @Test fun verifyFontSizingChangeTest() { // Goes through the settings and changes the default text on a webpage, then verifies if the text has changed. - val fenixApp = activityIntentTestRule.activity.applicationContext as FenixApplication + val fenixApp = composeTestRule.activity.applicationContext as FenixApplication val webpage = mockWebServer.loremIpsumAsset.url // This value will represent the text size percentage the webpage will scale to. The default value is 100%. val textSizePercentage = 180 - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openAccessibilitySubMenu { clickFontSizingSwitch() verifyEnabledMenuItems() changeTextSizeSlider(textSizePercentage) verifyTextSizePercentage(textSizePercentage) }.goBack { - }.goBack { - }.openNavigationToolbar { + }.goBack(composeTestRule) { + } + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(webpage) { checkTextSizeOnWebsite(textSizePercentage, fenixApp.components) }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openAccessibilitySubMenu { clickFontSizingSwitch() verifyMenuItemsAreDisabled() @@ -102,15 +107,15 @@ class SettingsGeneralTest : TestSetup() { fun setAppLanguageDifferentThanSystemLanguageTest() { val enLanguageHeaderText = getStringResource(R.string.preferences_language) - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { waitForAppWindowToBeUpdated() }.openLanguageSubMenu { waitForAppWindowToBeUpdated() registerAndCleanupIdlingResources( RecyclerViewIdlingResource( - activityIntentTestRule.activity.findViewById(R.id.locale_list), + composeTestRule.activity.findViewById(R.id.locale_list), 2, ), ) { @@ -129,12 +134,12 @@ class SettingsGeneralTest : TestSetup() { fun searchInLanguagesListTest() { val systemLocaleDefault = getStringResource(R.string.default_locale_text) - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { waitForAppWindowToBeUpdated() registerAndCleanupIdlingResources( - RecyclerViewIdlingResource(activityIntentTestRule.activity.findViewById(R.id.recycler_view), 1), + RecyclerViewIdlingResource(composeTestRule.activity.findViewById(R.id.recycler_view), 1), ) { verifyLanguageButton() } @@ -155,13 +160,13 @@ class SettingsGeneralTest : TestSetup() { val frenchLocale = LocaleListCompat.forLanguageTags("fr") runWithSystemLocaleChanged(frenchLocale) { - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser("test".toUri()) { }.openThreeDotMenu { - }.openSettings(localizedText = FR_SETTINGS) { + }.clickSettingsButton(localizedText = FR_SETTINGS) { waitForAppWindowToBeUpdated() registerAndCleanupIdlingResources( - RecyclerViewIdlingResource(activityIntentTestRule.activity.findViewById(R.id.recycler_view), 1), + RecyclerViewIdlingResource(composeTestRule.activity.findViewById(R.id.recycler_view), 1), ) { verifyLanguageButton(localizedText = FRENCH_LANGUAGE_HEADER) } @@ -175,9 +180,9 @@ class SettingsGeneralTest : TestSetup() { // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/1360557 @Test fun tabsSettingsMenuItemsTest() { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { verifyTabsButton() verifySettingsOptionSummary("Tabs", "Close manually") }.openTabsSubMenu { @@ -208,9 +213,9 @@ class SettingsGeneralTest : TestSetup() { @SmokeTest @Test fun changeDefaultBrowserSetting() { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { verifyDefaultBrowserToggle(false) clickDefaultBrowserSwitch() verifyAndroidDefaultAppsMenuAppears() diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsHTTPSOnlyModeTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsHTTPSOnlyModeTest.kt @@ -35,7 +35,7 @@ class SettingsHTTPSOnlyModeTest : TestSetup() { private val httpsOnlyBackButton = "Go Back (Recommended)" @get:Rule - val activityTestRule = + val composeTestRule = AndroidComposeTestRule( HomeActivityIntentTestRule.withDefaultSettingsOverrides(), ) { it.activity } @@ -46,9 +46,9 @@ class SettingsHTTPSOnlyModeTest : TestSetup() { // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/1724825 @Test fun httpsOnlyModeMenuItemsTest() { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openHttpsOnlyModeMenu { verifyHttpsOnlyModeMenuHeader() verifyHttpsOnlyModeSummary() @@ -74,9 +74,9 @@ class SettingsHTTPSOnlyModeTest : TestSetup() { @SmokeTest @Test fun httpsOnlyModeEnabledInNormalBrowsingTest() { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openHttpsOnlyModeMenu { clickHttpsOnlyModeSwitch() verifyHttpsOnlyOptionSelected( @@ -87,26 +87,30 @@ class SettingsHTTPSOnlyModeTest : TestSetup() { verifySettingsOptionSummary("HTTPS-Only Mode", "On in all tabs") exitMenu() } - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(secondHttpPageUrl.toUri()) { verifyPageContent("permission.site") - }.openNavigationToolbar { - verifyUrl(secondHttpsPageUrl) + }.openSearch { + verifyTypedToolbarText(secondHttpsPageUrl, exists = true) + }.dismissSearchBar { + } + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(insecureHttpPage.toUri()) { verifyPageContent(httpsOnlyErrorTitle) verifyPageContent(httpsOnlyErrorMessage) verifyPageContent(httpsOnlyErrorMessage2) verifyPageContent(httpsOnlyBackButton) - clickPageObject(itemContainingText(httpsOnlyBackButton)) + clickPageObject(composeTestRule, itemContainingText(httpsOnlyBackButton)) // Workaround required with Fission ON: // Click back twice to avoid https://bugzilla.mozilla.org/show_bug.cgi?id=1932498 if (itemContainingText(httpsOnlyBackButton).waitForExists(waitingTimeShort)) { - clickPageObject(itemContainingText(httpsOnlyBackButton)) + clickPageObject(composeTestRule, itemContainingText(httpsOnlyBackButton)) } verifyPageContent("permission.site") - }.openNavigationToolbar { + } + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(insecureHttpPage.toUri()) { - clickPageObject(itemContainingText(httpsOnlyContinueButton)) + clickPageObject(composeTestRule, itemContainingText(httpsOnlyContinueButton)) verifyPageContent("http.badssl.com") } } @@ -115,9 +119,9 @@ class SettingsHTTPSOnlyModeTest : TestSetup() { @Test @SkipLeaks fun httpsOnlyModeExceptionPersistsForCurrentSessionTest() { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openHttpsOnlyModeMenu { clickHttpsOnlyModeSwitch() verifyHttpsOnlyOptionSelected( @@ -126,15 +130,15 @@ class SettingsHTTPSOnlyModeTest : TestSetup() { ) exitMenu() } - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(insecureHttpPage.toUri()) { verifyPageContent(httpsOnlyErrorTitle) - clickPageObject(itemContainingText(httpsOnlyContinueButton)) + clickPageObject(composeTestRule, itemContainingText(httpsOnlyContinueButton)) verifyPageContent("http.badssl.com") - }.openTabDrawer(activityTestRule) { + }.openTabDrawer(composeTestRule) { closeTab() } - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(insecureHttpPage.toUri()) { verifyPageContent("http.badssl.com") } @@ -143,9 +147,9 @@ class SettingsHTTPSOnlyModeTest : TestSetup() { // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/1724828 @Test fun httpsOnlyModeEnabledOnlyInPrivateBrowsingTest() { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openHttpsOnlyModeMenu { clickHttpsOnlyModeSwitch() selectHttpsOnlyModeOption( @@ -156,26 +160,29 @@ class SettingsHTTPSOnlyModeTest : TestSetup() { verifySettingsOptionSummary("HTTPS-Only Mode", "On in private tabs") exitMenu() } - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(insecureHttpPage.toUri()) { verifyPageContent("http.badssl.com") - }.goToHomescreen(activityTestRule) { + }.goToHomescreen { }.togglePrivateBrowsingMode() - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(secondHttpPageUrl.toUri()) { verifyPageContent("Notifications") - }.openNavigationToolbar { - verifyUrl(secondHttpsPageUrl) + }.openSearch { + verifyTypedToolbarText(secondHttpsPageUrl, exists = true) + }.dismissSearchBar { + } + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(insecureHttpPage.toUri()) { verifyPageContent(httpsOnlyErrorTitle) verifyPageContent(httpsOnlyErrorMessage) verifyPageContent(httpsOnlyErrorMessage2) verifyPageContent(httpsOnlyBackButton) - clickPageObject(itemContainingText(httpsOnlyBackButton)) + clickPageObject(composeTestRule, itemContainingText(httpsOnlyBackButton)) // Workaround required with Fission ON: // Click back twice to avoid https://bugzilla.mozilla.org/show_bug.cgi?id=1932498 if (itemContainingText(httpsOnlyBackButton).waitForExists(waitingTimeShort)) { - clickPageObject(itemContainingText(httpsOnlyBackButton)) + clickPageObject(composeTestRule, itemContainingText(httpsOnlyBackButton)) } verifyPageContent("Notifications") } @@ -185,9 +192,9 @@ class SettingsHTTPSOnlyModeTest : TestSetup() { @Test @SkipLeaks fun turnOffHttpsOnlyModeTest() { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openHttpsOnlyModeMenu { clickHttpsOnlyModeSwitch() verifyHttpsOnlyOptionSelected( @@ -196,27 +203,28 @@ class SettingsHTTPSOnlyModeTest : TestSetup() { ) exitMenu() } - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(secondHttpPageUrl.toUri()) { verifyPageContent("permission.site") - }.openNavigationToolbar { - verifyUrl(secondHttpsPageUrl) + }.openSearch { + verifyTypedToolbarText(secondHttpsPageUrl, exists = true) + }.dismissSearchBar { + } + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(insecureHttpPage.toUri()) { verifyPageContent(httpsOnlyErrorTitle) verifyPageContent(httpsOnlyErrorMessage) verifyPageContent(httpsOnlyErrorMessage2) verifyPageContent(httpsOnlyBackButton) - clickPageObject(itemContainingText(httpsOnlyBackButton)) + clickPageObject(composeTestRule, itemContainingText(httpsOnlyBackButton)) // Workaround required with Fission ON: // Click back twice to avoid https://bugzilla.mozilla.org/show_bug.cgi?id=1932498 if (itemContainingText(httpsOnlyBackButton).waitForExists(waitingTimeShort)) { - clickPageObject(itemContainingText(httpsOnlyBackButton)) + clickPageObject(composeTestRule, itemContainingText(httpsOnlyBackButton)) } verifyPageContent("permission.site") - }.openNavigationToolbar { - }.goBackToBrowserScreen { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openHttpsOnlyModeMenu { clickHttpsOnlyModeSwitch() verifyHttpsOnlyModeIsEnabled(false) @@ -224,7 +232,7 @@ class SettingsHTTPSOnlyModeTest : TestSetup() { verifySettingsOptionSummary("HTTPS-Only Mode", "Off") exitMenu() } - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(insecureHttpPage.toUri()) { verifyPageContent("http.badssl.com") } diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsHomepageTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsHomepageTest.kt @@ -5,6 +5,7 @@ package org.mozilla.fenix.ui import androidx.compose.ui.test.junit4.AndroidComposeTestRule +import org.junit.Ignore import org.junit.Rule import org.junit.Test import org.mozilla.fenix.customannotations.SmokeTest @@ -14,7 +15,6 @@ import org.mozilla.fenix.helpers.RetryTestRule import org.mozilla.fenix.helpers.TestAssetHelper.getGenericAsset import org.mozilla.fenix.helpers.TestHelper.mDevice import org.mozilla.fenix.helpers.TestHelper.restartApp -import org.mozilla.fenix.helpers.TestHelper.verifySnackBarText import org.mozilla.fenix.helpers.TestSetup import org.mozilla.fenix.helpers.perf.DetectMemoryLeaksRule import org.mozilla.fenix.ui.robots.browserScreen @@ -42,15 +42,16 @@ class SettingsHomepageTest : TestSetup() { // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/1564843 @Test fun verifyHomepageSettingsTest() { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openHomepageSubMenu { verifyHomePageView() } } // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/1564859 + @Ignore("Disabled after enabling the composable toolbar and main menu: https://bugzilla.mozilla.org/show_bug.cgi?id=2006295") @Test fun verifyShortcutOptionTest() { // en-US defaults @@ -60,24 +61,25 @@ class SettingsHomepageTest : TestSetup() { ) val genericURL = mockWebServer.getGenericAsset(1) - homeScreen { + homeScreen(composeTestRule) { defaultTopSites.forEach { item -> - verifyExistingTopSitesTabs(composeTestRule, item) + verifyExistingTopSitesTabs(item) } }.openThreeDotMenu { - }.openCustomizeHome { + }.clickSettingsButton { + }.openHomepageSubMenu { clickShortcutsButton() - }.goBackToHomeScreen { + }.goBack { + }.goBack(composeTestRule) { defaultTopSites.forEach { item -> - verifyNotExistingTopSiteItem(composeTestRule, item) + verifyNotExistingTopSiteItem(item) } } // Disabling the "Shortcuts" homepage setting option should remove the "Add to shortcuts" from main menu option - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(genericURL.url) { }.openThreeDotMenu { - expandMenu() - verifyAddToShortcutsButton(shouldExist = false) + verifyAddToShortcutsButton(isDisplayed = false) } } @@ -89,14 +91,16 @@ class SettingsHomepageTest : TestSetup() { } val genericURL = mockWebServer.getGenericAsset(1) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(genericURL.url) { - }.goToHomescreen(composeTestRule) { + }.goToHomescreen { verifyRecentlyVisitedSectionIsDisplayed(true) }.openThreeDotMenu { - }.openCustomizeHome { + }.clickSettingsButton { + }.openHomepageSubMenu { clickRecentlyVisited() - }.goBackToHomeScreen { + }.goBack { + }.goBack(composeTestRule) { verifyRecentlyVisitedSectionIsDisplayed(false) } } @@ -107,15 +111,17 @@ class SettingsHomepageTest : TestSetup() { fun jumpBackInOptionTest() { val genericURL = mockWebServer.getGenericAsset(1) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(genericURL.url) { - }.goToHomescreen(composeTestRule) { + }.goToHomescreen { verifyJumpBackInSectionIsDisplayed() }.openThreeDotMenu { - }.openCustomizeHome { + }.clickSettingsButton { + }.openHomepageSubMenu { clickJumpBackInButton() - }.goBackToHomeScreen { - verifyJumpBackInSectionIsNotDisplayed(composeTestRule) + }.goBack { + }.goBack(composeTestRule) { + verifyJumpBackInSectionIsNotDisplayed() } } @@ -125,16 +131,18 @@ class SettingsHomepageTest : TestSetup() { fun recentBookmarksOptionTest() { val genericURL = mockWebServer.getGenericAsset(1) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(genericURL.url) { }.openThreeDotMenu { - }.bookmarkPage { - }.goToHomescreen(composeTestRule) { + }.clickBookmarkThisPageButton { + }.goToHomescreen { verifyBookmarksSectionIsDisplayed(exists = true) }.openThreeDotMenu { - }.openCustomizeHome { + }.clickSettingsButton { + }.openHomepageSubMenu { clickRecentBookmarksButton() - }.goBackToHomeScreen { + }.goBack { + }.goBack(composeTestRule) { verifyBookmarksSectionIsDisplayed(exists = false) } } @@ -145,10 +153,10 @@ class SettingsHomepageTest : TestSetup() { fun verifyOpeningScreenOptionsTest() { val genericURL = mockWebServer.getGenericAsset(1) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(genericURL.url) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { verifySettingsOptionSummary("Homepage", "Open on homepage after four hours") }.openHomepageSubMenu { verifySelectedOpeningScreenOption("Homepage after four hours of inactivity") @@ -158,10 +166,10 @@ class SettingsHomepageTest : TestSetup() { restartApp(composeTestRule.activityRule) - homeScreen { + homeScreen(composeTestRule) { verifyHomeScreen() }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { verifySettingsOptionSummary("Homepage", "Open on homepage") }.openHomepageSubMenu { clickOpeningScreenOption("Last tab") @@ -172,7 +180,7 @@ class SettingsHomepageTest : TestSetup() { restartApp(composeTestRule.activityRule) - browserScreen { + browserScreen(composeTestRule) { verifyUrl(genericURL.url.toString()) } } @@ -182,12 +190,13 @@ class SettingsHomepageTest : TestSetup() { fun verifyOpeningScreenAfterLaunchingExternalLinkTest() { val genericPage = mockWebServer.getGenericAsset(1) - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openHomepageSubMenu { clickOpeningScreenOption("Homepage") - }.goBackToHomeScreen {} + }.goBackToHomeScreen(composeTestRule) { + } composeTestRule.activityRule.applySettingsExceptions { it.isTermsOfServiceAccepted = true @@ -199,7 +208,7 @@ class SettingsHomepageTest : TestSetup() { } } - browserScreen { + browserScreen(composeTestRule) { verifyPageContent(genericPage.content) } } diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsPrivacyTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsPrivacyTest.kt @@ -38,9 +38,9 @@ class SettingsPrivacyTest : TestSetup() { // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2092698 @Test fun settingsPrivacyItemsTest() { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { verifySettingsToolbar() verifyPrivacyHeading() verifyPrivateBrowsingButton() @@ -62,7 +62,10 @@ class SettingsPrivacyTest : TestSetup() { // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/243362 @Test fun verifyDataCollectionSettingsTest() { - homeScreen {}.openThreeDotMenu {}.openSettings {}.openSettingsSubMenuDataCollection { + homeScreen(composeTestRule) { + }.openThreeDotMenu { + }.clickSettingsButton { + }.openSettingsSubMenuDataCollection { // Studies depends on the telemetry switch, if telemetry is off studies will be // turned off as well, and will require the app to be restarted. // Daily usage ping should default to telemetry pref value @@ -93,16 +96,16 @@ class SettingsPrivacyTest : TestSetup() { clearNotifications() } - homeScreen { + homeScreen(composeTestRule) { }.togglePrivateBrowsingMode() - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(defaultWebPage.url) { }.openNotificationShade { verifySystemNotificationExists("Close private tabs?") - }.closeNotificationTray { + }.closeNotificationTray(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { verifySettingsOptionSummary("Notifications", "Allowed") }.openSettingsSubMenuNotifications { verifyAllSystemNotificationsToggleState(true) @@ -114,9 +117,9 @@ class SettingsPrivacyTest : TestSetup() { // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2939287 @Test fun verifyTheDailyUsagePingCanBeEnabledAndDisabledTest() { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openSettingsSubMenuDataCollection { verifyDailyUsagePingToggle(composeTestRule, isChecked = true) clickDailyUsagePingToggle(composeTestRule) @@ -127,9 +130,9 @@ class SettingsPrivacyTest : TestSetup() { // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/3215044 @Test fun verifyTheCrashReportsOptionsTest() { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openSettingsSubMenuDataCollection { verifyTheCrashReportsSection(composeTestRule) verifyTheCrashReportOptionStates( diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsPrivateBrowsingTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsPrivateBrowsingTest.kt @@ -25,7 +25,7 @@ class SettingsPrivateBrowsingTest : TestSetup() { private val pageShortcutName = DataGenerationHelper.generateRandomString(5) @get:Rule - val activityTestRule = + val composeTestRule = AndroidComposeTestRule( HomeActivityIntentTestRule.withDefaultSettingsOverrides( skipOnboarding = true, @@ -38,9 +38,9 @@ class SettingsPrivateBrowsingTest : TestSetup() { // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/555822 @Test fun verifyPrivateBrowsingMenuItemsTest() { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openPrivateBrowsingSubMenu { verifyAddPrivateBrowsingShortcutButton() verifyOpenLinksInPrivateTab() @@ -56,33 +56,44 @@ class SettingsPrivateBrowsingTest : TestSetup() { val firstWebPage = mockWebServer.getGenericAsset(1) val secondWebPage = mockWebServer.getGenericAsset(2) - setOpenLinksInPrivateOn() + homeScreen(composeTestRule) { + }.openThreeDotMenu { + }.clickSettingsButton { + }.openPrivateBrowsingSubMenu { + verifyOpenLinksInPrivateTabEnabled() + clickOpenLinksInPrivateTabSwitch() + }.goBack { + }.goBack(composeTestRule) { + } - homeScreen { - verifyHomeComponent(activityTestRule) + homeScreen(composeTestRule) { + verifyHomeComponent() } AppAndSystemHelper.openAppFromExternalLink(firstWebPage.url.toString()) - browserScreen { + browserScreen(composeTestRule) { verifyUrl(firstWebPage.url.toString()) - }.openTabDrawer(activityTestRule) { + }.openTabDrawer(composeTestRule) { verifyPrivateBrowsingButtonIsSelected() }.closeTabDrawer { - }.goToHomescreen(activityTestRule) { } - - setOpenLinksInPrivateOff() - - homeScreen { - verifyHomeComponent(activityTestRule) + }.goToHomescreen(isPrivateModeEnabled = true) { + }.openThreeDotMenu { + }.clickSettingsButton { + }.openPrivateBrowsingSubMenu { + clickOpenLinksInPrivateTabSwitch() + verifyOpenLinksInPrivateTabOff() + }.goBack { + }.goBack(composeTestRule) { + verifyHomeComponent() } // We need to open a different link, otherwise it will open the same session AppAndSystemHelper.openAppFromExternalLink(secondWebPage.url.toString()) - browserScreen { + browserScreen(composeTestRule) { verifyUrl(secondWebPage.url.toString()) - }.openTabDrawer(activityTestRule) { + }.openTabDrawer(composeTestRule) { verifyNormalBrowsingButtonIsSelected() } } @@ -92,16 +103,25 @@ class SettingsPrivateBrowsingTest : TestSetup() { fun launchPageShortcutInPrivateBrowsingTest() { val defaultWebPage = mockWebServer.getGenericAsset(1) - setOpenLinksInPrivateOn() + homeScreen(composeTestRule) { + }.openThreeDotMenu { + }.clickSettingsButton { + }.openPrivateBrowsingSubMenu { + verifyOpenLinksInPrivateTabEnabled() + clickOpenLinksInPrivateTabSwitch() + }.goBack { + }.goBack(composeTestRule) { + } - homeScreen { - verifyHomeComponent(activityTestRule) + homeScreen(composeTestRule) { + verifyHomeComponent() } - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(defaultWebPage.url) { }.openThreeDotMenu { - }.openAddToHomeScreen { + clickTheMoreButton() + }.clickAddToHomeScreenButton { addShortcutName(pageShortcutName) clickAddShortcutButton() clickSystemHomeScreenShortcutAddButton() @@ -110,30 +130,38 @@ class SettingsPrivateBrowsingTest : TestSetup() { mDevice.waitForIdle() // We need to close the existing tab here, to open a different session - restartApp(activityTestRule.activityRule) + restartApp(composeTestRule.activityRule) - browserScreen { - }.openTabDrawer(activityTestRule) { + browserScreen(composeTestRule) { + }.openTabDrawer(composeTestRule) { verifyNormalBrowsingButtonIsSelected() closeTab() } - addToHomeScreen { + addToHomeScreen(composeTestRule) { }.searchAndOpenHomeScreenShortcut(pageShortcutName) { - }.openTabDrawer(activityTestRule) { + }.openTabDrawer(composeTestRule) { verifyPrivateBrowsingButtonIsSelected() closeTab() } - setOpenLinksInPrivateOff() + homeScreen(composeTestRule) { + }.openThreeDotMenu { + }.clickSettingsButton { + }.openPrivateBrowsingSubMenu { + clickOpenLinksInPrivateTabSwitch() + verifyOpenLinksInPrivateTabOff() + }.goBack { + }.goBack(composeTestRule) { + } - homeScreen { - verifyHomeComponent(activityTestRule) + homeScreen(composeTestRule) { + verifyHomeComponent() } - addToHomeScreen { + addToHomeScreen(composeTestRule) { }.searchAndOpenHomeScreenShortcut(pageShortcutName) { - }.openTabDrawer(activityTestRule) { + }.openTabDrawer(composeTestRule) { verifyNormalBrowsingButtonIsSelected() } } @@ -141,42 +169,17 @@ class SettingsPrivateBrowsingTest : TestSetup() { // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/414583 @Test fun addPrivateBrowsingShortcutFromSettingsTest() { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openPrivateBrowsingSubMenu { cancelPrivateShortcutAddition() addPrivateShortcutToHomescreen() verifyPrivateBrowsingShortcutIcon() - }.openPrivateBrowsingShortcut { - verifySearchView() - }.openBrowser { - }.openTabDrawer(activityTestRule) { - verifyPrivateBrowsingButtonIsSelected() + }.openPrivateBrowsingShortcut(composeTestRule) { + } + homeScreen(composeTestRule) { + verifyIfInPrivateOrNormalMode(privateBrowsingEnabled = true) } - } -} - -private fun setOpenLinksInPrivateOn() { - homeScreen { - }.openThreeDotMenu { - }.openSettings { - }.openPrivateBrowsingSubMenu { - verifyOpenLinksInPrivateTabEnabled() - clickOpenLinksInPrivateTabSwitch() - }.goBack { - }.goBack { - } -} - -private fun setOpenLinksInPrivateOff() { - homeScreen { - }.openThreeDotMenu { - }.openSettings { - }.openPrivateBrowsingSubMenu { - clickOpenLinksInPrivateTabSwitch() - verifyOpenLinksInPrivateTabOff() - }.goBack { - }.goBack { } } diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsSearchTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsSearchTest.kt @@ -10,6 +10,7 @@ import androidx.test.filters.SdkSuppress import okhttp3.mockwebserver.MockWebServer import org.junit.After import org.junit.Before +import org.junit.Ignore import org.junit.Rule import org.junit.Test import org.mozilla.fenix.customannotations.SkipLeaks @@ -45,7 +46,7 @@ class SettingsSearchTest : TestSetup() { ) @get:Rule - val activityTestRule = AndroidComposeTestRule( + val composeTestRule = AndroidComposeTestRule( HomeActivityIntentTestRule.withDefaultSettingsOverrides(), ) { it.activity } @@ -70,9 +71,9 @@ class SettingsSearchTest : TestSetup() { // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2203333 @Test fun verifySearchSettingsMenuItemsTest() { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openSearchSubMenu { verifyToolbarText("Search") verifySearchEnginesSectionHeader() @@ -95,9 +96,9 @@ class SettingsSearchTest : TestSetup() { // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2203307 @Test fun verifyDefaultSearchEnginesSettingsItemsTest() { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openSearchSubMenu { verifyDefaultSearchEngineHeader() openDefaultSearchEngineMenu() @@ -113,15 +114,15 @@ class SettingsSearchTest : TestSetup() { fun verifyTheDefaultSearchEngineCanBeChangedTest() { // Goes through the settings and changes the default search engine, then verifies it has changed. defaultSearchEngineList.forEach { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openSearchSubMenu { openDefaultSearchEngineMenu() changeDefaultSearchEngine(it) exitMenu() } - searchScreen { + searchScreen(composeTestRule) { verifySearchEngineIcon(it) } } @@ -134,7 +135,7 @@ class SettingsSearchTest : TestSetup() { // Check if "Top domain" suggestions for the address bar's autocomplete are enabled if (FxNimbus.features.suggestShippedDomains.value().enabled) { // If true it will use the hardcoded list of "top domain" suggestions for the address bar's autocomplete suggestions - homeScreen { + homeScreen(composeTestRule) { }.openSearch { typeSearch("mo") verifyTypedToolbarText("monster.com", exists = true) @@ -146,7 +147,7 @@ class SettingsSearchTest : TestSetup() { createHistoryItem("https://github.com/mozilla-mobile/fenix") createBookmarkItem("https://github.com/mozilla-mobile/focus-android", "focus-android", 1u) - homeScreen { + homeScreen(composeTestRule) { }.openSearch { typeSearch("moz") // "Top domain" suggestions from the address bar's autocomplete are disabled, "moz" shouldn't autocomplete to mozilla.org @@ -173,13 +174,13 @@ class SettingsSearchTest : TestSetup() { // Check if "Top domain" suggestions for the address bar's autocomplete are enabled if (FxNimbus.features.suggestShippedDomains.value().enabled) { // If true it will use the hardcoded list of "top domain" suggestions for the address bar's autocomplete suggestions - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openSearchSubMenu { toggleAutocomplete() }.goBack { - }.goBack { + }.goBack(composeTestRule) { }.openSearch { typeSearch("moz") verifyTypedToolbarText("moz", exists = true) @@ -190,13 +191,13 @@ class SettingsSearchTest : TestSetup() { createHistoryItem("https://github.com/mozilla-mobile/fenix") createBookmarkItem("https://github.com/mozilla-mobile/focus-android", "focus-android", 1u) - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openSearchSubMenu { toggleAutocomplete() }.goBack { - }.goBack { + }.goBack(composeTestRule) { }.openSearch { // Having the setting disabled, it should not autocomplete anymore with the history items url typeSearch("github.com/mozilla-mobile/f") @@ -215,19 +216,18 @@ class SettingsSearchTest : TestSetup() { createHistoryItem(websiteURL) - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openSearchSubMenu { switchSearchHistoryToggle() exitMenu() } - homeScreen { + homeScreen(composeTestRule) { }.openSearch { typeSearch("test") verifySuggestionsAreNotDisplayed( - activityTestRule, "Firefox Suggest", websiteURL, ) @@ -241,9 +241,9 @@ class SettingsSearchTest : TestSetup() { createBookmarkItem(website.url.toString(), website.title, 1u) - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openSearchSubMenu { switchSearchBookmarksToggle() // We want to avoid confusion between history and bookmarks searches, @@ -252,16 +252,15 @@ class SettingsSearchTest : TestSetup() { exitMenu() } - homeScreen { + homeScreen(composeTestRule) { }.openSearch { typeSearch("test") verifySuggestionsAreNotDisplayed( - activityTestRule, "Firefox Suggest", website.title, ) }.dismissSearchBar { - verifyHomeComponent(activityTestRule) + verifyHomeComponent() } } @@ -275,9 +274,9 @@ class SettingsSearchTest : TestSetup() { val url = "http://localhost:${searchMockServer.port}/searchResults.html?search=%s" } - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openSearchSubMenu { openDefaultSearchEngineMenu() openAddSearchEngineMenu() @@ -295,11 +294,11 @@ class SettingsSearchTest : TestSetup() { pressBack() }.goBack { verifySettingsOptionSummary("Search", customSearchEngine.title) - }.goBack { + }.goBack(composeTestRule) { }.openSearch { verifySearchEngineIcon(customSearchEngine.title) clickSearchSelectorButton() - verifySearchShortcutListContains(customSearchEngine.title) + verifySearchShortcutList(customSearchEngine.title, isSearchEngineDisplayed = true) } } @@ -311,9 +310,9 @@ class SettingsSearchTest : TestSetup() { val url = "http://localhost:${searchMockServer.port}/searchResults.html?search=%s" } - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openSearchSubMenu { openManageShortcutsMenu() openAddSearchEngineMenu() @@ -329,20 +328,20 @@ class SettingsSearchTest : TestSetup() { // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2203343 @Test fun verifyLearnMoreLinksFromAddSearchEngineSectionTest() { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openSearchSubMenu { openDefaultSearchEngineMenu() openAddSearchEngineMenu() - }.clickCustomSearchStringLearnMoreLink { + }.clickCustomSearchStringLearnMoreLink(composeTestRule) { verifyCustomSearchEngineLearnMoreURL() }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openSearchSubMenu { openDefaultSearchEngineMenu() openAddSearchEngineMenu() - }.clickCustomSearchSuggestionsLearnMoreLink { + }.clickCustomSearchSuggestionsLearnMoreLink(composeTestRule) { verifyCustomSearchEngineLearnMoreURL() } } @@ -357,11 +356,11 @@ class SettingsSearchTest : TestSetup() { } addCustomSearchEngine(searchMockServer, customSearchEngine.title) - restartApp(activityTestRule.activityRule) + restartApp(composeTestRule.activityRule) - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openSearchSubMenu { openDefaultSearchEngineMenu() verifyEngineListContains(customSearchEngine.title, shouldExist = true) @@ -386,9 +385,9 @@ class SettingsSearchTest : TestSetup() { val goodUrl = "http://localhost:${searchMockServer.port}/searchResults.html?search=%s" } - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openSearchSubMenu { openDefaultSearchEngineMenu() openAddSearchEngineMenu() @@ -411,11 +410,11 @@ class SettingsSearchTest : TestSetup() { val customSearchEngineTitle = "TestSearchEngine" addCustomSearchEngine(mockWebServer, searchEngineName = customSearchEngineTitle) - restartApp(activityTestRule.activityRule) + restartApp(composeTestRule.activityRule) - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openSearchSubMenu { openDefaultSearchEngineMenu() verifyEngineListContains(customSearchEngineTitle, shouldExist = true) @@ -428,9 +427,9 @@ class SettingsSearchTest : TestSetup() { verifyEngineListContains(customSearchEngineTitle, shouldExist = false) exitMenu() } - searchScreen { + searchScreen(composeTestRule) { clickSearchSelectorButton() - verifySearchShortcutListContains(customSearchEngineTitle, shouldExist = false) + verifySearchShortcutList(customSearchEngineTitle, isSearchEngineDisplayed = false) } } @@ -440,25 +439,25 @@ class SettingsSearchTest : TestSetup() { val customSearchEngineTitle = "TestSearchEngine" addCustomSearchEngine(mockWebServer, searchEngineName = customSearchEngineTitle) - restartApp(activityTestRule.activityRule) + restartApp(composeTestRule.activityRule) - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openSearchSubMenu { openManageShortcutsMenu() verifyEngineListContains(customSearchEngineTitle, shouldExist = true) - openCustomShortcutOverflowMenu(activityTestRule, customSearchEngineTitle) - clickDeleteSearchEngine(activityTestRule) + openCustomShortcutOverflowMenu(composeTestRule, customSearchEngineTitle) + clickDeleteSearchEngine(composeTestRule) verifyEngineListContains(customSearchEngineTitle, shouldExist = false) pressBack() openDefaultSearchEngineMenu() verifyEngineListContains(customSearchEngineTitle, shouldExist = false) exitMenu() } - searchScreen { + searchScreen(composeTestRule) { clickSearchSelectorButton() - verifySearchShortcutListContains(customSearchEngineTitle, shouldExist = false) + verifySearchShortcutList(customSearchEngineTitle, isSearchEngineDisplayed = false) } } @@ -469,28 +468,28 @@ class SettingsSearchTest : TestSetup() { @SmokeTest @Test fun verifyShowSearchSuggestionsToggleTest() { - homeScreen { + homeScreen(composeTestRule) { }.openSearch { // The Google related suggestions aren't always displayed on cold run // Bugzilla ticket: https://bugzilla.mozilla.org/show_bug.cgi?id=1813587 clickSearchSelectorButton() selectTemporarySearchMethod("DuckDuckGo") typeSearch("mozilla ") - verifySearchSuggestionsAreDisplayed(activityTestRule, "mozilla firefox") + verifySearchSuggestionsAreDisplayed("mozilla firefox") }.dismissSearchBar { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openSearchSubMenu { toggleShowSearchSuggestions() }.goBack { - }.goBack { + }.goBack(composeTestRule) { }.openSearch { // The Google related suggestions aren't always displayed on cold run // Bugzilla ticket: https://bugzilla.mozilla.org/show_bug.cgi?id=1813587 clickSearchSelectorButton() selectTemporarySearchMethod("DuckDuckGo") typeSearch("mozilla") - verifySuggestionsAreNotDisplayed(activityTestRule, "mozilla firefox") + verifySuggestionsAreNotDisplayed("mozilla firefox") } } @@ -498,13 +497,13 @@ class SettingsSearchTest : TestSetup() { // Tests the "Don't allow" option from private mode search suggestions onboarding dialog @Test fun doNotAllowSearchSuggestionsInPrivateBrowsingTest() { - homeScreen { - togglePrivateBrowsingModeOnOff(composeTestRule = activityTestRule) + homeScreen(composeTestRule) { + togglePrivateBrowsingModeOnOff() }.openSearch { typeSearch("mozilla") verifyAllowSuggestionsInPrivateModeDialog() denySuggestionsInPrivateMode() - verifySuggestionsAreNotDisplayed(activityTestRule, "mozilla firefox") + verifySuggestionsAreNotDisplayed("mozilla firefox") } } @@ -512,23 +511,23 @@ class SettingsSearchTest : TestSetup() { // Tests the "Allow" option from private mode search suggestions onboarding dialog @Test fun allowSearchSuggestionsInPrivateBrowsingTest() { - homeScreen { - togglePrivateBrowsingModeOnOff(composeTestRule = activityTestRule) + homeScreen(composeTestRule) { + togglePrivateBrowsingModeOnOff() }.openSearch { typeSearch("mozilla") verifyAllowSuggestionsInPrivateModeDialog() allowSuggestionsInPrivateMode() - verifySearchSuggestionsAreDisplayed(activityTestRule, "mozilla firefox") + verifySearchSuggestionsAreDisplayed("mozilla firefox") }.dismissSearchBar { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openSearchSubMenu { switchShowSuggestionsInPrivateSessionsToggle() }.goBack { - }.goBack { + }.goBack(composeTestRule) { }.openSearch { typeSearch("mozilla") - verifySuggestionsAreNotDisplayed(activityTestRule, "mozilla firefox") + verifySuggestionsAreNotDisplayed("mozilla firefox") } } @@ -536,61 +535,62 @@ class SettingsSearchTest : TestSetup() { @SdkSuppress(minSdkVersion = 34) @Test fun verifyShowVoiceSearchToggleTest() { - homeScreen { + homeScreen(composeTestRule) { }.openSearch { - verifyVoiceSearchButtonVisibility(true) + verifyVoiceSearchButton(isDisplayed = true) startVoiceSearch() + closeVoiceSearchDialog() }.dismissSearchBar { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openSearchSubMenu { toggleVoiceSearch() exitMenu() } - homeScreen { + homeScreen(composeTestRule) { }.openSearch { - verifyVoiceSearchButtonVisibility(false) + verifyVoiceSearchButton(isDisplayed = false) } } // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/412927 + @Ignore("Disabled after enabling the composable toolbar and main menu: https://bugzilla.mozilla.org/show_bug.cgi?id=2006295") @Test fun verifyShowClipboardSuggestionsToggleTest() { val link = "https://www.mozilla.org/en-US/" setTextToClipBoard(appContext, link) - homeScreen { - }.openNavigationToolbar { + navigationToolbar(composeTestRule) { verifyClipboardSuggestionsAreDisplayed(link, true) }.visitLinkFromClipboard { waitForPageToLoad(pageLoadWaitingTime = waitingTimeLong) - }.openTabDrawer(activityTestRule) { + }.openTabDrawer(composeTestRule) { }.openNewTab { } - navigationToolbar { + navigationToolbar(composeTestRule) { // After visiting the link from clipboard it shouldn't be displayed again verifyClipboardSuggestionsAreDisplayed(shouldBeDisplayed = false) }.goBackToHomeScreen { setTextToClipBoard(appContext, link) - }.openTabDrawer(activityTestRule) { + }.openTabDrawer { }.openNewTab { } - navigationToolbar { + navigationToolbar(composeTestRule) { verifyClipboardSuggestionsAreDisplayed(link, true) }.goBackToHomeScreen { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openSearchSubMenu { verifyShowClipboardSuggestionsEnabled(true) toggleClipboardSuggestion() verifyShowClipboardSuggestionsEnabled(false) exitMenu() } - homeScreen { - }.openTabDrawer(activityTestRule) { + homeScreen(composeTestRule) { + }.openTabDrawer { }.openNewTab { } - navigationToolbar { + navigationToolbar(composeTestRule) { verifyClipboardSuggestionsAreDisplayed(link, false) } } @@ -599,31 +599,30 @@ class SettingsSearchTest : TestSetup() { @Test @SkipLeaks fun verifyTheSearchEnginesListsRespectTheLocaleTest() { - runWithAppLocaleChanged(Locale.CHINA, activityTestRule.activityRule) { - // Checking search engines for CH locale - homeScreen { - }.openSearch { - clickSearchSelectorButton() - verifySearchShortcutListContains( + runWithAppLocaleChanged(Locale.CHINA, composeTestRule.activityRule) { + navigationToolbar(composeTestRule) { + }.clickSearchSelectorButton { + verifySearchShortcutList( "Google", "百度", "Bing", "DuckDuckGo", + isSearchEngineDisplayed = true, ) }.dismissSearchBar {} } - runWithAppLocaleChanged(Locale.FRENCH, activityTestRule.activityRule) { - // Checking search engines for FR locale - homeScreen { - }.openSearch { + runWithAppLocaleChanged(Locale.FRENCH, composeTestRule.activityRule) { + navigationToolbar(composeTestRule) { + }.clickSearchSelectorButton { clickSearchSelectorButton() - verifySearchShortcutListContains( + verifySearchShortcutList( "Google", "Bing", "DuckDuckGo", "Qwant", "Wikipédia (fr)", + isSearchEngineDisplayed = true, ) } } @@ -632,14 +631,14 @@ class SettingsSearchTest : TestSetup() { // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2203334 @Test fun verifyManageSearchShortcutsSettingsItemsTest() { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openSearchSubMenu { openManageShortcutsMenu() verifyToolbarText("Manage alternative search engines") verifyEnginesShortcutsListHeader() - verifyManageShortcutsList(activityTestRule) + verifyManageShortcutsList(composeTestRule) verifySearchShortcutChecked( EngineShortcut(name = "Google", checkboxIndex = 1, isChecked = true), EngineShortcut(name = "Bing", checkboxIndex = 4, isChecked = true), @@ -655,9 +654,9 @@ class SettingsSearchTest : TestSetup() { @SmokeTest @Test fun verifySearchShortcutChangesAreReflectedInSearchSelectorMenuTest() { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openSearchSubMenu { openManageShortcutsMenu() selectSearchShortcut(EngineShortcut(name = "Google", checkboxIndex = 1)) @@ -665,11 +664,11 @@ class SettingsSearchTest : TestSetup() { selectSearchShortcut(EngineShortcut(name = "YouTube", checkboxIndex = 16)) exitMenu() } - searchScreen { + searchScreen(composeTestRule) { clickSearchSelectorButton() - verifySearchShortcutListContains("Google", shouldExist = false) - verifySearchShortcutListContains("YouTube", shouldExist = true) - verifySearchShortcutListContains("Reddit", shouldExist = true) + verifySearchShortcutList("Google", isSearchEngineDisplayed = false) + verifySearchShortcutList("YouTube", isSearchEngineDisplayed = true) + verifySearchShortcutList("Reddit", isSearchEngineDisplayed = true) } } } diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsSitePermissionsTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsSitePermissionsTest.kt @@ -14,6 +14,7 @@ import org.junit.Test import org.mozilla.fenix.customannotations.SkipLeaks import org.mozilla.fenix.customannotations.SmokeTest import org.mozilla.fenix.helpers.AppAndSystemHelper.grantSystemPermission +import org.mozilla.fenix.helpers.HomeActivityIntentTestRule import org.mozilla.fenix.helpers.HomeActivityTestRule import org.mozilla.fenix.helpers.MatcherHelper.itemWithText import org.mozilla.fenix.helpers.TestAssetHelper.getGenericAsset @@ -21,6 +22,7 @@ import org.mozilla.fenix.helpers.TestAssetHelper.mutedVideoPageAsset import org.mozilla.fenix.helpers.TestAssetHelper.videoPageAsset import org.mozilla.fenix.helpers.TestAssetHelper.waitingTimeLong import org.mozilla.fenix.helpers.TestHelper.exitMenu +import org.mozilla.fenix.helpers.TestHelper.waitForAppWindowToBeUpdated import org.mozilla.fenix.helpers.TestSetup import org.mozilla.fenix.helpers.perf.DetectMemoryLeaksRule import org.mozilla.fenix.ui.robots.browserScreen @@ -41,7 +43,7 @@ class SettingsSitePermissionsTest : TestSetup() { private val permissionsTestPageHost = "mozilla-mobile.github.io" @get:Rule - val activityTestRule = AndroidComposeTestRule( + val composeTestRule = AndroidComposeTestRule( HomeActivityTestRule( isPWAsPromptEnabled = false, isDeleteSitePermissionsEnabled = true, @@ -54,9 +56,9 @@ class SettingsSitePermissionsTest : TestSetup() { // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/246974 @Test fun sitePermissionsItemsTest() { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openSettingsSubMenuSiteSettings { verifySiteSettingsToolbarTitle() verifyToolbarGoBackButton() @@ -82,9 +84,9 @@ class SettingsSitePermissionsTest : TestSetup() { @Test @SdkSuppress(minSdkVersion = 29) fun systemBlockedPermissionsRedirectToSystemAppSettingsTest() { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openSettingsSubMenuSiteSettings { }.openCamera { verifyBlockedByAndroidSection() @@ -123,32 +125,30 @@ class SettingsSitePermissionsTest : TestSetup() { val genericPage = mockWebServer.getGenericAsset(1) val videoTestPage = mockWebServer.videoPageAsset - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openSettingsSubMenuSiteSettings { }.openAutoPlay { verifySitePermissionsAutoPlaySubMenuItems() exitMenu() } - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(genericPage.url) { verifyPageContent(genericPage.content) - }.openTabDrawer(activityTestRule) { - closeTab() } - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(videoTestPage.url) { try { verifyPageContent(videoTestPage.content) - clickPageObject(itemWithText("Play")) + clickPageObject(composeTestRule, itemWithText("Play")) assertPlaybackState(browserStore, MediaSession.PlaybackState.PLAYING) } catch (e: AssertionError) { - navigationToolbar { + browserScreen(composeTestRule) { }.openThreeDotMenu { - }.refreshPage { + }.clickRefreshButton { verifyPageContent(videoTestPage.content) - clickPageObject(itemWithText("Play")) + clickPageObject(composeTestRule, itemWithText("Play")) assertPlaybackState(browserStore, MediaSession.PlaybackState.PLAYING) } } @@ -162,20 +162,18 @@ class SettingsSitePermissionsTest : TestSetup() { val genericPage = mockWebServer.getGenericAsset(1) val mutedVideoTestPage = mockWebServer.mutedVideoPageAsset - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(genericPage.url) { verifyPageContent(genericPage.content) - }.openTabDrawer(activityTestRule) { - closeTab() } - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(mutedVideoTestPage.url) { try { verifyPageContent("Media file is playing") } catch (e: AssertionError) { - navigationToolbar { + browserScreen(composeTestRule) { }.openThreeDotMenu { - }.refreshPage { + }.clickRefreshButton { verifyPageContent("Media file is playing") } } @@ -189,29 +187,27 @@ class SettingsSitePermissionsTest : TestSetup() { val genericPage = mockWebServer.getGenericAsset(1) val videoTestPage = mockWebServer.videoPageAsset - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openSettingsSubMenuSiteSettings { }.openAutoPlay { selectAutoplayOption("Allow audio and video") exitMenu() } - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(genericPage.url) { verifyPageContent(genericPage.content) - }.openTabDrawer(activityTestRule) { - closeTab() } - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(videoTestPage.url) { try { verifyPageContent(videoTestPage.content) assertPlaybackState(browserStore, MediaSession.PlaybackState.PLAYING) } catch (e: AssertionError) { - navigationToolbar { + browserScreen(composeTestRule) { }.openThreeDotMenu { - }.refreshPage { + }.clickRefreshButton { verifyPageContent(videoTestPage.content) assertPlaybackState(browserStore, MediaSession.PlaybackState.PLAYING) } @@ -224,22 +220,22 @@ class SettingsSitePermissionsTest : TestSetup() { fun verifyAutoplayAllowAudioVideoSettingOnMutedVideoTest() { val mutedVideoTestPage = mockWebServer.mutedVideoPageAsset - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openSettingsSubMenuSiteSettings { }.openAutoPlay { selectAutoplayOption("Allow audio and video") exitMenu() } - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(mutedVideoTestPage.url) { try { verifyPageContent("Media file is playing") } catch (e: AssertionError) { - navigationToolbar { + browserScreen(composeTestRule) { }.openThreeDotMenu { - }.refreshPage { + }.clickRefreshButton { verifyPageContent("Media file is playing") } } @@ -252,26 +248,26 @@ class SettingsSitePermissionsTest : TestSetup() { fun verifyAutoplayBlockAudioAndVideoSettingOnNotMutedVideoTest() { val videoTestPage = mockWebServer.videoPageAsset - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openSettingsSubMenuSiteSettings { }.openAutoPlay { selectAutoplayOption("Block audio and video") exitMenu() } - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(videoTestPage.url) { try { verifyPageContent(videoTestPage.content) - clickPageObject(itemWithText("Play")) + clickPageObject(composeTestRule, itemWithText("Play")) assertPlaybackState(browserStore, MediaSession.PlaybackState.PLAYING) } catch (e: AssertionError) { - navigationToolbar { + browserScreen(composeTestRule) { }.openThreeDotMenu { - }.refreshPage { + }.clickRefreshButton { verifyPageContent(videoTestPage.content) - clickPageObject(itemWithText("Play")) + clickPageObject(composeTestRule, itemWithText("Play")) assertPlaybackState(browserStore, MediaSession.PlaybackState.PLAYING) } } @@ -284,25 +280,25 @@ class SettingsSitePermissionsTest : TestSetup() { fun verifyAutoplayBlockAudioAndVideoSettingOnMutedVideoTest() { val mutedVideoTestPage = mockWebServer.mutedVideoPageAsset - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openSettingsSubMenuSiteSettings { }.openAutoPlay { selectAutoplayOption("Block audio and video") exitMenu() } - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(mutedVideoTestPage.url) { verifyPageContent("Media file not playing") - clickPageObject(itemWithText("Play")) + clickPageObject(composeTestRule, itemWithText("Play")) try { verifyPageContent("Media file is playing") } catch (e: AssertionError) { - navigationToolbar { + browserScreen(composeTestRule) { }.openThreeDotMenu { - }.refreshPage { - clickPageObject(itemWithText("Play")) + }.clickRefreshButton { + clickPageObject(composeTestRule, itemWithText("Play")) verifyPageContent("Media file is playing") } } @@ -312,17 +308,17 @@ class SettingsSitePermissionsTest : TestSetup() { // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/247362 @Test fun verifyCameraPermissionSettingsTest() { - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(permissionsTestPage.toUri()) { }.clickStartCameraButton { grantSystemPermission() verifyCameraPermissionPrompt(permissionsTestPageHost) pressBack() } - browserScreen { - navigationToolbar { + browserScreen(composeTestRule) { + browserScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openSettingsSubMenuSiteSettings { }.openCamera { verifySitePermissionsCommonSubMenuItems() @@ -330,7 +326,7 @@ class SettingsSitePermissionsTest : TestSetup() { exitMenu() } }.clickStartCameraButton {} - browserScreen { + browserScreen(composeTestRule) { verifyPageContent("Camera not allowed") } } @@ -338,17 +334,17 @@ class SettingsSitePermissionsTest : TestSetup() { // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/247364 @Test fun verifyMicrophonePermissionSettingsTest() { - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(permissionsTestPage.toUri()) { }.clickStartMicrophoneButton { grantSystemPermission() verifyMicrophonePermissionPrompt(permissionsTestPageHost) pressBack() } - browserScreen { - navigationToolbar { + browserScreen(composeTestRule) { + browserScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openSettingsSubMenuSiteSettings { }.openMicrophone { verifySitePermissionsCommonSubMenuItems() @@ -356,7 +352,7 @@ class SettingsSitePermissionsTest : TestSetup() { exitMenu() } }.clickStartMicrophoneButton {} - browserScreen { + browserScreen(composeTestRule) { verifyPageContent("Microphone not allowed") } } @@ -364,16 +360,16 @@ class SettingsSitePermissionsTest : TestSetup() { // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/247363 @Test fun verifyLocationPermissionSettingsTest() { - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(permissionsTestPage.toUri()) { }.clickGetLocationButton { verifyLocationPermissionPrompt(permissionsTestPageHost) pressBack() } - browserScreen { - navigationToolbar { + browserScreen(composeTestRule) { + browserScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openSettingsSubMenuSiteSettings { }.openLocation { verifySitePermissionsCommonSubMenuItems() @@ -381,7 +377,7 @@ class SettingsSitePermissionsTest : TestSetup() { exitMenu() } }.clickGetLocationButton {} - browserScreen { + browserScreen(composeTestRule) { verifyPageContent("User denied geolocation prompt") } } @@ -389,16 +385,16 @@ class SettingsSitePermissionsTest : TestSetup() { // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/247365 @Test fun verifyNotificationsPermissionSettingsTest() { - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(permissionsTestPage.toUri()) { }.clickOpenNotificationButton { verifyNotificationsPermissionPrompt(permissionsTestPageHost) pressBack() } - browserScreen { - navigationToolbar { + browserScreen(composeTestRule) { + browserScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openSettingsSubMenuSiteSettings { }.openNotification { verifyNotificationSubMenuItems() @@ -406,7 +402,7 @@ class SettingsSitePermissionsTest : TestSetup() { exitMenu() } }.clickOpenNotificationButton {} - browserScreen { + browserScreen(composeTestRule) { verifyPageContent("Notifications not allowed") } } @@ -414,16 +410,16 @@ class SettingsSitePermissionsTest : TestSetup() { // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/1923415 @Test fun verifyPersistentStoragePermissionSettingsTest() { - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(permissionsTestPage.toUri()) { }.clickRequestPersistentStorageAccessButton { verifyPersistentStoragePermissionPrompt(permissionsTestPageHost) pressBack() } - browserScreen { - navigationToolbar { + browserScreen(composeTestRule) { + browserScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openSettingsSubMenuSiteSettings { }.openPersistentStorage { verifySitePermissionsPersistentStorageSubMenuItems() @@ -431,7 +427,7 @@ class SettingsSitePermissionsTest : TestSetup() { exitMenu() } }.clickRequestPersistentStorageAccessButton {} - browserScreen { + browserScreen(composeTestRule) { verifyPageContent("Persistent storage permission denied") } } @@ -439,38 +435,37 @@ class SettingsSitePermissionsTest : TestSetup() { // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/1923417 @Test fun verifyDRMControlledContentPermissionSettingsTest() { - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(permissionsTestPage.toUri()) { }.clickRequestDRMControlledContentAccessButton { verifyDRMContentPermissionPrompt(permissionsTestPageHost) pressBack() - browserScreen { + browserScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openSettingsSubMenuSiteSettings { }.openDRMControlledContent { verifyDRMControlledContentSubMenuItems() selectDRMControlledContentPermissionSettingOption("Blocked") exitMenu() } - browserScreen { + browserScreen(composeTestRule) { }.clickRequestDRMControlledContentAccessButton {} - browserScreen { - verifyPageContent("DRM-controlled content not allowed") + browserScreen(composeTestRule) { + verifyDRMControlledContentPageContent("DRM-controlled content not allowed") }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openSettingsSubMenuSiteSettings { }.openDRMControlledContent { selectDRMControlledContentPermissionSettingOption("Allowed") exitMenu() } - browserScreen { + browserScreen(composeTestRule) { }.openThreeDotMenu { - }.refreshPage { - waitForPageToLoad(pageLoadWaitingTime = waitingTimeLong) + }.clickRefreshButton { }.clickRequestDRMControlledContentAccessButton {} - browserScreen { - verifyPageContent("DRM-controlled content allowed") + browserScreen(composeTestRule) { + verifyDRMControlledContentPageContent("DRM-controlled content allowed") } } } @@ -479,13 +474,13 @@ class SettingsSitePermissionsTest : TestSetup() { @SmokeTest @Test fun clearAllSitePermissionsExceptionsTest() { - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(permissionsTestPage.toUri()) { }.clickOpenNotificationButton { verifyNotificationsPermissionPrompt(permissionsTestPageHost) }.clickPagePermissionButton(true) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openSettingsSubMenuSiteSettings { }.openExceptions { verifyExceptionCreated(permissionsTestPageOrigin, true) @@ -501,13 +496,13 @@ class SettingsSitePermissionsTest : TestSetup() { // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/247007 @Test fun addAndClearOneWebPagePermission() { - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(permissionsTestPage.toUri()) { }.clickOpenNotificationButton { verifyNotificationsPermissionPrompt(permissionsTestPageHost) }.clickPagePermissionButton(true) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openSettingsSubMenuSiteSettings { }.openExceptions { verifyExceptionCreated(permissionsTestPageOrigin, true) @@ -524,13 +519,13 @@ class SettingsSitePermissionsTest : TestSetup() { // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/326477 @Test fun clearIndividuallyAWebPagePermission() { - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(permissionsTestPage.toUri()) { }.clickOpenNotificationButton { verifyNotificationsPermissionPrompt(permissionsTestPageHost) }.clickPagePermissionButton(true) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openSettingsSubMenuSiteSettings { }.openExceptions { verifyExceptionCreated(permissionsTestPageOrigin, true) diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SitePermissionsTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SitePermissionsTest.kt @@ -40,7 +40,7 @@ class SitePermissionsTest : TestSetup() { private val cameraManager = appContext.getSystemService(Context.CAMERA_SERVICE) as CameraManager private val micManager = appContext.getSystemService(Context.AUDIO_SERVICE) as AudioManager - @get:Rule(order = 0) + @get:Rule val composeTestRule = AndroidComposeTestRule( HomeActivityIntentTestRule( isPWAsPromptEnabled = false, @@ -81,7 +81,7 @@ class SitePermissionsTest : TestSetup() { fun audioVideoPermissionWithoutRememberingTheDecisionTest() { assumeTrue(cameraManager.cameraIdList.isNotEmpty()) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(testPage.toUri()) { waitForPageToLoad(pageLoadWaitingTime = waitingTimeLong) }.clickStartAudioVideoButton { @@ -100,7 +100,7 @@ class SitePermissionsTest : TestSetup() { assumeTrue(cameraManager.cameraIdList.isNotEmpty()) assumeTrue(micManager.microphones.isNotEmpty()) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(testPage.toUri()) { waitForPageToLoad(pageLoadWaitingTime = waitingTimeLong) }.clickStartAudioVideoButton { @@ -109,10 +109,10 @@ class SitePermissionsTest : TestSetup() { }.clickPagePermissionButton(false) { verifyPageContent("Camera and Microphone not allowed") }.openThreeDotMenu { - }.refreshPage { + }.clickRefreshButton { waitForPageToLoad(pageLoadWaitingTime = waitingTimeLong) }.clickStartAudioVideoButton { } - browserScreen { + browserScreen(composeTestRule) { verifyPageContent("Camera and Microphone not allowed") } } @@ -123,7 +123,7 @@ class SitePermissionsTest : TestSetup() { assumeTrue(cameraManager.cameraIdList.isNotEmpty()) assumeTrue(micManager.microphones.isNotEmpty()) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(testPage.toUri()) { waitForPageToLoad(pageLoadWaitingTime = waitingTimeLong) }.clickStartAudioVideoButton { @@ -132,10 +132,10 @@ class SitePermissionsTest : TestSetup() { }.clickPagePermissionButton(true) { verifyPageContent("Camera and Microphone allowed") }.openThreeDotMenu { - }.refreshPage { + }.clickRefreshButton { waitForPageToLoad(pageLoadWaitingTime = waitingTimeLong) }.clickStartAudioVideoButton { } - browserScreen { + browserScreen(composeTestRule) { verifyPageContent("Camera and Microphone allowed") } } @@ -145,7 +145,7 @@ class SitePermissionsTest : TestSetup() { fun microphonePermissionWithoutRememberingTheDecisionTest() { assumeTrue(micManager.microphones.isNotEmpty()) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(testPage.toUri()) { waitForPageToLoad(pageLoadWaitingTime = waitingTimeLong) }.clickStartMicrophoneButton { @@ -163,7 +163,7 @@ class SitePermissionsTest : TestSetup() { fun blockMicrophonePermissionRememberingTheDecisionTest() { assumeTrue(micManager.microphones.isNotEmpty()) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(testPage.toUri()) { waitForPageToLoad(pageLoadWaitingTime = waitingTimeLong) }.clickStartMicrophoneButton { @@ -172,10 +172,10 @@ class SitePermissionsTest : TestSetup() { }.clickPagePermissionButton(false) { verifyPageContent("Microphone not allowed") }.openThreeDotMenu { - }.refreshPage { + }.clickRefreshButton { waitForPageToLoad(pageLoadWaitingTime = waitingTimeLong) }.clickStartMicrophoneButton { } - browserScreen { + browserScreen(composeTestRule) { verifyPageContent("Microphone not allowed") } } @@ -185,7 +185,7 @@ class SitePermissionsTest : TestSetup() { fun allowMicrophonePermissionRememberingTheDecisionTest() { assumeTrue(micManager.microphones.isNotEmpty()) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(testPage.toUri()) { waitForPageToLoad(pageLoadWaitingTime = waitingTimeLong) }.clickStartMicrophoneButton { @@ -194,10 +194,10 @@ class SitePermissionsTest : TestSetup() { }.clickPagePermissionButton(true) { verifyPageContent("Microphone allowed") }.openThreeDotMenu { - }.refreshPage { + }.clickRefreshButton { waitForPageToLoad(pageLoadWaitingTime = waitingTimeLong) }.clickStartMicrophoneButton { } - browserScreen { + browserScreen(composeTestRule) { verifyPageContent("Microphone allowed") } } @@ -207,7 +207,7 @@ class SitePermissionsTest : TestSetup() { fun cameraPermissionWithoutRememberingDecisionTest() { assumeTrue(cameraManager.cameraIdList.isNotEmpty()) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(testPage.toUri()) { waitForPageToLoad(pageLoadWaitingTime = waitingTimeLong) }.clickStartCameraButton { @@ -225,7 +225,7 @@ class SitePermissionsTest : TestSetup() { fun blockCameraPermissionRememberingTheDecisionTest() { assumeTrue(cameraManager.cameraIdList.isNotEmpty()) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(testPage.toUri()) { waitForPageToLoad(pageLoadWaitingTime = waitingTimeLong) }.clickStartCameraButton { @@ -234,10 +234,10 @@ class SitePermissionsTest : TestSetup() { }.clickPagePermissionButton(false) { verifyPageContent("Camera not allowed") }.openThreeDotMenu { - }.refreshPage { + }.clickRefreshButton { waitForPageToLoad(pageLoadWaitingTime = waitingTimeLong) }.clickStartCameraButton { } - browserScreen { + browserScreen(composeTestRule) { verifyPageContent("Camera not allowed") } } @@ -247,7 +247,7 @@ class SitePermissionsTest : TestSetup() { fun allowCameraPermissionRememberingTheDecisionTest() { assumeTrue(cameraManager.cameraIdList.isNotEmpty()) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(testPage.toUri()) { waitForPageToLoad(pageLoadWaitingTime = waitingTimeLong) }.clickStartCameraButton { @@ -256,10 +256,10 @@ class SitePermissionsTest : TestSetup() { }.clickPagePermissionButton(true) { verifyPageContent("Camera allowed") }.openThreeDotMenu { - }.refreshPage { + }.clickRefreshButton { waitForPageToLoad(pageLoadWaitingTime = waitingTimeLong) }.clickStartCameraButton { } - browserScreen { + browserScreen(composeTestRule) { verifyPageContent("Camera allowed") } } @@ -268,14 +268,14 @@ class SitePermissionsTest : TestSetup() { @SmokeTest @Test fun blockNotificationsPermissionTest() { - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(testPage.toUri()) { }.clickOpenNotificationButton { verifyNotificationsPermissionPrompt(testPageHost) }.clickPagePermissionButton(false) { verifyPageContent("Notifications not allowed") }.openThreeDotMenu { - }.refreshPage { + }.clickRefreshButton { waitForPageToLoad(pageLoadWaitingTime = waitingTimeLong) }.clickOpenNotificationButton { verifyNotificationsPermissionPrompt(testPageHost, true) @@ -285,7 +285,7 @@ class SitePermissionsTest : TestSetup() { // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/251380 @Test fun allowNotificationsPermissionTest() { - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(testPage.toUri()) { }.clickOpenNotificationButton { verifyNotificationsPermissionPrompt(testPageHost) @@ -300,7 +300,7 @@ class SitePermissionsTest : TestSetup() { fun allowLocationPermissionsTest() { mockLocationUpdatesRule.setMockLocation() - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(testPage.toUri()) { }.clickGetLocationButton { verifyLocationPermissionPrompt(testPageHost) @@ -313,7 +313,7 @@ class SitePermissionsTest : TestSetup() { // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2334075 @Test fun blockLocationPermissionsTest() { - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(testPage.toUri()) { }.clickGetLocationButton { verifyLocationPermissionPrompt(testPageHost) @@ -324,10 +324,10 @@ class SitePermissionsTest : TestSetup() { @Test fun doNotAskAgainIsHiddenForLocationPermissionInPrivateMode() { - homeScreen { + homeScreen(composeTestRule) { }.togglePrivateBrowsingMode() - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(testPage.toUri()) { }.clickGetLocationButton { verifyLocationPermissionPrompt(testPageHost) @@ -342,10 +342,11 @@ class SitePermissionsTest : TestSetup() { val originHost = "mozilla-mobile.github.io" val currentHost = "localhost" - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(genericWebPage.url) { waitForPageToLoad() - }.openNavigationToolbar { + } + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(testPage) { waitForPageToLoad() }.clickRequestStorageAccessButton { diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SponsoredShortcutsTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SponsoredShortcutsTest.kt @@ -22,6 +22,7 @@ import org.mozilla.fenix.helpers.TestHelper.waitForAppWindowToBeUpdated import org.mozilla.fenix.helpers.TestSetup import org.mozilla.fenix.helpers.perf.DetectMemoryLeaksRule import org.mozilla.fenix.ui.robots.homeScreen +import org.mozilla.fenix.ui.robots.navigationToolbar /** * Tests Sponsored shortcuts functionality @@ -32,7 +33,7 @@ class SponsoredShortcutsTest : TestSetup() { private lateinit var sponsoredShortcutTitle2: String @get:Rule - val activityIntentTestRule = AndroidComposeTestRule( + val composeTestRule = AndroidComposeTestRule( HomeActivityIntentTestRule.withDefaultSettingsOverrides(skipOnboarding = true), ) { it.activity } @@ -46,11 +47,11 @@ class SponsoredShortcutsTest : TestSetup() { for (i in 1..RETRY_COUNT) { Log.i(TAG, "setUp: Started try #$i") try { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { - }.goBack { - verifyExistingTopSitesList(activityIntentTestRule) + }.clickSettingsButton { + }.goBack(composeTestRule) { + verifyExistingTopSitesList() } break @@ -69,17 +70,19 @@ class SponsoredShortcutsTest : TestSetup() { @SmokeTest @Test fun verifySponsoredShortcutsListTest() { - homeScreen { - verifyExistingTopSitesList(activityIntentTestRule) + homeScreen(composeTestRule) { + verifyExistingTopSitesList() defaultTopSitesList.values.forEach { value -> - verifyExistingTopSitesTabs(activityIntentTestRule, value) + verifyExistingTopSitesTabs(value) } }.openThreeDotMenu { - }.openCustomizeHome { + }.clickSettingsButton { + }.openHomepageSubMenu { verifySponsoredShortcutsCheckBox(true) clickSponsoredShortcuts() verifySponsoredShortcutsCheckBox(false) - }.goBackToHomeScreen { + }.goBack { + }.goBack(composeTestRule) { verifyNotExistingSponsoredTopSitesList() } } @@ -87,10 +90,10 @@ class SponsoredShortcutsTest : TestSetup() { // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/1729338 @Test fun openSponsoredShortcutTest() { - homeScreen { - verifyExistingTopSitesList(activityIntentTestRule) + homeScreen(composeTestRule) { + verifyExistingTopSitesList() sponsoredShortcutTitle = getSponsoredShortcutTitle(2) - }.openTopSiteTabWithTitle(activityIntentTestRule, sponsoredShortcutTitle) { + }.openTopSiteTabWithTitle(sponsoredShortcutTitle) { verifyUrl(sponsoredShortcutTitle) } } @@ -98,11 +101,11 @@ class SponsoredShortcutsTest : TestSetup() { // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/1729334 @Test fun openSponsoredShortcutInPrivateTabTest() { - homeScreen { - verifyExistingTopSitesList(activityIntentTestRule) + homeScreen(composeTestRule) { + verifyExistingTopSitesList() sponsoredShortcutTitle = getSponsoredShortcutTitle(2) - }.openContextMenuOnTopSitesWithTitle(activityIntentTestRule, sponsoredShortcutTitle) { - }.openTopSiteInPrivateTab(activityIntentTestRule) { + }.openContextMenuOnTopSitesWithTitle(sponsoredShortcutTitle) { + }.openTopSiteInPrivateTab { verifyUrl(sponsoredShortcutTitle) } } @@ -110,11 +113,11 @@ class SponsoredShortcutsTest : TestSetup() { // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/1729335 @Test fun openSponsorsAndYourPrivacyOptionTest() { - homeScreen { - verifyExistingTopSitesList(activityIntentTestRule) + homeScreen(composeTestRule) { + verifyExistingTopSitesList() sponsoredShortcutTitle = getSponsoredShortcutTitle(2) - }.openContextMenuOnTopSitesWithTitle(activityIntentTestRule, sponsoredShortcutTitle) { - }.clickSponsorsAndPrivacyButton(activityIntentTestRule) { + }.openContextMenuOnTopSitesWithTitle(sponsoredShortcutTitle) { + }.clickSponsorsAndPrivacyButton { verifySponsoredShortcutsLearnMoreURL() } } @@ -122,11 +125,11 @@ class SponsoredShortcutsTest : TestSetup() { // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/1729336 @Test fun openSponsoredShortcutsSettingsOptionTest() { - homeScreen { - verifyExistingTopSitesList(activityIntentTestRule) + homeScreen(composeTestRule) { + verifyExistingTopSitesList() sponsoredShortcutTitle = getSponsoredShortcutTitle(2) - }.openContextMenuOnTopSitesWithTitle(activityIntentTestRule, sponsoredShortcutTitle) { - }.clickSponsoredShortcutsSettingsButton(activityIntentTestRule) { + }.openContextMenuOnTopSitesWithTitle(sponsoredShortcutTitle) { + }.clickSponsoredShortcutsSettingsButton { verifyHomePageView() } } @@ -134,8 +137,8 @@ class SponsoredShortcutsTest : TestSetup() { // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/1729337 @Test fun verifySponsoredShortcutsDetailsTest() { - homeScreen { - verifyExistingTopSitesList(activityIntentTestRule) + homeScreen(composeTestRule) { + verifyExistingTopSitesList() sponsoredShortcutTitle = getSponsoredShortcutTitle(2) sponsoredShortcutTitle2 = getSponsoredShortcutTitle(3) @@ -153,44 +156,48 @@ class SponsoredShortcutsTest : TestSetup() { val thirdWebPage = mockWebServer.getGenericAsset(3) val fourthWebPage = mockWebServer.getGenericAsset(4) - homeScreen { - verifyExistingTopSitesList(activityIntentTestRule) + homeScreen(composeTestRule) { + verifyExistingTopSitesList() sponsoredShortcutTitle = getSponsoredShortcutTitle(2) sponsoredShortcutTitle2 = getSponsoredShortcutTitle(3) verifySponsoredShortcutDetails(sponsoredShortcutTitle, 2) verifySponsoredShortcutDetails(sponsoredShortcutTitle2, 3) - }.openNavigationToolbar { + } + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(firstWebPage.url) { verifyPageContent(firstWebPage.content) }.openThreeDotMenu { - expandMenuFully() - }.addToFirefoxHome { - }.goToHomescreen(activityIntentTestRule) { - verifyExistingTopSitesTabs(activityIntentTestRule, firstWebPage.title) - }.openNavigationToolbar { + clickTheMoreButton() + }.clickAddToShortcutsButton { + }.goToHomescreen { + verifyExistingTopSitesTabs(firstWebPage.title) + } + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(secondWebPage.url) { verifyPageContent(secondWebPage.content) }.openThreeDotMenu { - expandMenuFully() - }.addToFirefoxHome { - }.goToHomescreen(activityIntentTestRule) { - verifyExistingTopSitesTabs(activityIntentTestRule, secondWebPage.title) - }.openNavigationToolbar { + clickTheMoreButton() + }.clickAddToShortcutsButton { + }.goToHomescreen { + verifyExistingTopSitesTabs(secondWebPage.title) + } + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(thirdWebPage.url) { verifyPageContent(thirdWebPage.content) }.openThreeDotMenu { - expandMenuFully() - }.addToFirefoxHome { - }.goToHomescreen(activityIntentTestRule) { - verifyExistingTopSitesTabs(activityIntentTestRule, thirdWebPage.title) - }.openNavigationToolbar { + clickTheMoreButton() + }.clickAddToShortcutsButton { + }.goToHomescreen { + verifyExistingTopSitesTabs(thirdWebPage.title) + } + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(fourthWebPage.url) { verifyPageContent(fourthWebPage.content) }.openThreeDotMenu { - expandMenuFully() - }.addToFirefoxHome { - }.goToHomescreen(activityIntentTestRule) { + clickTheMoreButton() + }.clickAddToShortcutsButton { + }.goToHomescreen { verifySponsoredShortcutDetails(sponsoredShortcutTitle, 2) verifySponsoredShortcutDoesNotExist(sponsoredShortcutTitle2, 3) } @@ -208,8 +215,8 @@ class SponsoredShortcutsTest : TestSetup() { mockWebServer.loremIpsumAsset, ) - homeScreen { - verifyExistingTopSitesList(activityIntentTestRule) + homeScreen(composeTestRule) { + verifyExistingTopSitesList() sponsoredShortcutTitle = getSponsoredShortcutTitle(2) sponsoredShortcutTitle2 = getSponsoredShortcutTitle(3) @@ -223,7 +230,7 @@ class SponsoredShortcutsTest : TestSetup() { Pair(pagesList[2].title, pagesList[2].url.toString()), Pair(pagesList[3].title, pagesList[3].url.toString()), Pair(pagesList[4].title, pagesList[4].url.toString()), - activityTestRule = activityIntentTestRule.activityRule, + activityTestRule = composeTestRule.activityRule, ) verifySponsoredShortcutDoesNotExist(sponsoredShortcutTitle, 2) diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/TabbedBrowsingTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/TabbedBrowsingTest.kt @@ -58,9 +58,9 @@ class TabbedBrowsingTest : TestSetup() { @get:Rule(order = 1) val memoryLeaksRule = DetectMemoryLeaksRule() - @Rule(order = 2) - @JvmField - val retryTestRule = RetryTestRule(3) + // @Rule(order = 2) + // @JvmField + // val retryTestRule = RetryTestRule(3) // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/903599 @Ignore("disabled - https://bugzilla.mozilla.org/show_bug.cgi?id=1989405") @@ -68,7 +68,7 @@ class TabbedBrowsingTest : TestSetup() { fun closeAllTabsTest() { val defaultWebPage = mockWebServer.getGenericAsset(1) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(defaultWebPage.url) { }.openTabDrawer(composeTestRule) { verifyNormalTabsList() @@ -80,10 +80,10 @@ class TabbedBrowsingTest : TestSetup() { } // Repeat for Private Tabs - homeScreen { + homeScreen(composeTestRule) { }.togglePrivateBrowsingMode() - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(defaultWebPage.url) { }.openTabDrawer(composeTestRule) { verifyPrivateTabsList() @@ -99,7 +99,7 @@ class TabbedBrowsingTest : TestSetup() { fun closingTabsTest() { val genericURL = mockWebServer.getGenericAsset(1) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(genericURL.url) { }.openTabDrawer(composeTestRule) { verifyExistingOpenTabs("Test_Page_1") @@ -107,7 +107,7 @@ class TabbedBrowsingTest : TestSetup() { verifySnackBarText("Tab closed") clickSnackbarButton(composeTestRule, "UNDO") } - browserScreen { + browserScreen(composeTestRule) { verifyTabCounter("1") } } @@ -120,8 +120,8 @@ class TabbedBrowsingTest : TestSetup() { MockBrowserDataHelper.createTabItem(webPages[0].url.toString()) MockBrowserDataHelper.createTabItem(webPages[1].url.toString()) - homeScreen { - }.openTabDrawer(composeTestRule) { + homeScreen(composeTestRule) { + }.openTabDrawer { verifyExistingOpenTabs(webPages[0].title) verifyExistingOpenTabs(webPages[1].title) swipeTabRight(webPages[0].title) @@ -137,14 +137,14 @@ class TabbedBrowsingTest : TestSetup() { verifySnackBarText("Tab closed") clickSnackbarButton(composeTestRule, "UNDO") } - browserScreen { + browserScreen(composeTestRule) { verifyPageContent(webPages[1].content) }.openTabDrawer(composeTestRule) { verifyExistingOpenTabs(webPages[1].title) swipeTabLeft(webPages[1].title) verifySnackBarText("Tab closed") } - homeScreen { + homeScreen(composeTestRule) { verifyTabCounter("0") } } @@ -154,8 +154,9 @@ class TabbedBrowsingTest : TestSetup() { fun closingPrivateTabsTest() { val genericURL = mockWebServer.getGenericAsset(1) - homeScreen { }.togglePrivateBrowsingMode(switchPBModeOn = true) - navigationToolbar { + homeScreen(composeTestRule) { + }.togglePrivateBrowsingMode(switchPBModeOn = true) + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(genericURL.url) { }.openTabDrawer(composeTestRule) { verifyExistingOpenTabs("Test_Page_1") @@ -163,8 +164,8 @@ class TabbedBrowsingTest : TestSetup() { verifySnackBarText("Private tab closed") clickSnackbarButton(composeTestRule, "UNDO") } - browserScreen { - verifyTabCounter("1") + browserScreen(composeTestRule) { + verifyTabCounter("1", isPrivateBrowsingEnabled = true) } } @@ -175,17 +176,17 @@ class TabbedBrowsingTest : TestSetup() { fun verifyCloseAllPrivateTabsNotificationTest() { val defaultWebPage = mockWebServer.getGenericAsset(1) - homeScreen { + homeScreen(composeTestRule) { }.togglePrivateBrowsingMode() - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(defaultWebPage.url) { mDevice.openNotification() } notificationShade { verifyPrivateTabsNotification() - }.clickClosePrivateTabsNotification { + }.clickClosePrivateTabsNotification(composeTestRule) { verifyHomeScreen() } } @@ -193,8 +194,8 @@ class TabbedBrowsingTest : TestSetup() { // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/903600 @Test fun verifyEmptyTabTray() { - homeScreen { - }.openTabDrawer(composeTestRule) { + homeScreen(composeTestRule) { + }.openTabDrawer { verifyNormalBrowsingButtonIsSelected() verifyPrivateBrowsingButtonIsSelected(false) verifySyncedTabsButtonIsSelected(false) @@ -210,8 +211,8 @@ class TabbedBrowsingTest : TestSetup() { // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/903585 @Test fun verifyEmptyPrivateTabsTrayTest() { - homeScreen { - }.openTabDrawer(composeTestRule) { + homeScreen(composeTestRule) { + }.openTabDrawer { }.toggleToPrivateTabs { verifyNormalBrowsingButtonIsSelected(false) verifyPrivateBrowsingButtonIsSelected(true) @@ -230,7 +231,7 @@ class TabbedBrowsingTest : TestSetup() { fun verifyTabsTrayWithOpenTabTest() { val defaultWebPage = mockWebServer.getGenericAsset(1) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(defaultWebPage.url) { }.openTabDrawer(composeTestRule) { verifyNormalBrowsingButtonIsSelected() @@ -254,8 +255,8 @@ class TabbedBrowsingTest : TestSetup() { fun verifyPrivateTabsTrayWithOpenTabTest() { val website = mockWebServer.getGenericAsset(1) - homeScreen { - }.openTabDrawer(composeTestRule) { + homeScreen(composeTestRule) { + }.openTabDrawer { }.toggleToPrivateTabs { }.openNewTab { }.submitQuery(website.url.toString()) { @@ -278,19 +279,20 @@ class TabbedBrowsingTest : TestSetup() { val firstWebPage = mockWebServer.getGenericAsset(1) val secondWebPage = mockWebServer.getGenericAsset(2) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(firstWebPage.url) { waitForPageToLoad() - }.goToHomescreen(composeTestRule) { - }.openNavigationToolbar { + }.goToHomescreen(isPrivateModeEnabled = false) { + } + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(secondWebPage.url) { waitForPageToLoad() } - navigationToolbar { + navigationToolbar(composeTestRule) { }.openTabButtonShortcutsMenu { verifyTabButtonShortcutMenuItems() }.closeTabFromShortcutsMenu { - browserScreen { + browserScreen(composeTestRule) { verifyTabCounter("1") verifyPageContent(firstWebPage.content) } @@ -308,9 +310,9 @@ class TabbedBrowsingTest : TestSetup() { fun tabsCounterShortcutMenuNewPrivateTabTest() { val defaultWebPage = mockWebServer.getGenericAsset(1) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(defaultWebPage.url) {} - navigationToolbar { + navigationToolbar(composeTestRule) { }.openTabButtonShortcutsMenu { }.openNewPrivateTabFromShortcutsMenu { verifySearchBarPlaceholder("Search or enter address") @@ -325,9 +327,9 @@ class TabbedBrowsingTest : TestSetup() { fun tabsCounterShortcutMenuNewTabTest() { val defaultWebPage = mockWebServer.getGenericAsset(1) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(defaultWebPage.url) {} - navigationToolbar { + navigationToolbar(composeTestRule) { }.openTabButtonShortcutsMenu { }.openNewTabFromShortcutsMenu { verifySearchBarPlaceholder("Search or enter address") @@ -343,26 +345,28 @@ class TabbedBrowsingTest : TestSetup() { val firstWebPage = mockWebServer.getGenericAsset(1) val secondWebPage = mockWebServer.getGenericAsset(2) - homeScreen {}.togglePrivateBrowsingMode(switchPBModeOn = true) - navigationToolbar { + homeScreen(composeTestRule) { + }.togglePrivateBrowsingMode(switchPBModeOn = true) + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(firstWebPage.url) { waitForPageToLoad() - }.goToHomescreen(composeTestRule) { - }.openNavigationToolbar { + }.goToHomescreen(isPrivateModeEnabled = true) { + } + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(secondWebPage.url) { waitForPageToLoad() } - navigationToolbar { + navigationToolbar(composeTestRule) { }.openTabButtonShortcutsMenu { verifyTabButtonShortcutMenuItems() }.closeTabFromShortcutsMenu { - browserScreen { - verifyTabCounter("1") + browserScreen(composeTestRule) { + verifyTabCounter("1", isPrivateBrowsingEnabled = true) verifyPageContent(firstWebPage.content) } }.openTabButtonShortcutsMenu { }.closeTabFromShortcutsMenu { - homeScreen { + homeScreen(composeTestRule) { verifyIfInPrivateOrNormalMode(privateBrowsingEnabled = true) } } @@ -374,12 +378,13 @@ class TabbedBrowsingTest : TestSetup() { fun privateTabsCounterShortcutMenuNewPrivateTabTest() { val defaultWebPage = mockWebServer.getGenericAsset(1) - homeScreen {}.togglePrivateBrowsingMode(switchPBModeOn = true) - navigationToolbar { + homeScreen(composeTestRule) { + }.togglePrivateBrowsingMode(switchPBModeOn = true) + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(defaultWebPage.url) { waitForPageToLoad() } - navigationToolbar { + navigationToolbar(composeTestRule) { }.openTabButtonShortcutsMenu { }.openNewPrivateTabFromShortcutsMenu { verifySearchBarPlaceholder("Search or enter address") @@ -394,12 +399,13 @@ class TabbedBrowsingTest : TestSetup() { fun privateTabsCounterShortcutMenuNewTabTest() { val defaultWebPage = mockWebServer.getGenericAsset(1) - homeScreen {}.togglePrivateBrowsingMode(switchPBModeOn = true) - navigationToolbar { + homeScreen(composeTestRule) { + }.togglePrivateBrowsingMode(switchPBModeOn = true) + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(defaultWebPage.url) { verifyPageContent(defaultWebPage.content) } - navigationToolbar { + navigationToolbar(composeTestRule) { }.openTabButtonShortcutsMenu { }.openNewTabFromShortcutsMenu { verifySearchToolbar(isDisplayed = true) @@ -411,8 +417,8 @@ class TabbedBrowsingTest : TestSetup() { // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/1046683 @Test fun verifySyncedTabsWhenUserIsNotSignedInTest() { - navigationToolbar { - }.openTabDrawer(composeTestRule) { + homeScreen(composeTestRule) { + }.openTabDrawer { verifySyncedTabsButtonIsSelected(isSelected = false) }.toggleToSyncedTabs { verifySyncedTabsButtonIsSelected(isSelected = true) @@ -433,8 +439,7 @@ class TabbedBrowsingTest : TestSetup() { val sharingApp = "Gmail" val sharedUrlsString = "${firstWebsite.url}\n\n${secondWebsite.url}" - homeScreen { - }.openNavigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(firstWebsite.url) { verifyPageContent(firstWebsite.content) }.openTabDrawer(composeTestRule) { @@ -466,17 +471,17 @@ class TabbedBrowsingTest : TestSetup() { fun privateModeStaysAsDefaultAfterRestartTest() { val defaultWebPage = mockWebServer.getGenericAsset(1) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(defaultWebPage.url) { - }.goToHomescreen(composeTestRule) { + }.goToHomescreen { }.togglePrivateBrowsingMode() closeApp(composeTestRule.activityRule) restartApp(composeTestRule.activityRule) - homeScreen { + homeScreen(composeTestRule) { verifyPrivateBrowsingHomeScreenItems() - }.openTabDrawer(composeTestRule) { + }.openTabDrawer { }.toggleToNormalTabs { verifyExistingOpenTabs(defaultWebPage.title) } @@ -489,10 +494,10 @@ class TabbedBrowsingTest : TestSetup() { val firstWebPage = mockWebServer.getGenericAsset(1) val secondWebPage = mockWebServer.getGenericAsset(2) - homeScreen { + homeScreen(composeTestRule) { }.togglePrivateBrowsingMode() - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(firstWebPage.url) { }.openTabDrawer(composeTestRule) { }.openNewTab { @@ -500,9 +505,9 @@ class TabbedBrowsingTest : TestSetup() { } closeApp(composeTestRule.activityRule) restartApp(composeTestRule.activityRule) - homeScreen { + homeScreen(composeTestRule) { verifyPrivateBrowsingHomeScreenItems() - }.openTabDrawer(composeTestRule) { + }.openTabDrawer { verifyNoOpenTabsInPrivateBrowsing() } } @@ -519,12 +524,12 @@ class TabbedBrowsingTest : TestSetup() { MockBrowserDataHelper.createTabItem(webPages[2].url.toString()) MockBrowserDataHelper.createTabItem(webPages[3].url.toString()) - homeScreen { - }.openTabDrawer(composeTestRule) { + homeScreen(composeTestRule) { + }.openTabDrawer { verifyNormalTabsList() }.closeTabDrawer {} - homeScreen { - }.openTabDrawer(composeTestRule) { + homeScreen(composeTestRule) { + }.openTabDrawer { verifyOpenTabsOrder(title = webPages[0].title, position = 1, isListViewEnabled = true) verifyOpenTabsOrder(title = webPages[1].title, position = 2, isListViewEnabled = true) verifyOpenTabsOrder(title = webPages[2].title, position = 3, isListViewEnabled = true) @@ -546,12 +551,12 @@ class TabbedBrowsingTest : TestSetup() { MockBrowserDataHelper.createTabItem(webPages[2].url.toString()) MockBrowserDataHelper.createTabItem(webPages[3].url.toString()) - homeScreen { - }.openTabDrawer(composeTestRule) { + homeScreen(composeTestRule) { + }.openTabDrawer { verifyNormalTabsList() }.closeTabDrawer {} - homeScreen { - }.openTabDrawer(composeTestRule) { + homeScreen(composeTestRule) { + }.openTabDrawer { verifyOpenTabsOrder(title = webPages[0].title, position = 1) verifyOpenTabsOrder(title = webPages[1].title, position = 2) verifyOpenTabsOrder(title = webPages[2].title, position = 3) diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/TextFragmentsTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/TextFragmentsTest.kt @@ -16,7 +16,7 @@ import org.mozilla.fenix.ui.robots.navigationToolbar class TextFragmentsTest : TestSetup() { @get:Rule - val activityTestRule = AndroidComposeTestRule( + val composeTestRule = AndroidComposeTestRule( HomeActivityIntentTestRule.withDefaultSettingsOverrides(), ) { it.activity } @@ -30,11 +30,12 @@ class TextFragmentsTest : TestSetup() { val genericPage = mockWebServer.textFragmentAsset val textFragmentLink = genericPage.url.toString() + "#:~:text=Firefox" - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(textFragmentLink.toUri()) { verifyTextFragmentsPageContent("Firefox") }.openThreeDotMenu { - }.openAddToHomeScreen { + clickTheMoreButton() + }.clickAddToHomeScreenButton { clickAddShortcutButton() clickSystemHomeScreenShortcutAddButton() }.openHomeScreenShortcut(genericPage.title) { @@ -49,15 +50,15 @@ class TextFragmentsTest : TestSetup() { val genericPage = mockWebServer.textFragmentAsset val textFragmentLink = genericPage.url.toString() + "#:~:text=Firefox" - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(textFragmentLink.toUri()) { verifyTextFragmentsPageContent("Firefox") - }.openTabDrawer(activityTestRule) { + }.openTabDrawer(composeTestRule) { closeTabWithTitle(genericPage.title) } - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openHistory { + }.clickHistoryButton { verifyHistoryItemExists(true, genericPage.title) }.openWebsite(textFragmentLink.toUri()) { verifyTextFragmentsPageContent("Firefox") @@ -71,19 +72,19 @@ class TextFragmentsTest : TestSetup() { val genericPage = mockWebServer.textFragmentAsset val textFragmentLink = genericPage.url.toString() + "#:~:text=Firefox" - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(textFragmentLink.toUri()) { verifyTextFragmentsPageContent("Firefox") }.openThreeDotMenu { - }.bookmarkPage { + }.clickBookmarkThisPageButton { } - browserScreen { - }.openTabDrawer(activityTestRule) { + browserScreen(composeTestRule) { + }.openTabDrawer(composeTestRule) { closeTabWithTitle(genericPage.title) } - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openBookmarksMenu(activityTestRule) { + }.clickBookmarksButton { verifyBookmarkTitle(genericPage.title) }.openBookmarkWithTitle(genericPage.title) { verifyTextFragmentsPageContent("Firefox") @@ -97,7 +98,7 @@ class TextFragmentsTest : TestSetup() { val genericPage = mockWebServer.textFragmentAsset val textFragmentLink = genericPage.url.toString() + "#:~:text=Firefox" - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(textFragmentLink.toUri()) { verifyTextFragmentsPageContent("Firefox") }.openThreeDotMenu { diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/TextSelectionTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/TextSelectionTest.kt @@ -6,6 +6,7 @@ package org.mozilla.fenix.ui import androidx.compose.ui.test.junit4.AndroidComposeTestRule import mozilla.components.feature.sitepermissions.SitePermissionsRules +import org.junit.Ignore import org.junit.Rule import org.junit.Test import org.mozilla.fenix.customannotations.SmokeTest @@ -30,7 +31,7 @@ import org.mozilla.fenix.ui.robots.shareOverlay class TextSelectionTest : TestSetup() { @get:Rule(order = 0) - val activityIntentTestRule = + val composeTestRule = AndroidComposeTestRule( HomeActivityTestRule( isLocationPermissionEnabled = SitePermissionsRules.Action.BLOCKED, @@ -49,21 +50,22 @@ class TextSelectionTest : TestSetup() { val retryTestRule = RetryTestRule(3) // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2326832 + @Ignore("Disabled after enabling the composable toolbar and main menu: https://bugzilla.mozilla.org/show_bug.cgi?id=2006295") @SmokeTest @Test fun verifySelectAllTextOptionTest() { val genericURL = mockWebServer.getGenericAsset(1) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(genericURL.url) { - longClickPageObject(itemContainingText("content")) + longClickPageObject(composeTestRule, itemContainingText("content")) clickContextMenuItem("Select all") clickContextMenuItem("Copy") }.openNavigationToolbar { openEditURLView() } - searchScreen { + searchScreen(composeTestRule) { clickClearButton() longClickToolbar() clickPasteText() @@ -78,14 +80,14 @@ class TextSelectionTest : TestSetup() { fun verifyCopyTextOptionTest() { val genericURL = mockWebServer.getGenericAsset(1) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(genericURL.url) { - longClickPageObject(itemContainingText("content")) + longClickPageObject(composeTestRule, itemContainingText("content")) clickContextMenuItem("Copy") }.openNavigationToolbar { } - searchScreen { + searchScreen(composeTestRule) { clickClearButton() longClickToolbar() clickPasteText() @@ -98,9 +100,9 @@ class TextSelectionTest : TestSetup() { fun verifyShareSelectedTextOptionTest() { val genericURL = mockWebServer.getGenericAsset(1) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(genericURL.url) { - longClickPageObject(itemWithText(genericURL.content)) + longClickPageObject(composeTestRule, itemWithText(genericURL.content)) }.clickShareSelectedText { verifyAndroidShareLayout() } @@ -111,9 +113,9 @@ class TextSelectionTest : TestSetup() { fun verifySearchTextOptionTest() { val genericURL = mockWebServer.getGenericAsset(1) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(genericURL.url) { - longClickPageObject(itemContainingText("content")) + longClickPageObject(composeTestRule, itemContainingText("content")) clickContextMenuItem("Search") mDevice.waitForIdle() verifyUrl("content") @@ -122,18 +124,19 @@ class TextSelectionTest : TestSetup() { } // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2326831 + @Ignore("Disabled after enabling the composable toolbar and main menu: https://bugzilla.mozilla.org/show_bug.cgi?id=2006295") @SmokeTest @Test fun verifyPrivateSearchTextTest() { val genericURL = mockWebServer.getGenericAsset(1) - homeScreen { + homeScreen(composeTestRule) { }.togglePrivateBrowsingMode() - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(genericURL.url) { verifyPageContent(genericURL.content) - longClickPageObject(itemContainingText("content")) + longClickPageObject(composeTestRule, itemContainingText("content")) clickContextMenuItem("Private Search") mDevice.waitForIdle() verifyTabCounter("2") @@ -142,24 +145,25 @@ class TextSelectionTest : TestSetup() { } // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2326834 + @Ignore("Disabled after enabling the composable toolbar and main menu: https://bugzilla.mozilla.org/show_bug.cgi?id=2006295") @Test fun verifySelectAllPDFTextOptionTest() { val genericURL = mockWebServer.getGenericAsset(3) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(genericURL.url) { - clickPageObject(itemWithText("PDF form file")) - clickPageObject(itemWithResIdAndText("android:id/button2", "Cancel")) + clickPageObject(composeTestRule, itemWithText("PDF form file")) + clickPageObject(composeTestRule, itemWithResIdAndText("android:id/button2", "Cancel")) waitForPageToLoad() - longClickPageObject(itemContainingText("Crossing")) + longClickPageObject(composeTestRule, itemContainingText("Crossing")) clickContextMenuItem("Select all") clickContextMenuItem("Copy") }.openNavigationToolbar { openEditURLView() } - searchScreen { + searchScreen(composeTestRule) { clickClearButton() longClickToolbar() clickPasteText() @@ -177,16 +181,16 @@ class TextSelectionTest : TestSetup() { val genericURL = mockWebServer.getGenericAsset(3) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(genericURL.url) { - clickPageObject(itemWithText("PDF form file")) - clickPageObject(itemWithResIdAndText("android:id/button2", "Cancel")) - longClickPageObject(itemContainingText("Crossing")) + clickPageObject(composeTestRule, itemWithText("PDF form file")) + clickPageObject(composeTestRule, itemWithResIdAndText("android:id/button2", "Cancel")) + longClickPageObject(composeTestRule, itemContainingText("Crossing")) clickContextMenuItem("Copy") }.openNavigationToolbar { } - searchScreen { + searchScreen(composeTestRule) { clickClearButton() longClickToolbar() clickPasteText() @@ -200,11 +204,11 @@ class TextSelectionTest : TestSetup() { val genericURL = mockWebServer.getGenericAsset(3) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(genericURL.url) { - clickPageObject(itemWithText("PDF form file")) - clickPageObject(itemWithResIdAndText("android:id/button2", "Cancel")) - longClickPageObject(itemContainingText("Crossing")) + clickPageObject(composeTestRule, itemWithText("PDF form file")) + clickPageObject(composeTestRule, itemWithResIdAndText("android:id/button2", "Cancel")) + longClickPageObject(composeTestRule, itemContainingText("Crossing")) }.clickShareSelectedText { verifyAndroidShareLayout() } @@ -217,11 +221,11 @@ class TextSelectionTest : TestSetup() { val genericURL = mockWebServer.getGenericAsset(3) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(genericURL.url) { - clickPageObject(itemWithText("PDF form file")) - clickPageObject(itemWithResIdAndText("android:id/button2", "Cancel")) - longClickPageObject(itemContainingText("Crossing")) + clickPageObject(composeTestRule, itemWithText("PDF form file")) + clickPageObject(composeTestRule, itemWithResIdAndText("android:id/button2", "Cancel")) + longClickPageObject(composeTestRule, itemContainingText("Crossing")) clickContextMenuItem("Search") verifyUrl("Crossing") verifyTabCounter("2") @@ -229,19 +233,20 @@ class TextSelectionTest : TestSetup() { } // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2326837 + @Ignore("Disabled after enabling the composable toolbar and main menu: https://bugzilla.mozilla.org/show_bug.cgi?id=2006295") @Test fun verifyPrivateSearchPDFTextOptionTest() { val genericURL = mockWebServer.getGenericAsset(3) - homeScreen { + homeScreen(composeTestRule) { }.togglePrivateBrowsingMode() - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(genericURL.url) { - clickPageObject(itemWithText("PDF form file")) - clickPageObject(itemWithResIdAndText("android:id/button2", "Cancel")) - longClickPageObject(itemContainingText("Crossing")) + clickPageObject(composeTestRule, itemWithText("PDF form file")) + clickPageObject(composeTestRule, itemWithResIdAndText("android:id/button2", "Cancel")) + longClickPageObject(composeTestRule, itemContainingText("Crossing")) clickContextMenuItem("Private Search") verifyUrl("Crossing") verifyTabCounter("2") @@ -249,11 +254,12 @@ class TextSelectionTest : TestSetup() { } // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2326813 + @Ignore("Disabled after enabling the composable toolbar and main menu: https://bugzilla.mozilla.org/show_bug.cgi?id=2006295") @Test fun verifyUrlBarTextSelectionOptionsTest() { val genericURL = mockWebServer.getGenericAsset(1) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(genericURL.url) { }.openNavigationToolbar { longClickEditModeToolbar() @@ -262,11 +268,12 @@ class TextSelectionTest : TestSetup() { } // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2326814 + @Ignore("Disabled after enabling the composable toolbar and main menu: https://bugzilla.mozilla.org/show_bug.cgi?id=2006295") @Test fun verifyCopyUrlBarTextSelectionOptionTest() { val genericURL = mockWebServer.getGenericAsset(1) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(genericURL.url) { }.openNavigationToolbar { longClickEditModeToolbar() @@ -280,11 +287,12 @@ class TextSelectionTest : TestSetup() { } // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/2326815 + @Ignore("Disabled after enabling the composable toolbar and main menu: https://bugzilla.mozilla.org/show_bug.cgi?id=2006295") @Test fun verifyCutUrlBarTextSelectionOptionTest() { val genericURL = mockWebServer.getGenericAsset(1) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(genericURL.url) { }.openNavigationToolbar { longClickEditModeToolbar() @@ -297,12 +305,13 @@ class TextSelectionTest : TestSetup() { } // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/243845 + @Ignore("Disabled after enabling the composable toolbar and main menu: https://bugzilla.mozilla.org/show_bug.cgi?id=2006295") @SmokeTest @Test fun verifyShareUrlBarTextSelectionOptionTest() { val genericURL = mockWebServer.getGenericAsset(1) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(genericURL.url) { }.openNavigationToolbar { longClickEditModeToolbar() @@ -314,26 +323,27 @@ class TextSelectionTest : TestSetup() { } // TestRail link: https://mozilla.testrail.io/index.php?/cases/view/414316 + @Ignore("Disabled after enabling the composable toolbar and main menu: https://bugzilla.mozilla.org/show_bug.cgi?id=2006295") @Test fun urlBarQuickActionsTest() { val firstWebsite = mockWebServer.getGenericAsset(1) val secondWebsite = mockWebServer.getGenericAsset(2) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(firstWebsite.url) { longClickToolbar() clickContextMenuItem("Copy") } - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(secondWebsite.url) { longClickToolbar() clickContextMenuItem("Paste") } - searchScreen { + searchScreen(composeTestRule) { verifyTypedToolbarText(firstWebsite.url.toString(), exists = true) }.dismissSearchBar { } - browserScreen { + browserScreen(composeTestRule) { verifyUrl(secondWebsite.url.toString()) longClickToolbar() clickContextMenuItem("Paste & Go") diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/TopSitesTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/TopSitesTest.kt @@ -34,7 +34,7 @@ import org.mozilla.fenix.ui.robots.navigationToolbar class TopSitesTest : TestSetup() { @get:Rule - val activityIntentTestRule = AndroidComposeTestRule( + val composeTestRule = AndroidComposeTestRule( HomeActivityIntentTestRule.withDefaultSettingsOverrides(skipOnboarding = true), ) { it.activity } @@ -47,20 +47,20 @@ class TopSitesTest : TestSetup() { fun addAWebsiteAsATopSiteTest() { val defaultWebPage = mockWebServer.getGenericAsset(1) - homeScreen { - verifyExistingTopSitesList(activityIntentTestRule) + homeScreen(composeTestRule) { + verifyExistingTopSitesList() } - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(defaultWebPage.url) { verifyPageContent(defaultWebPage.content) }.openThreeDotMenu { - expandMenuFully() - verifyAddToShortcutsButton(shouldExist = true) - }.addToFirefoxHome { + clickTheMoreButton() + verifyAddToShortcutsButton(isDisplayed = true) + }.clickAddToShortcutsButton { verifySnackBarText(getStringResource(R.string.snackbar_added_to_shortcuts)) - }.goToHomescreen(activityIntentTestRule) { - verifyExistingTopSitesList(activityIntentTestRule) - verifyExistingTopSitesTabs(activityIntentTestRule, defaultWebPage.title) + }.goToHomescreen { + verifyExistingTopSitesList() + verifyExistingTopSitesTabs(defaultWebPage.title) } } @@ -71,19 +71,19 @@ class TopSitesTest : TestSetup() { MockBrowserDataHelper.addPinnedSite( Pair(webPage.title, webPage.url.toString()), - activityTestRule = activityIntentTestRule.activityRule, + activityTestRule = composeTestRule.activityRule, ) - homeScreen { - verifyExistingTopSitesList(activityIntentTestRule) - verifyExistingTopSitesTabs(activityIntentTestRule, webPage.title) - }.openTopSiteTabWithTitle(activityIntentTestRule, title = webPage.title) { + homeScreen(composeTestRule) { + verifyExistingTopSitesList() + verifyExistingTopSitesTabs(webPage.title) + }.openTopSiteTabWithTitle(title = webPage.title) { verifyUrl(webPage.url.toString().replace("http://", "")) - }.goToHomescreen(activityIntentTestRule) { - verifyExistingTopSitesList(activityIntentTestRule) - verifyExistingTopSitesTabs(activityIntentTestRule, webPage.title) - }.openContextMenuOnTopSitesWithTitle(activityIntentTestRule, webPage.title) { - verifyTopSiteContextMenuItems(activityIntentTestRule) + }.goToHomescreen { + verifyExistingTopSitesList() + verifyExistingTopSitesTabs(webPage.title) + }.openContextMenuOnTopSitesWithTitle(webPage.title) { + verifyTopSiteContextMenuItems() // Dismiss context menu popup mDevice.pressBack() } @@ -96,16 +96,16 @@ class TopSitesTest : TestSetup() { MockBrowserDataHelper.addPinnedSite( Pair(webPage.title, webPage.url.toString()), - activityTestRule = activityIntentTestRule.activityRule, + activityTestRule = composeTestRule.activityRule, ) - homeScreen { - verifyExistingTopSitesList(activityIntentTestRule) - verifyExistingTopSitesTabs(activityIntentTestRule, webPage.title) - }.openContextMenuOnTopSitesWithTitle(activityIntentTestRule, webPage.title) { - verifyTopSiteContextMenuItems(activityIntentTestRule) - }.openTopSiteInPrivateTab(activityIntentTestRule) { - verifyCurrentPrivateSession(activityIntentTestRule.activity.applicationContext) + homeScreen(composeTestRule) { + verifyExistingTopSitesList() + verifyExistingTopSitesTabs(webPage.title) + }.openContextMenuOnTopSitesWithTitle(webPage.title) { + verifyTopSiteContextMenuItems() + }.openTopSiteInPrivateTab { + verifyCurrentPrivateSession(composeTestRule.activity.applicationContext) } } @@ -118,18 +118,18 @@ class TopSitesTest : TestSetup() { MockBrowserDataHelper.addPinnedSite( Pair(webPage.title, webPage.url.toString()), - activityTestRule = activityIntentTestRule.activityRule, + activityTestRule = composeTestRule.activityRule, ) - homeScreen { - verifyExistingTopSitesList(activityIntentTestRule) - verifyExistingTopSitesTabs(activityIntentTestRule, webPage.title) - }.openContextMenuOnTopSitesWithTitle(activityIntentTestRule, webPage.title) { - verifyTopSiteContextMenuItems(activityIntentTestRule) - }.editTopSite(activityIntentTestRule, newPageTitle, newWebPageURL.url.toString()) { - verifyExistingTopSitesList(activityIntentTestRule) - verifyExistingTopSitesTabs(activityIntentTestRule, newPageTitle) - }.openTopSiteTabWithTitle(activityIntentTestRule, title = newPageTitle) { + homeScreen(composeTestRule) { + verifyExistingTopSitesList() + verifyExistingTopSitesTabs(webPage.title) + }.openContextMenuOnTopSitesWithTitle(webPage.title) { + verifyTopSiteContextMenuItems() + }.editTopSite(newPageTitle, newWebPageURL.url.toString()) { + verifyExistingTopSitesList() + verifyExistingTopSitesTabs(newPageTitle) + }.openTopSiteTabWithTitle(title = newPageTitle) { verifyUrl(newWebPageURL.url.toString()) } } @@ -141,15 +141,15 @@ class TopSitesTest : TestSetup() { MockBrowserDataHelper.addPinnedSite( Pair(webPage.title, webPage.url.toString()), - activityTestRule = activityIntentTestRule.activityRule, + activityTestRule = composeTestRule.activityRule, ) - homeScreen { - verifyExistingTopSitesList(activityIntentTestRule) - verifyExistingTopSitesTabs(activityIntentTestRule, webPage.title) - }.openContextMenuOnTopSitesWithTitle(activityIntentTestRule, webPage.title) { - verifyTopSiteContextMenuItems(activityIntentTestRule) - }.editTopSite(activityIntentTestRule, newPageTitle, "gl") { + homeScreen(composeTestRule) { + verifyExistingTopSitesList() + verifyExistingTopSitesTabs(webPage.title) + }.openContextMenuOnTopSitesWithTitle(webPage.title) { + verifyTopSiteContextMenuItems() + }.editTopSite(newPageTitle, "gl") { verifyTopSiteContextMenuUrlErrorMessage() } } @@ -161,16 +161,16 @@ class TopSitesTest : TestSetup() { MockBrowserDataHelper.addPinnedSite( Pair(webPage.title, webPage.url.toString()), - activityTestRule = activityIntentTestRule.activityRule, + activityTestRule = composeTestRule.activityRule, ) - homeScreen { - verifyExistingTopSitesList(activityIntentTestRule) - verifyExistingTopSitesTabs(activityIntentTestRule, webPage.title) - }.openContextMenuOnTopSitesWithTitle(activityIntentTestRule, webPage.title) { - verifyTopSiteContextMenuItems(activityIntentTestRule) - }.removeTopSite(activityIntentTestRule) { - verifyNotExistingTopSiteItem(activityIntentTestRule, webPage.title) + homeScreen(composeTestRule) { + verifyExistingTopSitesList() + verifyExistingTopSitesTabs(webPage.title) + }.openContextMenuOnTopSitesWithTitle(webPage.title) { + verifyTopSiteContextMenuItems() + }.removeTopSite { + verifyNotExistingTopSiteItem(webPage.title) } } @@ -181,18 +181,19 @@ class TopSitesTest : TestSetup() { MockBrowserDataHelper.addPinnedSite( Pair(webPage.title, webPage.url.toString()), - activityTestRule = activityIntentTestRule.activityRule, + activityTestRule = composeTestRule.activityRule, ) - homeScreen { - verifyExistingTopSitesList(activityIntentTestRule) - verifyExistingTopSitesTabs(activityIntentTestRule, webPage.title) - }.openTopSiteTabWithTitle(activityIntentTestRule, webPage.title) { + homeScreen(composeTestRule) { + verifyExistingTopSitesList() + verifyExistingTopSitesTabs(webPage.title) + }.openTopSiteTabWithTitle(webPage.title) { }.openThreeDotMenu { + clickTheMoreButton() verifyRemoveFromShortcutsButton() - }.clickRemoveFromShortcuts { - }.goToHomescreen(activityIntentTestRule) { - verifyNotExistingTopSiteItem(activityIntentTestRule, webPage.title) + }.clickRemoveFromShortcutsButton { + }.goToHomescreen { + verifyNotExistingTopSiteItem(webPage.title) } } @@ -200,10 +201,10 @@ class TopSitesTest : TestSetup() { // Expected for en-us defaults @Test fun verifyENLocalesDefaultTopSitesListTest() { - homeScreen { - verifyExistingTopSitesList(activityIntentTestRule) + homeScreen(composeTestRule) { + verifyExistingTopSitesList() defaultTopSitesList.values.forEach { value -> - verifyExistingTopSitesTabs(activityIntentTestRule, value) + verifyExistingTopSitesTabs(value) } } } @@ -215,20 +216,20 @@ class TopSitesTest : TestSetup() { val defaultWebPage = mockWebServer.getGenericAsset(1) for (i in 0..1) { - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(defaultWebPage.url) { waitForPageToLoad() } } - browserScreen { - }.goToHomescreen(activityIntentTestRule) { - verifyExistingTopSitesList(activityIntentTestRule) - verifyExistingTopSitesTabs(activityIntentTestRule, defaultWebPage.title) - }.openContextMenuOnTopSitesWithTitle(activityIntentTestRule, defaultWebPage.title) { - }.removeTopSite(activityIntentTestRule) { + browserScreen(composeTestRule) { + }.goToHomescreen { + verifyExistingTopSitesList() + verifyExistingTopSitesTabs(defaultWebPage.title) + }.openContextMenuOnTopSitesWithTitle(defaultWebPage.title) { + }.removeTopSite { }.openThreeDotMenu { - }.openHistory { + }.clickHistoryButton { verifyEmptyHistoryView() } } diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/TranslationsTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/TranslationsTest.kt @@ -19,6 +19,7 @@ import org.mozilla.fenix.helpers.TestAssetHelper.secondForeignWebPageAsset import org.mozilla.fenix.helpers.TestAssetHelper.waitingTimeLong import org.mozilla.fenix.helpers.TestSetup import org.mozilla.fenix.helpers.perf.DetectMemoryLeaksRule +import org.mozilla.fenix.tabstray.browser.compose.createListReorderState import org.mozilla.fenix.ui.robots.browserScreen import org.mozilla.fenix.ui.robots.navigationToolbar import org.mozilla.fenix.ui.robots.translationsRobot @@ -29,7 +30,6 @@ class TranslationsTest : TestSetup() { AndroidComposeTestRule( HomeActivityIntentTestRule( skipOnboarding = true, - isMenuRedesignEnabled = false, isMenuRedesignCFREnabled = false, isPageLoadTranslationsPromptEnabled = true, ), @@ -45,20 +45,20 @@ class TranslationsTest : TestSetup() { fun verifyTheFirstTranslationNotNowButtonFunctionalityTest() { val testPage = mockWebServer.firstForeignWebPageAsset - navigationToolbar { - }.enterURL(testPage.url) { + navigationToolbar(composeTestRule) { + }.enterURLAndEnterToBrowser(testPage.url) { } translationsRobot(composeTestRule) { verifyTranslationSheetIsDisplayed(isDisplayed = true) }.clickNotNowButton { - } - navigationToolbar { }.openThreeDotMenu { - }.clickTranslateButton(composeTestRule) { + clickTheMoreButton() + }.clickTranslateButton { verifyTranslationSheetIsDisplayed(isDisplayed = true) }.swipeCloseTranslationsSheet { }.openThreeDotMenu { - }.clickTranslateButton(composeTestRule) { + clickTheMoreButton() + }.clickTranslateButton { verifyTranslationSheetIsDisplayed(isDisplayed = true) } } @@ -69,16 +69,15 @@ class TranslationsTest : TestSetup() { fun verifyMainMenuTranslationButtonFunctionalityTest() { val testPage = mockWebServer.firstForeignWebPageAsset - navigationToolbar { - }.enterURL(testPage.url) { + navigationToolbar(composeTestRule) { + }.enterURLAndEnterToBrowser(testPage.url) { } translationsRobot(composeTestRule) { verifyTranslationSheetIsDisplayed(isDisplayed = true) }.clickNotNowButton { - } - navigationToolbar { }.openThreeDotMenu { - }.clickTranslateButton(composeTestRule) { + clickTheMoreButton() + }.clickTranslateButton { verifyTranslationSheetIsDisplayed(isDisplayed = true) }.clickTranslateButton { verifyPageContent("Article of the day") @@ -91,8 +90,8 @@ class TranslationsTest : TestSetup() { fun verifyTheDownloadLanguagesFunctionalityTest() { val firstTestPage = mockWebServer.firstForeignWebPageAsset - navigationToolbar { - }.enterURL(firstTestPage.url) { + navigationToolbar(composeTestRule) { + }.enterURLAndEnterToBrowser(firstTestPage.url) { } translationsRobot(composeTestRule) { verifyTranslationSheetIsDisplayed(isDisplayed = true) @@ -111,8 +110,8 @@ class TranslationsTest : TestSetup() { val firstTestPage = mockWebServer.firstForeignWebPageAsset val secondTestPage = mockWebServer.secondForeignWebPageAsset - navigationToolbar { - }.enterURL(firstTestPage.url) { + navigationToolbar(composeTestRule) { + }.enterURLAndEnterToBrowser(firstTestPage.url) { } translationsRobot(composeTestRule) { verifyTranslationSheetIsDisplayed(isDisplayed = true) @@ -130,7 +129,7 @@ class TranslationsTest : TestSetup() { }.goBackToTranslationOptionSheet { closeTranslationsSheet() } - browserScreen { + browserScreen(composeTestRule) { }.openTabDrawer(composeTestRule) { }.openNewTab { }.submitQuery(secondTestPage.url.toString()) { @@ -147,8 +146,8 @@ class TranslationsTest : TestSetup() { fun verifyFirstTranslationBottomSheetTranslateFunctionalityTest() { val testPage = mockWebServer.firstForeignWebPageAsset - navigationToolbar { - }.enterURL(testPage.url) { + navigationToolbar(composeTestRule) { + }.enterURLAndEnterToBrowser(testPage.url) { } translationsRobot(composeTestRule) { verifyTranslationSheetIsDisplayed(isDisplayed = true) @@ -162,15 +161,16 @@ class TranslationsTest : TestSetup() { fun verifyTheShowOriginalTranslationOptionTest() { val testPage = mockWebServer.firstForeignWebPageAsset - navigationToolbar { - }.enterURL(testPage.url) { + navigationToolbar(composeTestRule) { + }.enterURLAndEnterToBrowser(testPage.url) { } translationsRobot(composeTestRule) { verifyTranslationSheetIsDisplayed(isDisplayed = true) }.clickTranslateButton { verifyPageContent("Article of the day") }.openThreeDotMenu { - }.clickTranslateButton(composeTestRule) { + clickTheMoreButton() + }.clickTranslatedButton { verifyTranslationSheetIsDisplayed(isDisplayed = true) }.clickShowOriginalButton { verifyPageContent(testPage.content) @@ -182,15 +182,16 @@ class TranslationsTest : TestSetup() { fun changeTheTranslateToLanguageTest() { val testPage = mockWebServer.firstForeignWebPageAsset - navigationToolbar { - }.enterURL(testPage.url) { + navigationToolbar(composeTestRule) { + }.enterURLAndEnterToBrowser(testPage.url) { } translationsRobot(composeTestRule) { verifyTranslationSheetIsDisplayed(isDisplayed = true) }.clickTranslateButton { verifyPageContent("Article of the day") }.openThreeDotMenu { - }.clickTranslateButton(composeTestRule) { + clickTheMoreButton() + }.clickTranslatedButton { verifyTranslationSheetIsDisplayed(isDisplayed = true) clickTranslateToDropdown() clickTranslateToLanguage("Estonian") @@ -205,8 +206,8 @@ class TranslationsTest : TestSetup() { val firstTestPage = mockWebServer.firstForeignWebPageAsset val secondTestPage = mockWebServer.secondForeignWebPageAsset - navigationToolbar { - }.enterURL(secondTestPage.url) { + navigationToolbar(composeTestRule) { + }.enterURLAndEnterToBrowser(secondTestPage.url) { waitForPageToLoad(pageLoadWaitingTime = waitingTimeLong) } translationsRobot(composeTestRule) { @@ -225,11 +226,11 @@ class TranslationsTest : TestSetup() { }.goBackToTranslationOptionSheet { closeTranslationsSheet() } - browserScreen { + browserScreen(composeTestRule) { waitForPageToLoad(pageLoadWaitingTime = waitingTimeLong) verifyPageContent("Word of the day") } - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(firstTestPage.url) { verifyPageContent("Article of the day") } @@ -240,8 +241,8 @@ class TranslationsTest : TestSetup() { fun verifyTheSiteDeletionFromTheNeverTranslateListTest() { val firstTestPage = mockWebServer.firstForeignWebPageAsset - navigationToolbar { - }.enterURL(firstTestPage.url) { + navigationToolbar(composeTestRule) { + }.enterURLAndEnterToBrowser(firstTestPage.url) { } translationsRobot(composeTestRule) { verifyTranslationSheetIsDisplayed(isDisplayed = true) @@ -273,7 +274,7 @@ class TranslationsTest : TestSetup() { fun downloadLanguageWhileDataSaverModeIsOnTest() { val firstTestPage = mockWebServer.firstForeignWebPageAsset - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURL(firstTestPage.url) { } translationsRobot(composeTestRule) { @@ -300,8 +301,8 @@ class TranslationsTest : TestSetup() { val firstTestPage = mockWebServer.firstForeignWebPageAsset val secondTestPage = mockWebServer.secondForeignWebPageAsset - navigationToolbar { - }.enterURL(firstTestPage.url) { + navigationToolbar(composeTestRule) { + }.enterURLAndEnterToBrowser(firstTestPage.url) { } translationsRobot(composeTestRule) { verifyTranslationSheetIsDisplayed(isDisplayed = true) @@ -314,8 +315,8 @@ class TranslationsTest : TestSetup() { verifyPageContent(firstTestPage.content) } - navigationToolbar { - }.enterURL(secondTestPage.url) { + navigationToolbar(composeTestRule) { + }.enterURLAndEnterToBrowser(secondTestPage.url) { } translationsRobot(composeTestRule) { verifyTranslationSheetIsDisplayed(isDisplayed = false) @@ -329,20 +330,18 @@ class TranslationsTest : TestSetup() { val firstTestPage = mockWebServer.firstForeignWebPageAsset val secondTestPage = "https://mozilla-mobile.github.io/testapp/v2.0/germanForeignWebPage.html" - navigationToolbar { - }.enterURL(firstTestPage.url) { + navigationToolbar(composeTestRule) { + }.enterURLAndEnterToBrowser(firstTestPage.url) { } translationsRobot(composeTestRule) { verifyTranslationSheetIsDisplayed(isDisplayed = true) closeTranslationsSheet() } - browserScreen { + browserScreen(composeTestRule) { }.openTabDrawer(composeTestRule) { }.openNewTab { - }.dismissSearchBar { - } - navigationToolbar { - }.enterURL(secondTestPage.toUri()) { + }.submitQuery(secondTestPage) { + waitForPageToLoad() } translationsRobot(composeTestRule) { verifyTranslationSheetIsDisplayed(isDisplayed = true) diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/UnifiedTrustPanelTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/UnifiedTrustPanelTest.kt @@ -32,7 +32,6 @@ class UnifiedTrustPanelTest : TestSetup() { AndroidComposeTestRule( HomeActivityIntentTestRule( isUnifiedTrustPanelEnabled = true, - isComposableToolbarEnabled = false, isPWAsPromptEnabled = false, ), ) { it.activity } @@ -53,11 +52,11 @@ class UnifiedTrustPanelTest : TestSetup() { fun verifySecurePageConnectionFromQuickSettingsWithNoTrackersTest() { val firstPage = "https://mozilla-mobile.github.io/testapp" - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(firstPage.toUri()) { verifyPageContent("Lets test!") } - navigationToolbar { + navigationToolbar(composeTestRule) { }.openUnifiedTrustPanel { verifyUnifiedTrustPanelItems( composeTestRule = composeTestRule, @@ -90,13 +89,11 @@ class UnifiedTrustPanelTest : TestSetup() { val trackingProtectionPage = mockWebServer.enhancedTrackingProtectionAsset.url // browsing a generic page to allow GV to load on a fresh run - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(genericPage.url) { - }.openTabDrawer(composeTestRule) { - closeTab() + verifyPageContent(genericPage.content) } - - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(trackingProtectionPage) { verifyTrackingProtectionWebContent("social blocked") verifyTrackingProtectionWebContent("ads blocked") @@ -104,11 +101,12 @@ class UnifiedTrustPanelTest : TestSetup() { verifyTrackingProtectionWebContent("Fingerprinting blocked") verifyTrackingProtectionWebContent("Cryptomining blocked") } - navigationToolbar { + navigationToolbar(composeTestRule) { }.openUnifiedTrustPanel { verifyUnifiedTrustPanelItems( composeTestRule = composeTestRule, webSite = trackingProtectionPage.host.toString(), + shouldWebSiteURLBeDisplayed = false, webSiteURL = trackingProtectionPage.host.toString(), isTheWebSiteSecure = false, isEnhancedTrackingProtectionEnabled = true, @@ -119,6 +117,7 @@ class UnifiedTrustPanelTest : TestSetup() { verifyUnifiedTrustPanelItems( composeTestRule = composeTestRule, webSite = trackingProtectionPage.host.toString(), + shouldWebSiteURLBeDisplayed = false, webSiteURL = trackingProtectionPage.host.toString(), isTheWebSiteSecure = false, isEnhancedTrackingProtectionEnabled = false, @@ -135,11 +134,11 @@ class UnifiedTrustPanelTest : TestSetup() { val loginPage = "https://mozilla-mobile.github.io/testapp/loginForm" val originWebsite = "mozilla-mobile.github.io" - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(loginPage.toUri()) { waitForPageToLoad(waitingTimeLong) } - navigationToolbar { + navigationToolbar(composeTestRule) { }.openUnifiedTrustPanel { clickTheClearCookiesAndSiteDataButton(composeTestRule) verifyTheClearCookiesAndSiteDataDialog(composeTestRule, originWebsite) @@ -154,19 +153,20 @@ class UnifiedTrustPanelTest : TestSetup() { val trackingProtectionPage = "https://senglehardt.com/test/trackingprotection/test_pages/tracking_protection" // browsing a generic page to allow GV to load on a fresh run - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(genericPage.url) { } - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(trackingProtectionPage.toUri()) { verifyPageContent("Tracker Blocking") } - navigationToolbar { + navigationToolbar(composeTestRule) { }.openUnifiedTrustPanel { verifyUnifiedTrustPanelItems( composeTestRule = composeTestRule, webSite = trackingProtectionPage.toUri().host.toString(), + shouldWebSiteURLBeDisplayed = false, webSiteURL = trackingProtectionPage.toUri().host.toString(), isTheWebSiteSecure = true, isEnhancedTrackingProtectionEnabled = true, @@ -177,6 +177,7 @@ class UnifiedTrustPanelTest : TestSetup() { verifyUnifiedTrustPanelItems( composeTestRule = composeTestRule, webSite = trackingProtectionPage.toUri().host.toString(), + shouldWebSiteURLBeDisplayed = false, webSiteURL = trackingProtectionPage.toUri().host.toString(), isEnhancedTrackingProtectionEnabled = false, isTheWebSiteSecure = true, @@ -191,11 +192,11 @@ class UnifiedTrustPanelTest : TestSetup() { fun verifyInsecurePageConnectionFromQuickSettingsWithNoTrackersTest() { val genericPage = mockWebServer.getGenericAsset(1) - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(genericPage.url) { verifyPageContent(genericPage.content) } - navigationToolbar { + navigationToolbar(composeTestRule) { }.openUnifiedTrustPanel { verifyUnifiedTrustPanelItems( composeTestRule = composeTestRule, @@ -230,11 +231,11 @@ class UnifiedTrustPanelTest : TestSetup() { ), ) - browserScreen { + browserScreen(composeTestRule) { verifyPageContent("Lets test!") } - customTabScreen { + customTabScreen(composeTestRule) { }.openUnifiedTrustPanel { verifyUnifiedTrustPanelItems( composeTestRule = composeTestRule, @@ -272,7 +273,7 @@ class UnifiedTrustPanelTest : TestSetup() { ), ) - browserScreen { + browserScreen(composeTestRule) { verifyPageContent(genericPage.content) } @@ -282,14 +283,15 @@ class UnifiedTrustPanelTest : TestSetup() { ), ) - customTabScreen { + customTabScreen(composeTestRule) { verifyCustomTabUrl(customTabPage.toUri().host.toString()) } - customTabScreen { + customTabScreen(composeTestRule) { }.openUnifiedTrustPanel { verifyUnifiedTrustPanelItems( composeTestRule = composeTestRule, webSite = customTabPage.toUri().host.toString(), + shouldWebSiteURLBeDisplayed = false, webSiteURL = customTabPage.toUri().host.toString(), isTheWebSiteSecure = true, isEnhancedTrackingProtectionEnabled = true, @@ -300,6 +302,7 @@ class UnifiedTrustPanelTest : TestSetup() { verifyUnifiedTrustPanelItems( composeTestRule = composeTestRule, webSite = customTabPage.toUri().host.toString(), + shouldWebSiteURLBeDisplayed = false, webSiteURL = customTabPage.toUri().host.toString(), isEnhancedTrackingProtectionEnabled = false, isTheWebSiteSecure = true, @@ -321,11 +324,11 @@ class UnifiedTrustPanelTest : TestSetup() { ), ) - browserScreen { + browserScreen(composeTestRule) { verifyPageContent(customTabPage.content) } - customTabScreen { + customTabScreen(composeTestRule) { }.openUnifiedTrustPanel { verifyUnifiedTrustPanelItems( composeTestRule = composeTestRule, @@ -362,7 +365,7 @@ class UnifiedTrustPanelTest : TestSetup() { ), ) - customTabScreen { + customTabScreen(composeTestRule) { waitForPageToLoad(waitingTimeLong) }.openUnifiedTrustPanel { clickTheClearCookiesAndSiteDataButton(composeTestRule) @@ -383,18 +386,19 @@ class UnifiedTrustPanelTest : TestSetup() { ), ) - browserScreen { + browserScreen(composeTestRule) { verifyTrackingProtectionWebContent("social blocked") verifyTrackingProtectionWebContent("ads blocked") verifyTrackingProtectionWebContent("analytics blocked") verifyTrackingProtectionWebContent("Fingerprinting blocked") verifyTrackingProtectionWebContent("Cryptomining blocked") } - customTabScreen { + customTabScreen(composeTestRule) { }.openUnifiedTrustPanel { verifyUnifiedTrustPanelItems( composeTestRule = composeTestRule, webSite = customTabPage.host.toString(), + shouldWebSiteURLBeDisplayed = false, webSiteURL = customTabPage.host.toString(), isTheWebSiteSecure = false, isEnhancedTrackingProtectionEnabled = true, @@ -405,6 +409,7 @@ class UnifiedTrustPanelTest : TestSetup() { verifyUnifiedTrustPanelItems( composeTestRule = composeTestRule, webSite = customTabPage.host.toString(), + shouldWebSiteURLBeDisplayed = false, webSiteURL = customTabPage.host.toString(), isTheWebSiteSecure = false, isEnhancedTrackingProtectionEnabled = false, diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/UploadPermissionsTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/UploadPermissionsTest.kt @@ -1,6 +1,7 @@ package org.mozilla.fenix.ui import android.os.Build +import androidx.compose.ui.test.junit4.AndroidComposeTestRule import androidx.test.filters.SdkSuppress import mozilla.components.support.ktx.util.PromptAbuserDetector import org.junit.Rule @@ -22,7 +23,9 @@ import org.mozilla.fenix.ui.robots.navigationToolbar class UploadPermissionsTest : TestSetup() { @get:Rule - val activityTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides() + val composeTestRule = AndroidComposeTestRule( + HomeActivityIntentTestRule.withDefaultSettingsOverrides(), + ) { it.activity } @get:Rule val memoryLeaksRule = DetectMemoryLeaksRule() @@ -43,9 +46,9 @@ class UploadPermissionsTest : TestSetup() { fun fileUploadPermissionTest() { val testPage = mockWebServer.htmlControlsFormAsset - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(testPage.url) { - clickPageObject(itemWithResId("upload_file")) + clickPageObject(composeTestRule, itemWithResId("upload_file")) // Grant app permission to access storage grantSystemPermission() if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { @@ -61,9 +64,9 @@ class UploadPermissionsTest : TestSetup() { fun uploadSelectedAudioFilesWhileNoPermissionGrantedTest() { val testPage = mockWebServer.htmlControlsFormAsset - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(testPage.url) { - clickPageObject(itemWithResId("audioFileUpload")) + clickPageObject(composeTestRule, itemWithResId("audioFileUpload")) // Deny app access to voice recording denyPermission() // Deny app access to audio files storage @@ -77,9 +80,9 @@ class UploadPermissionsTest : TestSetup() { fun uploadSelectedAudioFilesWhenStoragePermissionGrantedTest() { val testPage = mockWebServer.htmlControlsFormAsset - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(testPage.url) { - clickPageObject(itemWithResId("audioFileUpload")) + clickPageObject(composeTestRule, itemWithResId("audioFileUpload")) // Deny app access to voice recording denyPermission() // Grant app access to audio files storage @@ -95,9 +98,9 @@ class UploadPermissionsTest : TestSetup() { fun uploadSelectedVideoOrImageFilesWhenStoragePermissionGrantedTest() { val testPage = mockWebServer.htmlControlsFormAsset - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(testPage.url) { - clickPageObject(itemWithResId("photosUpload")) + clickPageObject(composeTestRule, itemWithResId("photosUpload")) // Deny app access to pictures and video recordings denyPermission() verifySystemPhotoAndVideoPickerExists() diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/WebControlsTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/WebControlsTest.kt @@ -4,6 +4,7 @@ package org.mozilla.fenix.ui +import androidx.compose.ui.test.junit4.AndroidComposeTestRule import org.junit.Rule import org.junit.Test import org.mozilla.fenix.helpers.AppAndSystemHelper.assertNativeAppOpens @@ -35,10 +36,12 @@ class WebControlsTest : TestSetup() { private val phoneLink = "tel://1234567890" @get:Rule - val activityTestRule = HomeActivityTestRule( + val composeTestRule = AndroidComposeTestRule( + HomeActivityTestRule( shouldUseBottomToolbar = true, isOpenInAppBannerEnabled = false, - ) + ), + ) { it.activity } @get:Rule val memoryLeaksRule = DetectMemoryLeaksRule() @@ -52,16 +55,16 @@ class WebControlsTest : TestSetup() { val currentYear = currentDate.year val htmlControlsPage = mockWebServer.htmlControlsFormAsset - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(htmlControlsPage.url) { - clickPageObject(itemWithResId("calendar")) - clickPageObject(itemContainingText("CANCEL")) - clickPageObject(itemWithResId("submitDate")) + clickPageObject(composeTestRule, itemWithResId("calendar")) + clickPageObject(composeTestRule, itemContainingText("CANCEL")) + clickPageObject(composeTestRule, itemWithResId("submitDate")) verifyNoDateIsSelected() - clickPageObject(itemWithResId("calendar")) - clickPageObject(itemWithDescription("$currentMonth $currentDay")) - clickPageObject(itemContainingText("Set")) - clickPageObject(itemWithResId("submitDate")) + clickPageObject(composeTestRule, itemWithResId("calendar")) + clickPageObject(composeTestRule, itemWithDescription("$currentMonth $currentDay")) + clickPageObject(composeTestRule, itemContainingText("Set")) + clickPageObject(composeTestRule, itemWithResId("submitDate")) verifySelectedDate() } } @@ -71,16 +74,16 @@ class WebControlsTest : TestSetup() { fun verifyClockFormInteractionsTest() { val htmlControlsPage = mockWebServer.htmlControlsFormAsset - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(htmlControlsPage.url) { - clickPageObject(itemWithResId("clock")) - clickPageObject(itemContainingText("Cancel")) - clickPageObject(itemWithResId("submitTime")) + clickPageObject(composeTestRule, itemWithResId("clock")) + clickPageObject(composeTestRule, itemContainingText("Cancel")) + clickPageObject(composeTestRule, itemWithResId("submitTime")) verifyNoTimeIsSelected(hour, minute) - clickPageObject(itemWithResId("clock")) + clickPageObject(composeTestRule, itemWithResId("clock")) selectTime(hour, minute) - clickPageObject(itemContainingText("OK")) - clickPageObject(itemWithResId("submitTime")) + clickPageObject(composeTestRule, itemContainingText("OK")) + clickPageObject(composeTestRule, itemWithResId("submitTime")) verifySelectedTime(hour, minute) } } @@ -90,17 +93,17 @@ class WebControlsTest : TestSetup() { fun verifyColorPickerInteractionsTest() { val htmlControlsPage = mockWebServer.htmlControlsFormAsset - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(htmlControlsPage.url) { - clickPageObject(itemWithResId("colorPicker")) - clickPageObject(itemWithDescription(colorHexValue)) - clickPageObject(itemContainingText("CANCEL")) - clickPageObject(itemWithResId("submitColor")) + clickPageObject(composeTestRule, itemWithResId("colorPicker")) + clickPageObject(composeTestRule, itemWithDescription(colorHexValue)) + clickPageObject(composeTestRule, itemContainingText("CANCEL")) + clickPageObject(composeTestRule, itemWithResId("submitColor")) verifyColorIsNotSelected(colorHexValue) - clickPageObject(itemWithResId("colorPicker")) - clickPageObject(itemWithDescription(colorHexValue)) - clickPageObject(itemContainingText("SET")) - clickPageObject(itemWithResId("submitColor")) + clickPageObject(composeTestRule, itemWithResId("colorPicker")) + clickPageObject(composeTestRule, itemWithDescription(colorHexValue)) + clickPageObject(composeTestRule, itemContainingText("SET")) + clickPageObject(composeTestRule, itemWithResId("submitColor")) verifySelectedColor(colorHexValue) } } @@ -110,11 +113,11 @@ class WebControlsTest : TestSetup() { fun verifyDropdownMenuInteractionsTest() { val htmlControlsPage = mockWebServer.htmlControlsFormAsset - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(htmlControlsPage.url) { - clickPageObject(itemWithResId("dropDown")) - clickPageObject(itemContainingText("The National")) - clickPageObject(itemWithResId("submitOption")) + clickPageObject(composeTestRule, itemWithResId("dropDown")) + clickPageObject(composeTestRule, itemContainingText("The National")) + clickPageObject(composeTestRule, itemWithResId("submitOption")) verifySelectedDropDownOption("The National") } } @@ -124,12 +127,12 @@ class WebControlsTest : TestSetup() { fun verifyEmailLinkTest() { val externalLinksPage = mockWebServer.externalLinksAsset - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(externalLinksPage.url) { - clickPageObject(itemContainingText("Email link")) + clickPageObject(composeTestRule, itemContainingText("Email link")) waitForAppWindowToBeUpdated() - clickPageObject(itemWithResIdAndText("android:id/button1", "Open")) - assertNativeAppOpens(Constants.PackageName.GMAIL_APP, emailLink) + clickPageObject(composeTestRule, itemWithResIdAndText("android:id/button1", "Open")) + assertNativeAppOpens(composeTestRule, Constants.PackageName.GMAIL_APP, emailLink) } } @@ -138,12 +141,12 @@ class WebControlsTest : TestSetup() { fun verifyTelephoneLinkTest() { val externalLinksPage = mockWebServer.externalLinksAsset - navigationToolbar { + navigationToolbar(composeTestRule) { }.enterURLAndEnterToBrowser(externalLinksPage.url) { - clickPageObject(itemContainingText("Telephone link")) + clickPageObject(composeTestRule, itemContainingText("Telephone link")) waitForAppWindowToBeUpdated() - clickPageObject(itemWithResIdAndText("android:id/button1", "Open")) - assertNativeAppOpens(Constants.PackageName.PHONE_APP, phoneLink) + clickPageObject(composeTestRule, itemWithResIdAndText("android:id/button1", "Open")) + assertNativeAppOpens(composeTestRule, Constants.PackageName.PHONE_APP, phoneLink) } } } diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/helpers/BasePage.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/helpers/BasePage.kt @@ -7,8 +7,9 @@ package org.mozilla.fenix.ui.efficiency.helpers import android.util.Log import androidx.compose.ui.test.SemanticsNodeInteraction import androidx.compose.ui.test.assertIsDisplayed -import androidx.compose.ui.test.hasAnyDescendant import androidx.compose.ui.test.junit4.AndroidComposeTestRule +import androidx.compose.ui.test.onAllNodesWithTag +import androidx.compose.ui.test.onLast import androidx.compose.ui.test.onNodeWithContentDescription import androidx.compose.ui.test.onNodeWithTag import androidx.compose.ui.test.onNodeWithText @@ -21,18 +22,13 @@ import androidx.test.espresso.action.ViewActions.click import androidx.test.espresso.action.ViewActions.pressImeActionButton import androidx.test.espresso.action.ViewActions.typeText import androidx.test.espresso.assertion.ViewAssertions.matches -import androidx.test.espresso.matcher.ViewMatchers -import androidx.test.espresso.matcher.ViewMatchers.hasDescendant import androidx.test.espresso.matcher.ViewMatchers.isDisplayed 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.uiautomator.By import androidx.test.uiautomator.UiObject import androidx.test.uiautomator.UiSelector -import org.hamcrest.CoreMatchers.containsString -import org.mozilla.fenix.R import org.mozilla.fenix.helpers.HomeActivityIntentTestRule import org.mozilla.fenix.helpers.TestHelper.mDevice import org.mozilla.fenix.helpers.TestHelper.packageName @@ -306,6 +302,15 @@ abstract class BasePage( } } + SelectorStrategy.COMPOSE_ON_ALL_NODES_BY_TAG_ON_LAST -> { + try { + composeRule.onAllNodesWithTag(selector.value).onLast() + } catch (e: Exception) { + Log.i("mozGetElement", "Compose node not found for tag: ${selector.value}") + null + } + } + SelectorStrategy.COMPOSE_BY_TEXT -> { try { composeRule.onNodeWithText(selector.value, useUnmergedTree = true) diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/helpers/BaseTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/helpers/BaseTest.kt @@ -14,7 +14,6 @@ import org.mozilla.fenix.helpers.TestSetup abstract class BaseTest( private val skipOnboarding: Boolean = true, - private val isMenuRedesignEnabled: Boolean = false, private val isMenuRedesignCFREnabled: Boolean = false, private val isPageLoadTranslationsPromptEnabled: Boolean = false, ) : TestSetup() { @@ -24,7 +23,6 @@ abstract class BaseTest( AndroidComposeTestRule( HomeActivityIntentTestRule( skipOnboarding = skipOnboarding, - isMenuRedesignEnabled = isMenuRedesignEnabled, isMenuRedesignCFREnabled = isMenuRedesignCFREnabled, isPageLoadTranslationsPromptEnabled = isPageLoadTranslationsPromptEnabled, ), diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/helpers/PageContext.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/helpers/PageContext.kt @@ -14,7 +14,6 @@ import org.mozilla.fenix.ui.efficiency.pageObjects.DownloadsPage import org.mozilla.fenix.ui.efficiency.pageObjects.FindInPagePage import org.mozilla.fenix.ui.efficiency.pageObjects.HistoryPage import org.mozilla.fenix.ui.efficiency.pageObjects.HomePage -import org.mozilla.fenix.ui.efficiency.pageObjects.MainMenuComposePage import org.mozilla.fenix.ui.efficiency.pageObjects.MainMenuPage import org.mozilla.fenix.ui.efficiency.pageObjects.MicrosurveysPage import org.mozilla.fenix.ui.efficiency.pageObjects.NotificationPage @@ -67,7 +66,6 @@ class PageContext(val composeRule: AndroidComposeTestRule<HomeActivityIntentTest val history = HistoryPage(composeRule) val home = HomePage(composeRule) val mainMenu = MainMenuPage(composeRule) - val mainMenuCompose = MainMenuComposePage(composeRule) val microsurveys = MicrosurveysPage(composeRule) val notifications = NotificationPage(composeRule) val readerView = ReaderViewPage(composeRule) diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/helpers/Selector.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/helpers/Selector.kt @@ -29,6 +29,7 @@ enum class SelectorStrategy { */ COMPOSE_BY_CONTENT_DESCRIPTION, COMPOSE_BY_TAG, + COMPOSE_ON_ALL_NODES_BY_TAG_ON_LAST, COMPOSE_BY_TEXT, ESPRESSO_BY_ID, ESPRESSO_BY_TEXT, diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/BrowserPage.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/BrowserPage.kt @@ -22,9 +22,9 @@ class BrowserPage(composeRule: AndroidComposeTestRule<HomeActivityIntentTestRule from = "HomePage", to = pageName, steps = listOf( - NavigationStep.Click(ToolbarSelectors.URL_BAR_PLACE_HOLDER), - NavigationStep.EnterText(SearchBarSelectors.EDIT_SEARCHBAR_VIEW), - NavigationStep.PressEnter(SearchBarSelectors.EDIT_SEARCHBAR_VIEW), + NavigationStep.Click(ToolbarSelectors.TOOLBAR_URL_BOX), + NavigationStep.EnterText(SearchBarSelectors.TOOLBAR_IN_EDIT_MODE), + NavigationStep.PressEnter(SearchBarSelectors.TOOLBAR_IN_EDIT_MODE), ), ) @@ -32,9 +32,9 @@ class BrowserPage(composeRule: AndroidComposeTestRule<HomeActivityIntentTestRule from = pageName, to = pageName, steps = listOf( - NavigationStep.Click(SearchBarSelectors.URL_TEXT), - NavigationStep.EnterText(SearchBarSelectors.EDIT_SEARCHBAR_VIEW), - NavigationStep.PressEnter(SearchBarSelectors.EDIT_SEARCHBAR_VIEW), + NavigationStep.Click(ToolbarSelectors.TOOLBAR_URL_BOX), + NavigationStep.EnterText(SearchBarSelectors.TOOLBAR_IN_EDIT_MODE), + NavigationStep.PressEnter(SearchBarSelectors.TOOLBAR_IN_EDIT_MODE), ), ) @@ -42,8 +42,8 @@ class BrowserPage(composeRule: AndroidComposeTestRule<HomeActivityIntentTestRule from = "SearchBarComponent", to = pageName, steps = listOf( - NavigationStep.EnterText(SearchBarSelectors.EDIT_SEARCHBAR_VIEW), - NavigationStep.PressEnter(SearchBarSelectors.EDIT_SEARCHBAR_VIEW), + NavigationStep.EnterText(SearchBarSelectors.TOOLBAR_IN_EDIT_MODE), + NavigationStep.PressEnter(SearchBarSelectors.TOOLBAR_IN_EDIT_MODE), ), ) } diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/DownloadsPage.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/DownloadsPage.kt @@ -23,7 +23,7 @@ class DownloadsPage(composeRule: AndroidComposeTestRule<HomeActivityIntentTestRu to = pageName, steps = listOf( NavigationStep.Click(HomeSelectors.MAIN_MENU_BUTTON), - NavigationStep.Click(MainMenuSelectors.DOWNLOADS_BUTTON), + NavigationStep.Click(MainMenuSelectors.DOWLOADS_BUTTON), ), ) } diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/HomePage.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/HomePage.kt @@ -54,7 +54,7 @@ class HomePage(composeRule: AndroidComposeTestRule<HomeActivityIntentTestRule, * NavigationRegistry.register( from = "MainMenuPage", to = "DownloadsPage", - steps = listOf(NavigationStep.Click(MainMenuSelectors.DOWNLOADS_BUTTON)), + steps = listOf(NavigationStep.Click(MainMenuSelectors.DOWLOADS_BUTTON)), ) NavigationRegistry.register( diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/MainMenuComposePage.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/MainMenuComposePage.kt @@ -1,32 +0,0 @@ -/* 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.efficiency.pageObjects - -import androidx.compose.ui.test.junit4.AndroidComposeTestRule -import org.mozilla.fenix.helpers.HomeActivityIntentTestRule -import org.mozilla.fenix.ui.efficiency.helpers.BasePage -import org.mozilla.fenix.ui.efficiency.helpers.Selector -import org.mozilla.fenix.ui.efficiency.navigation.NavigationRegistry -import org.mozilla.fenix.ui.efficiency.navigation.NavigationStep -import org.mozilla.fenix.ui.efficiency.selectors.HomeSelectors -import org.mozilla.fenix.ui.efficiency.selectors.MainMenuComposeSelectors - -class MainMenuComposePage(composeRule: AndroidComposeTestRule<HomeActivityIntentTestRule, *>) : BasePage(composeRule) { - override val pageName = "MainMenuPage" - - init { - NavigationRegistry.register( - from = "HomePage", - to = pageName, - steps = listOf( - NavigationStep.Click(HomeSelectors.MAIN_MENU_BUTTON), - ), - ) - } - - override fun mozGetSelectorsByGroup(group: String): List<Selector> { - return MainMenuComposeSelectors.all.filter { it.groups.contains(group) } - } -} diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SearchBarComponent.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SearchBarComponent.kt @@ -21,14 +21,14 @@ class SearchBarComponent(composeRule: AndroidComposeTestRule<HomeActivityIntentT NavigationRegistry.register( from = "HomePage", to = pageName, - steps = listOf(NavigationStep.Click(ToolbarSelectors.URL_BAR_PLACE_HOLDER)), + steps = listOf(NavigationStep.Click(ToolbarSelectors.TOOLBAR_URL_BOX)), ) // Click search bar to edit or replace a URL NavigationRegistry.register( from = "BrowserPage", to = pageName, - steps = listOf(NavigationStep.Click(SearchBarSelectors.URL_TEXT)), + steps = listOf(NavigationStep.Click(ToolbarSelectors.TOOLBAR_URL_BOX)), ) } diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsAboutPage.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/pageObjects/SettingsAboutPage.kt @@ -11,7 +11,6 @@ import org.mozilla.fenix.ui.efficiency.helpers.Selector import org.mozilla.fenix.ui.efficiency.navigation.NavigationRegistry import org.mozilla.fenix.ui.efficiency.navigation.NavigationStep import org.mozilla.fenix.ui.efficiency.selectors.HomeSelectors -import org.mozilla.fenix.ui.efficiency.selectors.MainMenuSelectors import org.mozilla.fenix.ui.efficiency.selectors.SettingsAboutSelectors import org.mozilla.fenix.ui.efficiency.selectors.SettingsSelectors diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/HomeSelectors.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/HomeSelectors.kt @@ -4,6 +4,8 @@ package org.mozilla.fenix.ui.efficiency.selectors +import org.mozilla.fenix.R +import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource import org.mozilla.fenix.ui.efficiency.helpers.Selector import org.mozilla.fenix.ui.efficiency.helpers.SelectorStrategy @@ -23,8 +25,8 @@ object HomeSelectors { ) val MAIN_MENU_BUTTON = Selector( - strategy = SelectorStrategy.ESPRESSO_BY_ID, - value = "menuButton", + strategy = SelectorStrategy.COMPOSE_BY_CONTENT_DESCRIPTION, + value = getStringResource(R.string.content_description_menu), description = "Three Dot Menu", groups = listOf("requiredForPage"), ) diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/MainMenuComposeSelectors.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/MainMenuComposeSelectors.kt @@ -1,81 +0,0 @@ -/* 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.efficiency.selectors - -import org.mozilla.fenix.R -import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource -import org.mozilla.fenix.ui.efficiency.helpers.Selector -import org.mozilla.fenix.ui.efficiency.helpers.SelectorStrategy - -object MainMenuComposeSelectors { - - val NEW_PRIVATE_TAB_BUTTON = Selector( - strategy = SelectorStrategy.COMPOSE_BY_TEXT, - value = getStringResource(R.string.browser_menu_new_private_tab), - description = "Main menu New private tab button", - // Removed in https://bugzilla.mozilla.org/show_bug.cgi?id=1966222 as part of the menu redesign effort - groups = listOf("removedIn=141"), - ) - - val EXTENSIONS_BUTTON = Selector( - strategy = SelectorStrategy.COMPOSE_BY_TEXT, - value = getStringResource(R.string.browser_menu_extensions), - description = "Main menu Extensions button", - groups = listOf("requiredForPage"), - ) - - val BOOKMARKS_BUTTON = Selector( - strategy = SelectorStrategy.COMPOSE_BY_TEXT, - value = getStringResource(R.string.library_bookmarks), - description = "Main menu Bookmarks button", - groups = listOf("requiredForPage"), - ) - - val HISTORY_BUTTON = Selector( - strategy = SelectorStrategy.COMPOSE_BY_TEXT, - value = getStringResource(R.string.library_history), - description = "Main menu History button", - groups = listOf("requiredForPage"), - ) - - val DOWLOADS_BUTTON = Selector( - strategy = SelectorStrategy.COMPOSE_BY_TEXT, - value = getStringResource(R.string.library_downloads), - description = "Main menu Downloads button", - groups = listOf("requiredForPage"), - ) - - val PASSWORDS_BUTTON = Selector( - strategy = SelectorStrategy.COMPOSE_BY_TEXT, - value = getStringResource(R.string.browser_menu_passwords), - description = "Main menu Passwords button", - groups = listOf("requiredForPage"), - ) - - val SIGN_IN_BUTTON = Selector( - strategy = SelectorStrategy.COMPOSE_BY_TEXT, - value = getStringResource(R.string.browser_menu_sign_in), - description = "Main menu Sign in button", - groups = listOf("requiredForPage"), - ) - - val SETTINGS_BUTTON = Selector( - strategy = SelectorStrategy.COMPOSE_BY_TEXT, - value = getStringResource(R.string.browser_menu_settings), - description = "Main menu Settings button", - groups = listOf("requiredForPage"), - ) - - val all = listOf( - NEW_PRIVATE_TAB_BUTTON, - EXTENSIONS_BUTTON, - BOOKMARKS_BUTTON, - HISTORY_BUTTON, - DOWLOADS_BUTTON, - PASSWORDS_BUTTON, - SIGN_IN_BUTTON, - SETTINGS_BUTTON, - ) -} diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/MainMenuSelectors.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/MainMenuSelectors.kt @@ -10,54 +10,72 @@ import org.mozilla.fenix.ui.efficiency.helpers.Selector import org.mozilla.fenix.ui.efficiency.helpers.SelectorStrategy object MainMenuSelectors { - val SETTINGS_BUTTON = Selector( - strategy = SelectorStrategy.UIAUTOMATOR2_BY_TEXT, - value = getStringResource(R.string.browser_menu_settings), - description = "Main menu Settings Button", - groups = listOf("requiredForPage"), + + val NEW_PRIVATE_TAB_BUTTON = Selector( + strategy = SelectorStrategy.COMPOSE_BY_TEXT, + value = getStringResource(R.string.browser_menu_new_private_tab), + description = "Main menu New private tab button", + // Removed in https://bugzilla.mozilla.org/show_bug.cgi?id=1966222 as part of the menu redesign effort + groups = listOf("removedIn=141"), ) - val HISTORY_BUTTON = Selector( - strategy = SelectorStrategy.UIAUTOMATOR2_BY_TEXT, - value = getStringResource(R.string.library_history), - description = "Main menu History button", + val EXTENSIONS_BUTTON = Selector( + strategy = SelectorStrategy.COMPOSE_BY_TEXT, + value = getStringResource(R.string.browser_menu_extensions), + description = "Main menu Extensions button", groups = listOf("requiredForPage"), ) val BOOKMARKS_BUTTON = Selector( - strategy = SelectorStrategy.UIAUTOMATOR2_BY_TEXT, + strategy = SelectorStrategy.COMPOSE_BY_TEXT, value = getStringResource(R.string.library_bookmarks), description = "Main menu Bookmarks button", groups = listOf("requiredForPage"), ) - val DOWNLOADS_BUTTON = Selector( - strategy = SelectorStrategy.UIAUTOMATOR2_BY_TEXT, + val HISTORY_BUTTON = Selector( + strategy = SelectorStrategy.COMPOSE_BY_TEXT, + value = getStringResource(R.string.library_history), + description = "Main menu History button", + groups = listOf("requiredForPage"), + ) + + val DOWLOADS_BUTTON = Selector( + strategy = SelectorStrategy.COMPOSE_BY_TEXT, value = getStringResource(R.string.library_downloads), description = "Main menu Downloads button", groups = listOf("requiredForPage"), ) val PASSWORDS_BUTTON = Selector( - strategy = SelectorStrategy.UIAUTOMATOR2_BY_TEXT, + strategy = SelectorStrategy.COMPOSE_BY_TEXT, value = getStringResource(R.string.browser_menu_passwords), description = "Main menu Passwords button", groups = listOf("requiredForPage"), ) - val EXTENSIONS_BUTTON = Selector( - strategy = SelectorStrategy.UIAUTOMATOR_WITH_TEXT, - value = getStringResource(R.string.browser_menu_extensions), - description = "Main menu Extensions button", + val SIGN_IN_BUTTON = Selector( + strategy = SelectorStrategy.COMPOSE_BY_TEXT, + value = getStringResource(R.string.browser_menu_sign_in), + description = "Main menu Sign in button", + groups = listOf("requiredForPage"), + ) + + val SETTINGS_BUTTON = Selector( + strategy = SelectorStrategy.COMPOSE_BY_TEXT, + value = getStringResource(R.string.browser_menu_settings), + description = "Main menu Settings button", groups = listOf("requiredForPage"), ) val all = listOf( - HISTORY_BUTTON, + NEW_PRIVATE_TAB_BUTTON, + EXTENSIONS_BUTTON, BOOKMARKS_BUTTON, - DOWNLOADS_BUTTON, + HISTORY_BUTTON, + DOWLOADS_BUTTON, PASSWORDS_BUTTON, + SIGN_IN_BUTTON, SETTINGS_BUTTON, - EXTENSIONS_BUTTON, ) } diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SearchBarSelectors.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/SearchBarSelectors.kt @@ -4,14 +4,16 @@ package org.mozilla.fenix.ui.efficiency.selectors +import mozilla.components.compose.browser.toolbar.concept.BrowserToolbarTestTags.ADDRESSBAR_SEARCH_BOX +import mozilla.components.compose.browser.toolbar.concept.BrowserToolbarTestTags.SEARCH_SELECTOR import org.mozilla.fenix.ui.efficiency.helpers.Selector import org.mozilla.fenix.ui.efficiency.helpers.SelectorStrategy object SearchBarSelectors { - val EDIT_SEARCHBAR_VIEW = Selector( - strategy = SelectorStrategy.UIAUTOMATOR_WITH_RES_ID, - value = "mozac_browser_toolbar_edit_url_view", - description = "Empty edit search bar", + val TOOLBAR_IN_EDIT_MODE = Selector( + strategy = SelectorStrategy.COMPOSE_BY_TAG, + value = ADDRESSBAR_SEARCH_BOX, + description = "Toolbar in edit mode", groups = listOf(), ) @@ -23,14 +25,14 @@ object SearchBarSelectors { ) val SEARCH_ENGINE_SELECTOR = Selector( - strategy = SelectorStrategy.UIAUTOMATOR_WITH_RES_ID, - value = "search_selector", - description = "Search selector button", + strategy = SelectorStrategy.COMPOSE_BY_TAG, + value = SEARCH_SELECTOR, + description = "Search engine selector button", groups = listOf("requiredForPage"), ) val all = listOf( - EDIT_SEARCHBAR_VIEW, + TOOLBAR_IN_EDIT_MODE, URL_TEXT, SEARCH_ENGINE_SELECTOR, ) diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/ToolbarSelectors.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/selectors/ToolbarSelectors.kt @@ -4,33 +4,36 @@ package org.mozilla.fenix.ui.efficiency.selectors +import mozilla.components.compose.browser.toolbar.concept.BrowserToolbarTestTags.ADDRESSBAR_URL_BOX +import mozilla.components.compose.browser.toolbar.concept.BrowserToolbarTestTags.TABS_COUNTER import org.mozilla.fenix.ui.efficiency.helpers.Selector import org.mozilla.fenix.ui.efficiency.helpers.SelectorStrategy object ToolbarSelectors { val TOOLBAR = Selector( strategy = SelectorStrategy.UIAUTOMATOR_WITH_RES_ID, - value = "toolbar", + value = "composable_toolbar", description = "Toolbar", groups = listOf("requiredForPage"), ) val TAB_COUNTER = Selector( - strategy = SelectorStrategy.UIAUTOMATOR_WITH_RES_ID, - value = "tab_button", + strategy = SelectorStrategy.COMPOSE_BY_TAG, + value = TABS_COUNTER, description = "Tab counter button", groups = listOf("requiredForPage"), ) - val URL_BAR_PLACE_HOLDER = Selector( - strategy = SelectorStrategy.UIAUTOMATOR_WITH_TEXT, - value = "Search or enter address", - description = "URL bar place holder", + val TOOLBAR_URL_BOX = Selector( + strategy = SelectorStrategy.COMPOSE_ON_ALL_NODES_BY_TAG_ON_LAST, + value = ADDRESSBAR_URL_BOX, + description = "URL box", groups = listOf("requiredForPage"), ) val all = listOf( TOOLBAR, TAB_COUNTER, + TOOLBAR_URL_BOX, ) } diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/MainMenuComposeTest.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/efficiency/tests/MainMenuComposeTest.kt @@ -1,18 +0,0 @@ -/* 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.efficiency.tests - -import org.junit.Test -import org.mozilla.fenix.ui.efficiency.helpers.BaseTest - -class MainMenuComposeTest : BaseTest( - isMenuRedesignEnabled = true, -) { - - @Test - fun verifyMainMenuItemsTest() { - on.mainMenuCompose.navigateToPage() - } -} diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/AddToHomeScreenRobot.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/AddToHomeScreenRobot.kt @@ -25,21 +25,21 @@ import org.mozilla.fenix.helpers.TestHelper.packageName /** * Implementation of Robot Pattern for the Add to homescreen feature. */ -class AddToHomeScreenRobot { +class AddToHomeScreenRobot(private val composeTestRule: ComposeTestRule) { - fun verifyAddPrivateBrowsingShortcutButton(composeTestRule: ComposeTestRule) { + fun verifyAddPrivateBrowsingShortcutButton() { Log.i(TAG, "verifyAddPrivateBrowsingShortcutButton: Trying to verify \"Add to Home screen\" private browsing shortcut dialog button is displayed") composeTestRule.onNodeWithTag("private.add").assertIsDisplayed() Log.i(TAG, "verifyAddPrivateBrowsingShortcutButton: Verified \"Add to Home screen\" private browsing shortcut dialog button is displayed") } - fun verifyNoThanksPrivateBrowsingShortcutButton(composeTestRule: ComposeTestRule) { + fun verifyNoThanksPrivateBrowsingShortcutButton() { Log.i(TAG, "verifyNoThanksPrivateBrowsingShortcutButton: Trying to verify \"No thanks\" private browsing shortcut dialog button is displayed") composeTestRule.onNodeWithTag("private.cancel").assertIsDisplayed() Log.i(TAG, "verifyNoThanksPrivateBrowsingShortcutButton: Verified \"No thanks\" private browsing shortcut dialog button is displayed") } - fun clickAddPrivateBrowsingShortcutButton(composeTestRule: ComposeTestRule) { + fun clickAddPrivateBrowsingShortcutButton() { Log.i(TAG, "clickAddPrivateBrowsingShortcutButton: Trying to click \"Add to Home screen\" private browsing shortcut dialog button") composeTestRule.onNodeWithTag("private.add").performClick() Log.i(TAG, "clickAddPrivateBrowsingShortcutButton: Clicked \"Add to Home screen\" private browsing shortcut dialog button") @@ -68,7 +68,7 @@ class AddToHomeScreenRobot { fun verifyShortcutAdded(shortcutTitle: String) = assertUIObjectExists(itemContainingText(shortcutTitle)) - class Transition { + class Transition(private val composeTestRule: ComposeTestRule) { fun openHomeScreenShortcut(title: String, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { Log.i(TAG, "openHomeScreenShortcut: Waiting for $waitingTime ms until finding $title home screen shortcut") mDevice.wait( @@ -80,8 +80,8 @@ class AddToHomeScreenRobot { mDevice.findObject((UiSelector().text(title))).clickAndWaitForNewWindow(waitingTime) Log.i(TAG, "openHomeScreenShortcut: Clicked $title home screen shortcut and waited for $waitingTime ms for a new window") - BrowserRobot().interact() - return BrowserRobot.Transition() + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } fun searchAndOpenHomeScreenShortcut(title: String, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { @@ -102,15 +102,15 @@ class AddToHomeScreenRobot { shortcut().clickAndWaitForNewWindow() Log.i(TAG, "searchAndOpenHomeScreenShortcut: Clicked home screen shortcut: $title and waited for a new window") - BrowserRobot().interact() - return BrowserRobot.Transition() + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } } } -fun addToHomeScreen(interact: AddToHomeScreenRobot.() -> Unit): AddToHomeScreenRobot.Transition { - AddToHomeScreenRobot().interact() - return AddToHomeScreenRobot.Transition() +fun addToHomeScreen(composeTestRule: ComposeTestRule, interact: AddToHomeScreenRobot.() -> Unit): AddToHomeScreenRobot.Transition { + AddToHomeScreenRobot(composeTestRule).interact() + return AddToHomeScreenRobot.Transition(composeTestRule) } private fun cancelAddToHomeScreenButton() = diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/BookmarksRobot.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/BookmarksRobot.kt @@ -255,8 +255,8 @@ class BookmarksRobot(private val composeTestRule: ComposeTestRule) { composeTestRule.onNodeWithText(bookmarkTitle).performClick() Log.i(TAG, "openBookmarkWithTitle: Clicked bookmark with title: $bookmarkTitle") - BrowserRobot().interact() - return BrowserRobot.Transition() + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } @OptIn(ExperimentalTestApi::class) @@ -268,8 +268,8 @@ class BookmarksRobot(private val composeTestRule: ComposeTestRule) { composeTestRule.onNodeWithContentDescription(getStringResource(R.string.bookmark_search_button_content_description)).performClick() Log.i(TAG, "clickSearchButton: Clicked search bookmarks button") - SearchRobot().interact() - return SearchRobot.Transition() + SearchRobot(composeTestRule).interact() + return SearchRobot.Transition(composeTestRule) } fun goBackToBrowserScreen(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { @@ -277,8 +277,8 @@ class BookmarksRobot(private val composeTestRule: ComposeTestRule) { composeTestRule.onNodeWithContentDescription(getStringResource(R.string.bookmark_navigate_back_button_content_description)).performClick() Log.i(TAG, "goBackToBrowserScreen: Clicked go back button") - BrowserRobot().interact() - return BrowserRobot.Transition() + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } fun goBackToHomeScreen(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition { @@ -286,8 +286,8 @@ class BookmarksRobot(private val composeTestRule: ComposeTestRule) { composeTestRule.onNodeWithContentDescription(getStringResource(R.string.bookmark_navigate_back_button_content_description)).performClick() Log.i(TAG, "goBackToHomeScreen: Clicked go back button") - HomeScreenRobot().interact() - return HomeScreenRobot.Transition() + HomeScreenRobot(composeTestRule).interact() + return HomeScreenRobot.Transition(composeTestRule) } } } diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/BrowserRobot.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/BrowserRobot.kt @@ -10,6 +10,9 @@ import android.content.Context import android.net.Uri import android.os.SystemClock import android.util.Log +import androidx.compose.ui.semantics.SemanticsProperties +import androidx.compose.ui.semantics.getOrNull +import androidx.compose.ui.test.ComposeTimeoutException import androidx.compose.ui.test.ExperimentalTestApi import androidx.compose.ui.test.assertAny import androidx.compose.ui.test.assertIsDisplayed @@ -26,18 +29,13 @@ import androidx.compose.ui.test.onNodeWithTag import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.performClick import androidx.compose.ui.test.performTextInput +import androidx.core.net.toUri import androidx.test.espresso.Espresso.closeSoftKeyboard import androidx.test.espresso.Espresso.onView -import androidx.test.espresso.action.ViewActions.click import androidx.test.espresso.action.ViewActions.longClick -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.isDisplayed 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.uiautomator.By import androidx.test.uiautomator.By.text import androidx.test.uiautomator.UiObject @@ -46,12 +44,12 @@ import androidx.test.uiautomator.UiSelector import androidx.test.uiautomator.Until import mozilla.components.browser.state.selector.selectedTab import mozilla.components.browser.state.store.BrowserStore +import mozilla.components.compose.browser.toolbar.concept.BrowserToolbarTestTags.ADDRESSBAR_PROGRESSBAR import mozilla.components.compose.browser.toolbar.concept.BrowserToolbarTestTags.ADDRESSBAR_URL import mozilla.components.compose.browser.toolbar.concept.BrowserToolbarTestTags.ADDRESSBAR_URL_BOX import mozilla.components.compose.browser.toolbar.concept.BrowserToolbarTestTags.TABS_COUNTER import mozilla.components.concept.engine.mediasession.MediaSession import mozilla.components.concept.engine.utils.EngineReleaseChannel -import org.hamcrest.CoreMatchers.allOf import org.junit.Assert.assertTrue import org.junit.Assert.fail import org.mozilla.fenix.R @@ -95,12 +93,34 @@ import mozilla.components.feature.app.links.R as applinksR import mozilla.components.feature.contextmenu.R as contextmenuR import mozilla.components.feature.downloads.R as downloadsR import mozilla.components.feature.prompts.R as promptsR -import mozilla.components.ui.tabcounter.R as tabcounterR -class BrowserRobot { +class BrowserRobot(private val composeTestRule: ComposeTestRule) { private lateinit var sessionLoadedIdlingResource: SessionLoadedIdlingResource - fun waitForPageToLoad(pageLoadWaitingTime: Long = waitingTime) = assertUIObjectIsGone(progressBar(), waitingTime = pageLoadWaitingTime) + @OptIn(ExperimentalTestApi::class) + fun waitForPageToLoad(pageLoadWaitingTime: Long = waitingTime) { + Log.i(TAG, "waitForPageToLoad: Waiting for page load to complete.") + composeTestRule.waitUntilNodeCount(hasTestTag(ADDRESSBAR_PROGRESSBAR), 1, pageLoadWaitingTime) + try { + composeTestRule.waitUntil(pageLoadWaitingTime) { + val nodes = composeTestRule.onAllNodesWithTag(ADDRESSBAR_PROGRESSBAR) + .fetchSemanticsNodes(atLeastOneRootRequired = false) + + val rangeInfo = nodes.first().config + .getOrNull(SemanticsProperties.ProgressBarRangeInfo) + + val isComplete = rangeInfo?.current.also { + Log.i(TAG, "waitForPageToLoad: Current progress: $it%") + } == 100f + if (isComplete) { + Log.i(TAG, "waitForPageToLoad: Progress reached 100%.") + } + isComplete + } + } catch (_: ComposeTimeoutException) { + fail("Page did not finish loading within ${pageLoadWaitingTime}ms.") + } + } fun verifyCurrentPrivateSession(context: Context) { val selectedTab = context.components.core.store.state.selectedTab @@ -110,40 +130,10 @@ class BrowserRobot { } fun verifyUrl(url: String) { - sessionLoadedIdlingResource = SessionLoadedIdlingResource() - - registerAndCleanupIdlingResources(sessionLoadedIdlingResource) { - // Check if toolbar is displayed - // Check if a prompt is being displayed - if ( - !itemWithResId("$packageName:id/mozac_browser_toolbar_url_view").exists() && - itemWithResId("$packageName:id/title").exists() - ) { - Log.i(TAG, "verifyUrl: The toolbar is not displayed") - Log.i(TAG, "verifyUrl: A prompt is being displayed") - Log.i(TAG, "verifyUrl: Trying to click device back button") - // Dismiss the prompt by clicking the device back button - mDevice.pressBack() - Log.i(TAG, "verifyUrl: Clicked device back button") - Log.i(TAG, "verifyUrl: Waiting for $waitingTimeShort ms for $packageName window to be updated") - mDevice.waitForWindowUpdate(packageName, waitingTimeShort) - Log.i(TAG, "verifyUrl: Waited for $waitingTimeShort ms for $packageName window to be updated") - } - - assertUIObjectExists( - itemWithResIdContainingText( - "$packageName:id/mozac_browser_toolbar_url_view", - url.replace("http://", ""), - ), - ) - } - } - - fun verifyUrlWithComposableToolbar(composeTestRule: ComposeTestRule, url: String) { - Log.i(TAG, "verifyUrlWithComposableToolbar: Trying to verify $url") + Log.i(TAG, "verifyUrl: Trying to verify $url") composeTestRule.onAllNodesWithTag(ADDRESSBAR_URL, useUnmergedTree = true) - .assertAny(hasText(url.replace("http://", ""), substring = true)) - Log.i(TAG, "verifyUrlWithComposableToolbar: Verified $url") + .assertAny(hasText(url.replace("http://", ""), substring = true, ignoreCase = true)) + Log.i(TAG, "verifyUrl: Verified $url") } fun verifyHelpUrl() { @@ -162,10 +152,11 @@ class BrowserRobot { fun verifyWhatsNewURL() { try { - verifyUrl("/releaseNotes") + verifyUrl("firefox.com/en-US/firefox/android/") } catch (e: AssertionError) { Log.i(TAG, "verifyWhatsNewURL: AssertionError caught, checking redirect URL") - verifyUrl(SupportUtils.WHATS_NEW_URL) + val redirectURL = SupportUtils.WHATS_NEW_URL.toUri() + verifyUrl(redirectURL.authority?.removePrefix("www.") + redirectURL.encodedPath) } } @@ -189,7 +180,6 @@ class BrowserRobot { fun verifyETPLearnMoreURL() { // Get and log the URL in case there are failures in the future - Log.i(TAG, "verifyETPLearnMoreURL: ETP learn more URL = ${itemWithResId("$packageName:id/mozac_browser_toolbar_url_view").text}") try { verifyUrl("support.mozilla.org/en-US/kb/tracking-protection-firefox-android") } catch (e: AssertionError) { @@ -239,6 +229,12 @@ class BrowserRobot { } } + fun verifyDRMControlledContentPageContent(expectedText: String) { + Log.i(TAG, "verifyDRMControlledContentPageContent: Trying to verify that the DRM controlled content is: $expectedText") + mDevice.findObject(By.textContains(expectedText)) + Log.i(TAG, "verifyDRMControlledContentPageContent: Verified that the DRM controlled content is: $expectedText") + } + fun verifyTextFragmentsPageContent(expectedText: String) { for (i in 1..RETRY_COUNT) { Log.i(TAG, "verifyTextFragmentsPageContent: Started try #$i") @@ -251,9 +247,9 @@ class BrowserRobot { break } catch (e: AssertionError) { Log.i(TAG, "verifyTextFragmentsPageContent: AssertionError caught, executing fallback methods") - navigationToolbar { + browserScreen(composeTestRule) { }.openThreeDotMenu { - }.refreshPage { + }.clickRefreshButton { waitForPageToLoad() } } @@ -299,21 +295,27 @@ class BrowserRobot { assertUIObjectExists(cacheSizeInfo) break } catch (e: AssertionError) { - browserScreen { + browserScreen(this@BrowserRobot.composeTestRule) { }.openThreeDotMenu { - }.refreshPage { } + }.clickRefreshButton { + } } } } - fun verifyTabCounter(numberOfOpenTabs: String) = - onView( - allOf( - withId(tabcounterR.id.counter_text), - withText(numberOfOpenTabs), - withEffectiveVisibility(Visibility.VISIBLE), - ), - ).check(matches(isDisplayed())) + fun verifyTabCounter(numberOfOpenTabs: String, isPrivateBrowsingEnabled: Boolean = false) { + if (isPrivateBrowsingEnabled) { + Log.i(TAG, "verifyTabCounter: Trying to verify that the number of open private tabs is : $numberOfOpenTabs") + composeTestRule.onNodeWithContentDescription("Private Tabs Open: $numberOfOpenTabs. Tap to switch tabs.") + .assertIsDisplayed() + Log.i(TAG, "verifyTabCounter: Verified that the number of open private tabs is : $numberOfOpenTabs") + } else { + Log.i(TAG, "verifyTabCounter: Trying to verify that the number of open tabs is : $numberOfOpenTabs") + composeTestRule.onNodeWithContentDescription("Non-private Tabs Open: $numberOfOpenTabs. Tap to switch tabs.") + .assertIsDisplayed() + Log.i(TAG, "verifyTabCounter: Verified that the number of open tabs is : $numberOfOpenTabs") + } + } fun verifyContextMenuForLocalHostLinks(containsURL: Uri) { // If the link is directing to another local asset the "Download link" option is not available @@ -381,7 +383,7 @@ class BrowserRobot { fun verifyMenuButton() { Log.i(TAG, "verifyMenuButton: Trying to verify main menu button is displayed") - threeDotButton().check(matches(isDisplayed())) + composeTestRule.onNodeWithContentDescription(getStringResource(R.string.content_description_menu)).assertIsDisplayed() Log.i(TAG, "verifyMenuButton: Verified main menu button is displayed") } @@ -408,23 +410,23 @@ class BrowserRobot { assertUIObjectExists(itemWithResId("$packageName:id/engineView")) } - fun createBookmark(composeTestRule: ComposeTestRule, url: Uri, folder: String? = null) { - navigationToolbar { + fun createBookmark(url: Uri, folder: String? = null) { + navigationToolbar(this@BrowserRobot.composeTestRule) { }.enterURLAndEnterToBrowser(url) { // needs to wait for the right url to load before saving a bookmark verifyUrl(url.toString()) }.openThreeDotMenu { - }.bookmarkPage { + }.clickBookmarkThisPageButton { }.takeIf { !folder.isNullOrBlank() }?.let { it.openThreeDotMenu { - }.editBookmarkPage(composeTestRule) { + }.clickEditBookmarkButton { setParentFolder(folder!!) navigateUp() } } } - fun longClickPDFImage() = longClickPageObject(itemWithResId("pdfjs_internal_id_13R")) + fun longClickPDFImage() = longClickPageObject(this@BrowserRobot.composeTestRule, itemWithResId("pdfjs_internal_id_13R")) fun verifyPDFReaderToolbarItems() = assertUIObjectExists( @@ -432,7 +434,7 @@ class BrowserRobot { ) fun clickSubmitLoginButton() { - clickPageObject(itemWithResId("submit")) + clickPageObject(this@BrowserRobot.composeTestRule, itemWithResId("submit")) assertUIObjectIsGone(itemWithResId("submit")) Log.i(TAG, "clickSubmitLoginButton: Waiting for device to be idle for $waitingTimeLong ms") mDevice.waitForIdle(waitingTimeLong) @@ -440,8 +442,8 @@ class BrowserRobot { } fun enterPassword(password: String) { - clickPageObject(itemWithResId("password")) - setPageObjectText(itemWithResId("password"), password) + clickPageObject(this@BrowserRobot.composeTestRule, itemWithResId("password")) + setPageObjectText(this@BrowserRobot.composeTestRule, itemWithResId("password"), password) assertUIObjectIsGone(itemWithText(password)) } @@ -480,31 +482,14 @@ class BrowserRobot { try { Log.i(TAG, "swipeNavBarRight: Try block") Log.i(TAG, "swipeNavBarRight: Trying to perform swipe right action on navigation toolbar") - navURLBar().swipeRight(2) + itemWithResId("$packageName:id/composable_toolbar").swipeRight(2) Log.i(TAG, "swipeNavBarRight: Performed swipe right action on navigation toolbar") assertUIObjectIsGone(itemWithText(tabUrl)) } catch (e: AssertionError) { Log.i(TAG, "swipeNavBarRight: AssertionError caught, executing fallback methods") Log.i(TAG, "swipeNavBarRight: Trying to perform swipe right action on navigation toolbar") - navURLBar().swipeRight(2) - Log.i(TAG, "swipeNavBarRight: Performed swipe right action on navigation toolbar") - assertUIObjectIsGone(itemWithText(tabUrl)) - } - } - - fun swipeNavBarRightWithComposableToolbar(composeTestRule: ComposeTestRule, tabUrl: String) { - // failing to swipe on Firebase sometimes, so it tries again - try { - Log.i(TAG, "swipeNavBarRightWithComposableToolbar: Try block") - Log.i(TAG, "swipeNavBarRightWithComposableToolbar: Trying to perform swipe right action on navigation toolbar") - itemWithResId("$packageName:id/composable_toolbar").swipeRight(2) - Log.i(TAG, "swipeNavBarRightWithComposableToolbar: Performed swipe right action on navigation toolbar") - assertUIObjectIsGone(itemWithText(tabUrl)) - } catch (e: AssertionError) { - Log.i(TAG, "swipeNavBarRightWithComposableToolbar: AssertionError caught, executing fallback methods") - Log.i(TAG, "swipeNavBarRightWithComposableToolbar: Trying to perform swipe right action on navigation toolbar") itemWithResId("$packageName:id/composable_toolbar").swipeRight(2) - Log.i(TAG, "swipeNavBarRightWithComposableToolbar: Performed swipe right action on navigation toolbar") + Log.i(TAG, "swipeNavBarRight: Performed swipe right action on navigation toolbar") assertUIObjectIsGone(itemWithText(tabUrl)) } } @@ -514,31 +499,14 @@ class BrowserRobot { try { Log.i(TAG, "swipeNavBarLeft: Try block") Log.i(TAG, "swipeNavBarLeft: Trying to perform swipe left action on navigation toolbar") - navURLBar().swipeLeft(2) + itemWithResId("$packageName:id/composable_toolbar").swipeLeft(2) Log.i(TAG, "swipeNavBarLeft: Performed swipe left action on navigation toolbar") assertUIObjectIsGone(itemWithText(tabUrl)) } catch (e: AssertionError) { Log.i(TAG, "swipeNavBarLeft: AssertionError caught, executing fallback methods") Log.i(TAG, "swipeNavBarLeft: Trying to perform swipe left action on navigation toolbar") - navURLBar().swipeLeft(2) - Log.i(TAG, "swipeNavBarLeft: Performed swipe left action on navigation toolbar") - assertUIObjectIsGone(itemWithText(tabUrl)) - } - } - - fun swipeNavBarLeftWithComposableToolbar(composeTestRule: ComposeTestRule, tabUrl: String) { - // failing to swipe on Firebase sometimes, so it tries again - try { - Log.i(TAG, "swipeNavBarLeftWithComposableToolbar: Try block") - Log.i(TAG, "swipeNavBarLeftWithComposableToolbar: Trying to perform swipe left action on navigation toolbar") itemWithResId("$packageName:id/composable_toolbar").swipeLeft(2) - Log.i(TAG, "swipeNavBarLeftWithComposableToolbar: Performed swipe left action on navigation toolbar") - assertUIObjectIsGone(itemWithText(tabUrl)) - } catch (e: AssertionError) { - Log.i(TAG, "swipeNavBarLeftWithComposableToolbar: AssertionError caught, executing fallback methods") - Log.i(TAG, "swipeNavBarLeftWithComposableToolbar: Trying to perform swipe left action on navigation toolbar") - itemWithResId("$packageName:id/composable_toolbar").swipeLeft(2) - Log.i(TAG, "swipeNavBarLeftWithComposableToolbar: Performed swipe left action on navigation toolbar") + Log.i(TAG, "swipeNavBarLeft: Performed swipe left action on navigation toolbar") assertUIObjectIsGone(itemWithText(tabUrl)) } } @@ -558,19 +526,19 @@ class BrowserRobot { if (i == RETRY_COUNT) { throw e } else { - clickPageObject(itemWithResId("username")) + clickPageObject(this@BrowserRobot.composeTestRule, itemWithResId("username")) } } } } @OptIn(ExperimentalTestApi::class) - fun clickSuggestedLogin(composeTestRule: ComposeTestRule, userName: String) { + fun clickSuggestedLogin(userName: String) { Log.i(TAG, "clickSuggestedLogin: Waiting for the suggested user name: $userName to exist") - composeTestRule.waitUntilAtLeastOneExists(hasText(userName)) + this@BrowserRobot.composeTestRule.waitUntilAtLeastOneExists(hasText(userName)) Log.i(TAG, "clickSuggestedLogin: Waited for the suggested user name: $userName to exist") Log.i(TAG, "clickSuggestedLogin: Trying to click $userName login suggestion") - composeTestRule.onNodeWithText(userName).performClick() + this@BrowserRobot.composeTestRule.onNodeWithText(userName).performClick() Log.i(TAG, "clickSuggestedLogin: Clicked $userName login suggestion") } @@ -606,8 +574,8 @@ class BrowserRobot { if (i == RETRY_COUNT) { throw e } else { - clickPageObject(itemWithResId("city")) - clickPageObject(itemWithResId("country")) + clickPageObject(this@BrowserRobot.composeTestRule, itemWithResId("city")) + clickPageObject(this@BrowserRobot.composeTestRule, itemWithResId("country")) } } } @@ -684,16 +652,16 @@ class BrowserRobot { } @OptIn(ExperimentalTestApi::class) - fun verifySuggestedUserName(composeTestRule: ComposeTestRule, userName: String) { + fun verifySuggestedUserName(userName: String) { Log.i(TAG, "verifySuggestedUserName: Waiting for the suggested user name: $userName to exist") - composeTestRule.waitUntilAtLeastOneExists(hasText(userName)) + this@BrowserRobot.composeTestRule.waitUntilAtLeastOneExists(hasText(userName)) Log.i(TAG, "verifySuggestedUserName: Waited for the suggested user name: $userName to exist") Log.i(TAG, "verifySuggestedUserName: Trying to assert that user name: $userName exists") - composeTestRule.onNodeWithText(userName).assertExists() + this@BrowserRobot.composeTestRule.onNodeWithText(userName).assertExists() Log.i(TAG, "verifySuggestedUserName: Asserted that user name: $userName exists") } - fun verifyPrefilledLoginCredentials(composeTestRule: ComposeTestRule, userName: String, password: String, credentialsArePrefilled: Boolean) { + fun verifyPrefilledLoginCredentials(userName: String, password: String, credentialsArePrefilled: Boolean) { // Sometimes the assertion of the pre-filled logins fails so we are re-trying after refreshing the page for (i in 1..RETRY_COUNT) { try { @@ -709,14 +677,14 @@ class BrowserRobot { if (i == RETRY_COUNT) { throw e } else { - browserScreen { + browserScreen(this@BrowserRobot.composeTestRule) { }.openThreeDotMenu { - }.refreshPage { + }.clickRefreshButton { clearTextFieldItem(itemWithResId("username")) clickSuggestedLoginsButton() - verifySuggestedUserName(composeTestRule, userName) - clickSuggestedLogin(composeTestRule, userName) - clickPageObject(itemWithResId("togglePassword")) + verifySuggestedUserName(userName) + clickSuggestedLogin(userName) + clickPageObject(this.composeTestRule, itemWithResId("togglePassword")) } } } @@ -763,9 +731,9 @@ class BrowserRobot { } else { Log.e(TAG, "On try $i, trackers are not: $state") - navigationToolbar { + browserScreen(composeTestRule) { }.openThreeDotMenu { - }.refreshPage { + }.clickRefreshButton { } } } @@ -806,10 +774,10 @@ class BrowserRobot { Log.i(TAG, "verifySelectedDate: AssertionError caught, executing fallback methods") Log.e(TAG, "Selected time isn't displayed ${e.localizedMessage}") - clickPageObject(itemWithResId("calendar")) - clickPageObject(itemWithDescription("$currentDay $currentMonth $currentYear")) - clickPageObject(itemContainingText("OK")) - clickPageObject(itemWithResId("submitDate")) + clickPageObject(this@BrowserRobot.composeTestRule, itemWithResId("calendar")) + clickPageObject(this@BrowserRobot.composeTestRule, itemWithDescription("$currentDay $currentMonth $currentYear")) + clickPageObject(this@BrowserRobot.composeTestRule, itemContainingText("OK")) + clickPageObject(this@BrowserRobot.composeTestRule, itemWithResId("submitDate")) } } @@ -834,12 +802,12 @@ class BrowserRobot { Log.i(TAG, "verifySelectedTime: AssertionError caught, executing fallback methods") Log.e(TAG, "Selected time isn't displayed ${e.localizedMessage}") - clickPageObject(itemWithResId("clock")) - clickPageObject(itemContainingText("CLEAR")) - clickPageObject(itemWithResId("clock")) + clickPageObject(this@BrowserRobot.composeTestRule, itemWithResId("clock")) + clickPageObject(this@BrowserRobot.composeTestRule, itemContainingText("CLEAR")) + clickPageObject(this@BrowserRobot.composeTestRule, itemWithResId("clock")) selectTime(hour, minute) - clickPageObject(itemContainingText("OK")) - clickPageObject(itemWithResId("submitTime")) + clickPageObject(this@BrowserRobot.composeTestRule, itemContainingText("OK")) + clickPageObject(this@BrowserRobot.composeTestRule, itemWithResId("submitTime")) } } assertUIObjectExists(itemContainingText("Selected time is: $hour:$minute")) @@ -856,10 +824,10 @@ class BrowserRobot { Log.i(TAG, "verifySelectedColor: AssertionError caught, executing fallback methods") Log.e(TAG, "Selected color isn't displayed ${e.localizedMessage}") - clickPageObject(itemWithResId("colorPicker")) - clickPageObject(itemWithDescription(hexValue)) - clickPageObject(itemContainingText("SET")) - clickPageObject(itemWithResId("submitColor")) + clickPageObject(this@BrowserRobot.composeTestRule, itemWithResId("colorPicker")) + clickPageObject(this@BrowserRobot.composeTestRule, itemWithDescription(hexValue)) + clickPageObject(this@BrowserRobot.composeTestRule, itemContainingText("SET")) + clickPageObject(this@BrowserRobot.composeTestRule, itemWithResId("submitColor")) } } @@ -884,9 +852,9 @@ class BrowserRobot { Log.i(TAG, "verifySelectedDropDownOption: AssertionError caught, executing fallback methods") Log.e(TAG, "Selected option isn't displayed ${e.localizedMessage}") - clickPageObject(itemWithResId("dropDown")) - clickPageObject(itemContainingText(optionName)) - clickPageObject(itemWithResId("submitOption")) + clickPageObject(this@BrowserRobot.composeTestRule, itemWithResId("dropDown")) + clickPageObject(this@BrowserRobot.composeTestRule, itemContainingText(optionName)) + clickPageObject(this@BrowserRobot.composeTestRule, itemWithResId("submitOption")) } } @@ -980,11 +948,11 @@ class BrowserRobot { if (i == RETRY_COUNT) { throw e } else { - browserScreen { + browserScreen(this@BrowserRobot.composeTestRule) { }.openThreeDotMenu { - }.refreshPage { + }.clickRefreshButton { waitForPageToLoad(pageLoadWaitingTime = waitingTimeLong) - clickPageObject(pageObject) + clickPageObject(this.composeTestRule, pageObject) } } } @@ -1052,9 +1020,9 @@ class BrowserRobot { if (i == RETRY_COUNT) { throw e } else { - browserScreen { + browserScreen(this@BrowserRobot.composeTestRule) { }.openThreeDotMenu { - }.refreshPage { + }.clickRefreshButton { waitForPageToLoad(pageLoadWaitingTime = waitingTimeLong) } } @@ -1208,9 +1176,9 @@ class BrowserRobot { Log.i(TAG, "selectToAlwaysOpenDownloadedFileWithApp: Clicked the \"Always\" button from the \"Open with\" prompt") } - fun verifyWebCompatReporterViewItems(composeTestRule: ComposeTestRule, websiteURL: String) { + fun verifyWebCompatReporterViewItems(websiteURL: String) { Log.i(TAG, "verifyWebCompatReporterViewItems: Trying to verify that the report broken site description is displayed") - composeTestRule.onNodeWithContentDescription( + this@BrowserRobot.composeTestRule.onNodeWithContentDescription( getStringResource( R.string.webcompat_reporter_description_3, appName, @@ -1219,22 +1187,22 @@ class BrowserRobot { ).assertIsDisplayed() Log.i(TAG, "verifyWebCompatReporterViewItems: Verified that the report broken site description is displayed") Log.i(TAG, "verifyWebCompatReporterViewItems: Trying to verify that the \"URL\" header is displayed") - composeTestRule.onNodeWithText(getStringResource(R.string.webcompat_reporter_label_url)).assertIsDisplayed() + this@BrowserRobot.composeTestRule.onNodeWithText(getStringResource(R.string.webcompat_reporter_label_url)).assertIsDisplayed() Log.i(TAG, "verifyWebCompatReporterViewItems: Verified that the \"What’s broken?\" header is displayed") Log.i(TAG, "verifyWebCompatReporterViewItems: Trying to verify that the $websiteURL url is displayed") - composeTestRule.onNodeWithText(websiteURL).assertIsDisplayed() + this@BrowserRobot.composeTestRule.onNodeWithText(websiteURL).assertIsDisplayed() Log.i(TAG, "verifyWebCompatReporterViewItems: Verified that the $websiteURL url is displayed") Log.i(TAG, "verifyWebCompatReporterViewItems: Trying to verify that the \"What’s broken?\" header is displayed") - composeTestRule.onNodeWithText(getStringResource(R.string.webcompat_reporter_label_whats_broken_2)).assertIsDisplayed() + this@BrowserRobot.composeTestRule.onNodeWithText(getStringResource(R.string.webcompat_reporter_label_whats_broken_2)).assertIsDisplayed() Log.i(TAG, "verifyWebCompatReporterViewItems: Verified that the \"What’s broken?\" header is displayed") Log.i(TAG, "verifyWebCompatReporterViewItems: Trying to verify that the \"Choose a reason\" field is displayed") - composeTestRule.onNodeWithText(getStringResource(R.string.webcompat_reporter_choose_reason_2)).assertIsDisplayed() + this@BrowserRobot.composeTestRule.onNodeWithText(getStringResource(R.string.webcompat_reporter_choose_reason_2)).assertIsDisplayed() Log.i(TAG, "verifyWebCompatReporterViewItems: Verified that the \"Choose a reason\" field is displayed") Log.i(TAG, "verifyWebCompatReporterViewItems: Trying to verify that the \"Please choose a reason\" error message is displayed") - composeTestRule.onNodeWithTag(BROKEN_SITE_REPORTER_CHOOSE_REASON_BUTTON).assertIsDisplayed() + this@BrowserRobot.composeTestRule.onNodeWithTag(BROKEN_SITE_REPORTER_CHOOSE_REASON_BUTTON).assertIsDisplayed() Log.i(TAG, "verifyWebCompatReporterViewItems: Verified that the \"Please choose a reason\" error message is displayed") Log.i(TAG, "verifyWebCompatReporterViewItems: Trying to verify that the \"Describe the problem (optional)\" field is displayed") - composeTestRule.onNodeWithText(getStringResource(R.string.webcompat_reporter_label_description)).assertIsDisplayed() + this@BrowserRobot.composeTestRule.onNodeWithText(getStringResource(R.string.webcompat_reporter_label_description)).assertIsDisplayed() Log.i(TAG, "verifyWebCompatReporterViewItems: Verified that the \"Describe the problem (optional)\" field is displayed") if (appContext.components.core.engine.version.releaseChannel !== EngineReleaseChannel.RELEASE) { Log.i( @@ -1245,7 +1213,7 @@ class BrowserRobot { TAG, "verifyWebCompatReporterViewItems: Trying to verify that the \"Add more info\" link is displayed", ) - composeTestRule.onNodeWithText(getStringResource(R.string.webcompat_reporter_add_more_info)) + this@BrowserRobot.composeTestRule.onNodeWithText(getStringResource(R.string.webcompat_reporter_add_more_info)) .assertIsDisplayed() Log.i( TAG, @@ -1253,10 +1221,10 @@ class BrowserRobot { ) } Log.i(TAG, "verifyWebCompatReporterViewItems: Trying to verify that the \"Cancel\" button is displayed") - composeTestRule.onNodeWithText(getStringResource(R.string.webcompat_reporter_cancel)).assertIsDisplayed() + this@BrowserRobot.composeTestRule.onNodeWithText(getStringResource(R.string.webcompat_reporter_cancel)).assertIsDisplayed() Log.i(TAG, "verifyWebCompatReporterViewItems: Verified that the \"Cancel \" button is displayed") Log.i(TAG, "verifyWebCompatReporterViewItems: Trying to verify that the \"Send\" button is displayed") - composeTestRule.onNodeWithText(getStringResource(R.string.webcompat_reporter_send)).assertIsDisplayed() + this@BrowserRobot.composeTestRule.onNodeWithText(getStringResource(R.string.webcompat_reporter_send)).assertIsDisplayed() Log.i(TAG, "verifyWebCompatReporterViewItems: Verified that the \"Send \" button is displayed") } @@ -1309,35 +1277,35 @@ class BrowserRobot { Log.i(TAG, "clickBrokenSiteFormSendButton: Clicked the \"Cancel\" button") } - fun describeBrokenSiteProblem(composeTestRule: ComposeTestRule, problemDescription: String) { + fun describeBrokenSiteProblem(problemDescription: String) { Log.i(TAG, "describeBrokenSiteProblem: Trying to click the \"Describe the problem (optional)\" field") - composeTestRule.onNodeWithText(getStringResource(R.string.webcompat_reporter_label_description)).performClick() + this@BrowserRobot.composeTestRule.onNodeWithText(getStringResource(R.string.webcompat_reporter_label_description)).performClick() Log.i(TAG, "describeBrokenSiteProblem: Clicked the \"Describe the problem (optional)\" field") Log.i(TAG, "describeBrokenSiteProblem: Trying to set the text of the \"Describe the problem (optional)\" field to $problemDescription") - composeTestRule.onNode(hasText(getStringResource(R.string.webcompat_reporter_label_description))).performTextInput(problemDescription) + this@BrowserRobot.composeTestRule.onNode(hasText(getStringResource(R.string.webcompat_reporter_label_description))).performTextInput(problemDescription) Log.i(TAG, "describeBrokenSiteProblem: Set the text of the \"Describe the problem (optional)\" field to $problemDescription") } - fun verifyBrokenSiteProblem(composeTestRule: ComposeTestRule, problemDescription: String, isDisplayed: Boolean) { + fun verifyBrokenSiteProblem(problemDescription: String, isDisplayed: Boolean) { if (isDisplayed) { Log.i(TAG, "verifyBrokenSiteProblem: Trying to verify that the $problemDescription broken site problem is displayed") - composeTestRule.onNodeWithText(problemDescription).assertIsDisplayed() + this@BrowserRobot.composeTestRule.onNodeWithText(problemDescription).assertIsDisplayed() Log.i(TAG, "verifyBrokenSiteProblem: Verified that the $problemDescription broken site problem is displayed") } else { Log.i(TAG, "verifyBrokenSiteProblem: Trying to verify that the $problemDescription broken site problem is not displayed") - composeTestRule.onNodeWithText(problemDescription).assertIsNotDisplayed() + this@BrowserRobot.composeTestRule.onNodeWithText(problemDescription).assertIsNotDisplayed() Log.i(TAG, "verifyBrokenSiteProblem: Verified that the $problemDescription broken site problem is not displayed") } } - fun verifySendButtonIsEnabled(composeTestRule: ComposeTestRule, isEnabled: Boolean) { + fun verifySendButtonIsEnabled(isEnabled: Boolean) { if (isEnabled) { Log.i(TAG, "verifySendButtonIsEnabled: Trying to verify that the the \"Send\" button is enabled") - composeTestRule.onNodeWithTag(BROKEN_SITE_REPORTER_SEND_BUTTON).assertIsEnabled() + this@BrowserRobot.composeTestRule.onNodeWithTag(BROKEN_SITE_REPORTER_SEND_BUTTON).assertIsEnabled() Log.i(TAG, "verifySendButtonIsEnabled: Verified that the the \"Send\" button is enabled") } else { Log.i(TAG, "verifySendButtonIsEnabled: Trying to verify that the the \"Send\" button is not enabled") - composeTestRule.onNodeWithTag(BROKEN_SITE_REPORTER_SEND_BUTTON).assertIsNotEnabled() + this@BrowserRobot.composeTestRule.onNodeWithTag(BROKEN_SITE_REPORTER_SEND_BUTTON).assertIsNotEnabled() Log.i(TAG, "verifySendButtonIsEnabled: Verified that the the \"Send\" button is not enabled") } } @@ -1377,9 +1345,9 @@ class BrowserRobot { if (i == RETRY_COUNT) { throw e } else { - browserScreen { + browserScreen(this@BrowserRobot.composeTestRule) { }.openThreeDotMenu { - }.refreshPage { + }.clickRefreshButton { waitForPageToLoad(pageLoadWaitingTime = waitingTimeLong) } if (isSmartBlockFixesItem) { @@ -1391,112 +1359,51 @@ class BrowserRobot { } fun clickWebCompatPageItem(itemText: String) { - clickPageObject(itemContainingText(itemText)) + clickPageObject(this@BrowserRobot.composeTestRule, itemContainingText(itemText)) } - class Transition { + class Transition(private val composeTestRule: ComposeTestRule) { fun openThreeDotMenu(interact: ThreeDotMenuMainRobot.() -> Unit): ThreeDotMenuMainRobot.Transition { - Log.i(TAG, "openThreeDotMenu: Waiting for device to be idle for $waitingTime ms") - mDevice.waitForIdle(waitingTime) - Log.i(TAG, "openThreeDotMenu: Device was idle for $waitingTime ms") - Log.i(TAG, "openThreeDotMenu: Trying to click the main menu button") - threeDotButton().perform(click()) - Log.i(TAG, "openThreeDotMenu: Clicked the main menu button") - - ThreeDotMenuMainRobot().interact() - return ThreeDotMenuMainRobot.Transition() - } - - fun openThreeDotMenu(composeTestRule: ComposeTestRule, interact: ThreeDotMenuMainRobotCompose.() -> Unit): ThreeDotMenuMainRobotCompose.Transition { Log.i(TAG, "openThreeDotMenu: Trying to click main menu button") - itemWithDescription(getStringResource(R.string.content_description_menu)).click() - Log.i(TAG, "openThreeDotMenu: Clicked main menu button") - waitForAppWindowToBeUpdated() - - ThreeDotMenuMainRobotCompose(composeTestRule).interact() - return ThreeDotMenuMainRobotCompose.Transition(composeTestRule) - } - - fun openThreeDotMenuWithComposableToolbar(composeTestRule: ComposeTestRule, interact: ThreeDotMenuMainRobotCompose.() -> Unit): ThreeDotMenuMainRobotCompose.Transition { - Log.i(TAG, "openThreeDotMenuWithComposableToolbar: Trying to click main menu button") composeTestRule.onNodeWithContentDescription(getStringResource(R.string.content_description_menu)).performClick() - Log.i(TAG, "openThreeDotMenuWithComposableToolbar: Clicked main menu button") + Log.i(TAG, "openThreeDotMenu: Clicked main menu button") assertUIObjectExists(itemWithResId("$packageName:id/design_bottom_sheet")) - ThreeDotMenuMainRobotCompose(composeTestRule).interact() - return ThreeDotMenuMainRobotCompose.Transition(composeTestRule) - } - - fun openNavigationToolbar(interact: NavigationToolbarRobot.() -> Unit): NavigationToolbarRobot.Transition { - navURLBar().waitForExists(waitingTime) - Log.i(TAG, "openNavigationToolbar: Trying to click the address bar.") - navURLBar().click() - Log.i(TAG, "openNavigationToolbar: Clicked the address bar.") - Log.i(TAG, "openNavigationToolbar: Waiting for $waitingTime ms for for search bar to exist") - searchBar().waitForExists(waitingTime) - Log.i(TAG, "openNavigationToolbar: Waited for $waitingTime ms for for search bar to exist") - - NavigationToolbarRobot().interact() - return NavigationToolbarRobot.Transition() + ThreeDotMenuMainRobot(composeTestRule).interact() + return ThreeDotMenuMainRobot.Transition(composeTestRule) } @OptIn(ExperimentalTestApi::class) - fun openSearchWithComposableToolbar(composeTestRule: ComposeTestRule, interact: SearchRobot.() -> Unit): SearchRobot.Transition { + fun openSearch(interact: SearchRobot.() -> Unit): SearchRobot.Transition { composeTestRule.waitUntilAtLeastOneExists(hasTestTag(ADDRESSBAR_URL_BOX), waitingTime) - Log.i(TAG, "openSearchWithComposableToolbar: Trying to click navigation toolbar") + Log.i(TAG, "openSearch: Trying to click navigation toolbar") composeTestRule.onAllNodesWithTag(ADDRESSBAR_URL_BOX).onLast().performClick() - Log.i(TAG, "openSearchWithComposableToolbar: Clicked navigation toolbar") + Log.i(TAG, "openSearch: Clicked navigation toolbar") waitForAppWindowToBeUpdated() - SearchRobot().interact() - return SearchRobot.Transition() + SearchRobot(composeTestRule).interact() + return SearchRobot.Transition(composeTestRule) } - fun openTabDrawer(composeTestRule: HomeActivityComposeTestRule, interact: TabDrawerRobot.() -> Unit): TabDrawerRobot.Transition { - for (i in 1..RETRY_COUNT) { - try { - Log.i(TAG, "openTabDrawer: Started try #$i") - mDevice.waitForObjects( - mDevice.findObject( - UiSelector() - .resourceId("$packageName:id/mozac_browser_toolbar_browser_actions"), - ), - waitingTime, - ) - Log.i(TAG, "openTabDrawer: Trying to click the tab counter button") - tabsCounter().click() - Log.i(TAG, "openTabDrawer: Clicked the tab counter button") - Log.i(TAG, "openTabDrawer: Trying to verify the tabs tray exists") - composeTestRule.onNodeWithTag(TabsTrayTestTag.TABS_TRAY).assertExists() - Log.i(TAG, "openTabDrawer: Verified the tabs tray exists") - - break - } catch (e: AssertionError) { - Log.i(TAG, "openTabDrawer: AssertionError caught, executing fallback methods") - if (i == RETRY_COUNT) { - throw e - } else { - Log.i(TAG, "openTabDrawer: Waiting for device to be idle") - mDevice.waitForIdle() - Log.i(TAG, "openTabDrawer: Waited for device to be idle") - } - } - } - Log.i(TAG, "openTabDrawer: Trying to verify the tabs tray new tab FAB button exists") - composeTestRule.onNodeWithTag(TabsTrayTestTag.FAB).assertExists() - Log.i(TAG, "openTabDrawer: Verified the tabs tray new tab FAB button exists") + @OptIn(ExperimentalTestApi::class) + fun openNavigationToolbar(interact: NavigationToolbarRobot.() -> Unit): NavigationToolbarRobot.Transition { + composeTestRule.waitUntilAtLeastOneExists(hasTestTag(ADDRESSBAR_URL_BOX), waitingTime) + Log.i(TAG, "openNavigationToolbar: Trying to click navigation toolbar") + composeTestRule.onAllNodesWithTag(ADDRESSBAR_URL_BOX).onLast().performClick() + Log.i(TAG, "openNavigationToolbar: Clicked navigation toolbar") + waitForAppWindowToBeUpdated() - TabDrawerRobot(composeTestRule).interact() - return TabDrawerRobot.Transition(composeTestRule) + NavigationToolbarRobot(composeTestRule).interact() + return NavigationToolbarRobot.Transition(composeTestRule) } - fun openTabDrawerWithComposableToolbar(composeTestRule: HomeActivityComposeTestRule, interact: TabDrawerRobot.() -> Unit): TabDrawerRobot.Transition { - Log.i(TAG, "openTabDrawerWithComposableToolbar: Trying to click the tab counter button") + fun openTabDrawer(composeTestRule: HomeActivityComposeTestRule, interact: TabDrawerRobot.() -> Unit): TabDrawerRobot.Transition { + Log.i(TAG, "openTabDrawer: Trying to click the tab counter button") composeTestRule.onNodeWithTag(TABS_COUNTER).performClick() - Log.i(TAG, "openTabDrawerWithComposableToolbar: Clicked the tab counter button") - Log.i(TAG, "openTabDrawerWithComposableToolbar: Trying to verify the tabs tray exists") + Log.i(TAG, "openTabDrawer: Clicked the tab counter button") + Log.i(TAG, "openTabDrawer: Trying to verify the tabs tray exists") composeTestRule.onNodeWithTag(TabsTrayTestTag.TABS_TRAY).assertExists() - Log.i(TAG, "openTabDrawerWithComposableToolbar: Verified the tabs tray exists") + Log.i(TAG, "openTabDrawer: Verified the tabs tray exists") Log.i(TAG, "openTabDrawer: Trying to verify the tabs tray new tab FAB button exists") composeTestRule.onNodeWithTag(TabsTrayTestTag.FAB).assertExists() Log.i(TAG, "openTabDrawer: Verified the tabs tray new tab FAB button exists") @@ -1515,41 +1422,28 @@ class BrowserRobot { } @OptIn(ExperimentalTestApi::class) - fun goToHomescreen(composeTestRule: ComposeTestRule, interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition { - Log.i(TAG, "goToHomescreen: Trying to click the go to home screen button.") - itemWithResId("$packageName:id/mozac_browser_toolbar_navigation_actions").click() - Log.i(TAG, "goToHomescreen: Clicked the go to home screen button.") - Log.i(TAG, "goToHomescreen: Waiting for home screen to exist") - composeTestRule.waitUntilAtLeastOneExists(hasTestTag(HOMEPAGE)) - Log.i(TAG, "goToHomescreen: Waited for home screen to exist") - - HomeScreenRobot().interact() - return HomeScreenRobot.Transition() - } - - @OptIn(ExperimentalTestApi::class) - fun goToHomescreenWithComposableToolbar(composeTestRule: ComposeTestRule, isPrivateModeEnabled: Boolean = false, interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition { + fun goToHomescreen(isPrivateModeEnabled: Boolean = false, interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition { if (isPrivateModeEnabled) { - Log.i(TAG, "goToHomescreenWithComposableToolbar: Trying to click the \"New private tab\" button.") + Log.i(TAG, "goToHomescreen: Trying to click the \"New private tab\" button.") composeTestRule.onNodeWithContentDescription("New private tab").performClick() - Log.i(TAG, "goToHomescreenWithComposableToolbar: Clicked the \"New private tab\" button.") + Log.i(TAG, "goToHomescreen: Clicked the \"New private tab\" button.") } else { - Log.i(TAG, "goToHomescreenWithComposableToolbar: Trying to click the \"New tab\" button.") + Log.i(TAG, "goToHomescreen: Trying to click the \"New tab\" button.") composeTestRule.onNodeWithContentDescription("New tab").performClick() - Log.i(TAG, "goToHomescreenWithComposableToolbar: Clicked the \"New tab\" button.") + Log.i(TAG, "goToHomescreen: Clicked the \"New tab\" button.") } - Log.i(TAG, "goToHomescreenWithComposableToolbar: Trying to close the keyboard.") + Log.i(TAG, "goToHomescreen: Trying to close the keyboard.") closeSoftKeyboard() - Log.i(TAG, "goToHomescreenWithComposableToolbar: Closed the keyboard.") - Log.i(TAG, "goToHomescreenWithComposableToolbar: Waiting for home screen to exist") + Log.i(TAG, "goToHomescreen: Closed the keyboard.") + Log.i(TAG, "goToHomescreen: Waiting for home screen to exist") composeTestRule.waitUntilAtLeastOneExists(hasTestTag(HOMEPAGE)) - Log.i(TAG, "goToHomescreenWithComposableToolbar: Waited for home screen to exist") - Log.i(TAG, "goToHomescreenWithComposableToolbar: Trying to click the device back button") + Log.i(TAG, "goToHomescreen: Waited for home screen to exist") + Log.i(TAG, "goToHomescreen: Trying to click the device back button") mDevice.pressBack() - Log.i(TAG, "goToHomescreenWithComposableToolbar: Clicked the device back button") + Log.i(TAG, "goToHomescreen: Clicked the device back button") - HomeScreenRobot().interact() - return HomeScreenRobot.Transition() + HomeScreenRobot(composeTestRule).interact() + return HomeScreenRobot.Transition(composeTestRule) } fun goBack(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition { @@ -1557,18 +1451,18 @@ class BrowserRobot { mDevice.pressBack() Log.i(TAG, "goBack: Clicked device back button") - HomeScreenRobot().interact() - return HomeScreenRobot.Transition() + HomeScreenRobot(composeTestRule).interact() + return HomeScreenRobot.Transition(composeTestRule) } fun clickTabCrashedCloseButton(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition { - clickPageObject(itemWithText("Close tab")) + clickPageObject(composeTestRule, itemWithText("Close tab")) Log.i(TAG, "clickTabCrashedCloseButton: Waiting for device to be idle") mDevice.waitForIdle() Log.i(TAG, "clickTabCrashedCloseButton: Waited for device to be idle") - HomeScreenRobot().interact() - return HomeScreenRobot.Transition() + HomeScreenRobot(composeTestRule).interact() + return HomeScreenRobot.Transition(composeTestRule) } fun clickShareSelectedText(interact: ShareOverlayRobot.() -> Unit): ShareOverlayRobot.Transition { @@ -1579,51 +1473,51 @@ class BrowserRobot { } fun clickDownloadLink(title: String, interact: DownloadRobot.() -> Unit): DownloadRobot.Transition { - clickPageObject(itemContainingText(title)) + clickPageObject(composeTestRule, itemContainingText(title)) - DownloadRobot().interact() - return DownloadRobot.Transition() + DownloadRobot(composeTestRule).interact() + return DownloadRobot.Transition(composeTestRule) } fun clickStartCameraButton(interact: SitePermissionsRobot.() -> Unit): SitePermissionsRobot.Transition { // Test page used for testing permissions located at https://mozilla-mobile.github.io/testapp/permissions - clickPageObject(itemWithText("Open camera")) + clickPageObject(composeTestRule, itemWithText("Open camera")) - SitePermissionsRobot().interact() - return SitePermissionsRobot.Transition() + SitePermissionsRobot(composeTestRule).interact() + return SitePermissionsRobot.Transition(composeTestRule) } fun clickStartMicrophoneButton(interact: SitePermissionsRobot.() -> Unit): SitePermissionsRobot.Transition { // Test page used for testing permissions located at https://mozilla-mobile.github.io/testapp/permissions - clickPageObject(itemWithText("Open microphone")) + clickPageObject(composeTestRule, itemWithText("Open microphone")) - SitePermissionsRobot().interact() - return SitePermissionsRobot.Transition() + SitePermissionsRobot(composeTestRule).interact() + return SitePermissionsRobot.Transition(composeTestRule) } fun clickStartAudioVideoButton(interact: SitePermissionsRobot.() -> Unit): SitePermissionsRobot.Transition { // Test page used for testing permissions located at https://mozilla-mobile.github.io/testapp/permissions - clickPageObject(itemWithText("Camera & Microphone")) + clickPageObject(composeTestRule, itemWithText("Camera & Microphone")) - SitePermissionsRobot().interact() - return SitePermissionsRobot.Transition() + SitePermissionsRobot(composeTestRule).interact() + return SitePermissionsRobot.Transition(composeTestRule) } fun clickOpenNotificationButton(interact: SitePermissionsRobot.() -> Unit): SitePermissionsRobot.Transition { // Test page used for testing permissions located at https://mozilla-mobile.github.io/testapp/permissions - clickPageObject(itemWithText("Open notifications dialogue")) + clickPageObject(composeTestRule, itemWithText("Open notifications dialogue")) mDevice.waitForObjects(mDevice.findObject(UiSelector().textContains("Allow to send notifications?"))) - SitePermissionsRobot().interact() - return SitePermissionsRobot.Transition() + SitePermissionsRobot(composeTestRule).interact() + return SitePermissionsRobot.Transition(composeTestRule) } fun clickGetLocationButton(interact: SitePermissionsRobot.() -> Unit): SitePermissionsRobot.Transition { // Test page used for testing permissions located at https://mozilla-mobile.github.io/testapp/permissions - clickPageObject(itemWithText("Get Location")) + clickPageObject(composeTestRule, itemWithText("Get Location")) - SitePermissionsRobot().interact() - return SitePermissionsRobot.Transition() + SitePermissionsRobot(composeTestRule).interact() + return SitePermissionsRobot.Transition(composeTestRule) } fun clickRequestStorageAccessButton(interact: SitePermissionsRobot.() -> Unit): SitePermissionsRobot.Transition { @@ -1631,7 +1525,7 @@ class BrowserRobot { Log.i(TAG, "clickRequestStorageAccessButton: Started try #$i") try { // Clicks the "request storage access" button from the "cross-site-cookies.html" local asset - clickPageObject(itemContainingText("requestStorageAccess()")) + clickPageObject(composeTestRule, itemContainingText("requestStorageAccess()")) assertUIObjectExists( itemWithResId("$packageName:id/deny_button"), itemWithResId("$packageName:id/allow_button"), @@ -1646,48 +1540,37 @@ class BrowserRobot { } } - SitePermissionsRobot().interact() - return SitePermissionsRobot.Transition() + SitePermissionsRobot(composeTestRule).interact() + return SitePermissionsRobot.Transition(composeTestRule) } fun clickRequestPersistentStorageAccessButton(interact: SitePermissionsRobot.() -> Unit): SitePermissionsRobot.Transition { // Clicks the "Persistent storage" button from "https://mozilla-mobile.github.io/testapp/permissions" - clickPageObject(itemWithResId("persistentStorageButton")) + clickPageObject(composeTestRule, itemWithResId("persistentStorageButton")) - SitePermissionsRobot().interact() - return SitePermissionsRobot.Transition() + SitePermissionsRobot(composeTestRule).interact() + return SitePermissionsRobot.Transition(composeTestRule) } fun clickRequestDRMControlledContentAccessButton(interact: SitePermissionsRobot.() -> Unit): SitePermissionsRobot.Transition { // Clicks the "DRM-controlled content" button from "https://mozilla-mobile.github.io/testapp/permissions" - clickPageObject(itemWithResId("drmPermissionButton")) + clickPageObject(composeTestRule, itemWithResId("drmPermissionButton")) - SitePermissionsRobot().interact() - return SitePermissionsRobot.Transition() + SitePermissionsRobot(composeTestRule).interact() + return SitePermissionsRobot.Transition(composeTestRule) } fun openSiteSecuritySheet(interact: SiteSecurityRobot.() -> Unit): SiteSecurityRobot.Transition { - Log.i(TAG, "openSiteSecuritySheet: Waiting for $waitingTime ms for site security toolbar button to exist") - siteInfoToolbarButton().waitForExists(waitingTime) - Log.i(TAG, "openSiteSecuritySheet: Waited for $waitingTime ms for site security toolbar button to exist") Log.i(TAG, "openSiteSecuritySheet: Trying to click the site security toolbar button and wait for $waitingTime ms for a new window") - siteInfoToolbarButton().clickAndWaitForNewWindow(waitingTime) - Log.i(TAG, "openSiteSecuritySheet: Clicked the site security toolbar button and waited for $waitingTime ms for a new window") - - SiteSecurityRobot().interact() - return SiteSecurityRobot.Transition() - } - - fun openSiteSecuritySheetWithComposableToolbar(composeTestRule: ComposeTestRule, interact: SiteSecurityRobot.() -> Unit): SiteSecurityRobot.Transition { - Log.i(TAG, "openSiteSecuritySheetWithComposableToolbar: Trying to click the site security toolbar button and wait for $waitingTime ms for a new window") composeTestRule.onNodeWithContentDescription(getStringResource(toolbarR.string.mozac_browser_toolbar_content_description_site_info)).performClick() - Log.i(TAG, "openSiteSecuritySheetWithComposableToolbar: Clicked the site security toolbar button and waited for $waitingTime ms for a new window") + Log.i(TAG, "openSiteSecuritySheet: Clicked the site security toolbar button and waited for $waitingTime ms for a new window") + waitForAppWindowToBeUpdated() SiteSecurityRobot().interact() return SiteSecurityRobot.Transition() } - fun clickManageAddressButton(composeTestRule: ComposeTestRule, interact: SettingsSubMenuAutofillRobot.() -> Unit): SettingsSubMenuAutofillRobot.Transition { + fun clickManageAddressButton(interact: SettingsSubMenuAutofillRobot.() -> Unit): SettingsSubMenuAutofillRobot.Transition { Log.i(TAG, "clickManageAddressButton: Trying to click the manage address button and wait for $waitingTime ms for a new window") itemWithResId("$packageName:id/manage_addresses") .clickAndWaitForNewWindow(waitingTime) @@ -1697,7 +1580,7 @@ class BrowserRobot { return SettingsSubMenuAutofillRobot.Transition(composeTestRule) } - fun clickManageCreditCardsButton(composeTestRule: ComposeTestRule, interact: SettingsSubMenuAutofillRobot.() -> Unit): SettingsSubMenuAutofillRobot.Transition { + fun clickManageCreditCardsButton(interact: SettingsSubMenuAutofillRobot.() -> Unit): SettingsSubMenuAutofillRobot.Transition { Log.i(TAG, "clickManageCreditCardsButton: Trying to click the manage credit cards button and wait for $waitingTime ms for a new window") itemWithResId("$packageName:id/manage_credit_cards") .clickAndWaitForNewWindow(waitingTime) @@ -1727,8 +1610,8 @@ class BrowserRobot { ).click() Log.i(TAG, "clickDownloadPDFButton: Clicked the download PDF button") - DownloadRobot().interact() - return DownloadRobot.Transition() + DownloadRobot(composeTestRule).interact() + return DownloadRobot.Transition(composeTestRule) } fun clickShareButtonFromRedesignedToolbar(interact: ShareOverlayRobot.() -> Unit): ShareOverlayRobot.Transition { @@ -1746,15 +1629,15 @@ class BrowserRobot { itemWithDescription("Navigate back").click() Log.i(TAG, "clickShareButtonFromRedesignedToolbar: Clicked the \"Navigate back\" button") - BrowserRobot().interact() - return BrowserRobot.Transition() + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } } } -fun browserScreen(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { - BrowserRobot().interact() - return BrowserRobot.Transition() +fun browserScreen(composeTestRule: ComposeTestRule, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } private fun navURLBar() = itemWithResId("$packageName:id/toolbar") @@ -1776,7 +1659,7 @@ private fun selectCreditCardButton() = itemWithResId("$packageName:id/select_cre private fun siteInfoToolbarButton() = itemWithResId("$packageName:id/mozac_browser_toolbar_site_info_indicator") -fun clickPageObject(item: UiObject) { +fun clickPageObject(composeTestRule: ComposeTestRule, item: UiObject) { for (i in 1..RETRY_COUNT) { try { Log.i(TAG, "clickPageObject: Started try #$i") @@ -1786,6 +1669,7 @@ fun clickPageObject(item: UiObject) { Log.i(TAG, "clickPageObject: Trying to click ${item.selector}") item.click() Log.i(TAG, "clickPageObject: Clicked ${item.selector}") + waitForAppWindowToBeUpdated() break } catch (e: UiObjectNotFoundException) { @@ -1793,9 +1677,9 @@ fun clickPageObject(item: UiObject) { if (i == RETRY_COUNT) { throw e } else { - browserScreen { + browserScreen(composeTestRule) { }.openThreeDotMenu { - }.refreshPage { + }.clickRefreshButton { waitForPageToLoad(pageLoadWaitingTime = waitingTimeLong) } } @@ -1803,7 +1687,7 @@ fun clickPageObject(item: UiObject) { } } -fun longClickPageObject(item: UiObject) { +fun longClickPageObject(composeTestRule: ComposeTestRule, item: UiObject) { for (i in 1..RETRY_COUNT) { try { Log.i(TAG, "longClickPageObject: Started try #$i") @@ -1820,9 +1704,9 @@ fun longClickPageObject(item: UiObject) { if (i == RETRY_COUNT) { throw e } else { - browserScreen { + browserScreen(composeTestRule) { }.openThreeDotMenu { - }.refreshPage { + }.clickRefreshButton { waitForPageToLoad() } } @@ -1843,7 +1727,7 @@ fun clickContextMenuItem(item: String) { Log.i(TAG, "clickContextMenuItem: Waiting for $waitingTimeShort ms for $packageName window to be updated") } -fun setPageObjectText(webPageItem: UiObject, text: String) { +fun setPageObjectText(composeTestRule: ComposeTestRule, webPageItem: UiObject, text: String) { for (i in 1..RETRY_COUNT) { Log.i(TAG, "setPageObjectText: Started try #$i") try { @@ -1865,9 +1749,9 @@ fun setPageObjectText(webPageItem: UiObject, text: String) { if (i == RETRY_COUNT) { throw e } else { - browserScreen { + browserScreen(composeTestRule) { }.openThreeDotMenu { - }.refreshPage { + }.clickRefreshButton { waitForPageToLoad(pageLoadWaitingTime = waitingTimeLong) } } diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/CollectionRobot.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/CollectionRobot.kt @@ -39,7 +39,7 @@ import org.mozilla.fenix.helpers.TestHelper.waitForAppWindowToBeUpdated import org.mozilla.fenix.helpers.click import org.mozilla.fenix.helpers.ext.waitNotNull -class CollectionRobot { +class CollectionRobot(private val composeTestRule: ComposeTestRule) { fun verifySelectCollectionScreen() = assertUIObjectExists( @@ -90,7 +90,7 @@ class CollectionRobot { } @OptIn(ExperimentalTestApi::class) - fun verifyTabSavedInCollection(composeTestRule: ComposeTestRule, title: String, visible: Boolean = true) { + fun verifyTabSavedInCollection(title: String, visible: Boolean = true) { if (visible) { Log.i(TAG, "verifyTabSavedInCollection: Waiting for $waitingTime until tab with title: $title exists") composeTestRule.waitUntilAtLeastOneExists(hasText(title), waitingTime) @@ -109,7 +109,7 @@ class CollectionRobot { } @OptIn(ExperimentalTestApi::class) - fun verifyCollectionTabUrl(composeTestRule: ComposeTestRule, isDisplayed: Boolean, url: String) { + fun verifyCollectionTabUrl(isDisplayed: Boolean, url: String) { if (isDisplayed) { Log.i(TAG, "verifyCollectionTabUrl: Waiting for $waitingTime until tab with url: $url exists") composeTestRule.waitUntilAtLeastOneExists(hasText(url)) @@ -127,7 +127,7 @@ class CollectionRobot { } } - fun verifyShareCollectionButtonIsVisible(composeTestRule: ComposeTestRule, visible: Boolean) { + fun verifyShareCollectionButtonIsVisible(visible: Boolean) { if (visible) { Log.i(TAG, "verifyShareCollectionButtonIsVisible: Trying to verify that the share button is displayed") composeTestRule.onNodeWithContentDescription("Share").assertIsDisplayed() @@ -139,46 +139,46 @@ class CollectionRobot { } } - fun verifyCollectionMenuIsVisible(visible: Boolean, rule: ComposeTestRule) { + fun verifyCollectionMenuIsVisible(visible: Boolean) { if (visible) { Log.i(TAG, "verifyCollectionMenuIsVisible: Trying to verify collection three dot button exists") - collectionThreeDotButton(rule).assertExists() + collectionThreeDotButton(composeTestRule).assertExists() Log.i(TAG, "verifyCollectionMenuIsVisible: Verified collection three dot button exists") Log.i(TAG, "verifyCollectionMenuIsVisible: Trying to verify collection three dot button is displayed") - collectionThreeDotButton(rule).assertIsDisplayed() + collectionThreeDotButton(composeTestRule).assertIsDisplayed() Log.i(TAG, "verifyCollectionMenuIsVisible: Verified collection three dot button is displayed") } else { Log.i(TAG, "verifyCollectionMenuIsVisible: Trying to verify collection three dot button does not exist") - collectionThreeDotButton(rule) + collectionThreeDotButton(composeTestRule) .assertDoesNotExist() Log.i(TAG, "verifyCollectionMenuIsVisible: Verified collection three dot button does not exist") } } - fun clickCollectionThreeDotButton(rule: ComposeTestRule) { + fun clickCollectionThreeDotButton() { Log.i(TAG, "clickCollectionThreeDotButton: Trying to verify three dot button is displayed") - collectionThreeDotButton(rule).assertIsDisplayed() + collectionThreeDotButton(composeTestRule).assertIsDisplayed() Log.i(TAG, "clickCollectionThreeDotButton: Verified three dot button is displayed") Log.i(TAG, "clickCollectionThreeDotButton: Trying to click three dot button") - collectionThreeDotButton(rule).performClick() + collectionThreeDotButton(composeTestRule).performClick() Log.i(TAG, "clickCollectionThreeDotButton: Clicked three dot button") } - fun selectOpenTabs(rule: ComposeTestRule) { + fun selectOpenTabs() { Log.i(TAG, "selectOpenTabs: Trying to verify \"Open tabs\" menu option is displayed") - rule.onNode(hasText("Open tabs")).assertIsDisplayed() + composeTestRule.onNode(hasText("Open tabs")).assertIsDisplayed() Log.i(TAG, "selectOpenTabs: Verified \"Open tabs\" menu option is displayed") Log.i(TAG, "selectOpenTabs: Trying to click \"Open tabs\" menu option") - rule.onNode(hasText("Open tabs")).performClick() + composeTestRule.onNode(hasText("Open tabs")).performClick() Log.i(TAG, "selectOpenTabs: Clicked \"Open tabs\" menu option") } - fun selectRenameCollection(rule: ComposeTestRule) { + fun selectRenameCollection() { Log.i(TAG, "selectRenameCollection: Trying to verify \"Rename collection\" menu option is displayed") - rule.onNode(hasText("Rename collection")).assertIsDisplayed() + composeTestRule.onNode(hasText("Rename collection")).assertIsDisplayed() Log.i(TAG, "selectRenameCollection: Verified \"Rename collection\" menu option is displayed") Log.i(TAG, "selectRenameCollection: Trying to click \"Rename collection\" menu option") - rule.onNode(hasText("Rename collection")).performClick() + composeTestRule.onNode(hasText("Rename collection")).performClick() Log.i(TAG, "selectRenameCollection: Clicked \"Rename collection\" menu option") Log.i(TAG, "selectRenameCollection: Waiting for $waitingTime ms for collection name text field to exist") mainMenuEditCollectionNameField().waitForExists(waitingTime) @@ -186,28 +186,28 @@ class CollectionRobot { } @OptIn(ExperimentalTestApi::class) - fun selectAddTabToCollection(rule: ComposeTestRule) { + fun selectAddTabToCollection() { Log.i(TAG, "selectAddTabToCollection: Trying to verify \"Add tab\" menu option is displayed") - rule.onNode(hasText("Add tab")).assertIsDisplayed() + composeTestRule.onNode(hasText("Add tab")).assertIsDisplayed() Log.i(TAG, "selectAddTabToCollection: Verified \"Add tab\" menu option is displayed") Log.i(TAG, "selectAddTabToCollection: Trying to click \"Add tab\" menu option") - rule.onNode(hasText("Add tab")).performClick() + composeTestRule.onNode(hasText("Add tab")).performClick() Log.i(TAG, "selectAddTabToCollection: Clicked \"Add tab\" menu option") Log.i(TAG, "selectAddTabToCollection: Waiting for the \"Add tab\" menu option to not exist") - rule.waitUntilDoesNotExist(hasText("Add tab")) + composeTestRule.waitUntilDoesNotExist(hasText("Add tab")) Log.i(TAG, "selectAddTabToCollection: Waited for the \"Add tab\" menu option to not exist") } @OptIn(ExperimentalTestApi::class) - fun selectDeleteCollection(rule: ComposeTestRule) { + fun selectDeleteCollection() { Log.i(TAG, "selectDeleteCollection: Trying to verify \"Delete collection\" menu option is displayed") - rule.onNode(hasText("Delete collection")).assertIsDisplayed() + composeTestRule.onNode(hasText("Delete collection")).assertIsDisplayed() Log.i(TAG, "selectDeleteCollection: Verified \"Delete collection\" menu option is displayed") Log.i(TAG, "selectDeleteCollection: Trying to click \"Delete collection\" menu option") - rule.onNode(hasText("Delete collection")).performClick() + composeTestRule.onNode(hasText("Delete collection")).performClick() Log.i(TAG, "selectDeleteCollection: Clicked \"Delete collection\" menu option") Log.i(TAG, "selectDeleteCollection: Waiting for the \"Delete collection\" menu option to not exist") - rule.waitUntilDoesNotExist(hasText("Delete collection")) + composeTestRule.waitUntilDoesNotExist(hasText("Delete collection")) Log.i(TAG, "selectDeleteCollection: Waited for the \"Delete collection\" menu option to not exist") } @@ -245,9 +245,8 @@ class CollectionRobot { Log.i(TAG, "goBackInCollectionFlow: Clicked collection creation flow back button") } - class Transition { + class Transition(private val composeTestRule: ComposeTestRule) { fun collapseCollection( - composeTestRule: ComposeTestRule, title: String, interact: HomeScreenRobot.() -> Unit, ): HomeScreenRobot.Transition { @@ -258,8 +257,8 @@ class CollectionRobot { composeTestRule.waitForIdle() Log.i(TAG, "collapseCollection: Waiting for compose test rule to be idle") - HomeScreenRobot().interact() - return HomeScreenRobot.Transition() + HomeScreenRobot(composeTestRule).interact() + return HomeScreenRobot.Transition(composeTestRule) } // names a collection saved from the 3dot menu @@ -280,8 +279,8 @@ class CollectionRobot { // wait for the collection creation wrapper to be dismissed mDevice.waitNotNull(Until.gone(By.res("$packageName:id/createCollectionWrapper"))) - BrowserRobot().interact() - return BrowserRobot.Transition() + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } fun selectExistingCollection( @@ -295,12 +294,12 @@ class CollectionRobot { collectionTitle(title).click() Log.i(TAG, "selectExistingCollection: Clicked collection with title: $title") - BrowserRobot().interact() - return BrowserRobot.Transition() + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } @OptIn(ExperimentalTestApi::class) - fun clickShareCollectionButton(composeTestRule: ComposeTestRule, interact: ShareOverlayRobot.() -> Unit): ShareOverlayRobot.Transition { + fun clickShareCollectionButton(interact: ShareOverlayRobot.() -> Unit): ShareOverlayRobot.Transition { Log.i(TAG, "clickShareCollectionButton: Waiting for $waitingTime ms for share collection button to exist") composeTestRule.waitUntilExactlyOneExists(hasContentDescription("Share"), waitingTime) Log.i(TAG, "clickShareCollectionButton: Waited for $waitingTime ms for share collection button to exist") @@ -314,9 +313,9 @@ class CollectionRobot { } } -fun collectionRobot(interact: CollectionRobot.() -> Unit): CollectionRobot.Transition { - CollectionRobot().interact() - return CollectionRobot.Transition() +fun collectionRobot(composeTestRule: ComposeTestRule, interact: CollectionRobot.() -> Unit): CollectionRobot.Transition { + CollectionRobot(composeTestRule).interact() + return CollectionRobot.Transition(composeTestRule) } private fun collectionTitle(title: String) = itemWithText(title) diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/CustomTabRobot.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/CustomTabRobot.kt @@ -5,15 +5,15 @@ package org.mozilla.fenix.ui.robots import android.net.Uri import android.util.Log -import androidx.compose.ui.test.ExperimentalTestApi import androidx.compose.ui.test.assertIsDisplayed -import androidx.compose.ui.test.hasText +import androidx.compose.ui.test.hasTestTag import androidx.compose.ui.test.junit4.ComposeTestRule -import androidx.compose.ui.test.onAllNodesWithContentDescription +import androidx.compose.ui.test.onFirst import androidx.compose.ui.test.onNodeWithContentDescription import androidx.compose.ui.test.onNodeWithTag import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.performClick +import androidx.compose.ui.test.performTouchInput import androidx.test.espresso.Espresso.onView import androidx.test.espresso.action.ViewActions.click import androidx.test.espresso.assertion.ViewAssertions.matches @@ -23,10 +23,10 @@ import androidx.test.espresso.matcher.ViewMatchers.withId import androidx.test.espresso.matcher.ViewMatchers.withText import androidx.test.uiautomator.By import androidx.test.uiautomator.UiSelector +import mozilla.components.compose.browser.toolbar.concept.BrowserToolbarTestTags.ADDRESSBAR_URL_BOX import org.mozilla.fenix.R import org.mozilla.fenix.components.menu.MenuDialogTestTag.DESKTOP_SITE_OFF import org.mozilla.fenix.components.menu.MenuDialogTestTag.DESKTOP_SITE_ON -import org.mozilla.fenix.helpers.Constants.LONG_CLICK_DURATION import org.mozilla.fenix.helpers.Constants.TAG import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource import org.mozilla.fenix.helpers.MatcherHelper.assertUIObjectExists @@ -34,7 +34,6 @@ import org.mozilla.fenix.helpers.MatcherHelper.itemContainingText import org.mozilla.fenix.helpers.MatcherHelper.itemWithDescription import org.mozilla.fenix.helpers.MatcherHelper.itemWithResId import org.mozilla.fenix.helpers.MatcherHelper.itemWithResIdAndText -import org.mozilla.fenix.helpers.MatcherHelper.itemWithResIdContainingText import org.mozilla.fenix.helpers.TestAssetHelper import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime import org.mozilla.fenix.helpers.TestHelper.appName @@ -42,42 +41,23 @@ import org.mozilla.fenix.helpers.TestHelper.mDevice import org.mozilla.fenix.helpers.TestHelper.packageName import org.mozilla.fenix.helpers.TestHelper.waitForAppWindowToBeUpdated import org.mozilla.fenix.helpers.TestHelper.waitForObjects -import org.mozilla.fenix.helpers.click import mozilla.components.feature.customtabs.R as customtabsR /** * Implementation of the robot pattern for Custom tabs */ -class CustomTabRobot { +class CustomTabRobot(private val composeTestRule: ComposeTestRule) { - fun verifyCustomTabsSiteInfoButton() = - assertUIObjectExists( - itemWithResId("$packageName:id/mozac_browser_toolbar_site_info_indicator"), - ) - - fun verifyCustomTabsSiteInfoButtonWithComposableToolbar(composeTestRule: ComposeTestRule) { - Log.i(TAG, "verifyCustomTabsSiteInfoButtonWithComposableToolbar: Trying to verify that the site info button is displayed") + fun verifyCustomTabsSiteInfoButton() { + Log.i(TAG, "verifyCustomTabsSiteInfoButton: Trying to verify that the site info button is displayed") composeTestRule.onNodeWithContentDescription("Site information").assertIsDisplayed() - Log.i(TAG, "verifyCustomTabsSiteInfoButtonWithComposableToolbar: Verified that the site info button is displayed") + Log.i(TAG, "verifyCustomTabsSiteInfoButton: Verified that the site info button is displayed") } - fun verifyCustomTabsShareButton() = - assertUIObjectExists( - itemWithDescription(getStringResource(customtabsR.string.mozac_feature_customtabs_share_link)), - ) - - fun verifyCustomTabsShareButtonWithComposableToolbar(composeTestRule: ComposeTestRule) { - Log.i(TAG, "verifyCustomTabsShareButtonWithComposableToolbar: Trying to verify that the share button is displayed") - composeTestRule.onNodeWithContentDescription("Share link").assertIsDisplayed() - Log.i(TAG, "verifyCustomTabsShareButtonWithComposableToolbar: Verified that the share button is displayed") - } - - fun verifyMainMenuButton() = assertUIObjectExists(mainMenuButton()) - - fun verifyMainMenuComposeButtonWithComposableToolbar(composeTestRule: ComposeTestRule) { - Log.i(TAG, "verifyMainMenuComposeButtonWithComposableToolbar: Trying to verify that the main menu button is displayed") + fun verifyMainMenuButton() { + Log.i(TAG, "verifyMainMenuButton: Trying to verify that the main menu button is displayed") composeTestRule.onNodeWithContentDescription("More options").assertIsDisplayed() - Log.i(TAG, "verifyMainMenuComposeButtonWithComposableToolbar: Verified that the main menu button is displayed") + Log.i(TAG, "verifyMainMenuButton: Verified that the main menu button is displayed") } fun verifyDesktopSiteButtonExists() { @@ -101,7 +81,7 @@ class CustomTabRobot { Log.i(TAG, "verifyOpenInBrowserButtonExists: Verified that the \"Open in Firefox\" button is displayed") } - fun verifyOpenInBrowserComposeButtonExists(composeTestRule: ComposeTestRule) { + fun verifyOpenInBrowserComposeButtonExists() { Log.i(TAG, "verifyOpenInBrowserComposeButtonExists: Trying to verify that the \"Open in Firefox\" button is displayed") composeTestRule.openInBrowserButtonFromRedesignedToolbar().assertIsDisplayed() Log.i(TAG, "verifyOpenInBrowserComposeButtonExists: Verified that the \"Open in Firefox\" button is displayed") @@ -117,79 +97,49 @@ class CustomTabRobot { fun verifyCustomTabCloseButton() { Log.i(TAG, "verifyCustomTabCloseButton: Trying to verify that the close custom tab button is displayed") - closeButton().check(matches(isDisplayed())) - Log.i(TAG, "verifyCustomTabCloseButton: Verified that the close custom tab button is displayed") - } - - fun verifyCustomTabCloseButtonWithComposableToolbar(composeTestRule: ComposeTestRule) { - Log.i(TAG, "verifyCustomTabCloseButtonWithComposableToolbar: Trying to verify that the close custom tab button is displayed") composeTestRule.onNodeWithContentDescription(getStringResource(customtabsR.string.mozac_feature_customtabs_exit_button)).assertIsDisplayed() - Log.i(TAG, "verifyCustomTabCloseButtonWithComposableToolbar: Verified that the close custom tab button is displayed") + Log.i(TAG, "verifyCustomTabCloseButton: Verified that the close custom tab button is displayed") } fun verifyCustomTabToolbarTitle(title: String) { - waitForPageToLoad() - - mDevice.waitForObjects( - mDevice.findObject( - UiSelector() - .resourceId("$packageName:id/mozac_browser_toolbar_title_view") - .textContains(title), - ) - .getFromParent( - UiSelector().resourceId("$packageName:id/mozac_browser_toolbar_origin_view"), - ), - waitingTime, - ) - - assertUIObjectExists( - itemWithResIdContainingText("$packageName:id/mozac_browser_toolbar_title_view", title), - ) - } - - fun verifyCustomTabToolbarTitleWithComposableToolbar(composeTestRule: ComposeTestRule, title: String) { - Log.i(TAG, "verifyCustomTabToolbarTitleWithComposableToolbar: Trying to verify that the custom tab title: $title is displayed") - composeTestRule.onNodeWithText(title, useUnmergedTree = true).assertIsDisplayed() - Log.i(TAG, "verifyCustomTabToolbarTitleWithComposableToolbar: Verified that the custom tab title: $title is displayed") + Log.i(TAG, "verifyCustomTabToolbarTitle: Trying to verify that the custom tab title: $title is displayed") + composeTestRule.onNodeWithText(title, substring = true, useUnmergedTree = true).assertIsDisplayed() + Log.i(TAG, "verifyCustomTabToolbarTitle: Verified that the custom tab title: $title is displayed") } fun verifyCustomTabUrl(url: String) { val uri = Uri.parse(url) val expectedText = uri.host ?: url // fallback if host is null - - assertUIObjectExists( - itemWithResIdContainingText("$packageName:id/mozac_browser_toolbar_url_view", expectedText), - ) - } - - fun verifyCustomTabUrlWithComposableToolbar(composeTestRule: ComposeTestRule, url: String) { - val uri = Uri.parse(url) - val expectedText = uri.host ?: url // fallback if host is null - Log.i(TAG, "verifyCustomTabUrlWithComposableToolbar: Trying to verify that the custom tab url: $expectedText is displayed") + Log.i(TAG, "verifyCustomTabUrl: Trying to verify that the custom tab url: $expectedText is displayed") composeTestRule.onNodeWithText(expectedText, substring = true, useUnmergedTree = true).assertIsDisplayed() - Log.i(TAG, "verifyCustomTabUrlWithComposableToolbar: Verified that the custom tab url: $expectedText is displayed") + Log.i(TAG, "verifyCustomTabUrl: Verified that the custom tab url: $expectedText is displayed") } - fun longCLickAndCopyToolbarUrl() { - mDevice.waitForObjects( - mDevice.findObject(UiSelector().resourceId("$packageName:id/toolbar")), - waitingTime, - ) - Log.i(TAG, "longCLickAndCopyToolbarUrl: Trying to long click the custom tab toolbar") - customTabToolbar().click(LONG_CLICK_DURATION) - Log.i(TAG, "longCLickAndCopyToolbarUrl: Long clicked the custom tab toolbar") - clickContextMenuItem("Copy") + fun longClickAndCopyToolbarUrl() { + Log.i(TAG, "longClickAndCopyToolbarUrl: Trying to long click the custom tab toolbar") + composeTestRule.onAllNodes(hasTestTag(ADDRESSBAR_URL_BOX)).onFirst().performTouchInput { + down(center) + advanceEventTime(10000) + up() + } + Log.i(TAG, "longClickAndCopyToolbarUrl: Long clicked the custom tab toolbar") + Log.i(TAG, "longClickAndCopyToolbarUrl: Waiting for compose rule to be idle") + composeTestRule.waitForIdle() + Log.i(TAG, "longClickAndCopyToolbarUrl: Waited for compose rule to be idle") + Log.i(TAG, "longClickAndCopyToolbarUrl: Trying to click the \"Copy\" option") + composeTestRule.onNodeWithText("Copy", useUnmergedTree = true).performClick() + Log.i(TAG, "longClickAndCopyToolbarUrl: Clicked the \"Copy\" option") } fun fillAndSubmitLoginCredentials(userName: String, password: String) { Log.i(TAG, "fillAndSubmitLoginCredentials: Waiting for device to be idle for $waitingTime ms") mDevice.waitForIdle(waitingTime) Log.i(TAG, "fillAndSubmitLoginCredentials: Waited for device to be idle for $waitingTime ms") - setPageObjectText(itemWithResId("username"), userName) + setPageObjectText(composeTestRule, itemWithResId("username"), userName) waitForAppWindowToBeUpdated() - setPageObjectText(itemWithResId("password"), password) + setPageObjectText(composeTestRule, itemWithResId("password"), password) waitForAppWindowToBeUpdated() - clickPageObject(itemWithResId("submit")) + clickPageObject(composeTestRule, itemWithResId("submit")) mDevice.waitForObjects( mDevice.findObject(UiSelector().resourceId("$packageName:id/save_confirm")), waitingTime, @@ -204,23 +154,14 @@ class CustomTabRobot { fun clickCustomTabCloseButton() { Log.i(TAG, "clickCustomTabCloseButton: Trying to click close custom tab button") - closeButton().click() - Log.i(TAG, "clickCustomTabCloseButton: Clicked close custom tab button") - } - - fun clickCustomTabCloseButtonWithComposableToolbar(composeTestRule: ComposeTestRule) { - Log.i(TAG, "clickCustomTabCloseButtonWithComposableToolbar: Trying to click close custom tab button") composeTestRule.onNodeWithContentDescription(getStringResource(customtabsR.string.mozac_feature_customtabs_exit_button)).performClick() - Log.i(TAG, "clickCustomTabCloseButtonWithComposableToolbar: Clicked close custom tab button") + Log.i(TAG, "clickCustomTabCloseButton: Clicked close custom tab button") } - fun verifyCustomTabActionButton(customTabActionButtonDescription: String) = - assertUIObjectExists(itemWithDescription(customTabActionButtonDescription)) - - fun verifyCustomTabActionButtonWithComposableToolbar(composeTestRule: ComposeTestRule, customTabActionButtonDescription: String) { - Log.i(TAG, "verifyCustomTabActionButtonWithComposableToolbar: Trying to verify that the custom tab action button is displayed") + fun verifyCustomTabActionButton(customTabActionButtonDescription: String) { + Log.i(TAG, "verifyCustomTabActionButton: Trying to verify that the custom tab action button is displayed") composeTestRule.onNodeWithContentDescription(customTabActionButtonDescription).assertIsDisplayed() - Log.i(TAG, "verifyCustomTabActionButtonWithComposableToolbar: Verified that the custom tab action button is displayed") + Log.i(TAG, "verifyCustomTabActionButton: Verified that the custom tab action button is displayed") } fun verifyPDFReaderToolbarItems() = @@ -228,7 +169,7 @@ class CustomTabRobot { itemWithResIdAndText("download", "Download"), ) - fun verifyRedesignedCustomTabsMainMenuItemsExist(customMenuItem: String, exist: Boolean, waitingTime: Long = TestAssetHelper.waitingTime) = + fun verifyCustomTabsMainMenuItems(customMenuItem: String, exist: Boolean, waitingTime: Long = TestAssetHelper.waitingTime) = assertUIObjectExists( itemContainingText(getStringResource(R.string.browser_menu_back)), itemContainingText(getStringResource(R.string.browser_menu_forward)), @@ -243,13 +184,13 @@ class CustomTabRobot { waitingTime = waitingTime, ) - fun verifySwitchToDesktopSiteButton(composeTestRule: ComposeTestRule) { + fun verifySwitchToDesktopSiteButton() { Log.i(TAG, "verifySwitchToDesktopSiteButton: Trying to verify that the \"Desktop site\" button is displayed.") composeTestRule.desktopSiteButton().assertIsDisplayed() Log.i(TAG, "verifySwitchToDesktopSiteButton: Verified that the \"Switch to desktop site\" button is displayed.") } - fun verifyDesktopSiteButtonState(composeTestRule: ComposeTestRule, isEnabled: Boolean) { + fun verifyDesktopSiteButtonState(isEnabled: Boolean) { if (isEnabled) { Log.i(TAG, "verifyDesktopSiteButtonState: Trying to verify that the \"Desktop site\" button is set to \"On\".") composeTestRule.enabledDesktopSiteButton().assertIsDisplayed() @@ -261,48 +202,20 @@ class CustomTabRobot { } } - fun clickSwitchToDesktopSiteButton(composeTestRule: ComposeTestRule) { + fun clickSwitchToDesktopSiteButton() { Log.i(TAG, "clickSwitchToDesktopSiteButton: Trying to click the \"Desktop site\" button.") composeTestRule.desktopSiteButton().performClick() Log.i(TAG, "clickSwitchToDesktopSiteButton: Clicked the \"Desktop site\" button.") } - class Transition { + class Transition(private val composeTestRule: ComposeTestRule) { fun openMainMenu(interact: CustomTabRobot.() -> Unit): Transition { - mainMenuButton().also { - Log.i(TAG, "openMainMenu: Waiting for $waitingTime ms for the main menu button to exist") - it.waitForExists(waitingTime) - Log.i(TAG, "openMainMenu: Waited for $waitingTime ms for the main menu button to exist") - Log.i(TAG, "openMainMenu: Trying to click the main menu button") - it.click() - Log.i(TAG, "openMainMenu: Clicked the main menu button") - } - - CustomTabRobot().interact() - return Transition() - } - - fun openMainMenuFromRedesignedToolbar(interact: CustomTabRobot.() -> Unit): Transition { - mainMenuButtonFromRedesignedToolbar().also { - Log.i(TAG, "openMainMenuFromRedesignedToolbar: Waiting for $waitingTime ms for the main menu button to exist") - it.waitForExists(waitingTime) - Log.i(TAG, "openMainMenuFromRedesignedToolbar: Waited for $waitingTime ms for the main menu button to exist") - Log.i(TAG, "openMainMenuFromRedesignedToolbar: Trying to click the main menu button") - it.click() - Log.i(TAG, "openMainMenuFromRedesignedToolbar: Clicked the main menu button") - } - - CustomTabRobot().interact() - return Transition() - } - - fun openMainMenuWithComposableToolbar(composeTestRule: ComposeTestRule, interact: CustomTabRobot.() -> Unit): Transition { - Log.i(TAG, "openMainMenuWithComposableToolbar: Trying to click the main menu button") + Log.i(TAG, "openMainMenu: Trying to click the main menu button") composeTestRule.onNodeWithContentDescription(getStringResource(R.string.content_description_menu)).performClick() - Log.i(TAG, "openMainMenuWithComposableToolbar: Clicked the main menu button") + Log.i(TAG, "openMainMenu: Clicked the main menu button") - CustomTabRobot().interact() - return Transition() + CustomTabRobot(composeTestRule).interact() + return Transition(composeTestRule) } fun clickOpenInBrowserButton(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { @@ -310,11 +223,11 @@ class CustomTabRobot { openInBrowserButton().perform(click()) Log.i(TAG, "clickOpenInBrowserButton: Clicked the \"Open in Firefox\" button") - BrowserRobot().interact() - return BrowserRobot.Transition() + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } - fun clickOpenInBrowserButtonFromRedesignedToolbar(composeTestRule: ComposeTestRule, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { + fun clickOpenInBrowserButtonFromRedesignedToolbar(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { Log.i(TAG, "clickOpenInBrowserButtonFromRedesignedToolbar: Trying to click the \"Open in Firefox\" button") composeTestRule.openInBrowserButtonFromRedesignedToolbar().performClick() Log.i(TAG, "clickOpenInBrowserButtonFromRedesignedToolbar: Clicked the \"Open in Firefox\" button") @@ -322,8 +235,8 @@ class CustomTabRobot { mDevice.waitForIdle(waitingTime) Log.i(TAG, "clickOpenInBrowserButtonFromRedesignedToolbar: Waited for device to be idle") - BrowserRobot().interact() - return BrowserRobot.Transition() + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } fun clickShareButton(interact: ShareOverlayRobot.() -> Unit): ShareOverlayRobot.Transition { @@ -336,7 +249,7 @@ class CustomTabRobot { return ShareOverlayRobot.Transition() } - fun clickShareButtonFromRedesignedMenu(composeTestRule: ComposeTestRule, interact: ShareOverlayRobot.() -> Unit): ShareOverlayRobot.Transition { + fun clickShareButtonFromRedesignedMenu(interact: ShareOverlayRobot.() -> Unit): ShareOverlayRobot.Transition { Log.i(TAG, "clickShareButtonFromRedesignedMenu: Trying to click the redesigned main menu share button from custom tab") composeTestRule.shareButton().performClick() Log.i(TAG, "clickShareButtonFromRedesignedMenu: Clicked the redesigned main menu share button from custom tab") @@ -345,7 +258,7 @@ class CustomTabRobot { return ShareOverlayRobot.Transition() } - fun clickFindInPageButton(composeTestRule: ComposeTestRule, interact: FindInPageRobot.() -> Unit): FindInPageRobot.Transition { + fun clickFindInPageButton(interact: FindInPageRobot.() -> Unit): FindInPageRobot.Transition { Log.i(TAG, "clickFindInPageButton: Trying to click the \"Find In Page\" button from the new main menu design.") composeTestRule.findInPageButton().performClick() Log.i(TAG, "clickFindInPageButton: Clicked the \"Find In Page\" button from the new main menu design.") @@ -359,44 +272,42 @@ class CustomTabRobot { itemWithResId("$packageName:id/touch_outside").clickTopLeft() Log.i(TAG, "clickOutsideTheMainMenu: Clicked click outside the main menu.") - BrowserRobot().interact() - return BrowserRobot.Transition() + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } - fun clickBackButtonFromMenu(composeTestRule: ComposeTestRule, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { + fun clickBackButtonFromMenu(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { Log.i(TAG, "clickBackButtonFromMenu: Trying to click the \"Back\" button from custom tab main menu.") composeTestRule.backButton().performClick() Log.i(TAG, "clickBackButtonFromMenu: Clicked the \"Back\" button from custom tab main menu.") - BrowserRobot().interact() - return BrowserRobot.Transition() + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } - fun clickForwardButtonFromMenu(composeTestRule: ComposeTestRule, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { + fun clickForwardButtonFromMenu(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { Log.i(TAG, "clickForwardButtonFromMenu: Trying to click the \"Forward\" button from custom tab main menu.") composeTestRule.forwardButton().performClick() Log.i(TAG, "clickForwardButtonFromMenu: Clicked the \"Forward\" button from custom tab main menu.") - BrowserRobot().interact() - return BrowserRobot.Transition() + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } - fun clickRefreshButton(composeTestRule: ComposeTestRule, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { + fun clickRefreshButton(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { Log.i(TAG, "clickRefreshButton: Trying to click the \"Refresh\" button from custom tab main menu.") composeTestRule.refreshButton().performClick() Log.i(TAG, "clickRefreshButton: Clicked the \"Refresh\" button from custom tab main menu.") - BrowserRobot().interact() - return BrowserRobot.Transition() + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } fun openUnifiedTrustPanel(interact: UnifiedTrustPanelRobot.() -> Unit): UnifiedTrustPanelRobot.Transition { - Log.i(TAG, "openUnifiedTrustPanel: Waiting for $waitingTime ms for site security button to exist") - itemWithResId("$packageName:id/mozac_browser_toolbar_site_info_indicator").waitForExists(waitingTime) - Log.i(TAG, "openUnifiedTrustPanel: Waited for $waitingTime ms for site security button to exist") - Log.i(TAG, "openUnifiedTrustPanel: Trying to click site security button") - itemWithResId("$packageName:id/mozac_browser_toolbar_site_info_indicator").click() - Log.i(TAG, "openUnifiedTrustPanel: Clicked site security button") + Log.i(TAG, "openSiteSecuritySheet: Trying to click the site security toolbar button and wait for $waitingTime ms for a new window") + composeTestRule.onNodeWithContentDescription("Site information").performClick() + Log.i(TAG, "openSiteSecuritySheet: Clicked the site security toolbar button and waited for $waitingTime ms for a new window") + waitForAppWindowToBeUpdated() UnifiedTrustPanelRobot().interact() return UnifiedTrustPanelRobot.Transition() @@ -404,9 +315,9 @@ class CustomTabRobot { } } -fun customTabScreen(interact: CustomTabRobot.() -> Unit): CustomTabRobot.Transition { - CustomTabRobot().interact() - return CustomTabRobot.Transition() +fun customTabScreen(composeTestRule: ComposeTestRule, interact: CustomTabRobot.() -> Unit): CustomTabRobot.Transition { + CustomTabRobot(composeTestRule).interact() + return CustomTabRobot.Transition(composeTestRule) } private fun mainMenuButton() = itemWithResId("$packageName:id/mozac_browser_toolbar_menu") diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/DeepLinkRobot.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/DeepLinkRobot.kt @@ -11,7 +11,7 @@ import androidx.core.net.toUri import androidx.test.platform.app.InstrumentationRegistry import org.mozilla.fenix.BuildConfig.DEEP_LINK_SCHEME -class DeepLinkRobot { +class DeepLinkRobot(private val composeTestRule: ComposeTestRule) { private fun openDeepLink(url: String) { val context = InstrumentationRegistry.getInstrumentation().targetContext val intent = Intent().apply { @@ -35,20 +35,20 @@ class DeepLinkRobot { .build() .toString() openDeepLink(deepLink) - return browserScreen(interact) + return browserScreen(composeTestRule, interact) } fun openHomeScreen(interact: HomeScreenRobot.() -> Unit) = - openDeepLink("home").run { homeScreen(interact) } + openDeepLink("home").run { homeScreen(composeTestRule, interact) } fun openBookmarks(composeTestRule: ComposeTestRule, interact: BookmarksRobot.() -> Unit) = openDeepLink("urls_bookmarks").run { composeBookmarksMenu(composeTestRule, interact) } fun openHistory(interact: HistoryRobot.() -> Unit) = - openDeepLink("urls_history").run { historyMenu(interact) } + openDeepLink("urls_history").run { historyMenu(composeTestRule, interact) } fun openCollections(interact: HomeScreenRobot.() -> Unit) = - openDeepLink("home_collections").run { homeScreen(interact) } + openDeepLink("home_collections").run { homeScreen(composeTestRule, interact) } fun openSettings(interact: SettingsRobot.() -> Unit) = openDeepLink("settings").run { settings(interact) } diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/DownloadRobot.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/DownloadRobot.kt @@ -37,12 +37,10 @@ import org.mozilla.fenix.helpers.AppAndSystemHelper.getPermissionAllowID import org.mozilla.fenix.helpers.Constants.PackageName.GOOGLE_APPS_PHOTOS import org.mozilla.fenix.helpers.Constants.TAG import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource -import org.mozilla.fenix.helpers.HomeActivityComposeTestRule import org.mozilla.fenix.helpers.MatcherHelper.assertUIObjectExists import org.mozilla.fenix.helpers.MatcherHelper.itemContainingText import org.mozilla.fenix.helpers.MatcherHelper.itemWithResId import org.mozilla.fenix.helpers.MatcherHelper.itemWithResIdContainingText -import org.mozilla.fenix.helpers.MatcherHelper.itemWithText import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime import org.mozilla.fenix.helpers.TestAssetHelper.waitingTimeLong import org.mozilla.fenix.helpers.TestHelper.mDevice @@ -54,7 +52,7 @@ import mozilla.components.feature.downloads.R as downloadsR * Implementation of Robot Pattern for download UI handling. */ -class DownloadRobot { +class DownloadRobot(private val composeTestRule: ComposeTestRule) { fun verifyDownloadPrompt(fileName: String) { var currentTries = 0 @@ -73,7 +71,7 @@ class DownloadRobot { Log.i(TAG, "verifyDownloadPrompt: AssertionError caught, executing fallback methods") Log.e("DOWNLOAD_ROBOT", "Failed to find locator: ${e.localizedMessage}") - browserScreen { + browserScreen(this@DownloadRobot.composeTestRule) { }.clickDownloadLink(fileName) { } } @@ -88,18 +86,18 @@ class DownloadRobot { ) @OptIn(ExperimentalTestApi::class) - fun verifyDownloadFailedSnackbar(composeTestRule: ComposeTestRule, fileName: String) { + fun verifyDownloadFailedSnackbar(fileName: String) { Log.i(TAG, "verifyDownloadFailedSnackbar: Waiting for the snackbar to exist") - composeTestRule.waitUntilExactlyOneExists(hasTestTag(SNACKBAR_TEST_TAG)) + this@DownloadRobot.composeTestRule.waitUntilExactlyOneExists(hasTestTag(SNACKBAR_TEST_TAG)) Log.i(TAG, "verifyDownloadFailedSnackbar: Waited for the snackbar to exist") Log.i(TAG, "verifyDownloadFailedSnackbar: Trying to verify that the \"Download failed\" snackbar message exists") - composeTestRule.onNodeWithText(getStringResource(R.string.download_item_status_failed), useUnmergedTree = true).assertIsDisplayed() + this@DownloadRobot.composeTestRule.onNodeWithText(getStringResource(R.string.download_item_status_failed), useUnmergedTree = true).assertIsDisplayed() Log.i(TAG, "verifyDownloadFailedSnackbar: Verified that the \"Download failed\" snackbar message exists") Log.i(TAG, "verifyDownloadFailedSnackbar: Trying to verify that the \"Details\" snackbar button exists") - composeTestRule.onNodeWithText(getStringResource(R.string.download_failed_snackbar_action_details), useUnmergedTree = true).assertIsDisplayed() + this@DownloadRobot.composeTestRule.onNodeWithText(getStringResource(R.string.download_failed_snackbar_action_details), useUnmergedTree = true).assertIsDisplayed() Log.i(TAG, "verifyDownloadFailedSnackbar: Verified that the \"Details\" snackbar button exists") Log.i(TAG, "verifyDownloadFailedSnackbar: Trying to verify that the file name: $fileName exists") - composeTestRule.onNodeWithText(fileName, useUnmergedTree = true).assertIsDisplayed() + this@DownloadRobot.composeTestRule.onNodeWithText(fileName, useUnmergedTree = true).assertIsDisplayed() Log.i(TAG, "verifyDownloadFailedSnackbar: Verified that the file name: $fileName exists") } @@ -117,21 +115,21 @@ class DownloadRobot { fun verifyDownloadedFileName(fileName: String) = assertUIObjectExists(itemContainingText(fileName)) - fun openMultiSelectMoreOptionsMenu(composeTestRule: ComposeTestRule) { + fun openMultiSelectMoreOptionsMenu() { Log.i(TAG, "openMultiSelectMoreOptionsMenu: Trying to click multi-select more options button") - composeTestRule.onNodeWithContentDescription(getStringResource(R.string.content_description_menu)).performClick() + this@DownloadRobot.composeTestRule.onNodeWithContentDescription(getStringResource(R.string.content_description_menu)).performClick() Log.i(TAG, "openMultiSelectMoreOptionsMenu: Clicked multi-select more options button") } - fun clickMultiSelectRemoveButton(composeTestRule: ComposeTestRule) { + fun clickMultiSelectRemoveButton() { Log.i(TAG, "clickMultiSelectRemoveButton: Trying to click multi-select remove button") - composeTestRule.onNodeWithText(getStringResource(R.string.download_delete_item)).performClick() + this@DownloadRobot.composeTestRule.onNodeWithText(getStringResource(R.string.download_delete_item)).performClick() Log.i(TAG, "clickMultiSelectRemoveButton: Clicked multi-select remove button") } - fun clickMultiSelectDeleteDialogButton(composeTestRule: ComposeTestRule) { + fun clickMultiSelectDeleteDialogButton() { Log.i(TAG, "clickMultiSelectDeleteDialogButton: Trying to click the \"Delete\" dialog button") - composeTestRule + this@DownloadRobot.composeTestRule .onNodeWithText( getStringResource(R.string.download_delete_multi_select_dialog_confirm), ignoreCase = true, @@ -140,7 +138,7 @@ class DownloadRobot { } fun openPageAndDownloadFile(url: Uri, downloadFile: String) { - navigationToolbar { + navigationToolbar(this@DownloadRobot.composeTestRule) { }.enterURLAndEnterToBrowser(url) { waitForPageToLoad(pageLoadWaitingTime = waitingTimeLong) }.clickDownloadLink(downloadFile) { @@ -150,70 +148,68 @@ class DownloadRobot { } @OptIn(ExperimentalTestApi::class) - fun verifyDownloadedFileExistsInDownloadsList(testRule: HomeActivityComposeTestRule, fileName: String) { + fun verifyDownloadedFileExistsInDownloadsList(fileName: String) { Log.i(TAG, "verifyDownloadedFileName: Trying to verify that the downloaded file: $fileName is displayed") - testRule.waitUntilAtLeastOneExists( + this@DownloadRobot.composeTestRule.waitUntilAtLeastOneExists( hasTestTag("${DownloadsListTestTag.DOWNLOADS_LIST_ITEM}.$fileName"), ) - testRule.onNodeWithTag("${DownloadsListTestTag.DOWNLOADS_LIST_ITEM}.$fileName") + this@DownloadRobot.composeTestRule.onNodeWithTag("${DownloadsListTestTag.DOWNLOADS_LIST_ITEM}.$fileName") .assertIsDisplayed() Log.i(TAG, "verifyDownloadedFileName: Trying to verify that the downloaded file: $fileName is displayed") } @OptIn(ExperimentalTestApi::class) - fun verifyDownloadFileIsNotDisplayed(testRule: HomeActivityComposeTestRule, fileName: String) { + fun verifyDownloadFileIsNotDisplayed(fileName: String) { Log.i(TAG, "verifyDownloadFileIsNotDisplayed: Trying to verify that the downloaded file: $fileName is not displayed") - testRule.waitUntilDoesNotExist( + this@DownloadRobot.composeTestRule.waitUntilDoesNotExist( hasTestTag("${DownloadsListTestTag.DOWNLOADS_LIST_ITEM}.$fileName"), ) - testRule.onNodeWithTag("${DownloadsListTestTag.DOWNLOADS_LIST_ITEM}.$fileName") + this@DownloadRobot.composeTestRule.onNodeWithTag("${DownloadsListTestTag.DOWNLOADS_LIST_ITEM}.$fileName") .assertIsNotDisplayed() Log.i(TAG, "verifyDownloadFileIsNotDisplayed: Trying to verify that the downloaded file: $fileName is not displayed") } @OptIn(ExperimentalTestApi::class) - fun verifyEmptyDownloadsList(testRule: HomeActivityComposeTestRule) { + fun verifyEmptyDownloadsList() { Log.i(TAG, "verifyEmptyDownloadsList: Waiting for $waitingTime until the \"No downloads yet\" list message exists") - testRule.waitUntilAtLeastOneExists(hasText(testRule.activity.getString(R.string.download_empty_message_2)), waitingTime) + this@DownloadRobot.composeTestRule.waitUntilAtLeastOneExists(hasText(getStringResource(R.string.download_empty_message_2)), waitingTime) Log.i(TAG, "verifyEmptyDownloadsList: Waited for $waitingTime until the \"No downloads yet\" list message exists") Log.i(TAG, "verifyEmptyDownloadsList: Trying to verify that the \"No downloads yet\" list message is displayed") - testRule.onNodeWithText(text = testRule.activity.getString(R.string.download_empty_message_2)) + this@DownloadRobot.composeTestRule.onNodeWithText(getStringResource(R.string.download_empty_message_2)) .assertIsDisplayed() Log.i(TAG, "verifyEmptyDownloadsList: Verified that the \"No downloads yet\" list message is displayed") Log.i(TAG, "verifyEmptyDownloadsList: Waiting for $waitingTime until the \"Files you download will appear here.\" list message exists") - testRule.waitUntilAtLeastOneExists(hasText(testRule.activity.getString(R.string.download_empty_description)), waitingTime) + this@DownloadRobot.composeTestRule.waitUntilAtLeastOneExists(hasText(getStringResource(R.string.download_empty_description)), waitingTime) Log.i(TAG, "verifyEmptyDownloadsList: Waited for $waitingTime until the \"Files you download will appear here.\" list message exists") Log.i(TAG, "verifyEmptyDownloadsList: Trying to verify that the \"Files you download will appear here.\" list message is displayed") - testRule.onNodeWithText(text = testRule.activity.getString(R.string.download_empty_description)) + this@DownloadRobot.composeTestRule.onNodeWithText(getStringResource(R.string.download_empty_description)) .assertIsDisplayed() Log.i(TAG, "verifyEmptyDownloadsList: Verified that the \"Files you download will appear here.\" list message is displayed") } - fun deleteDownloadedItem(testRule: HomeActivityComposeTestRule, fileName: String) { + fun deleteDownloadedItem(fileName: String) { Log.i(TAG, "deleteDownloadedItem: Trying to click the delete menu item to delete downloaded file: $fileName") - testRule.onNodeWithText(testRule.activity.getString(R.string.download_delete_item)) - .performClick() + this@DownloadRobot.composeTestRule.onNodeWithText(getStringResource(R.string.download_delete_item)).performClick() Log.i(TAG, "deleteDownloadedItem: Clicked the delete menu item to delete downloaded file: $fileName") } - fun clickDownloadItemMenuIcon(testRule: HomeActivityComposeTestRule, fileName: String) { + fun clickDownloadItemMenuIcon(fileName: String) { Log.i(TAG, "clickDownloadItemMenuIcon: Trying to click the menu overflow icon to open item menu: $fileName") - testRule.onNodeWithTag("${DownloadsListTestTag.DOWNLOADS_LIST_ITEM_MENU}.$fileName") - .performClick() + this@DownloadRobot.composeTestRule.onNodeWithTag("${DownloadsListTestTag.DOWNLOADS_LIST_ITEM_MENU}.$fileName").performClick() Log.i(TAG, "clickDownloadItemMenuIcon: Clicked the menu overflow icon to open item menu: $fileName") } - fun clickDownloadedItem(testRule: ComposeTestRule, fileName: String) { + fun clickDownloadedItem(fileName: String) { Log.i(TAG, "clickDownloadedItem: Trying to click downloaded file: $fileName") - testRule.onNodeWithTag("${DownloadsListTestTag.DOWNLOADS_LIST_ITEM}.$fileName") + this@DownloadRobot.composeTestRule.onNodeWithTag("${DownloadsListTestTag.DOWNLOADS_LIST_ITEM}.$fileName") .performClick() Log.i(TAG, "clickDownloadedItem: Clicked downloaded file: $fileName") } - fun longClickDownloadedItem(testRule: HomeActivityComposeTestRule, title: String) { + fun longClickDownloadedItem(title: String) { Log.i(TAG, "longClickDownloadedItem: Trying to long click downloaded file: $title") - testRule.onNodeWithTag("${DownloadsListTestTag.DOWNLOADS_LIST_ITEM}.$title") + this@DownloadRobot.composeTestRule.onNodeWithTag("${DownloadsListTestTag.DOWNLOADS_LIST_ITEM}.$title") .performTouchInput { longClick() } @@ -221,42 +217,42 @@ class DownloadRobot { } @OptIn(ExperimentalTestApi::class) - fun clickDownloadsFilter(filter: String, composeTestRule: ComposeTestRule) { - composeTestRule.waitUntilExactlyOneExists((hasText(filter))) + fun clickDownloadsFilter(filter: String) { + this@DownloadRobot.composeTestRule.waitUntilExactlyOneExists((hasText(filter))) Log.i(TAG, "clickImagesFilter: Trying to click the \"Images\" downloads filter") - composeTestRule.onNodeWithText(filter).performClick() + this@DownloadRobot.composeTestRule.onNodeWithText(filter).performClick() Log.i(TAG, "clickImagesFilter: Clicked the \"Images\" download downloads filter") } - fun clickTryAgainDownloadMenuButton(composeTestRule: ComposeTestRule) { + fun clickTryAgainDownloadMenuButton() { Log.i(TAG, "clickDownloadedItem: Trying to click the \"Try again\"button") - composeTestRule.onNodeWithContentDescription(getStringResource(R.string.download_retry_action)) + this@DownloadRobot.composeTestRule.onNodeWithContentDescription(getStringResource(R.string.download_retry_action)) .performClick() Log.i(TAG, "clickDownloadedItem: Clicked the \"Try again\" button") } @OptIn(ExperimentalTestApi::class) - fun verifyDownloadFileFailedMessage(composeTestRule: ComposeTestRule, fileName: String) { + fun verifyDownloadFileFailedMessage(fileName: String) { Log.i(TAG, "verifyDownloadFileFailedMessage: Trying to verify the download failed for file: $fileName message") - composeTestRule.onNodeWithText(fileName, useUnmergedTree = true).assert(hasAnySibling(hasText(getStringResource(R.string.download_item_status_failed)))) + this@DownloadRobot.composeTestRule.onNodeWithText(fileName, useUnmergedTree = true).assert(hasAnySibling(hasText(getStringResource(R.string.download_item_status_failed)))) Log.i(TAG, "verifyDownloadFileFailedMessage: Verified the download failed for file: $fileName message") } - fun verifyPauseDownloadMenuButtonButton(composeTestRule: ComposeTestRule) { + fun verifyPauseDownloadMenuButtonButton() { Log.i(TAG, "verifyPauseDownloadMenuButtonButton: Trying to click the \"Try again\"button") - composeTestRule.onNodeWithContentDescription(getStringResource(R.string.download_pause_action)) + this@DownloadRobot.composeTestRule.onNodeWithContentDescription(getStringResource(R.string.download_pause_action)) .assertIsDisplayed() Log.i(TAG, "verifyPauseDownloadMenuButtonButton: Clicked the \"Try again\" button") } - class Transition { + class Transition(private val composeTestRule: ComposeTestRule) { fun clickDownload(interact: DownloadRobot.() -> Unit): Transition { Log.i(TAG, "clickDownload: Trying to click the \"Download\" download prompt button") downloadButton().click() Log.i(TAG, "clickDownload: Clicked the \"Download\" download prompt button") - DownloadRobot().interact() - return Transition() + DownloadRobot(composeTestRule).interact() + return Transition(composeTestRule) } fun closeDownloadPrompt(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { @@ -264,8 +260,8 @@ class DownloadRobot { itemWithResId("$packageName:id/download_dialog_close_button").click() Log.i(TAG, "closeDownloadPrompt: Clicked the close download prompt button") - BrowserRobot().interact() - return BrowserRobot.Transition() + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } fun clickOpen(type: String, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { @@ -286,8 +282,8 @@ class DownloadRobot { ) Log.i(TAG, "clickOpen: Verified that the open intent is matched with associated data type") - BrowserRobot().interact() - return BrowserRobot.Transition() + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } fun clickAllowPermission(interact: DownloadRobot.() -> Unit): Transition { @@ -299,36 +295,36 @@ class DownloadRobot { mDevice.findObject(By.res(getPermissionAllowID() + ":id/permission_allow_button")).click() Log.i(TAG, "clickAllowPermission: Clicked the \"ALLOW\" permission button") - DownloadRobot().interact() - return Transition() + DownloadRobot(composeTestRule).interact() + return Transition(composeTestRule) } - fun exitDownloadsManagerToBrowser(composeTestRule: ComposeTestRule, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { + fun exitDownloadsManagerToBrowser(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { Log.i(TAG, "exitDownloadsManagerToBrowser: Trying to click the navigate up toolbar button") composeTestRule.onNodeWithContentDescription(getStringResource(R.string.download_navigate_back_description)).performClick() Log.i(TAG, "exitDownloadsManagerToBrowser: Clicked the navigate up toolbar button") - BrowserRobot().interact() - return BrowserRobot.Transition() + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } - fun goBackToHomeScreen(composeTestRule: ComposeTestRule, interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition { + fun goBackToHomeScreen(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition { Log.i(TAG, "goBackToHomeScreen: Trying to click the navigate up toolbar button") composeTestRule.onNodeWithContentDescription(getStringResource(R.string.download_navigate_back_description)).performClick() Log.i(TAG, "goBackToHomeScreen: Clicked the navigate up toolbar button") - HomeScreenRobot().interact() - return HomeScreenRobot.Transition() + HomeScreenRobot(composeTestRule).interact() + return HomeScreenRobot.Transition(composeTestRule) } @OptIn(ExperimentalTestApi::class) - fun shareDownloadedItem(testRule: HomeActivityComposeTestRule, fileName: String, interact: ShareOverlayRobot.() -> Unit): ShareOverlayRobot.Transition { + fun shareDownloadedItem(fileName: String, interact: ShareOverlayRobot.() -> Unit): ShareOverlayRobot.Transition { Log.i(TAG, "shareDownloadedItem: Trying to click the Share file menu item to share downloaded file: $fileName") - testRule.onNodeWithText(testRule.activity.getString(R.string.download_share_file)) + composeTestRule.onNodeWithText(getStringResource(R.string.download_share_file)) .performClick() Log.i(TAG, "shareDownloadedItem: Clicked the Share file menu item to share downloaded file: $fileName") Log.i(TAG, "shareDownloadedItem: Waiting for $waitingTime until the share button does not exist") - testRule.waitUntilDoesNotExist(hasText(testRule.activity.getString(R.string.download_share_file)), waitingTime) + composeTestRule.waitUntilDoesNotExist(hasText(getStringResource(R.string.download_share_file)), waitingTime) Log.i(TAG, "shareDownloadedItem: Waited for $waitingTime until the share button does not exist") ShareOverlayRobot().interact() @@ -346,9 +342,9 @@ class DownloadRobot { } } -fun downloadRobot(interact: DownloadRobot.() -> Unit): DownloadRobot.Transition { - DownloadRobot().interact() - return DownloadRobot.Transition() +fun downloadRobot(composeTestRule: ComposeTestRule, interact: DownloadRobot.() -> Unit): DownloadRobot.Transition { + DownloadRobot(composeTestRule).interact() + return DownloadRobot.Transition(composeTestRule) } private fun downloadButton() = diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/EnhancedTrackingProtectionRobot.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/EnhancedTrackingProtectionRobot.kt @@ -7,6 +7,7 @@ package org.mozilla.fenix.ui.robots import android.util.Log +import androidx.compose.ui.test.junit4.ComposeTestRule import androidx.test.espresso.Espresso.onView import androidx.test.espresso.assertion.ViewAssertions.matches import androidx.test.espresso.matcher.RootMatchers @@ -51,20 +52,6 @@ class EnhancedTrackingProtectionRobot { Log.i(TAG, "verifyEnhancedTrackingProtectionSheetStatus: Verified ETP toggle is checked: $state") } - fun verifyETPSwitchVisibility(visible: Boolean) { - if (visible) { - Log.i(TAG, "verifyETPSwitchVisibility: Trying to verify ETP toggle is displayed") - enhancedTrackingProtectionSwitch() - .check(matches(isDisplayed())) - Log.i(TAG, "verifyETPSwitchVisibility: Verified ETP toggle is displayed") - } else { - Log.i(TAG, "verifyETPSwitchVisibility: Trying to verify ETP toggle is not displayed") - enhancedTrackingProtectionSwitch() - .check(matches(not(isDisplayed()))) - Log.i(TAG, "verifyETPSwitchVisibility: Verified ETP toggle is not displayed") - } - } - fun verifyCrossSiteCookiesBlocked(isBlocked: Boolean) { assertUIObjectExists(itemWithResId("$packageName:id/cross_site_tracking")) Log.i(TAG, "verifyCrossSiteCookiesBlocked: Trying to click cross site cookies block list button") @@ -234,14 +221,14 @@ class EnhancedTrackingProtectionRobot { return Transition() } - fun closeEnhancedTrackingProtectionSheet(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { + fun closeEnhancedTrackingProtectionSheet(composeTestRule: ComposeTestRule, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { // Back out of the Enhanced Tracking Protection sheet Log.i(TAG, "closeEnhancedTrackingProtectionSheet: Trying to click device back button") mDevice.pressBack() Log.i(TAG, "closeEnhancedTrackingProtectionSheet: Clicked device back button") - BrowserRobot().interact() - return BrowserRobot.Transition() + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } fun toggleEnhancedTrackingProtectionFromSheet(interact: EnhancedTrackingProtectionRobot.() -> Unit): Transition { diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/FindInPageRobot.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/FindInPageRobot.kt @@ -7,6 +7,7 @@ package org.mozilla.fenix.ui.robots import android.util.Log +import androidx.compose.ui.test.junit4.ComposeTestRule import androidx.test.espresso.Espresso.onView import androidx.test.espresso.action.ViewActions.clearText import androidx.test.espresso.action.ViewActions.typeText @@ -73,18 +74,18 @@ class FindInPageRobot { fun verifyFindInPageResult(ratioCounter: String) = assertUIObjectExists(itemContainingText(ratioCounter)) class Transition { - fun closeFindInPageWithCloseButton(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { + fun closeFindInPageWithCloseButton(composeTestRule: ComposeTestRule, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { Log.i(TAG, "closeFindInPageWithCloseButton: Waiting for device to be idle") mDevice.waitForIdle() Log.i(TAG, "closeFindInPageWithCloseButton: Device was idle") Log.i(TAG, "closeFindInPageWithCloseButton: Trying to close find in page button") findInPageCloseButton().click() Log.i(TAG, "closeFindInPageWithCloseButton: Clicked close find in page button") - BrowserRobot().interact() - return BrowserRobot.Transition() + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } - fun closeFindInPageWithBackButton(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { + fun closeFindInPageWithBackButton(composeTestRule: ComposeTestRule, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { Log.i(TAG, "closeFindInPageWithBackButton: Waiting for device to be idle") mDevice.waitForIdle() Log.i(TAG, "closeFindInPageWithBackButton: Device was idle") @@ -97,8 +98,8 @@ class FindInPageRobot { mDevice.pressBack() Log.i(TAG, "closeFindInPageWithBackButton: Pressed 2x the device back button") - BrowserRobot().interact() - return BrowserRobot.Transition() + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } } } diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/HistoryRobot.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/HistoryRobot.kt @@ -6,6 +6,7 @@ package org.mozilla.fenix.ui.robots import android.net.Uri import android.util.Log +import androidx.compose.ui.test.junit4.ComposeTestRule import androidx.test.espresso.Espresso.onView import androidx.test.espresso.assertion.ViewAssertions.matches import androidx.test.espresso.matcher.RootMatchers.isDialog @@ -171,14 +172,14 @@ class HistoryRobot { Log.i(TAG, "openSearchGroup: Clicked search group: $searchTerm") } - class Transition { + class Transition(private val composeTestRule: ComposeTestRule) { fun goBackToHomeScreen(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition { Log.i(TAG, "goBackToHomeScreen: Trying to click go back button") onView(withContentDescription("Navigate up")).click() Log.i(TAG, "goBackToHomeScreen: Clicked go back button") - HomeScreenRobot().interact() - return HomeScreenRobot.Transition() + HomeScreenRobot(composeTestRule).interact() + return HomeScreenRobot.Transition(composeTestRule) } fun goBack(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { @@ -186,8 +187,8 @@ class HistoryRobot { onView(withContentDescription("Navigate up")).click() Log.i(TAG, "goBack: Clicked go back menu button") - BrowserRobot().interact() - return BrowserRobot.Transition() + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } fun openWebsite(url: Uri, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { @@ -196,8 +197,8 @@ class HistoryRobot { onView(withText(url.toString())).click() Log.i(TAG, "openWebsite: Clicked history item with url: $url") - BrowserRobot().interact() - return BrowserRobot.Transition() + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } fun openWebsiteFromSearchGroup(url: Uri, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { @@ -206,8 +207,8 @@ class HistoryRobot { onView(withText(url.toString())).click() Log.i(TAG, "openWebsiteFromSearchGroup: Clicked group item with url: $url") - BrowserRobot().interact() - return BrowserRobot.Transition() + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } fun openRecentlyClosedTabs(interact: RecentlyClosedTabsRobot.() -> Unit): RecentlyClosedTabsRobot.Transition { @@ -227,15 +228,15 @@ class HistoryRobot { itemWithResId("$packageName:id/history_search").click() Log.i(TAG, "clickSearchButton: Clicked search history button") - SearchRobot().interact() - return SearchRobot.Transition() + SearchRobot(composeTestRule).interact() + return SearchRobot.Transition(composeTestRule) } } } -fun historyMenu(interact: HistoryRobot.() -> Unit): HistoryRobot.Transition { +fun historyMenu(composeTestRule: ComposeTestRule, interact: HistoryRobot.() -> Unit): HistoryRobot.Transition { HistoryRobot().interact() - return HistoryRobot.Transition() + return HistoryRobot.Transition(composeTestRule) } private fun testPageTitle() = onView(withId(R.id.title)) diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/HomeScreenRobot.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/HomeScreenRobot.kt @@ -33,32 +33,28 @@ import androidx.compose.ui.test.performScrollToNode import androidx.compose.ui.test.performTouchInput import androidx.test.espresso.Espresso.onView import androidx.test.espresso.action.ViewActions -import androidx.test.espresso.action.ViewActions.click import androidx.test.espresso.assertion.PositionAssertions.isPartiallyBelow import androidx.test.espresso.assertion.ViewAssertions.matches import androidx.test.espresso.matcher.RootMatchers import androidx.test.espresso.matcher.ViewMatchers -import androidx.test.espresso.matcher.ViewMatchers.Visibility -import androidx.test.espresso.matcher.ViewMatchers.isDisplayed -import androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility import androidx.test.espresso.matcher.ViewMatchers.withId import androidx.test.espresso.matcher.ViewMatchers.withText import androidx.test.uiautomator.By import androidx.test.uiautomator.UiScrollable import androidx.test.uiautomator.UiSelector -import androidx.test.uiautomator.Until import mozilla.components.compose.browser.toolbar.concept.BrowserToolbarTestTags.ADDRESSBAR_URL_BOX +import mozilla.components.compose.browser.toolbar.concept.BrowserToolbarTestTags.TABS_COUNTER import org.hamcrest.CoreMatchers.allOf import org.junit.Assert.assertTrue import org.mozilla.fenix.R import org.mozilla.fenix.helpers.Constants.RETRY_COUNT import org.mozilla.fenix.helpers.Constants.TAG import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource -import org.mozilla.fenix.helpers.HomeActivityComposeTestRule import org.mozilla.fenix.helpers.MatcherHelper.assertItemIsChecked import org.mozilla.fenix.helpers.MatcherHelper.assertUIObjectExists import org.mozilla.fenix.helpers.MatcherHelper.itemContainingText import org.mozilla.fenix.helpers.MatcherHelper.itemWithClassNameAndIndex +import org.mozilla.fenix.helpers.MatcherHelper.itemWithDescription import org.mozilla.fenix.helpers.MatcherHelper.itemWithIndex import org.mozilla.fenix.helpers.MatcherHelper.itemWithResId import org.mozilla.fenix.helpers.MatcherHelper.itemWithResIdAndIndex @@ -70,8 +66,6 @@ import org.mozilla.fenix.helpers.TestAssetHelper.waitingTimeShort import org.mozilla.fenix.helpers.TestHelper.appName import org.mozilla.fenix.helpers.TestHelper.mDevice import org.mozilla.fenix.helpers.TestHelper.packageName -import org.mozilla.fenix.helpers.click -import org.mozilla.fenix.helpers.ext.waitNotNull import org.mozilla.fenix.home.topsites.TopSitesTestTag import org.mozilla.fenix.home.topsites.TopSitesTestTag.TOP_SITE_CARD_FAVICON import org.mozilla.fenix.home.ui.HomepageTestTag.HOMEPAGE @@ -85,12 +79,11 @@ import org.mozilla.fenix.ui.util.PositionOnScreenMatcher.Position.BOTTOM import org.mozilla.fenix.ui.util.PositionOnScreenMatcher.Position.TOP import org.mozilla.fenix.ui.util.isAtPosition import mozilla.components.browser.menu.R as menuR -import mozilla.components.ui.tabcounter.R as tabcounterR /** * Implementation of Robot Pattern for the home screen menu. */ -class HomeScreenRobot { +class HomeScreenRobot(private val composeTestRule: ComposeTestRule) { fun verifyNavigationToolbar() = assertUIObjectExists(navigationToolbar()) fun verifyHomeScreen() = assertUIObjectExists(homeScreen()) @@ -109,25 +102,14 @@ class HomeScreenRobot { fun verifyHomePrivateBrowsingButton() = assertUIObjectExists(privateBrowsingButton()) fun verifyHomeMenuButton() = assertUIObjectExists(menuButton()) - fun verifyTabButton() { - Log.i(TAG, "verifyTabButton: Trying to verify tab counter button is visible") - onView(allOf(withId(R.id.tab_button), isDisplayed())).check( - matches( - withEffectiveVisibility( - Visibility.VISIBLE, - ), - ), - ) - Log.i(TAG, "verifyTabButton: Verified tab counter button is visible") - } - fun verifyCollectionsHeader(composeTestRule: ComposeTestRule) { + fun verifyCollectionsHeader() { Log.i(TAG, "verifyCollectionsHeader: Trying to verify collections header is visible") - composeTestRule.onNodeWithText(getStringResource(R.string.collections_header)).assertIsDisplayed() + this@HomeScreenRobot.composeTestRule.onNodeWithText(getStringResource(R.string.collections_header)).assertIsDisplayed() Log.i(TAG, "verifyCollectionsHeader: Verified collections header is visible") } - fun verifyNoCollectionsText(composeTestRule: ComposeTestRule) { + fun verifyNoCollectionsText() { Log.i(TAG, "verifyNoCollectionsText: Trying to verify empty collections placeholder text is displayed") - composeTestRule.onNodeWithText(getStringResource(R.string.no_collections_description2)).assertIsDisplayed() + this@HomeScreenRobot.composeTestRule.onNodeWithText(getStringResource(R.string.no_collections_description2)).assertIsDisplayed() Log.i(TAG, "verifyNoCollectionsText: Verified empty collections placeholder text is displayed") } @@ -135,23 +117,28 @@ class HomeScreenRobot { Log.i(TAG, "verifyHomeWordmark: Scrolled 3x to the beginning of the home screen") assertUIObjectExists(homepageWordmarkLogo(), homepageWordmarkText()) } - fun verifyHomeComponent(composeTestRule: ComposeTestRule) { + fun verifyHomeComponent() { Log.i(TAG, "verifyHomeComponent: Trying to verify home screen view is visible") - composeTestRule.onNodeWithTag(HOMEPAGE).assertIsDisplayed() + this@HomeScreenRobot.composeTestRule.onNodeWithTag(HOMEPAGE).assertIsDisplayed() Log.i(TAG, "verifyHomeComponent: Verified home screen view is visible") } - fun verifyTabCounter(numberOfOpenTabs: String) = - onView( - allOf( - withId(tabcounterR.id.counter_text), - withText(numberOfOpenTabs), - withEffectiveVisibility(Visibility.VISIBLE), - ), - ).check(matches(isDisplayed())) + fun verifyTabCounter(numberOfOpenTabs: String, isPrivateBrowsingEnabled: Boolean = false) { + if (isPrivateBrowsingEnabled) { + Log.i(TAG, "verifyTabCounter: Trying to verify that the number of open private tabs is : $numberOfOpenTabs") + composeTestRule.onNodeWithContentDescription("Private Tabs Open: $numberOfOpenTabs. Tap to switch tabs.") + .assertIsDisplayed() + Log.i(TAG, "verifyTabCounter: Verified that the number of open private tabs is : $numberOfOpenTabs") + } else { + Log.i(TAG, "verifyTabCounter: Trying to verify that the number of open tabs is : $numberOfOpenTabs") + composeTestRule.onNodeWithContentDescription("Non-private Tabs Open: $numberOfOpenTabs. Tap to switch tabs.") + .assertIsDisplayed() + Log.i(TAG, "verifyTabCounter: Verified that the number of open tabs is : $numberOfOpenTabs") + } + } - fun verifyFirstOnboardingCard(composeTestRule: ComposeTestRule) { - composeTestRule.also { + fun verifyFirstOnboardingCard() { + this@HomeScreenRobot.composeTestRule.also { Log.i(TAG, "verifyFirstOnboardingCard: Trying to verify that the first onboarding screen title exists") it.onNodeWithText( getStringResource(R.string.juno_onboarding_default_browser_title_nimbus_2), @@ -175,8 +162,8 @@ class HomeScreenRobot { } } - fun verifySecondOnboardingCard(composeTestRule: ComposeTestRule) { - composeTestRule.also { + fun verifySecondOnboardingCard() { + this@HomeScreenRobot.composeTestRule.also { Log.i(TAG, "verifySecondOnboardingCard: Trying to verify that the second onboarding screen title exists") it.onNodeWithText( getStringResource(R.string.juno_onboarding_add_search_widget_title), @@ -200,8 +187,8 @@ class HomeScreenRobot { } } - fun verifyThirdOnboardingCard(composeTestRule: ComposeTestRule) { - composeTestRule.also { + fun verifyThirdOnboardingCard() { + this@HomeScreenRobot.composeTestRule.also { Log.i(TAG, "verifyThirdOnboardingCard: Trying to verify that the third onboarding screen title exists") it.onNodeWithText( getStringResource(R.string.juno_onboarding_sign_in_title_2), @@ -225,25 +212,25 @@ class HomeScreenRobot { } } - fun clickDefaultCardNotNowOnboardingButton(composeTestRule: ComposeTestRule) { + fun clickDefaultCardNotNowOnboardingButton() { Log.i(TAG, "clickNotNowOnboardingButton: Trying to click \"Not now\" onboarding button") - composeTestRule.onNodeWithTag( + this@HomeScreenRobot.composeTestRule.onNodeWithTag( getStringResource(R.string.juno_onboarding_default_browser_title_nimbus_2) + "onboarding_card.negative_button", ).performClick() Log.i(TAG, "clickNotNowOnboardingButton: Clicked \"Not now\" onboarding button") } - fun clickAddSearchWidgetNotNowOnboardingButton(composeTestRule: ComposeTestRule) { + fun clickAddSearchWidgetNotNowOnboardingButton() { Log.i(TAG, "clickNotNowOnboardingButton: Trying to click \"Not now\" onboarding button") - composeTestRule.onNodeWithTag( + this@HomeScreenRobot.composeTestRule.onNodeWithTag( getStringResource(R.string.juno_onboarding_add_search_widget_title) + "onboarding_card.negative_button", ).performClick() Log.i(TAG, "clickNotNowOnboardingButton: Clicked \"Not now\" onboarding button") } - fun clickSyncSignInWidgetNotNowOnboardingButton(composeTestRule: ComposeTestRule) { + fun clickSyncSignInWidgetNotNowOnboardingButton() { Log.i(TAG, "clickNotNowOnboardingButton: Trying to click \"Not now\" onboarding button") - composeTestRule.onNodeWithTag( + this@HomeScreenRobot.composeTestRule.onNodeWithTag( getStringResource(R.string.juno_onboarding_sign_in_title_2) + "onboarding_card.negative_button", ).performClick() Log.i(TAG, "clickNotNowOnboardingButton: Clicked \"Not now\" onboarding button") @@ -266,22 +253,22 @@ class HomeScreenRobot { } @OptIn(ExperimentalTestApi::class) - fun verifyExistingTopSitesList(composeTestRule: ComposeTestRule) { + fun verifyExistingTopSitesList() { Log.i(TAG, "verifyExistingTopSitesList: Waiting for $waitingTime ms until the top sites list exists") - composeTestRule.waitUntilAtLeastOneExists(hasTestTag(TopSitesTestTag.TOP_SITES), timeoutMillis = waitingTime) + this@HomeScreenRobot.composeTestRule.waitUntilAtLeastOneExists(hasTestTag(TopSitesTestTag.TOP_SITES), timeoutMillis = waitingTime) Log.i(TAG, "verifyExistingTopSitesList: Waited for $waitingTime ms until the top sites list to exists") Log.i(TAG, "verifyExistingTopSitesList: Trying to verify that the top sites list is displayed") - composeTestRule.onNodeWithTag(TopSitesTestTag.TOP_SITES).assertIsDisplayed() + this@HomeScreenRobot.composeTestRule.onNodeWithTag(TopSitesTestTag.TOP_SITES).assertIsDisplayed() Log.i(TAG, "verifyExistingTopSitesList: Verified that the top sites list is displayed") } - fun verifyNotExistingTopSiteItem(composeTestRule: ComposeTestRule, vararg titles: String) { + fun verifyNotExistingTopSiteItem(vararg titles: String) { titles.forEach { title -> Log.i(TAG, "verifyNotExistingTopSiteItem: Waiting for $waitingTime ms for top site with title: $title to exist") itemContainingText(title).waitForExists(waitingTime) Log.i(TAG, "verifyNotExistingTopSiteItem: Waited for $waitingTime ms for top site with title: $title to exist") Log.i(TAG, "verifyNotExistingTopSiteItem: Trying to verify that top site with title: $title does not exist") - composeTestRule.topSiteItem(title).assertDoesNotExist() + this@HomeScreenRobot.composeTestRule.topSiteItem(title).assertDoesNotExist() Log.i(TAG, "verifyNotExistingTopSiteItem: Verified that top site with title: $title does not exist") } } @@ -305,16 +292,16 @@ class HomeScreenRobot { ) @OptIn(ExperimentalTestApi::class) - fun verifyExistingTopSitesTabs(composeTestRule: ComposeTestRule, vararg titles: String) { + fun verifyExistingTopSitesTabs(vararg titles: String) { titles.forEach { title -> Log.i(TAG, "verifyExistingTopSiteItem: Waiting for $waitingTime ms until the top site with title: $title exists") - composeTestRule.waitUntilAtLeastOneExists( + this@HomeScreenRobot.composeTestRule.waitUntilAtLeastOneExists( hasTestTag(TopSitesTestTag.TOP_SITE_ITEM_ROOT).and(hasAnyChild(hasText(title))), timeoutMillis = waitingTimeLong, ) Log.i(TAG, "verifyExistingTopSiteItem: Waited for $waitingTimeLong ms until the top site with title: $title exists") Log.i(TAG, "verifyExistingTopSiteItem: Trying to verify that the top site with title: $title exists") - composeTestRule.topSiteItem(title).assertExists() + this@HomeScreenRobot.composeTestRule.topSiteItem(title).assertExists() Log.i(TAG, "verifyExistingTopSiteItem: Verified that the top site with title: $title exists") } } @@ -342,27 +329,27 @@ class HomeScreenRobot { ), ) } - fun verifyTopSiteContextMenuItems(composeTestRule: ComposeTestRule) { - verifyTopSiteContextMenuOpenInPrivateTabButton(composeTestRule) - verifyTopSiteContextMenuRemoveButton(composeTestRule) - verifyTopSiteContextMenuEditButton(composeTestRule) + fun verifyTopSiteContextMenuItems() { + verifyTopSiteContextMenuOpenInPrivateTabButton() + verifyTopSiteContextMenuRemoveButton() + verifyTopSiteContextMenuEditButton() } - fun verifyTopSiteContextMenuOpenInPrivateTabButton(composeTestRule: ComposeTestRule) { + fun verifyTopSiteContextMenuOpenInPrivateTabButton() { Log.i(TAG, "verifyTopSiteContextMenuOpenInPrivateTabButton: Trying to verify that the \"Open in private tab\" menu button exists") - composeTestRule.contextMenuItemOpenInPrivateTab().assertExists() + this@HomeScreenRobot.composeTestRule.contextMenuItemOpenInPrivateTab().assertExists() Log.i(TAG, "verifyTopSiteContextMenuOpenInPrivateTabButton: Verified that the \"Open in private tab\" menu button exists") } - fun verifyTopSiteContextMenuEditButton(composeTestRule: ComposeTestRule) { + fun verifyTopSiteContextMenuEditButton() { Log.i(TAG, "verifyTopSiteContextMenuEditButton: Trying to verify that the \"Edit\" menu button exists") - composeTestRule.contextMenuItemEdit().assertExists() + this@HomeScreenRobot.composeTestRule.contextMenuItemEdit().assertExists() Log.i(TAG, "verifyTopSiteContextMenuEditButton: Verified that the \"Edit\" menu button exists") } - fun verifyTopSiteContextMenuRemoveButton(composeTestRule: ComposeTestRule) { + fun verifyTopSiteContextMenuRemoveButton() { Log.i(TAG, "verifyTopSiteContextMenuRemoveButton: Trying to verify that the \"Remove\" menu button exists") - composeTestRule.contextMenuItemRemove().assertExists() + this@HomeScreenRobot.composeTestRule.contextMenuItemRemove().assertExists() Log.i(TAG, "verifyTopSiteContextMenuRemoveButton: Verified that the \"Remove\" menu button exists") } @@ -374,8 +361,8 @@ class HomeScreenRobot { assertUIObjectExists(itemContainingText(getStringResource(R.string.recent_tabs_header))) } - fun verifyJumpBackInSectionIsNotDisplayed(composeTestRule: ComposeTestRule) = - composeTestRule.onNodeWithText(getStringResource(R.string.recent_tabs_header)).assertIsNotDisplayed() + fun verifyJumpBackInSectionIsNotDisplayed() = + this@HomeScreenRobot.composeTestRule.onNodeWithText(getStringResource(R.string.recent_tabs_header)).assertIsNotDisplayed() fun verifyJumpBackInItemTitle(testRule: ComposeTestRule, itemTitle: String) { Log.i(TAG, "verifyJumpBackInItemTitle: Trying to verify jump back in item with title: $itemTitle") @@ -394,41 +381,41 @@ class HomeScreenRobot { fun verifyBookmarksSectionIsDisplayed(exists: Boolean) = assertUIObjectExists(itemContainingText(getStringResource(R.string.home_bookmarks_title)), exists = exists) - fun verifyRecentlyVisitedSearchGroupDisplayed(composeTestRule: ComposeTestRule, shouldBeDisplayed: Boolean, searchTerm: String, groupSize: Int) { + fun verifyRecentlyVisitedSearchGroupDisplayed(shouldBeDisplayed: Boolean, searchTerm: String, groupSize: Int) { // checks if the search group exists in the Recently visited section if (shouldBeDisplayed) { Log.i(TAG, "verifyRecentlyVisitedSearchGroupDisplayed: Trying to verify that the \"Recently visited\" section is displayed") - composeTestRule.onNodeWithText("Recently visited").assertIsDisplayed() + this@HomeScreenRobot.composeTestRule.onNodeWithText("Recently visited").assertIsDisplayed() Log.i(TAG, "verifyRecentlyVisitedSearchGroupDisplayed: Verified that the \"Recently visited\" section is displayed") Log.i(TAG, "verifyRecentlyVisitedSearchGroupDisplayed: Trying to verify that the search group: $searchTerm has $groupSize pages") - composeTestRule.onNodeWithText(searchTerm, useUnmergedTree = true).assert(hasAnySibling(hasText("$groupSize pages"))) + this@HomeScreenRobot.composeTestRule.onNodeWithText(searchTerm, useUnmergedTree = true).assert(hasAnySibling(hasText("$groupSize pages"))) Log.i(TAG, "verifyRecentlyVisitedSearchGroupDisplayed: Verified that the search group: $searchTerm has $groupSize pages") } else { Log.i(TAG, "verifyRecentlyVisitedSearchGroupDisplayed: Trying to verify that the search group: $searchTerm is not displayed") - composeTestRule.onNodeWithText(searchTerm, useUnmergedTree = true).assertIsNotDisplayed() + this@HomeScreenRobot.composeTestRule.onNodeWithText(searchTerm, useUnmergedTree = true).assertIsNotDisplayed() Log.i(TAG, "verifyRecentlyVisitedSearchGroupDisplayed: Verified that the search group: $searchTerm is not displayed") } } // Collections elements @OptIn(ExperimentalTestApi::class) - fun verifyCollectionIsDisplayed(composeTestRule: ComposeTestRule, title: String, collectionExists: Boolean = true) { + fun verifyCollectionIsDisplayed(title: String, collectionExists: Boolean = true) { if (collectionExists) { - composeTestRule.waitUntilExactlyOneExists(hasText(title), waitingTime) + this@HomeScreenRobot.composeTestRule.waitUntilExactlyOneExists(hasText(title), waitingTime) Log.i(TAG, "verifyCollectionIsDisplayed: Trying to verify that collection with title: $title is displayed") - composeTestRule.onNodeWithText(title).assertIsDisplayed() + this@HomeScreenRobot.composeTestRule.onNodeWithText(title).assertIsDisplayed() Log.i(TAG, "verifyCollectionIsDisplayed: Verified that collection with title: $title is displayed") } else { - composeTestRule.waitUntilDoesNotExist(hasText(title), waitingTime) + this@HomeScreenRobot.composeTestRule.waitUntilDoesNotExist(hasText(title), waitingTime) Log.i(TAG, "verifyCollectionIsDisplayed: Trying to verify that collection with title: $title is not displayed") - composeTestRule.onNodeWithText(title).assertIsNotDisplayed() + this@HomeScreenRobot.composeTestRule.onNodeWithText(title).assertIsNotDisplayed() Log.i(TAG, "verifyCollectionIsDisplayed: Verified that collection with title: $title is not displayed") } } - fun togglePrivateBrowsingModeOnOff(composeTestRule: ComposeTestRule) { + fun togglePrivateBrowsingModeOnOff() { Log.i(TAG, "togglePrivateBrowsingModeOnOff: Trying to click private browsing home screen button") - composeTestRule.onNodeWithContentDescription(getStringResource(R.string.content_description_private_browsing)).performClick() + this@HomeScreenRobot.composeTestRule.onNodeWithContentDescription(getStringResource(R.string.content_description_private_browsing)).performClick() Log.i(TAG, "togglePrivateBrowsingModeOnOff: Clicked private browsing home screen button") } @@ -440,9 +427,9 @@ class HomeScreenRobot { } } - fun verifyPocketRecommendedStoriesItems(composeTestRule: ComposeTestRule) { + fun verifyPocketRecommendedStoriesItems() { Log.i(TAG, "verifyPocketRecommendedStoriesItems: Trying to scroll into view the \"Stories\" pocket section") - composeTestRule.onNodeWithTag("homepage.view").performScrollToNode(hasTestTag("pocket.stories")) + this@HomeScreenRobot.composeTestRule.onNodeWithTag("homepage.view").performScrollToNode(hasTestTag("pocket.stories")) Log.i(TAG, "verifyPocketRecommendedStoriesItems: Scrolled into view the \"Stories\" pocket section") for (position in 0..7) { Log.i(TAG, "verifyPocketRecommendedStoriesItems: Trying to scroll into view the featured pocket story from position: $position") @@ -467,21 +454,8 @@ class HomeScreenRobot { // } // } - fun verifyAddressBarPosition(bottomPosition: Boolean) { - Log.i(TAG, "verifyAddressBarPosition: Trying to verify toolbar is set to top: $bottomPosition") - onView(withId(R.id.toolbarLayout)) - .check( - if (bottomPosition) { - matches(isAtPosition(BOTTOM)) - } else { - matches(isAtPosition(TOP)) - }, - ) - Log.i(TAG, "verifyAddressBarPosition: Verified toolbar position is set to top: $bottomPosition") - } - - fun verifyComposableToolbarPosition(bottomPosition: Boolean) { - Log.i(TAG, "verifyComposableToolbarPosition: Trying to verify toolbar is set to top: $bottomPosition") + fun verifyToolbarPosition(bottomPosition: Boolean) { + Log.i(TAG, "verifyToolbarPosition: Trying to verify toolbar is set to top: $bottomPosition") onView(withId(R.id.composable_toolbar)) .check( if (bottomPosition) { @@ -490,7 +464,7 @@ class HomeScreenRobot { matches(isAtPosition(TOP)) }, ) - Log.i(TAG, "verifyComposableToolbarPosition: Verified toolbar position is set to top: $bottomPosition") + Log.i(TAG, "verifyToolbarPosition: Verified toolbar position is set to top: $bottomPosition") } fun verifyNavigationToolbarIsSetToTheBottomOfTheHomeScreen() { @@ -534,9 +508,9 @@ class HomeScreenRobot { ) } - class Transition { + class Transition(private val composeTestRule: ComposeTestRule) { - fun openTabDrawerFromRedesignedToolbar(composeTestRule: HomeActivityComposeTestRule, interact: TabDrawerRobot.() -> Unit): TabDrawerRobot.Transition { + fun openTabDrawerFromRedesignedToolbar(interact: TabDrawerRobot.() -> Unit): TabDrawerRobot.Transition { for (i in 1..RETRY_COUNT) { try { Log.i(TAG, "openTabDrawerFromRedesignedToolbar: Started try #$i") @@ -568,89 +542,40 @@ class HomeScreenRobot { return TabDrawerRobot.Transition(composeTestRule) } - fun openTabDrawer(composeTestRule: HomeActivityComposeTestRule, interact: TabDrawerRobot.() -> Unit): TabDrawerRobot.Transition { - Log.i(TAG, "openTabDrawer: Waiting for device to be idle for $waitingTime ms") - mDevice.waitForIdle(waitingTime) - Log.i(TAG, "openTabDrawer: Device was idle for $waitingTime ms") - Log.i(TAG, "openTabDrawer: Trying to click tab counter button") - onView(withId(R.id.tab_button)).click() - Log.i(TAG, "openTabDrawer: Clicked tab counter button") + fun openTabDrawer(interact: TabDrawerRobot.() -> Unit): TabDrawerRobot.Transition { + Log.i(TAG, "openTabDrawer: Trying to click the tab counter button") + composeTestRule.onNodeWithTag(TABS_COUNTER).performClick() + Log.i(TAG, "openTabDrawer: Clicked the tab counter button") Log.i(TAG, "openTabDrawer: Trying to verify the tabs tray exists") composeTestRule.onNodeWithTag(TabsTrayTestTag.TABS_TRAY).assertExists() Log.i(TAG, "openTabDrawer: Verified the tabs tray exists") + Log.i(TAG, "openTabDrawer: Trying to verify the tabs tray new tab FAB button exists") + composeTestRule.onNodeWithTag(TabsTrayTestTag.FAB).assertExists() + Log.i(TAG, "openTabDrawer: Verified the tabs tray new tab FAB button exists") TabDrawerRobot(composeTestRule).interact() return TabDrawerRobot.Transition(composeTestRule) } fun openThreeDotMenu(interact: ThreeDotMenuMainRobot.() -> Unit): ThreeDotMenuMainRobot.Transition { - // Issue: https://github.com/mozilla-mobile/fenix/issues/21578 - try { - Log.i(TAG, "openThreeDotMenu: Try block") - mDevice.waitNotNull( - Until.findObject(By.res("$packageName:id/menuButton")), - waitingTime, - ) - } catch (e: AssertionError) { - Log.i(TAG, "openThreeDotMenu: Catch block") - Log.i(TAG, "openThreeDotMenu: Trying to click device back button") - mDevice.pressBack() - Log.i(TAG, "openThreeDotMenu: Clicked device back button") - } finally { - Log.i(TAG, "openThreeDotMenu: Finally block") - Log.i(TAG, "openThreeDotMenu: Trying to click main menu button") - threeDotButton().perform(click()) - Log.i(TAG, "openThreeDotMenu: Clicked main menu button") - } - - ThreeDotMenuMainRobot().interact() - return ThreeDotMenuMainRobot.Transition() - } - - fun openThreeDotMenu(composeTestRule: ComposeTestRule, interact: ThreeDotMenuMainRobotCompose.() -> Unit): ThreeDotMenuMainRobotCompose.Transition { - Log.i(TAG, "openThreeDotMenuFromRedesignedToolbar: Trying to click main menu button") - itemWithResId("$packageName:id/menuButton").click() - Log.i(TAG, "openThreeDotMenuFromRedesignedToolbar: Clicked main menu button") - assertUIObjectExists(itemWithResId("$packageName:id/design_bottom_sheet")) - - ThreeDotMenuMainRobotCompose(composeTestRule).interact() - return ThreeDotMenuMainRobotCompose.Transition(composeTestRule) - } - - fun openThreeDotMenuWithComposableToolbar(composeTestRule: ComposeTestRule, interact: ThreeDotMenuMainRobotCompose.() -> Unit): ThreeDotMenuMainRobotCompose.Transition { - Log.i(TAG, "openThreeDotMenuWithComposableToolbar: Trying to click main menu button") + Log.i(TAG, "openThreeDotMenu: Trying to click main menu button") composeTestRule.onNodeWithContentDescription(getStringResource(R.string.content_description_menu)).performClick() - Log.i(TAG, "openThreeDotMenuWithComposableToolbar: Clicked main menu button") + Log.i(TAG, "openThreeDotMenu: Clicked main menu button") assertUIObjectExists(itemWithResId("$packageName:id/design_bottom_sheet")) - ThreeDotMenuMainRobotCompose(composeTestRule).interact() - return ThreeDotMenuMainRobotCompose.Transition(composeTestRule) - } - - fun openSearch(interact: SearchRobot.() -> Unit): SearchRobot.Transition { - Log.i(TAG, "openSearch: Waiting for $waitingTime ms for the navigation toolbar to exist") - navigationToolbar().waitForExists(waitingTime) - Log.i(TAG, "openSearch: Waited for $waitingTime ms for the navigation toolbar to exist") - Log.i(TAG, "openSearch: Trying to click navigation toolbar") - navigationToolbar().click() - Log.i(TAG, "openSearch: Clicked navigation toolbar") - Log.i(TAG, "openSearch: Waiting for device to be idle") - mDevice.waitForIdle() - Log.i(TAG, "openSearch: Device was idle") - - SearchRobot().interact() - return SearchRobot.Transition() + ThreeDotMenuMainRobot(composeTestRule).interact() + return ThreeDotMenuMainRobot.Transition(composeTestRule) } @OptIn(ExperimentalTestApi::class) - fun openSearchWithComposableToolbar(composeTestRule: ComposeTestRule, interact: SearchRobot.() -> Unit): SearchRobot.Transition { + fun openSearch(interact: SearchRobot.() -> Unit): SearchRobot.Transition { composeTestRule.waitUntilAtLeastOneExists(hasTestTag(ADDRESSBAR_URL_BOX), waitingTime) - Log.i(TAG, "openSearchWithComposableToolbar: Trying to click navigation toolbar") + Log.i(TAG, "openSearch: Trying to click navigation toolbar") composeTestRule.onNodeWithTag(ADDRESSBAR_URL_BOX).performClick() - Log.i(TAG, "openSearchWithComposableToolbar: Clicked navigation toolbar") + Log.i(TAG, "openSearch: Clicked navigation toolbar") - SearchRobot().interact() - return SearchRobot.Transition() + SearchRobot(composeTestRule).interact() + return SearchRobot.Transition(composeTestRule) } fun togglePrivateBrowsingMode(switchPBModeOn: Boolean = true) { @@ -690,8 +615,8 @@ class HomeScreenRobot { Log.i(TAG, "triggerPrivateBrowsingShortcutPrompt: Clicked private browsing button") } - AddToHomeScreenRobot().interact() - return AddToHomeScreenRobot.Transition() + AddToHomeScreenRobot(composeTestRule).interact() + return AddToHomeScreenRobot.Transition(composeTestRule) } fun pressBack() { @@ -700,21 +625,7 @@ class HomeScreenRobot { Log.i(TAG, "pressBack: Clicked device back button") } - fun openNavigationToolbar(interact: NavigationToolbarRobot.() -> Unit): NavigationToolbarRobot.Transition { - Log.i(TAG, "openNavigationToolbar: Waiting for $waitingTime ms for navigation the toolbar to exist") - mDevice.findObject(UiSelector().resourceId("$packageName:id/toolbar")) - .waitForExists(waitingTime) - Log.i(TAG, "openNavigationToolbar: Waited for $waitingTime ms for the navigation toolbar to exist") - Log.i(TAG, "openNavigationToolbar: Trying to click the navigation toolbar") - navigationToolbar().click() - Log.i(TAG, "openNavigationToolbar: Clicked the navigation toolbar") - - NavigationToolbarRobot().interact() - return NavigationToolbarRobot.Transition() - } - fun openContextMenuOnTopSitesWithTitle( - composeTestRule: ComposeTestRule, title: String, interact: HomeScreenRobot.() -> Unit, ): Transition { @@ -725,12 +636,11 @@ class HomeScreenRobot { composeTestRule.topSiteItem(title).performTouchInput { longClick() } Log.i(TAG, "openContextMenuOnTopSitesWithTitle: Long clicked top site with title: $title") - HomeScreenRobot().interact() - return Transition() + HomeScreenRobot(composeTestRule).interact() + return Transition(composeTestRule) } fun openTopSiteTabWithTitle( - composeTestRule: ComposeTestRule, title: String, interact: BrowserRobot.() -> Unit, ): BrowserRobot.Transition { @@ -741,12 +651,11 @@ class HomeScreenRobot { composeTestRule.topSiteItem(title).performClick() Log.i(TAG, "openTopSiteTabWithTitle: Clicked top site with title: $title") - BrowserRobot().interact() - return BrowserRobot.Transition() + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } fun editTopSite( - composeTestRule: ComposeTestRule, title: String, url: String, interact: HomeScreenRobot.() -> Unit, @@ -776,12 +685,12 @@ class HomeScreenRobot { itemWithResIdContainingText("android:id/button1", "Save").click() Log.i(TAG, "editTopSite: Clicked the \"Save\" dialog button") - HomeScreenRobot().interact() - return Transition() + HomeScreenRobot(composeTestRule).interact() + return Transition(composeTestRule) } @OptIn(ExperimentalTestApi::class) - fun removeTopSite(composeTestRule: ComposeTestRule, interact: HomeScreenRobot.() -> Unit): Transition { + fun removeTopSite(interact: HomeScreenRobot.() -> Unit): Transition { Log.i(TAG, "removeTopSite: Trying to click the \"Remove\" menu button") composeTestRule.contextMenuItemRemove().performClick() Log.i(TAG, "removeTopSite: Clicked the \"Remove\" menu button") @@ -789,12 +698,11 @@ class HomeScreenRobot { composeTestRule.waitUntilDoesNotExist(hasTestTag(TopSitesTestTag.REMOVE), waitingTime) Log.i(TAG, "removeTopSite: Waited for $waitingTime ms until the \"Remove\" menu button does not exist") - HomeScreenRobot().interact() - return Transition() + HomeScreenRobot(composeTestRule).interact() + return Transition(composeTestRule) } fun openTopSiteInPrivateTab( - composeTestRule: ComposeTestRule, interact: BrowserRobot.() -> Unit, ): BrowserRobot.Transition { Log.i(TAG, "openTopSiteInPrivateTab: Trying to click the \"Open in private tab\" menu button") @@ -802,20 +710,20 @@ class HomeScreenRobot { Log.i(TAG, "openTopSiteInPrivateTab: Clicked the \"Open in private tab\" menu button") composeTestRule.waitForIdle() - BrowserRobot().interact() - return BrowserRobot.Transition() + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } - fun clickSponsorsAndPrivacyButton(composeTestRule: ComposeTestRule, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { + fun clickSponsorsAndPrivacyButton(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { Log.i(TAG, "clickSponsorsAndPrivacyButton: Trying to click \"Our sponsors & your privacy\" context menu button and wait for $waitingTime ms for a new window") composeTestRule.onNodeWithText(getStringResource(R.string.top_sites_menu_sponsor_privacy)).performClick() Log.i(TAG, "clickSponsorsAndPrivacyButton: Clicked \"Our sponsors & your privacy\" context menu button and waited for $waitingTime ms for a new window") - BrowserRobot().interact() - return BrowserRobot.Transition() + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } - fun clickSponsoredShortcutsSettingsButton(composeTestRule: ComposeTestRule, interact: SettingsSubMenuHomepageRobot.() -> Unit): SettingsSubMenuHomepageRobot.Transition { + fun clickSponsoredShortcutsSettingsButton(interact: SettingsSubMenuHomepageRobot.() -> Unit): SettingsSubMenuHomepageRobot.Transition { Log.i(TAG, "clickSponsoredShortcutsSettingsButton: Trying to click \"Settings\" context menu button and wait for $waitingTime for a new window") composeTestRule.onNodeWithText(getStringResource(R.string.top_sites_menu_settings)).performClick() Log.i(TAG, "clickSponsoredShortcutsSettingsButton: Clicked \"Settings\" context menu button and waited for $waitingTime for a new window") @@ -824,16 +732,16 @@ class HomeScreenRobot { return SettingsSubMenuHomepageRobot.Transition() } - fun openPrivateBrowsingModeLearnMoreLink(composeTestRule: ComposeTestRule, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { + fun openPrivateBrowsingModeLearnMoreLink(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { Log.i(TAG, "openPrivateBrowsingModeLearnMoreLink: Trying to click private browsing home screen link") composeTestRule.onNodeWithTag(HOMEPAGE_PRIVATE_BROWSING_LEARN_MORE_LINK).performClick() Log.i(TAG, "openPrivateBrowsingModeLearnMoreLink: Clicked private browsing home screen link") - BrowserRobot().interact() - return BrowserRobot.Transition() + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } - fun clickSaveTabsToCollectionButton(composeTestRule: HomeActivityComposeTestRule, interact: TabDrawerRobot.() -> Unit): TabDrawerRobot.Transition { + fun clickSaveTabsToCollectionButton(interact: TabDrawerRobot.() -> Unit): TabDrawerRobot.Transition { Log.i(TAG, "clickSaveTabsToCollectionButton: Trying to click save tabs to collection button") saveTabsToCollectionButton(composeTestRule).performClick() Log.i(TAG, "clickSaveTabsToCollectionButton: Clicked save tabs to collection button") @@ -841,7 +749,7 @@ class HomeScreenRobot { return TabDrawerRobot.Transition(composeTestRule) } - fun expandCollection(composeTestRule: ComposeTestRule, title: String, interact: CollectionRobot.() -> Unit): CollectionRobot.Transition { + fun expandCollection(title: String, interact: CollectionRobot.() -> Unit): CollectionRobot.Transition { Log.i(TAG, "expandCollection: Trying to click collection with title: $title") composeTestRule.onNodeWithText(title).performClick() Log.i(TAG, "expandCollection: Clicked collection with title: $title") @@ -849,20 +757,20 @@ class HomeScreenRobot { composeTestRule.waitForIdle() Log.i(TAG, "expandCollection: Waited for compose test rule to be idle") - CollectionRobot().interact() - return CollectionRobot.Transition() + CollectionRobot(composeTestRule).interact() + return CollectionRobot.Transition(composeTestRule) } - fun openRecentlyVisitedSearchGroupHistoryList(composeTestRule: ComposeTestRule, title: String, interact: HistoryRobot.() -> Unit): HistoryRobot.Transition { + fun openRecentlyVisitedSearchGroupHistoryList(title: String, interact: HistoryRobot.() -> Unit): HistoryRobot.Transition { Log.i(TAG, "openRecentlyVisitedSearchGroupHistoryList: Trying to click recently visited search group with title: $title") composeTestRule.onNodeWithText(title).performClick() Log.i(TAG, "openRecentlyVisitedSearchGroupHistoryList: Clicked recently visited search group with title: $title") HistoryRobot().interact() - return HistoryRobot.Transition() + return HistoryRobot.Transition(composeTestRule) } - fun clickJumpBackInShowAllButton(composeTestRule: HomeActivityComposeTestRule, interact: TabDrawerRobot.() -> Unit): TabDrawerRobot.Transition { + fun clickJumpBackInShowAllButton(interact: TabDrawerRobot.() -> Unit): TabDrawerRobot.Transition { Log.i(TAG, "clickJumpBackInShowAllButton: Trying to click \"Show all\" button and wait for $waitingTime ms for a new window") mDevice .findObject( @@ -884,12 +792,11 @@ class HomeScreenRobot { ).clickAndWaitForNewWindow(waitingTime) Log.i(TAG, "clickPocketStoryItem: Clicked pocket story item published at position: $position and wait for $waitingTime ms for a new window") - BrowserRobot().interact() - return BrowserRobot.Transition() + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } fun clickSetAsDefaultBrowserOnboardingButton( - composeTestRule: ComposeTestRule, interact: SettingsRobot.() -> Unit, ): SettingsRobot.Transition { Log.i(TAG, "clickSetAsDefaultBrowserOnboardingButton: Trying to click \"Set as default browser\" onboarding button") @@ -903,7 +810,6 @@ class HomeScreenRobot { } fun clickSignInOnboardingButton( - composeTestRule: ComposeTestRule, interact: SyncSignInRobot.() -> Unit, ): SyncSignInRobot.Transition { Log.i(TAG, "clickSignInOnboardingButton: Trying to click \"Sign in\" onboarding button") @@ -913,14 +819,14 @@ class HomeScreenRobot { Log.i(TAG, "clickSignInOnboardingButton: Clicked \"Sign in\" onboarding button") SyncSignInRobot().interact() - return SyncSignInRobot.Transition() + return SyncSignInRobot.Transition(composeTestRule) } } } -fun homeScreen(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition { - HomeScreenRobot().interact() - return HomeScreenRobot.Transition() +fun homeScreen(composeTestRule: ComposeTestRule, interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition { + HomeScreenRobot(composeTestRule).interact() + return HomeScreenRobot.Transition(composeTestRule) } private fun homeScreenList() = @@ -963,9 +869,9 @@ private fun homepageWordmarkText() = itemWithResId(HOMEPAGE_WORDMARK_TEXT) private fun navigationToolbar() = - itemWithResId("$packageName:id/toolbar") + itemWithResId("$packageName:id/composable_toolbar") private fun menuButton() = - itemWithResId("$packageName:id/menuButton") + itemWithDescription(getStringResource(R.string.content_description_menu)) private fun tabCounter(numberOfOpenTabs: String) = itemWithResIdAndText("$packageName:id/counter_text", numberOfOpenTabs) diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/LibrarySubMenusMultipleSelectionToolbarRobot.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/LibrarySubMenusMultipleSelectionToolbarRobot.kt @@ -149,17 +149,17 @@ class LibrarySubMenusMultipleSelectionToolbarRobot { Log.i(TAG, "clickMultiSelectThreeDotButton: Clicked the multi-selection three dot button") } - class Transition { + class Transition(private val composeTestRule: ComposeTestRule) { fun closeToolbarReturnToHistory(interact: HistoryRobot.() -> Unit): HistoryRobot.Transition { Log.i(TAG, "closeToolbarReturnToHistory: Trying to click the navigate up toolbar button") closeToolbarButton().click() Log.i(TAG, "closeToolbarReturnToHistory: Clicked the navigate up toolbar button") HistoryRobot().interact() - return HistoryRobot.Transition() + return HistoryRobot.Transition(composeTestRule) } - fun clickOpenNewTab(composeTestRule: HomeActivityComposeTestRule, interact: TabDrawerRobot.() -> Unit): TabDrawerRobot.Transition { + fun clickOpenNewTab(interact: TabDrawerRobot.() -> Unit): TabDrawerRobot.Transition { Log.i(TAG, "clickOpenNewTab: Trying to click the multi-select \"Open in a new tab\" context menu button") openInNewTabButton().click() Log.i(TAG, "clickOpenNewTab: Clicked the multi-select \"Open in a new tab\" context menu button") @@ -171,7 +171,7 @@ class LibrarySubMenusMultipleSelectionToolbarRobot { return TabDrawerRobot.Transition(composeTestRule) } - fun clickOpenInNewTabButton(composeTestRule: HomeActivityComposeTestRule, interact: TabDrawerRobot.() -> Unit): TabDrawerRobot.Transition { + fun clickOpenInNewTabButton(interact: TabDrawerRobot.() -> Unit): TabDrawerRobot.Transition { Log.i(TAG, "clickOpenInNewTabButton: Trying to click the multi-select \"Open in a new tab\" context menu button") redesignedBookmarksOpenInNewTabButton(composeTestRule).performClick() Log.i(TAG, "clickOpenInNewTabButton: Clicked the multi-select \"Open in a new tab\" context menu button") @@ -183,7 +183,7 @@ class LibrarySubMenusMultipleSelectionToolbarRobot { return TabDrawerRobot.Transition(composeTestRule) } - fun clickOpenPrivateTab(composeTestRule: HomeActivityComposeTestRule, interact: TabDrawerRobot.() -> Unit): TabDrawerRobot.Transition { + fun clickOpenPrivateTab(interact: TabDrawerRobot.() -> Unit): TabDrawerRobot.Transition { Log.i(TAG, "clickOpenPrivateTab: Trying to click the multi-select \"Open in a private tab\" context menu button") openInPrivateTabButton().click() Log.i(TAG, "clickOpenPrivateTab: Clicked the multi-select \"Open in a private tab\" context menu button") @@ -194,9 +194,9 @@ class LibrarySubMenusMultipleSelectionToolbarRobot { } } -fun multipleSelectionToolbar(interact: LibrarySubMenusMultipleSelectionToolbarRobot.() -> Unit): LibrarySubMenusMultipleSelectionToolbarRobot.Transition { +fun multipleSelectionToolbar(composeTestRule: ComposeTestRule, interact: LibrarySubMenusMultipleSelectionToolbarRobot.() -> Unit): LibrarySubMenusMultipleSelectionToolbarRobot.Transition { LibrarySubMenusMultipleSelectionToolbarRobot().interact() - return LibrarySubMenusMultipleSelectionToolbarRobot.Transition() + return LibrarySubMenusMultipleSelectionToolbarRobot.Transition(composeTestRule) } private fun closeToolbarButton() = onView(withContentDescription("Navigate up")) diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/MicrosurveysRobot.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/MicrosurveysRobot.kt @@ -31,12 +31,13 @@ import org.mozilla.fenix.helpers.TestHelper.packageName @OptIn(ExperimentalTestApi::class) class MicrosurveysRobot { - fun verifySurveyButton() = assertUIObjectExists(itemContainingText(getStringResource(R.string.preferences_take_survey))) + fun verifySurveyButton(composeTestRule: ComposeTestRule) { + composeTestRule.onNodeWithText(getStringResource(R.string.preferences_take_survey), useUnmergedTree = true).assertIsDisplayed() + } - fun verifySurveyNoThanksButton() = - assertUIObjectExists( - itemContainingText(getStringResource(R.string.preferences_not_take_survey)), - ) + fun verifySurveyNoThanksButton(composeTestRule: ComposeTestRule) { + composeTestRule.onNodeWithText(getStringResource(R.string.preferences_not_take_survey), useUnmergedTree = true).assertIsDisplayed() + } fun verifyHomeScreenSurveyCloseButton(exists: Boolean) = assertUIObjectExists(itemWithDescription("Close"), exists = exists) @@ -170,17 +171,14 @@ class MicrosurveysRobot { verifyHomeScreenSurveyCloseButton(exists) } - class Transition { + class Transition(private val composeTestRule: ComposeTestRule) { fun clickSurveyButton(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { - Log.i(TAG, "clickSurveyButton: Waiting for $waitingTime for the survey button to exist") - surveyButton().waitForExists(waitingTime) - Log.i(TAG, "clickSurveyButton: Waited for $waitingTime for the survey button to exist") Log.i(TAG, "clickSurveyButton: Trying to click the survey button") - surveyButton().click() + composeTestRule.onNodeWithText(getStringResource(R.string.preferences_take_survey), useUnmergedTree = true).performClick() Log.i(TAG, "clickSurveyButton: Clicked the survey button") - BrowserRobot().interact() - return BrowserRobot.Transition() + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } fun clickNoThanksSurveyButton(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { @@ -191,8 +189,8 @@ class MicrosurveysRobot { surveyNoThanksButton().click() Log.i(TAG, "clickNoThanksSurveyButton: Clicked the \"No thanks\" button") - BrowserRobot().interact() - return BrowserRobot.Transition() + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } fun clickHomeScreenSurveyCloseButton(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { @@ -203,8 +201,8 @@ class MicrosurveysRobot { homescreenSurveyCloseButton().click() Log.i(TAG, "clickHomeScreenSurveyCloseButton: Clicked the close survey button") - BrowserRobot().interact() - return BrowserRobot.Transition() + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } fun collapseSurveyByTappingBackButton(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { @@ -215,15 +213,15 @@ class MicrosurveysRobot { mDevice.waitForIdle() Log.i(TAG, "collapseSurveyByTappingBackButton: Waited for device to be idle") - BrowserRobot().interact() - return BrowserRobot.Transition() + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } } } -fun surveyScreen(interact: MicrosurveysRobot.() -> Unit): MicrosurveysRobot.Transition { +fun surveyScreen(composeTestRule: ComposeTestRule, interact: MicrosurveysRobot.() -> Unit): MicrosurveysRobot.Transition { MicrosurveysRobot().interact() - return MicrosurveysRobot.Transition() + return MicrosurveysRobot.Transition(composeTestRule) } private fun surveyButton() = diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/NavigationToolbarRobot.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/NavigationToolbarRobot.kt @@ -9,9 +9,11 @@ package org.mozilla.fenix.ui.robots import android.net.Uri import android.os.Build import android.util.Log +import android.view.KeyEvent import androidx.compose.ui.test.ExperimentalTestApi import androidx.compose.ui.test.assert import androidx.compose.ui.test.assertIsDisplayed +import androidx.compose.ui.test.assertIsNotDisplayed import androidx.compose.ui.test.hasContentDescription import androidx.compose.ui.test.hasTestTag import androidx.compose.ui.test.junit4.ComposeTestRule @@ -19,22 +21,22 @@ import androidx.compose.ui.test.onAllNodesWithTag import androidx.compose.ui.test.onLast import androidx.compose.ui.test.onNodeWithContentDescription import androidx.compose.ui.test.onNodeWithTag +import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.performClick import androidx.compose.ui.test.performImeAction import androidx.compose.ui.test.performTextReplacement -import androidx.recyclerview.widget.RecyclerView +import androidx.compose.ui.test.performTouchInput import androidx.test.espresso.AppNotIdleException import androidx.test.espresso.Espresso.onView import androidx.test.espresso.action.ViewActions -import androidx.test.espresso.action.ViewActions.longClick import androidx.test.espresso.action.ViewActions.pressImeActionButton import androidx.test.espresso.assertion.PositionAssertions.isCompletelyAbove import androidx.test.espresso.assertion.PositionAssertions.isPartiallyBelow import androidx.test.espresso.assertion.ViewAssertions.matches -import androidx.test.espresso.contrib.RecyclerViewActions import androidx.test.espresso.matcher.ViewMatchers.Visibility import androidx.test.espresso.matcher.ViewMatchers.hasDescendant import androidx.test.espresso.matcher.ViewMatchers.isCompletelyDisplayed +import androidx.test.espresso.matcher.ViewMatchers.isRoot import androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility import androidx.test.espresso.matcher.ViewMatchers.withId import androidx.test.espresso.matcher.ViewMatchers.withText @@ -44,17 +46,14 @@ import androidx.test.uiautomator.UiSelector import androidx.test.uiautomator.Until import mozilla.components.compose.browser.toolbar.concept.BrowserToolbarTestTags.ADDRESSBAR_SEARCH_BOX import mozilla.components.compose.browser.toolbar.concept.BrowserToolbarTestTags.ADDRESSBAR_URL_BOX +import mozilla.components.compose.browser.toolbar.concept.BrowserToolbarTestTags.SEARCH_SELECTOR +import mozilla.components.compose.browser.toolbar.concept.BrowserToolbarTestTags.TABS_COUNTER import org.hamcrest.CoreMatchers.allOf -import org.junit.Assert.assertTrue import org.mozilla.fenix.R -import org.mozilla.fenix.helpers.AppAndSystemHelper.registerAndCleanupIdlingResources -import org.mozilla.fenix.helpers.Constants import org.mozilla.fenix.helpers.Constants.LONG_CLICK_DURATION import org.mozilla.fenix.helpers.Constants.RETRY_COUNT import org.mozilla.fenix.helpers.Constants.TAG import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource -import org.mozilla.fenix.helpers.HomeActivityComposeTestRule -import org.mozilla.fenix.helpers.MatcherHelper.assertItemTextEquals import org.mozilla.fenix.helpers.MatcherHelper.assertUIObjectExists import org.mozilla.fenix.helpers.MatcherHelper.assertUIObjectIsGone import org.mozilla.fenix.helpers.MatcherHelper.itemWithDescription @@ -67,11 +66,9 @@ import org.mozilla.fenix.helpers.TestAssetHelper.waitingTimeShort import org.mozilla.fenix.helpers.TestHelper.appContext import org.mozilla.fenix.helpers.TestHelper.mDevice import org.mozilla.fenix.helpers.TestHelper.packageName -import org.mozilla.fenix.helpers.TestHelper.waitForObjects -import org.mozilla.fenix.helpers.click +import org.mozilla.fenix.helpers.TestHelper.waitForAppWindowToBeUpdated import org.mozilla.fenix.helpers.ext.waitNotNull import org.mozilla.fenix.helpers.matchers.hasItemsCount -import org.mozilla.fenix.tabstray.TabsTrayTestTag import mozilla.components.browser.menu.R as menuR import mozilla.components.browser.toolbar.R as toolbarR import mozilla.components.ui.tabcounter.R as tabcounterR @@ -79,7 +76,7 @@ import mozilla.components.ui.tabcounter.R as tabcounterR /** * Implementation of Robot Pattern for the URL toolbar. */ -class NavigationToolbarRobot { +class NavigationToolbarRobot(private val composeTestRule: ComposeTestRule) { fun verifyUrl(url: String) { Log.i(TAG, "verifyUrl: Trying to verify toolbar text matches $url") onView(withId(toolbarR.id.mozac_browser_toolbar_url_view)).check(matches(withText(url))) @@ -88,10 +85,9 @@ class NavigationToolbarRobot { fun verifyTabButtonShortcutMenuItems() { Log.i(TAG, "verifyTabButtonShortcutMenuItems: Trying to verify tab counter shortcut options") - onView(withId(menuR.id.mozac_browser_menu_recyclerView)) - .check(matches(hasDescendant(withText("Close tab")))) - .check(matches(hasDescendant(withText("New private tab")))) - .check(matches(hasDescendant(withText("New tab")))) + composeTestRule.onNodeWithText("Close tab", useUnmergedTree = true).assertIsDisplayed() + composeTestRule.onNodeWithText("New private tab", useUnmergedTree = true).assertIsDisplayed() + composeTestRule.onNodeWithText("New tab", useUnmergedTree = true).assertIsDisplayed() Log.i(TAG, "verifyTabButtonShortcutMenuItems: Verified tab counter shortcut options") } @@ -113,14 +109,42 @@ class NavigationToolbarRobot { Log.i(TAG, "verifyTabButtonShortcutMenuItemsForPrivateHomescreen: Verified tab counter shortcut options") } - fun verifyReaderViewDetected(exists: Boolean = false) { - assertUIObjectExists(readerViewToggle(), exists = exists) + fun verifyReaderViewToolbarButton(isDisplayed: Boolean = false) { + waitForAppWindowToBeUpdated() + if (isDisplayed) { + Log.i(TAG, "verifyReaderViewToolbarButton: Trying to verify that the reader view toolbar button is displayed") + composeTestRule.onNodeWithContentDescription( + getStringResource(R.string.browser_menu_read), + useUnmergedTree = true, + ).assertIsDisplayed() + Log.i(TAG, "verifyReaderViewToolbarButton: Verified that the reader view toolbar button is displayed") + } else { + Log.i(TAG, "verifyReaderViewToolbarButton: Trying to verify that the reader view toolbar button is not displayed") + composeTestRule.onNodeWithContentDescription( + getStringResource(R.string.browser_menu_read), + useUnmergedTree = true, + ).assertIsNotDisplayed() + Log.i(TAG, "verifyReaderViewToolbarButton: Verified that the reader view toolbar button is not displayed") + } } - fun toggleReaderView() { - Log.i(TAG, "toggleReaderView: Trying to click the reader view button") - readerViewToggle().click() - Log.i(TAG, "toggleReaderView: Clicked the reader view button") + fun clickReaderViewToolbarButton(isReaderViewEnabled: Boolean) { + if (isReaderViewEnabled) { + Log.i(TAG, "clickReaderViewToolbarButton: Trying to click the \"Close reader view\" toolbar button") + composeTestRule.onNodeWithContentDescription( + getStringResource(R.string.browser_menu_read_close), + useUnmergedTree = true, + ).performClick() + Log.i(TAG, "clickReaderViewToolbarButton: Clicked the \"Close reader view\" toolbar button") + } else { + Log.i(TAG, "clickReaderViewToolbarButton: Trying to click the \"Reader view\" toolbar button") + composeTestRule.onNodeWithContentDescription( + getStringResource(R.string.browser_menu_read), + useUnmergedTree = true, + ).performClick() + Log.i(TAG, "clickReaderViewToolbarButton: Clicked the \"Reader view\" toolbar button") + } + waitForAppWindowToBeUpdated() } fun verifyClipboardSuggestionsAreDisplayed(link: String = "", shouldBeDisplayed: Boolean) { @@ -172,30 +196,16 @@ class NavigationToolbarRobot { ), ) - // New unified search UI selector - fun verifySearchBarPlaceholder(text: String) { - Log.i(TAG, "verifySearchBarPlaceholder: Waiting for $waitingTime ms for the toolbar to exist") - homeUrlBar().waitForExists(waitingTime) - Log.i(TAG, "verifySearchBarPlaceholder: Waited for $waitingTime ms for the toolbar to exist") - assertItemTextEquals(homeUrlBar(), expectedText = text) - } - - fun verifySearchBarPlaceholderWithComposableToolbar(composeTestRule: ComposeTestRule) { - Log.i(TAG, "verifySearchBarPlaceholderWithComposableToolbar: Trying to verify that the search bar place holder is \"Search or enter address\"") + fun verifySearchBarPlaceholder() { + Log.i(TAG, "verifySearchBarPlaceholder: Trying to verify that the search bar place holder is \"Search or enter address\"") composeTestRule.onNodeWithTag(ADDRESSBAR_URL_BOX).assert(hasContentDescription("Search or enter address")) - Log.i(TAG, "verifySearchBarPlaceholderWithComposableToolbar: Verified that the search bar place holder is \"Search or enter address\"") + Log.i(TAG, "verifySearchBarPlaceholder: Verified that the search bar place holder is \"Search or enter address\"") } - // New unified search UI selector - fun verifyDefaultSearchEngine(engineName: String) = - assertUIObjectExists( - searchSelectorButton().getChild(UiSelector().descriptionStartsWith(engineName)), - ) - - fun verifyDefaultSearchEngineWithComposableToolbar(composeTestRule: ComposeTestRule, engineName: String) { - Log.i(TAG, "verifyDefaultSearchEngineWithComposableToolbar: Trying to verify that default search engine is: $engineName is displayed") + fun verifyDefaultSearchEngine(engineName: String) { + Log.i(TAG, "verifyDefaultSearchEngine: Trying to verify that default search engine is: $engineName is displayed") composeTestRule.onNodeWithContentDescription(getStringResource(R.string.search_engine_selector_content_description, engineName)).assertIsDisplayed() - Log.i(TAG, "verifyDefaultSearchEngineWithComposableToolbar: Verified that default search engine is: $engineName is displayed") + Log.i(TAG, "verifyDefaultSearchEngine: Verified that default search engine is: $engineName is displayed") } fun verifyTextSelectionOptions(vararg textSelectionOptions: String) { @@ -224,9 +234,9 @@ class NavigationToolbarRobot { break } catch (e: AssertionError) { Log.i(TAG, "verifyTranslationButton: AssertionError caught, executing fallback methods") - navigationToolbar { + browserScreen(composeTestRule) { }.openThreeDotMenu { - }.refreshPage { } + }.clickRefreshButton { } } } } else { @@ -306,54 +316,26 @@ class NavigationToolbarRobot { Log.i(TAG, "verifyNavBarBarPosition: Verified the toolbar navbar position is at the bottom: $isAtBottom.") } - class Transition { + class Transition(private val composeTestRule: ComposeTestRule) { private lateinit var sessionLoadedIdlingResource: SessionLoadedIdlingResource fun enterURLAndEnterToBrowser( url: Uri, interact: BrowserRobot.() -> Unit, ): BrowserRobot.Transition { - sessionLoadedIdlingResource = SessionLoadedIdlingResource() - - openEditURLView() - Log.i(TAG, "enterURLAndEnterToBrowser: Trying to set toolbar text to: $url") - awesomeBar().setText(url.toString()) - Log.i(TAG, "enterURLAndEnterToBrowser: Toolbar text was set to: $url") - Log.i(TAG, "enterURLAndEnterToBrowser: Trying to press device enter button") - pressImeActionOnAwesomeBar() - Log.i(TAG, "enterURLAndEnterToBrowser: Pressed device enter button") - - registerAndCleanupIdlingResources(sessionLoadedIdlingResource) { - Log.i(TAG, "enterURLAndEnterToBrowser: Trying to assert that home screen layout or download button or the total cookie protection contextual hint exist") - assertTrue( - itemWithResId("$packageName:id/browserLayout").waitForExists(waitingTime) || - itemWithResId("$packageName:id/download_button").waitForExists(waitingTime) || - itemWithResId("cfr.dismiss").waitForExists(waitingTime), - ) - Log.i(TAG, "enterURLAndEnterToBrowser: Asserted that home screen layout or download button or the total cookie protection contextual hint exist") - } - - BrowserRobot().interact() - return BrowserRobot.Transition() - } - - fun enterURLAndEnterToBrowserWithComposableToolbar( - composeTestRule: ComposeTestRule, - url: Uri, - interact: BrowserRobot.() -> Unit, - ): BrowserRobot.Transition { - Log.i(TAG, "enterURLAndEnterToBrowserWithComposableToolbar: Trying to click navigation toolbar") + Log.i(TAG, "enterURLAndEnterToBrowser: Trying to click navigation toolbar") composeTestRule.onAllNodesWithTag(ADDRESSBAR_URL_BOX).onLast().performClick() - Log.i(TAG, "enterURLAndEnterToBrowserWithComposableToolbar: Clicked navigation toolbar") - Log.i(TAG, "enterURLAndEnterToBrowserWithComposableToolbar: Trying to set toolbar text to: $url and perform IME action") + Log.i(TAG, "enterURLAndEnterToBrowser: Clicked navigation toolbar") + Log.i(TAG, "enterURLAndEnterToBrowser: Trying to set toolbar text to: $url and perform IME action") composeTestRule.onNodeWithTag(ADDRESSBAR_SEARCH_BOX).apply { performTextReplacement(url.toString()) performImeAction() } - Log.i(TAG, "enterURLAndEnterToBrowserWithComposableToolbar: Toolbar text was set to: $url and IME action performed") + Log.i(TAG, "enterURLAndEnterToBrowser: Toolbar text was set to: $url and IME action performed") + waitForAppWindowToBeUpdated() - BrowserRobot().interact() - return BrowserRobot.Transition() + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } fun enterURL( @@ -370,113 +352,22 @@ class NavigationToolbarRobot { pressImeActionOnAwesomeBar() Log.i(TAG, "enterURLAndEnterToBrowser: Pressed device enter button") - BrowserRobot().interact() - return BrowserRobot.Transition() - } - - fun openTabCrashReporter(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { - val crashUrl = "about:crashcontent" - - sessionLoadedIdlingResource = SessionLoadedIdlingResource() - - openEditURLView() - Log.i(TAG, "openTabCrashReporter: Trying to set toolbar text to: $crashUrl") - awesomeBar().setText(crashUrl) - Log.i(TAG, "openTabCrashReporter: Toolbar text was set to: $crashUrl") - Log.i(TAG, "openTabCrashReporter: Trying to press device enter button") - pressImeActionOnAwesomeBar() - Log.i(TAG, "openTabCrashReporter: Pressed device enter button") - - registerAndCleanupIdlingResources(sessionLoadedIdlingResource) { - Log.i(TAG, "openTabCrashReporter: Trying to find the tab crasher image") - mDevice.findObject(UiSelector().resourceId("$packageName:id/crash_tab_image")) - Log.i(TAG, "openTabCrashReporter: Found the tab crasher image") - } - - BrowserRobot().interact() - return BrowserRobot.Transition() - } - - fun openThreeDotMenu(interact: ThreeDotMenuMainRobot.() -> Unit): ThreeDotMenuMainRobot.Transition { - mDevice.waitNotNull(Until.findObject(By.res("$packageName:id/mozac_browser_toolbar_menu")), waitingTime) - Log.i(TAG, "openThreeDotMenu: Trying to click the main menu button") - threeDotButton().click() - Log.i(TAG, "openThreeDotMenu: Clicked the main menu button") - - ThreeDotMenuMainRobot().interact() - return ThreeDotMenuMainRobot.Transition() - } - - fun openTabDrawer(composeTestRule: HomeActivityComposeTestRule, interact: TabDrawerRobot.() -> Unit): TabDrawerRobot.Transition { - for (i in 1..Constants.RETRY_COUNT) { - try { - Log.i(TAG, "openTabDrawer: Started try #$i") - mDevice.waitForObjects( - mDevice.findObject( - UiSelector() - .resourceId("$packageName:id/mozac_browser_toolbar_browser_actions"), - ), - waitingTime, - ) - Log.i(TAG, "openTabDrawer: Trying to click the tabs tray button") - tabTrayButton().click() - Log.i(TAG, "openTabDrawer: Clicked the tabs tray button") - Log.i(TAG, "openTabDrawer: Trying to verify that the tabs tray exists") - composeTestRule.onNodeWithTag(TabsTrayTestTag.TABS_TRAY).assertExists() - Log.i(TAG, "openTabDrawer: Verified that the tabs tray exists") - - break - } catch (e: AssertionError) { - Log.i(TAG, "openTabDrawer: AssertionError caught, executing fallback methods") - if (i == Constants.RETRY_COUNT) { - throw e - } else { - Log.i(TAG, "openTabDrawer: Waiting for device to be idle") - mDevice.waitForIdle() - Log.i(TAG, "openTabDrawer: Waited for device to be idle") - } - } - } - Log.i(TAG, "openTabDrawer: Trying to verify the tabs tray new tab FAB button exists") - composeTestRule.onNodeWithTag(TabsTrayTestTag.FAB).assertExists() - Log.i(TAG, "openTabDrawer: Verified the tabs tray new tab FAB button exists") - - TabDrawerRobot(composeTestRule).interact() - return TabDrawerRobot.Transition(composeTestRule) + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } fun visitLinkFromClipboard(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { - Log.i(TAG, "visitLinkFromClipboard: Waiting for $waitingTimeShort ms for clear address button to exist") - if (clearAddressBarButton().waitForExists(waitingTimeShort)) { - Log.i(TAG, "visitLinkFromClipboard: Waited for $waitingTimeShort ms for clear address button to exist") - Log.i(TAG, "visitLinkFromClipboard: Trying to click the clear address button") - clearAddressBarButton().click() - Log.i(TAG, "visitLinkFromClipboard: Clicked the clear address button") - } - - mDevice.waitNotNull( - Until.findObject(By.res("$packageName:id/clipboard_title")), - waitingTime, - ) - - // On Android 12 or above we don't SHOW the URL unless the user requests to do so. - // See for more information https://github.com/mozilla-mobile/fenix/issues/22271 - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) { - mDevice.waitNotNull( - Until.findObject(By.res("$packageName:id/clipboard_url")), - waitingTime, - ) - } + composeTestRule.onNodeWithText(getStringResource(R.string.awesomebar_clipboard_title)).assertIsDisplayed() Log.i(TAG, "visitLinkFromClipboard: Trying to click the fill link from clipboard button") - fillLinkButton().click() + composeTestRule.onNodeWithText(getStringResource(R.string.awesomebar_clipboard_title)).performClick() Log.i(TAG, "visitLinkFromClipboard: Clicked the fill link from clipboard button") - + waitForAppWindowToBeUpdated() Log.i(TAG, "visitLinkFromClipboard: Trying to press device enter button") - mDevice.pressEnter() + onView(isRoot()).perform(ViewActions.pressKey(KeyEvent.KEYCODE_ENTER)) Log.i(TAG, "visitLinkFromClipboard: Pressed device enter button") - BrowserRobot().interact() - return BrowserRobot.Transition() + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } fun goBackToHomeScreen(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition { @@ -487,8 +378,8 @@ class NavigationToolbarRobot { mDevice.waitForWindowUpdate(packageName, waitingTimeShort) Log.i(TAG, "goBackToHomeScreen: Waited for $waitingTimeShort ms for $packageName window to be updated") - HomeScreenRobot().interact() - return HomeScreenRobot.Transition() + HomeScreenRobot(composeTestRule).interact() + return HomeScreenRobot.Transition(composeTestRule) } fun goBackToBrowserScreen(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { @@ -499,122 +390,74 @@ class NavigationToolbarRobot { mDevice.waitForWindowUpdate(packageName, waitingTimeShort) Log.i(TAG, "goBackToBrowserScreen: Waited for $waitingTimeShort ms for $packageName window to be updated") - BrowserRobot().interact() - return BrowserRobot.Transition() + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } fun openTabButtonShortcutsMenu(interact: NavigationToolbarRobot.() -> Unit): Transition { - mDevice.waitNotNull(Until.findObject(By.res("$packageName:id/counter_root"))) Log.i(TAG, "openTabButtonShortcutsMenu: Trying to long click the tab counter button") - tabsCounter().perform(longClick()) + composeTestRule.onNodeWithTag(TABS_COUNTER).performTouchInput { + down(center) + advanceEventTime(10000) + up() + } Log.i(TAG, "openTabButtonShortcutsMenu: Long clicked the tab counter button") - NavigationToolbarRobot().interact() - return Transition() + NavigationToolbarRobot(composeTestRule).interact() + return Transition(composeTestRule) } fun closeTabFromShortcutsMenu(interact: NavigationToolbarRobot.() -> Unit): Transition { - Log.i(TAG, "closeTabFromShortcutsMenu: Waiting for device to be idle for $waitingTime ms") - mDevice.waitForIdle(waitingTime) - Log.i(TAG, "closeTabFromShortcutsMenu: Waited for device to be idle for $waitingTime ms") Log.i(TAG, "closeTabFromShortcutsMenu: Trying to click the \"Close tab\" button") - onView(withId(menuR.id.mozac_browser_menu_recyclerView)) - .perform( - RecyclerViewActions.actionOnItem<RecyclerView.ViewHolder>( - hasDescendant( - withText("Close tab"), - ), - ViewActions.click(), - ), - ) + composeTestRule.onNodeWithText("Close tab", useUnmergedTree = true).performClick() Log.i(TAG, "closeTabFromShortcutsMenu: Clicked the \"Close tab\" button") - NavigationToolbarRobot().interact() - return Transition() + NavigationToolbarRobot(composeTestRule).interact() + return Transition(composeTestRule) } fun openNewTabFromShortcutsMenu(interact: SearchRobot.() -> Unit): SearchRobot.Transition { - Log.i(TAG, "openNewTabFromShortcutsMenu: Waiting for device to be idle for $waitingTime ms") - mDevice.waitForIdle(waitingTime) - Log.i(TAG, "openNewTabFromShortcutsMenu: Waited for device to be idle for $waitingTime ms") Log.i(TAG, "openNewTabFromShortcutsMenu: Trying to click the \"New tab\" button") - onView(withId(menuR.id.mozac_browser_menu_recyclerView)) - .perform( - RecyclerViewActions.actionOnItem<RecyclerView.ViewHolder>( - hasDescendant( - withText("New tab"), - ), - ViewActions.click(), - ), - ) + composeTestRule.onNodeWithText("New tab", useUnmergedTree = true).performClick() Log.i(TAG, "openNewTabFromShortcutsMenu: Clicked the \"New tab\" button") - SearchRobot().interact() - return SearchRobot.Transition() + SearchRobot(composeTestRule).interact() + return SearchRobot.Transition(composeTestRule) } fun openNewPrivateTabFromShortcutsMenu(interact: SearchRobot.() -> Unit): SearchRobot.Transition { - Log.i(TAG, "openNewPrivateTabFromShortcutsMenu: Waiting for device to be idle for $waitingTime ms") - mDevice.waitForIdle(waitingTime) - Log.i(TAG, "openNewPrivateTabFromShortcutsMenu: Waited for device to be idle for $waitingTime ms") Log.i(TAG, "openNewPrivateTabFromShortcutsMenu: Trying to click the \"New private tab\" button") - onView(withId(menuR.id.mozac_browser_menu_recyclerView)) - .perform( - RecyclerViewActions.actionOnItem<RecyclerView.ViewHolder>( - hasDescendant( - withText("New private tab"), - ), - ViewActions.click(), - ), - ) + composeTestRule.onNodeWithText("New private tab", useUnmergedTree = true).performClick() Log.i(TAG, "openNewPrivateTabFromShortcutsMenu: Clicked the \"New private tab\" button") - SearchRobot().interact() - return SearchRobot.Transition() - } - - fun clickUrlbar(interact: SearchRobot.() -> Unit): SearchRobot.Transition { - Log.i(TAG, "clickUrlbar: Trying to click the toolbar") - urlBar().click() - Log.i(TAG, "clickUrlbar: Clicked the toolbar") - Log.i(TAG, "clickUrlbar: Waiting for $waitingTime ms for the edit mode toolbar to exist") - mDevice.findObject( - UiSelector().resourceId("$packageName:id/mozac_browser_toolbar_edit_url_view"), - ).waitForExists(waitingTime) - Log.i(TAG, "clickUrlbar: Waited for $waitingTime ms for the edit mode toolbar to exist") - - SearchRobot().interact() - return SearchRobot.Transition() + SearchRobot(composeTestRule).interact() + return SearchRobot.Transition(composeTestRule) } @OptIn(ExperimentalTestApi::class) - fun clickURLBarWithComposableToolbar(composeTestRule: ComposeTestRule, interact: SearchRobot.() -> Unit): SearchRobot.Transition { - Log.i(TAG, "clickURLBarWithComposableToolbar: Waiting for $waitingTime until the URL bar to exist") + fun clickURLBar(interact: SearchRobot.() -> Unit): SearchRobot.Transition { + Log.i(TAG, "clickURLBar: Waiting for $waitingTime until the URL bar to exist") composeTestRule.waitUntilAtLeastOneExists(hasTestTag(ADDRESSBAR_URL_BOX), waitingTime) - Log.i(TAG, "clickURLBarWithComposableToolbar: Waited for $waitingTime until the URL bar to exist") - Log.i(TAG, "clickURLBarWithComposableToolbar: Trying to click navigation toolbar") + Log.i(TAG, "clickURLBar: Waited for $waitingTime until the URL bar to exist") + Log.i(TAG, "clickURLBar: Trying to click navigation toolbar") composeTestRule.onNodeWithTag(ADDRESSBAR_URL_BOX).performClick() - Log.i(TAG, "clickURLBarWithComposableToolbar: Clicked navigation toolbar") + Log.i(TAG, "clickURLBar: Clicked navigation toolbar") composeTestRule.waitForIdle() - SearchRobot().interact() - return SearchRobot.Transition() + SearchRobot(composeTestRule).interact() + return SearchRobot.Transition(composeTestRule) } fun clickSearchSelectorButton(interact: SearchRobot.() -> Unit): SearchRobot.Transition { - Log.i(TAG, "clickSearchSelectorButton: Waiting for $waitingTime ms for the search selector button to exist") - searchSelectorButton().waitForExists(waitingTime) - Log.i(TAG, "clickSearchSelectorButton: Waited for $waitingTime ms for the search selector button to exist") Log.i(TAG, "clickSearchSelectorButton: Trying to click the search selector button") - searchSelectorButton().click() + composeTestRule.onNodeWithTag(SEARCH_SELECTOR).performClick() Log.i(TAG, "clickSearchSelectorButton: Clicked the search selector button") - SearchRobot().interact() - return SearchRobot.Transition() + SearchRobot(composeTestRule).interact() + return SearchRobot.Transition(composeTestRule) } fun clickTranslateButton( - composeTestRule: ComposeTestRule, isPageTranslated: Boolean = false, originalLanguage: String = "", translatedLanguage: String = "", @@ -636,7 +479,7 @@ class NavigationToolbarRobot { // New navbar design home screen search button @OptIn(ExperimentalTestApi::class) - fun clickHomeScreenSearchButton(composeTestRule: ComposeTestRule, interact: SearchRobot.() -> Unit): SearchRobot.Transition { + fun clickHomeScreenSearchButton(interact: SearchRobot.() -> Unit): SearchRobot.Transition { Log.i(TAG, "clickHomeScreenSearchButton: Waiting for $waitingTime ms for the search button to exist.") composeTestRule.waitUntilAtLeastOneExists(hasContentDescription("Search or enter address")) Log.i(TAG, "clickHomeScreenSearchButton: Waited for $waitingTime ms for the search button to exist.") @@ -644,20 +487,15 @@ class NavigationToolbarRobot { composeTestRule.onNodeWithContentDescription("Search or enter address").performClick() Log.i(TAG, "clickHomeScreenSearchButton: Clicked the nav bar search button.") - SearchRobot().interact() - return SearchRobot.Transition() + SearchRobot(composeTestRule).interact() + return SearchRobot.Transition(composeTestRule) } fun openUnifiedTrustPanel(interact: UnifiedTrustPanelRobot.() -> Unit): UnifiedTrustPanelRobot.Transition { - Log.i(TAG, "openUnifiedTrustPanel: Waiting for $waitingTime ms for site security button to exist") - itemWithResId("$packageName:id/mozac_browser_toolbar_site_info_indicator").waitForExists(waitingTime) - Log.i(TAG, "openUnifiedTrustPanel: Waited for $waitingTime ms for site security button to exist") - Log.i(TAG, "openUnifiedTrustPanel: Trying to click site security button") - itemWithResId("$packageName:id/mozac_browser_toolbar_site_info_indicator").click() - Log.i(TAG, "openUnifiedTrustPanel: Clicked site security button") - Log.i(TAG, "openUnifiedTrustPanel: Waiting for $waitingTime for the unified trust panel to exist") - itemWithResId("$packageName:id/design_bottom_sheet").waitForExists(waitingTime) - Log.i(TAG, "openUnifiedTrustPanel: Waited for $waitingTime for the unified trust panel to exist") + Log.i(TAG, "openSiteSecuritySheet: Trying to click the site security toolbar button and wait for $waitingTime ms for a new window") + composeTestRule.onNodeWithContentDescription("Site information").performClick() + Log.i(TAG, "openSiteSecuritySheet: Clicked the site security toolbar button and waited for $waitingTime ms for a new window") + waitForAppWindowToBeUpdated() UnifiedTrustPanelRobot().interact() return UnifiedTrustPanelRobot.Transition() @@ -665,9 +503,9 @@ class NavigationToolbarRobot { } } -fun navigationToolbar(interact: NavigationToolbarRobot.() -> Unit): NavigationToolbarRobot.Transition { - NavigationToolbarRobot().interact() - return NavigationToolbarRobot.Transition() +fun navigationToolbar(composeTestRule: ComposeTestRule, interact: NavigationToolbarRobot.() -> Unit): NavigationToolbarRobot.Transition { + NavigationToolbarRobot(composeTestRule).interact() + return NavigationToolbarRobot.Transition(composeTestRule) } fun openEditURLView() { diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/NotificationRobot.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/NotificationRobot.kt @@ -9,6 +9,7 @@ import android.content.Context import android.os.Build import android.os.Build.VERSION.SDK_INT import android.util.Log +import androidx.compose.ui.test.junit4.ComposeTestRule import androidx.test.uiautomator.UiObject import androidx.test.uiautomator.UiScrollable import androidx.test.uiautomator.UiSelector @@ -171,6 +172,7 @@ class NotificationRobot { // Performs swipe action on download system notifications fun swipeDownloadNotification( + composeTestRule: ComposeTestRule, direction: String, shouldDismissNotification: Boolean, canExpandNotification: Boolean = true, @@ -240,7 +242,7 @@ class NotificationRobot { throw e } else { notificationShade { - }.closeNotificationTray { + }.closeNotificationTray(composeTestRule) { }.openNotificationShade { // The download complete system notification can't be expanded if (canExpandNotification) { @@ -269,9 +271,9 @@ class NotificationRobot { Log.i(TAG, "clickNotification: Clicked the $notificationMessage notification and waited for $waitingTimeShort ms for a new window") } - class Transition { + class Transition() { - fun clickClosePrivateTabsNotification(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition { + fun clickClosePrivateTabsNotification(composeTestRule: ComposeTestRule, interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition { try { assertUIObjectExists(closePrivateTabsNotification()) } catch (e: AssertionError) { @@ -283,17 +285,17 @@ class NotificationRobot { closePrivateTabsNotification().click() Log.i(TAG, "clickClosePrivateTabsNotification: Clicked the close private tabs notification") - HomeScreenRobot().interact() - return HomeScreenRobot.Transition() + HomeScreenRobot(composeTestRule).interact() + return HomeScreenRobot.Transition(composeTestRule) } - fun closeNotificationTray(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { + fun closeNotificationTray(composeTestRule: ComposeTestRule, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { Log.i(TAG, "closeNotificationTray: Trying to click device back button") mDevice.pressBack() Log.i(TAG, "closeNotificationTray: Clicked device back button") - BrowserRobot().interact() - return BrowserRobot.Transition() + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } } } diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ReaderViewRobot.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ReaderViewRobot.kt @@ -8,6 +8,7 @@ package org.mozilla.fenix.ui.robots import android.content.Context import android.util.Log +import androidx.compose.ui.test.junit4.ComposeTestRule import androidx.test.espresso.Espresso.onView import androidx.test.espresso.assertion.ViewAssertions.matches import androidx.test.espresso.matcher.ViewMatchers @@ -15,9 +16,9 @@ import androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility import androidx.test.espresso.matcher.ViewMatchers.withId import androidx.test.platform.app.InstrumentationRegistry import org.junit.Assert.assertEquals -import org.mozilla.fenix.R import org.mozilla.fenix.helpers.Constants.TAG import org.mozilla.fenix.helpers.TestHelper.mDevice +import org.mozilla.fenix.helpers.TestHelper.waitForAppWindowToBeUpdated import org.mozilla.fenix.helpers.click import mozilla.components.feature.readerview.R as readerviewR @@ -162,13 +163,14 @@ class ReaderViewRobot { class Transition { - fun closeAppearanceMenu(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { - Log.i(TAG, "closeAppearanceMenu: Trying to click device back button") + fun closeReaderViewControlMenu(composeTestRule: ComposeTestRule, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { + Log.i(TAG, "closeReaderViewControlMenu: Trying to click device back button") mDevice.pressBack() - Log.i(TAG, "closeAppearanceMenu: Clicked device back button") + Log.i(TAG, "closeReaderViewControlMenu: Clicked device back button") + waitForAppWindowToBeUpdated() - BrowserRobot().interact() - return BrowserRobot.Transition() + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } fun toggleSansSerif(interact: ReaderViewRobot.() -> Unit): Transition { diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/RecentlyClosedTabsRobot.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/RecentlyClosedTabsRobot.kt @@ -6,6 +6,7 @@ package org.mozilla.fenix.ui.robots import android.net.Uri import android.util.Log +import androidx.compose.ui.test.junit4.ComposeTestRule import androidx.test.espresso.Espresso.onView import androidx.test.espresso.assertion.ViewAssertions.matches import androidx.test.espresso.matcher.ViewMatchers.Visibility @@ -91,7 +92,7 @@ class RecentlyClosedTabsRobot { } class Transition { - fun clickRecentlyClosedItem(title: String, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { + fun clickRecentlyClosedItem(composeTestRule: ComposeTestRule, title: String, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { recentlyClosedTabsPageTitle(title).also { Log.i(TAG, "clickRecentlyClosedItem: Waiting for $waitingTimeShort ms for recently closed tab with title: $title to exist") it.waitForExists(waitingTimeShort) @@ -104,8 +105,8 @@ class RecentlyClosedTabsRobot { mDevice.waitForIdle() Log.i(TAG, "clickRecentlyClosedItem: Waited for device to be idle") - BrowserRobot().interact() - return BrowserRobot.Transition() + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } fun clickOpenInNewTab(testRule: HomeActivityComposeTestRule, interact: TabDrawerRobot.() -> Unit): TabDrawerRobot.Transition { @@ -135,13 +136,13 @@ class RecentlyClosedTabsRobot { return ShareOverlayRobot.Transition() } - fun goBackToHistoryMenu(interact: HistoryRobot.() -> Unit): HistoryRobot.Transition { + fun goBackToHistoryMenu(composeTestRule: ComposeTestRule, interact: HistoryRobot.() -> Unit): HistoryRobot.Transition { Log.i(TAG, "goBackToHistoryMenu: Trying to click navigate up toolbar button") onView(withContentDescription("Navigate up")).click() Log.i(TAG, "goBackToHistoryMenu: Clicked navigate up toolbar button") HistoryRobot().interact() - return HistoryRobot.Transition() + return HistoryRobot.Transition(composeTestRule) } } } diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SearchRobot.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SearchRobot.kt @@ -18,6 +18,7 @@ import androidx.compose.ui.test.hasContentDescription import androidx.compose.ui.test.hasTestTag import androidx.compose.ui.test.hasText import androidx.compose.ui.test.junit4.ComposeTestRule +import androidx.compose.ui.test.longClick import androidx.compose.ui.test.onAllNodesWithTag import androidx.compose.ui.test.onNodeWithContentDescription import androidx.compose.ui.test.onNodeWithTag @@ -25,6 +26,7 @@ import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.performClick import androidx.compose.ui.test.performImeAction import androidx.compose.ui.test.performTextReplacement +import androidx.compose.ui.test.performTouchInput import androidx.test.espresso.Espresso.closeSoftKeyboard import androidx.test.espresso.Espresso.onView import androidx.test.espresso.action.ViewActions.pressImeActionButton @@ -41,21 +43,13 @@ import org.junit.Assert.assertTrue import org.mozilla.fenix.R import org.mozilla.fenix.helpers.AppAndSystemHelper.grantSystemPermission import org.mozilla.fenix.helpers.AppAndSystemHelper.isPackageInstalled -import org.mozilla.fenix.helpers.AppAndSystemHelper.registerAndCleanupIdlingResources -import org.mozilla.fenix.helpers.Constants.LONG_CLICK_DURATION import org.mozilla.fenix.helpers.Constants.PackageName.GOOGLE_QUICK_SEARCH import org.mozilla.fenix.helpers.Constants.RETRY_COUNT import org.mozilla.fenix.helpers.Constants.SPEECH_RECOGNITION import org.mozilla.fenix.helpers.Constants.TAG import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource -import org.mozilla.fenix.helpers.MatcherHelper.assertItemTextContains -import org.mozilla.fenix.helpers.MatcherHelper.assertItemTextEquals -import org.mozilla.fenix.helpers.MatcherHelper.assertUIObjectExists -import org.mozilla.fenix.helpers.MatcherHelper.assertUIObjectIsGone import org.mozilla.fenix.helpers.MatcherHelper.itemWithDescription import org.mozilla.fenix.helpers.MatcherHelper.itemWithResId -import org.mozilla.fenix.helpers.MatcherHelper.itemWithResIdAndText -import org.mozilla.fenix.helpers.MatcherHelper.itemWithText import org.mozilla.fenix.helpers.SessionLoadedIdlingResource import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime import org.mozilla.fenix.helpers.TestAssetHelper.waitingTimeShort @@ -70,60 +64,58 @@ import mozilla.components.feature.qr.R as qrR /** * Implementation of Robot Pattern for the search fragment. */ -class SearchRobot { - fun verifySearchView() = assertUIObjectExists(itemWithResId("$packageName:id/search_wrapper")) +class SearchRobot(private val composeTestRule: ComposeTestRule) { - fun verifySearchToolbar(isDisplayed: Boolean) = - assertUIObjectExists( - itemWithResId("$packageName:id/mozac_browser_toolbar_edit_url_view"), - exists = isDisplayed, - ) - - fun verifyScanButtonVisibility(visible: Boolean = true) = - assertUIObjectExists(scanButton(), exists = visible) + fun verifySearchToolbar(isDisplayed: Boolean) { + if (isDisplayed) { + Log.i(TAG, "verifyScanButton: Trying to verify that the edit mode toolbar is displayed") + composeTestRule.onNodeWithTag(ADDRESSBAR_SEARCH_BOX).assertIsDisplayed() + Log.i(TAG, "verifyScanButton: Verified that the edit mode toolbar is displayed") + } else { + Log.i(TAG, "verifyScanButton: Trying to verify that the edit mode toolbar is not displayed") + composeTestRule.onNodeWithTag(ADDRESSBAR_SEARCH_BOX).assertIsNotDisplayed() + Log.i(TAG, "verifyScanButton: Verified that the edit mode toolbar is not displayed") + } + } @OptIn(ExperimentalTestApi::class) - fun verifyScanButtonWithComposableToolbar(composeTestRule: ComposeTestRule, isDisplayed: Boolean) { + fun verifyScanButton(isDisplayed: Boolean) { if (isDisplayed) { - Log.i(TAG, "verifyScanButtonWithComposableToolbar: Waiting for $waitingTime until the scan QR button is exists") - composeTestRule.waitUntilExactlyOneExists(hasContentDescription(getStringResource(qrR.string.mozac_feature_qr_scanner)), waitingTime) - Log.i(TAG, "verifyScanButtonWithComposableToolbar: Waited for $waitingTime until the scan QR button is exists") - Log.i(TAG, "verifyScanButtonWithComposableToolbar: Trying to verify that the scan QR button is displayed") - composeTestRule.onNodeWithContentDescription(getStringResource(qrR.string.mozac_feature_qr_scanner)) + Log.i(TAG, "verifyScanButton: Waiting for $waitingTime until the scan QR button is exists") + this@SearchRobot.composeTestRule.waitUntilExactlyOneExists(hasContentDescription(getStringResource(qrR.string.mozac_feature_qr_scanner)), waitingTime) + Log.i(TAG, "verifyScanButton: Waited for $waitingTime until the scan QR button is exists") + Log.i(TAG, "verifyScanButton: Trying to verify that the scan QR button is displayed") + this@SearchRobot.composeTestRule.onNodeWithContentDescription(getStringResource(qrR.string.mozac_feature_qr_scanner)) .assertIsDisplayed() - Log.i(TAG, "verifyScanButtonWithComposableToolbar: Verified that the scan QR button is displayed") + Log.i(TAG, "verifyScanButton: Verified that the scan QR button is displayed") } else { - Log.i(TAG, "verifyScanButtonWithComposableToolbar: Waiting for $waitingTime until the scan QR button does not is exist") - composeTestRule.waitUntilDoesNotExist(hasContentDescription(getStringResource(qrR.string.mozac_feature_qr_scanner)), waitingTime) - Log.i(TAG, "verifyScanButtonWithComposableToolbar: Waited for $waitingTime until the scan QR button does not is exist") - Log.i(TAG, "verifyScanButtonWithComposableToolbar: Trying to verify that the scan QR button is not displayed") - composeTestRule.onNodeWithContentDescription(getStringResource(qrR.string.mozac_feature_qr_scanner)) + Log.i(TAG, "verifyScanButton: Waiting for $waitingTime until the scan QR button does not is exist") + this@SearchRobot.composeTestRule.waitUntilDoesNotExist(hasContentDescription(getStringResource(qrR.string.mozac_feature_qr_scanner)), waitingTime) + Log.i(TAG, "verifyScanButton: Waited for $waitingTime until the scan QR button does not is exist") + Log.i(TAG, "verifyScanButton: Trying to verify that the scan QR button is not displayed") + this@SearchRobot.composeTestRule.onNodeWithContentDescription(getStringResource(qrR.string.mozac_feature_qr_scanner)) .assertIsNotDisplayed() - Log.i(TAG, "verifyScanButtonWithComposableToolbar: Verified that the scan QR button is not displayed") + Log.i(TAG, "verifyScanButton: Verified that the scan QR button is not displayed") } } - fun verifyVoiceSearchButtonVisibility(enabled: Boolean) = - assertUIObjectExists(voiceSearchButton(), exists = enabled) - - fun verifyVoiceSearchButtonWithComposableToolbar(composeTestRule: ComposeTestRule, isDisplayed: Boolean) { + fun verifyVoiceSearchButton(isDisplayed: Boolean) { if (isDisplayed) { - Log.i(TAG, "verifyVoiceSearchButtonWithComposableToolbar: Trying to verify that the voice search button is displayed") - composeTestRule.onNodeWithContentDescription(getStringResource(R.string.voice_search_content_description)) + Log.i(TAG, "verifyVoiceSearchButton: Trying to verify that the voice search button is displayed") + this@SearchRobot.composeTestRule.onNodeWithContentDescription(getStringResource(R.string.voice_search_content_description)) .assertIsDisplayed() - Log.i(TAG, "verifyVoiceSearchButtonWithComposableToolbar: Verified that the voice search button is displayed") + Log.i(TAG, "verifyVoiceSearchButton: Verified that the voice search button is displayed") } else { - Log.i(TAG, "verifyVoiceSearchButtonWithComposableToolbar: Trying to verify that the voice search button is not displayed") - composeTestRule.onNodeWithContentDescription(getStringResource(R.string.voice_search_content_description)) + Log.i(TAG, "verifyVoiceSearchButton: Trying to verify that the voice search button is not displayed") + this@SearchRobot.composeTestRule.onNodeWithContentDescription(getStringResource(R.string.voice_search_content_description)) .assertIsNotDisplayed() - Log.i(TAG, "verifyVoiceSearchButtonWithComposableToolbar: Verified that the voice search button is not displayed") + Log.i(TAG, "verifyVoiceSearchButton: Verified that the voice search button is not displayed") } } - // Device or AVD requires a Google Services Android OS installation fun startVoiceSearch() { Log.i(TAG, "startVoiceSearch: Trying to click the voice search button button") - voiceSearchButton().click() + this@SearchRobot.composeTestRule.onNodeWithContentDescription(getStringResource(R.string.voice_search_content_description)).performClick() Log.i(TAG, "startVoiceSearch: Clicked the voice search button button") grantSystemPermission() @@ -135,20 +127,6 @@ class SearchRobot { } } - fun startVoiceSearchWithComposableToolbar(composeTestRule: ComposeTestRule) { - Log.i(TAG, "startVoiceSearchWithComposableToolbar: Trying to click the voice search button button") - composeTestRule.onNodeWithContentDescription(getStringResource(R.string.voice_search_content_description)).performClick() - Log.i(TAG, "startVoiceSearchWithComposableToolbar: Clicked the voice search button button") - grantSystemPermission() - - if (isPackageInstalled(GOOGLE_QUICK_SEARCH)) { - Log.i(TAG, "startVoiceSearchWithComposableToolbar: $GOOGLE_QUICK_SEARCH is installed") - Log.i(TAG, "startVoiceSearchWithComposableToolbar: Trying to verify the intent to: $GOOGLE_QUICK_SEARCH") - Intents.intended(IntentMatchers.hasAction(SPEECH_RECOGNITION)) - Log.i(TAG, "startVoiceSearchWithComposableToolbar: Verified the intent to: $GOOGLE_QUICK_SEARCH") - } - } - fun closeVoiceSearchDialog() { Log.i(TAG, "closeVoiceSearchDialog: Trying to click device back button") mDevice.pressBack() @@ -156,10 +134,10 @@ class SearchRobot { } @OptIn(ExperimentalTestApi::class) - fun verifyTheSuggestionsHeader(rule: ComposeTestRule, headerText: String) { + fun verifyTheSuggestionsHeader(headerText: String) { Log.i(TAG, "verifyTheFirefoxSuggestHeader: Trying to verify the Firefox Suggest header is displayed.") - rule.waitUntilExactlyOneExists(hasText(headerText), waitingTime) - rule.onNodeWithText(headerText).assertIsDisplayed() + this@SearchRobot.composeTestRule.waitUntilExactlyOneExists(hasText(headerText), waitingTime) + this@SearchRobot.composeTestRule.onNodeWithText(headerText).assertIsDisplayed() Log.i(TAG, "verifyTheFirefoxSuggestHeader: Verified the Firefox Suggest header is displayed.") } @@ -169,7 +147,6 @@ class SearchRobot { */ @OptIn(ExperimentalTestApi::class) fun verifySponsoredSuggestionsResults( - rule: ComposeTestRule, vararg searchSuggestions: String, searchTerm: String, shouldEditKeyword: Boolean = false, @@ -177,7 +154,7 @@ class SearchRobot { shouldUseSearchShort: Boolean = false, searchEngineName: String = "", ) { - rule.waitForIdle() + this@SearchRobot.composeTestRule.waitForIdle() for (i in 1..RETRY_COUNT) { Log.i(TAG, "verifySponsoredSuggestionsResults: Started try #$i") try { @@ -186,7 +163,7 @@ class SearchRobot { closeSoftKeyboard() Log.i(TAG, "verifySponsoredSuggestionsResults: Performed \"Close soft keyboard\" action") Log.i(TAG, "verifySponsoredSuggestionsResults: Waiting for $waitingTime ms until $searchSuggestion search suggestion exists") - rule.waitUntilExactlyOneExists(hasText(searchSuggestion), waitingTime) + this@SearchRobot.composeTestRule.waitUntilExactlyOneExists(hasText(searchSuggestion), waitingTime) Log.i(TAG, "verifySponsoredSuggestionsResults: Waited for $waitingTime ms until $searchSuggestion search suggestion exists") } @@ -197,7 +174,7 @@ class SearchRobot { throw e } else { mDevice.pressBack() - homeScreen { + homeScreen(this@SearchRobot.composeTestRule) { }.openSearch { if (shouldUseSearchShort) { clickSearchSelectorButton() @@ -213,7 +190,7 @@ class SearchRobot { } for (searchSuggestion in searchSuggestions) { Log.i(TAG, "verifySponsoredSuggestionsResults: Trying to verify that $searchSuggestion search suggestion exists") - rule.onNodeWithText(searchSuggestion).assertIsDisplayed() + this@SearchRobot.composeTestRule.onNodeWithText(searchSuggestion).assertIsDisplayed() Log.i(TAG, "verifySponsoredSuggestionsResults: Verified that $searchSuggestion search suggestion exists") } } @@ -223,8 +200,8 @@ class SearchRobot { * For sponsored suggestions, use [verifySponsoredSuggestionsResults]. */ @OptIn(ExperimentalTestApi::class) - fun verifySearchSuggestionsAreDisplayed(rule: ComposeTestRule, vararg searchSuggestions: String) { - rule.waitForIdle() + fun verifySearchSuggestionsAreDisplayed(vararg searchSuggestions: String) { + this@SearchRobot.composeTestRule.waitForIdle() for (searchSuggestion in searchSuggestions) { Log.i( TAG, @@ -239,8 +216,8 @@ class SearchRobot { TAG, "verifySearchSuggestionsAreDisplayed: Waiting for $waitingTime ms until $searchSuggestion search suggestion exists.", ) - rule.waitUntilExactlyOneExists(hasText(searchSuggestion), waitingTime) - rule.onAllNodesWithTag("mozac.awesomebar.suggestion") + this@SearchRobot.composeTestRule.waitUntilExactlyOneExists(hasText(searchSuggestion), waitingTime) + this@SearchRobot.composeTestRule.onAllNodesWithTag("mozac.awesomebar.suggestion") .assertAny( hasText(searchSuggestion, substring = true), ) @@ -251,13 +228,13 @@ class SearchRobot { } } - fun verifySuggestionsAreNotDisplayed(rule: ComposeTestRule, vararg searchSuggestions: String) { + fun verifySuggestionsAreNotDisplayed(vararg searchSuggestions: String) { Log.i(TAG, "verifySuggestionsAreNotDisplayed: Waiting for compose test rule to be idle") - rule.waitForIdle() + this@SearchRobot.composeTestRule.waitForIdle() Log.i(TAG, "verifySuggestionsAreNotDisplayed: Waited for compose test rule to be idle") for (searchSuggestion in searchSuggestions) { Log.i(TAG, "verifySuggestionsAreNotDisplayed: Trying to verify that there are no $searchSuggestion related search suggestions") - rule.onAllNodesWithTag("mozac.awesomebar.suggestions") + this@SearchRobot.composeTestRule.onAllNodesWithTag("mozac.awesomebar.suggestions") .assertAny( hasText(searchSuggestion) .not(), @@ -266,22 +243,16 @@ class SearchRobot { } } - fun verifySuggestionsWithComposableToolbarAreNotDisplayed(composeTestRule: ComposeTestRule) { - Log.i(TAG, "verifySuggestionsWithComposableToolbarAreNotDisplayed: Trying to verify that no search suggestions are displayed") - composeTestRule.onNodeWithTag("mozac.awesomebar.suggestions").assertIsNotDisplayed() - Log.i(TAG, "verifySuggestionsWithComposableToolbarAreNotDisplayed: Verified that no search suggestions are displayed") - } - @OptIn(ExperimentalTestApi::class) - fun verifySearchSuggestionsCount(rule: ComposeTestRule, numberOfSuggestions: Int, searchTerm: String) { + fun verifySearchSuggestionsCount(numberOfSuggestions: Int, searchTerm: String) { for (i in 1..RETRY_COUNT) { Log.i(TAG, "verifySearchSuggestionsCount: Started try #$i") try { Log.i(TAG, "verifySearchSuggestionsCount: Compose test rule is waiting for $waitingTime ms until the note count equals to: $numberOfSuggestions") - rule.waitUntilNodeCount(hasTestTag("mozac.awesomebar.suggestion"), numberOfSuggestions, waitingTime) + this@SearchRobot.composeTestRule.waitUntilNodeCount(hasTestTag("mozac.awesomebar.suggestion"), numberOfSuggestions, waitingTime) Log.i(TAG, "verifySearchSuggestionsCount: Compose test rule waited for $waitingTime ms until the note count equals to: $numberOfSuggestions") Log.i(TAG, "verifySearchSuggestionsCount: Trying to verify that the count of the search suggestions equals: $numberOfSuggestions") - rule.onAllNodesWithTag("mozac.awesomebar.suggestion").assertCountEquals(numberOfSuggestions) + this@SearchRobot.composeTestRule.onAllNodesWithTag("mozac.awesomebar.suggestion").assertCountEquals(numberOfSuggestions) Log.i(TAG, "verifySearchSuggestionsCount: Verified that the count of the search suggestions equals: $numberOfSuggestions") break @@ -293,7 +264,7 @@ class SearchRobot { Log.i(TAG, "verifySearchSuggestionsCount: Trying to click device back button") mDevice.pressBack() Log.i(TAG, "verifySearchSuggestionsCount: Clicked device back button") - homeScreen { + homeScreen(this@SearchRobot.composeTestRule) { }.openSearch { typeSearch(searchTerm) } @@ -302,31 +273,22 @@ class SearchRobot { } } - fun verifyAllowSuggestionsInPrivateModeDialog() = - assertUIObjectExists( - itemWithText(getStringResource(R.string.search_suggestions_onboarding_title)), - itemWithText(getStringResource(R.string.search_suggestions_onboarding_text)), - itemWithText("Learn more"), - itemWithText(getStringResource(R.string.search_suggestions_onboarding_allow_button)), - itemWithText(getStringResource(R.string.search_suggestions_onboarding_do_not_allow_button)), - ) - - fun verifyAllowSuggestionsInPrivateModeDialogWithComposableToolbar(composeTestRule: ComposeTestRule) { - Log.i(TAG, "verifyAllowSuggestionsInPrivateModeDialogWithComposableToolbar: Trying to verify that the private browsing search suggestion title is displayed") - composeTestRule.onNodeWithText(getStringResource(R.string.search_suggestions_onboarding_title), useUnmergedTree = true).assertIsDisplayed() - Log.i(TAG, "verifyAllowSuggestionsInPrivateModeDialogWithComposableToolbar: Verified that the private browsing search suggestion title is displayed") - Log.i(TAG, "verifyAllowSuggestionsInPrivateModeDialogWithComposableToolbar: Trying to verify that the private browsing search suggestion message is displayed") - composeTestRule.onNodeWithText(getStringResource(R.string.search_suggestions_onboarding_text), useUnmergedTree = true).assertIsDisplayed() - Log.i(TAG, "verifyAllowSuggestionsInPrivateModeDialogWithComposableToolbar: Verified that the private browsing search suggestion message is displayed") - Log.i(TAG, "verifyAllowSuggestionsInPrivateModeDialogWithComposableToolbar: Trying to verify that the \"Learn more\" link is displayed") - composeTestRule.onNodeWithContentDescription("Learn more Links available", useUnmergedTree = true).assertIsDisplayed() - Log.i(TAG, "verifyAllowSuggestionsInPrivateModeDialogWithComposableToolbar: Verified that the \"Learn more\" link is displayed") - Log.i(TAG, "verifyAllowSuggestionsInPrivateModeDialogWithComposableToolbar: Trying to verify that the \"Allow\" button is displayed") - composeTestRule.onNodeWithText(getStringResource(R.string.search_suggestions_onboarding_allow_button), useUnmergedTree = true).assertIsDisplayed() - Log.i(TAG, "verifyAllowSuggestionsInPrivateModeDialogWithComposableToolbar: Verified that the \"Allow\" button is displayed") - Log.i(TAG, "verifyAllowSuggestionsInPrivateModeDialogWithComposableToolbar: Trying to verify that the \"Don't allow\" button is displayed") - composeTestRule.onNodeWithText(getStringResource(R.string.search_suggestions_onboarding_do_not_allow_button), useUnmergedTree = true).assertIsDisplayed() - Log.i(TAG, "verifyAllowSuggestionsInPrivateModeDialogWithComposableToolbar: Verified that the \"Don't allow\" button is displayed") + fun verifyAllowSuggestionsInPrivateModeDialog() { + Log.i(TAG, "verifyAllowSuggestionsInPrivateModeDialog: Trying to verify that the private browsing search suggestion title is displayed") + this@SearchRobot.composeTestRule.onNodeWithText(getStringResource(R.string.search_suggestions_onboarding_title), useUnmergedTree = true).assertIsDisplayed() + Log.i(TAG, "verifyAllowSuggestionsInPrivateModeDialog: Verified that the private browsing search suggestion title is displayed") + Log.i(TAG, "verifyAllowSuggestionsInPrivateModeDialog: Trying to verify that the private browsing search suggestion message is displayed") + this@SearchRobot.composeTestRule.onNodeWithText(getStringResource(R.string.search_suggestions_onboarding_text), useUnmergedTree = true).assertIsDisplayed() + Log.i(TAG, "verifyAllowSuggestionsInPrivateModeDialog: Verified that the private browsing search suggestion message is displayed") + Log.i(TAG, "verifyAllowSuggestionsInPrivateModeDialog: Trying to verify that the \"Learn more\" link is displayed") + this@SearchRobot.composeTestRule.onNodeWithContentDescription("Learn more Links available", useUnmergedTree = true).assertIsDisplayed() + Log.i(TAG, "verifyAllowSuggestionsInPrivateModeDialog: Verified that the \"Learn more\" link is displayed") + Log.i(TAG, "verifyAllowSuggestionsInPrivateModeDialog: Trying to verify that the \"Allow\" button is displayed") + this@SearchRobot.composeTestRule.onNodeWithText(getStringResource(R.string.search_suggestions_onboarding_allow_button), useUnmergedTree = true).assertIsDisplayed() + Log.i(TAG, "verifyAllowSuggestionsInPrivateModeDialog: Verified that the \"Allow\" button is displayed") + Log.i(TAG, "verifyAllowSuggestionsInPrivateModeDialog: Trying to verify that the \"Don't allow\" button is displayed") + this@SearchRobot.composeTestRule.onNodeWithText(getStringResource(R.string.search_suggestions_onboarding_do_not_allow_button), useUnmergedTree = true).assertIsDisplayed() + Log.i(TAG, "verifyAllowSuggestionsInPrivateModeDialog: Verified that the \"Don't allow\" button is displayed") } fun denySuggestionsInPrivateMode() { @@ -345,95 +307,59 @@ class SearchRobot { Log.i(TAG, "allowSuggestionsInPrivateMode: Clicked the \"Allow\" button") } - fun verifySearchSelectorButton() = assertUIObjectExists(searchSelectorButton()) + fun verifySearchSelectorButton() { + Log.i(TAG, "verifySearchSelectorButton: Trying to verify that the search selector button is displayed") + composeTestRule.onNodeWithTag(SEARCH_SELECTOR).assertIsDisplayed() + Log.i(TAG, "verifySearchSelectorButton: Verified that the search selector button is displayed") + } fun clickSearchSelectorButton() { - Log.i(TAG, "clickSearchSelectorButton: Waiting for $waitingTime ms for search selector button to exist") - searchSelectorButton().waitForExists(waitingTime) - Log.i(TAG, "clickSearchSelectorButton: Waited for $waitingTime ms for search selector button to exist") Log.i(TAG, "clickSearchSelectorButton: Trying to click the search selector button") - searchSelectorButton().click() - Log.i(TAG, "clickSearchSelectorButton: Clicked the search selector button") - } - - fun clickSearchSelectorButtonWithComposableToolbar(composeTestRule: ComposeTestRule) { - Log.i(TAG, "clickSearchSelectorButtonWithComposableToolbar: Trying to click the search selector button") composeTestRule.onNodeWithTag(SEARCH_SELECTOR).performClick() - Log.i(TAG, "clickSearchSelectorButtonWithComposableToolbar: Clicked the search selector button") + Log.i(TAG, "clickSearchSelectorButton: Clicked the search selector button") } - fun verifySearchEngineIcon(name: String) = assertUIObjectExists(itemWithDescription(name)) - - fun verifySearchEngineIconWithComposableToolbar(composeTestRule: ComposeTestRule, name: String) { - Log.i(TAG, "verifySearchEngineIconWithComposableToolbar: Trying to verify that search selector icon for: $name search engine is displayed") + fun verifySearchEngineIcon(name: String) { + Log.i(TAG, "verifySearchEngineIcon: Trying to verify that search selector icon for: $name search engine is displayed") composeTestRule.onNodeWithContentDescription(getStringResource(R.string.search_engine_selector_content_description, name)).assertIsDisplayed() - Log.i(TAG, "verifySearchEngineIconWithComposableToolbar: Verified that search selector icon for: $name search engine is displayed") + Log.i(TAG, "verifySearchEngineIcon: Verified that search selector icon for: $name search engine is displayed") } - fun verifySearchBarPlaceholder(text: String) { - Log.i(TAG, "verifySearchBarPlaceholder: Waiting for $waitingTime ms for the edit mode toolbar to exist") - browserToolbarEditView().waitForExists(waitingTime) - Log.i(TAG, "verifySearchBarPlaceholder: Waited for $waitingTime ms for the edit mode toolbar to exist") - assertItemTextEquals(browserToolbarEditView(), expectedText = text) - } - - fun verifySearchBarPlaceholderWithComposableToolbar( - composeTestRule: ComposeTestRule, - searchHint: String, - ) { - Log.i(TAG, "verifySearchBarPlaceholderWithComposableToolbar: Verify hint is $searchHint") - composeTestRule + fun verifySearchBarPlaceholder(searchHint: String) { + Log.i(TAG, "verifySearchBarPlaceholder: Verify hint is $searchHint") + this@SearchRobot.composeTestRule .onNodeWithTag(ADDRESSBAR_SEARCH_BOX) .assert(hasText(searchHint)) .assertIsDisplayed() - Log.i(TAG, "verifySearchBarPlaceholderWithComposableToolbar: Verification successful") + Log.i(TAG, "verifySearchBarPlaceholder: Verification successful") } - fun verifySearchShortcutListContains(vararg searchEngineName: String, shouldExist: Boolean = true) { - searchEngineName.forEach { - if (shouldExist) { - assertUIObjectExists( - searchShortcutList().getChild(UiSelector().text(it)), - ) + fun verifySearchShortcutList(vararg searchEngineNames: String, isSearchEngineDisplayed: Boolean) { + for (searchEngineName in searchEngineNames) { + if (isSearchEngineDisplayed) { + Log.i(TAG, "verifySearchShortcutList: Trying to verify the $searchEngineName search shortcut is displayed") + this@SearchRobot.composeTestRule.onNodeWithContentDescription(searchEngineName) + .assertIsDisplayed() + Log.i(TAG, "verifySearchShortcutList: Verified the $searchEngineName search shortcut is displayed") } else { - assertUIObjectIsGone(searchShortcutList().getChild(UiSelector().text(it))) + Log.i(TAG, "verifySearchShortcutList: Trying to verify the $searchEngineName search shortcut is not displayed") + this@SearchRobot.composeTestRule.onNodeWithContentDescription(searchEngineName) + .assertIsNotDisplayed() + Log.i(TAG, "verifySearchShortcutList: Verified the $searchEngineName search shortcut is not displayed") } } } - fun verifySearchShortcutListWithComposableToolbar(composeTestRule: ComposeTestRule, vararg searchEngineNames: String) { - for (searchEngineName in searchEngineNames) { - Log.i(TAG, "verifySearchShortcutListWithComposableToolbar: Trying to verify the $searchEngineName search shortcut is displayed") - composeTestRule.onNodeWithContentDescription(searchEngineName).assertIsDisplayed() - Log.i(TAG, "verifySearchShortcutListWithComposableToolbar: Verified the $searchEngineName search shortcut is displayed") - } - } - - // New unified search UI search selector. fun selectTemporarySearchMethod(searchEngineName: String) { Log.i(TAG, "selectTemporarySearchMethod: Trying to click the $searchEngineName search shortcut") - searchShortcutList().getChild(UiSelector().text(searchEngineName)).click() - Log.i(TAG, "selectTemporarySearchMethod: Clicked the $searchEngineName search shortcut") - } - - fun selectTemporarySearchMethodWithComposableToolbar(composeTestRule: ComposeTestRule, searchEngineName: String) { - Log.i(TAG, "selectTemporarySearchMethodWithComposableToolbar: Trying to click the $searchEngineName search shortcut") composeTestRule.onNodeWithContentDescription(searchEngineName).performClick() - Log.i(TAG, "selectTemporarySearchMethodWithComposableToolbar: Clicked the $searchEngineName search shortcut") + Log.i(TAG, "selectTemporarySearchMethod: Clicked the $searchEngineName search shortcut") } fun clickScanButton() { - waitForAppWindowToBeUpdated() - assertUIObjectExists(scanButton()) - Log.i(TAG, "clickScanButton: Trying to click the scan button and wait for $waitingTimeShort ms for a new window") - scanButton().clickAndWaitForNewWindow(waitingTimeShort) - Log.i(TAG, "clickScanButton: Clicked the scan button and waited for $waitingTimeShort ms for a new window") - } - - fun clickScanButtonWithComposableToolbar(composeTestRule: ComposeTestRule) { - Log.i(TAG, "clickScanButtonWithComposableToolbar: Trying to click the scan button") - composeTestRule.onNodeWithContentDescription(getStringResource(qrR.string.mozac_feature_qr_scanner)).performClick() - Log.i(TAG, "clickScanButtonWithComposableToolbar: Clicked the scan button") + Log.i(TAG, "clickScanButton: Trying to click the scan button") + this@SearchRobot.composeTestRule.onNodeWithContentDescription(getStringResource(qrR.string.mozac_feature_qr_scanner)).performClick() + Log.i(TAG, "clickScanButton: Clicked the scan button") } fun clickDismissPermissionRequiredDialog() { @@ -468,36 +394,18 @@ class SearchRobot { } fun typeSearch(searchTerm: String) { - Log.i(TAG, "typeSearch: Waiting for $waitingTime ms for the edit mode toolbar to exist") - browserToolbarEditView().waitForExists(waitingTime) - Log.i(TAG, "typeSearch: Waited for $waitingTime ms for the edit mode toolbar to exist") Log.i(TAG, "typeSearch: Trying to set the edit mode toolbar text to $searchTerm") - browserToolbarEditView().setText(searchTerm) + this@SearchRobot.composeTestRule.onNodeWithTag(ADDRESSBAR_SEARCH_BOX).performTextReplacement(searchTerm) Log.i(TAG, "typeSearch: Edit mode toolbar text was set to $searchTerm") - Log.i(TAG, "typeSearch: Waiting for device to be idle") - mDevice.waitForIdle() - Log.i(TAG, "typeSearch: Waited for device to be idle") - } - - fun typeSearchWithComposableToolbar(composeTestRule: ComposeTestRule, searchTerm: String) { - Log.i(TAG, "typeSearchWithComposableToolbar: Trying to set the edit mode toolbar text to $searchTerm") - composeTestRule.onNodeWithTag(ADDRESSBAR_SEARCH_BOX).performTextReplacement(searchTerm) - Log.i(TAG, "typeSearchWithComposableToolbar: Edit mode toolbar text was set to $searchTerm") } fun clickClearButton() { Log.i(TAG, "clickClearButton: Trying to click the clear button") - clearButton().click() - Log.i(TAG, "clickClearButton: Clicked the clear button") - } - - fun clickClearButtonWithComposableToolbar(composeTestRule: ComposeTestRule) { - Log.i(TAG, "clickClearButtonWithComposableToolbar: Trying to click the clear button") composeTestRule.onNodeWithContentDescription(getStringResource(toolbarR.string.mozac_clear_button_description)).performClick() - Log.i(TAG, "clickClearButtonWithComposableToolbar: Clicked the clear button") - Log.i(TAG, "clickClearButtonWithComposableToolbar: Waiting for compose test rule to be idle") + Log.i(TAG, "clickClearButton: Clicked the clear button") + Log.i(TAG, "clickClearButton: Waiting for compose test rule to be idle") composeTestRule.waitForIdle() - Log.i(TAG, "clickClearButtonWithComposableToolbar: Waited for compose test rule to be idle") + Log.i(TAG, "clickClearButton: Waited for compose test rule to be idle") } fun tapOutsideToDismissSearchBar() { @@ -512,12 +420,9 @@ class SearchRobot { } fun longClickToolbar() { - Log.i(TAG, "longClickToolbar: Waiting for $waitingTime ms for the toolbar to exist") - mDevice.findObject(UiSelector().resourceId("$packageName:id/toolbar")) - .waitForExists(waitingTime) - Log.i(TAG, "longClickToolbar: Waited for $waitingTime ms for the toolbar to exist") + composeTestRule.waitForIdle() Log.i(TAG, "longClickToolbar: Trying to perform long click on the toolbar") - mDevice.findObject(By.res("$packageName:id/toolbar")).click(LONG_CLICK_DURATION) + composeTestRule.onNodeWithTag("ADDRESSBAR_SEARCH_BOX").performTouchInput { longClick() } Log.i(TAG, "longClickToolbar: Performed long click on the toolbar") } @@ -538,7 +443,7 @@ class SearchRobot { if (i == RETRY_COUNT) { throw e } else { - searchScreen { + searchScreen(this@SearchRobot.composeTestRule) { }.dismissSearchBar { }.openSearch { clickClearButton() @@ -549,24 +454,19 @@ class SearchRobot { } } - fun verifyTranslatedFocusedNavigationToolbar(toolbarHintString: String) = - assertItemTextContains(browserToolbarEditView(), itemText = toolbarHintString) - - fun verifyTypedToolbarText(expectedText: String, exists: Boolean) = - assertUIObjectExists( - itemWithResIdAndText("$packageName:id/mozac_browser_toolbar_edit_url_view", expectedText), - exists = exists, - waitingTime = waitingTimeShort, - ) + fun verifyTranslatedNavigationToolbarHint(toolbarHintString: String) { + Log.i(TAG, "verifyTranslatedNavigationToolbarHint: Trying to verify that the translated toolbar has: $toolbarHintString as a hint") + composeTestRule.onNode( + hasText(toolbarHintString), + useUnmergedTree = true, + ).assertIsDisplayed() + Log.i(TAG, "verifyTranslatedNavigationToolbarHint: Verified that the translated toolbar has: $toolbarHintString as a hint") + } - fun verifyTypedToolbarTextWithComposableToolbar( - composeTestRule: ComposeTestRule, - expectedText: String, - exists: Boolean, - ) { - Log.i(TAG, "verifyTypedToolbarTextWithComposableToolbar: Verifying that text '$expectedText' exists?: $exists") + fun verifyTypedToolbarText(expectedText: String, exists: Boolean) { + Log.i(TAG, "verifyTypedToolbarText: Verifying that text '$expectedText' exists?: $exists") - val editToolbar = composeTestRule.onNode( + val editToolbar = this@SearchRobot.composeTestRule.onNode( hasTestTag(ADDRESSBAR_SEARCH_BOX) and hasText(expectedText), useUnmergedTree = true, ) @@ -576,7 +476,7 @@ class SearchRobot { false -> editToolbar.assertIsNotDisplayed() } - Log.i(TAG, "verifyTypedToolbarTextWithComposableToolbar: Verification successful.") + Log.i(TAG, "verifyTypedToolbarText: Verification successful.") } fun verifySearchBarPosition(bottomPosition: Boolean) { @@ -603,82 +503,35 @@ class SearchRobot { } } - class Transition { + class Transition(private val composeTestRule: ComposeTestRule) { private lateinit var sessionLoadedIdlingResource: SessionLoadedIdlingResource fun dismissSearchBar(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition { - for (i in 0..1) { - try { - Log.i(TAG, "dismissSearchBar: Trying to click device back button") - mDevice.pressBack() - Log.i(TAG, "dismissSearchBar: Clicked device back button") - assertUIObjectIsGone(searchWrapper()) - - break - } catch (e: AssertionError) { - if (i == 1) { - throw e - } - } - } + Log.i(TAG, "dismissSearchBar: Trying to click device back button") + mDevice.pressBack() + Log.i(TAG, "dismissSearchBar: Clicked device back button") + waitForAppWindowToBeUpdated() - HomeScreenRobot().interact() - return HomeScreenRobot.Transition() - } - - fun openBrowser(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { - Log.i(TAG, "openBrowser: Waiting for device to be idle") - mDevice.waitForIdle() - Log.i(TAG, "openBrowser: Waited for device to be idle") - Log.i(TAG, "openBrowser: Trying to set the edit mode toolbar text to: mozilla") - browserToolbarEditView().setText("mozilla\n") - Log.i(TAG, "openBrowser: Edit mode toolbar text was set to: mozilla") - Log.i(TAG, "openBrowser: Trying to click device enter button") - pressImeActionOnToolbarEditView() - Log.i(TAG, "openBrowser: Clicked device enter button") - - BrowserRobot().interact() - return BrowserRobot.Transition() + HomeScreenRobot(composeTestRule).interact() + return HomeScreenRobot.Transition(composeTestRule) } fun submitQuery(query: String, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { - sessionLoadedIdlingResource = SessionLoadedIdlingResource() - - Log.i(TAG, "submitQuery: Trying to set the edit mode toolbar text to: $query") - browserToolbarEditView().setText(query) - Log.i(TAG, "submitQuery: Edit mode toolbar text was set to: $query") - Log.i(TAG, "submitQuery: Trying to click device enter button") - pressImeActionOnToolbarEditView() - Log.i(TAG, "submitQuery: Clicked device enter button") - - registerAndCleanupIdlingResources(sessionLoadedIdlingResource) { - assertUIObjectExists(itemWithResId("$packageName:id/browserLayout")) - } - - BrowserRobot().interact() - return BrowserRobot.Transition() - } - - fun submitQueryWithComposableToolbar( - composeTestRule: ComposeTestRule, - query: String, - interact: BrowserRobot.() -> Unit, - ): BrowserRobot.Transition { - Log.i(TAG, "submitQueryWithComposableToolbar: Trying to set toolbar text to: $query and pressing IME action") + Log.i(TAG, "submitQuery: Trying to set toolbar text to: $query and pressing IME action") composeTestRule.onNodeWithTag(ADDRESSBAR_SEARCH_BOX).apply { performTextReplacement(query) performImeAction() } - Log.i(TAG, "submitQueryWithComposableToolbar: Toolbar text was set to: $query and IME action performed") + Log.i(TAG, "submitQuery: Toolbar text was set to: $query and IME action performed") - BrowserRobot().interact() - return BrowserRobot.Transition() + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } fun clickSearchEngineSettings(interact: SettingsSubMenuSearchRobot.() -> Unit): SettingsSubMenuSearchRobot.Transition { Log.i(TAG, "clickSearchEngineSettings: Trying to click the \"Search settings\" button") - searchShortcutList().getChild(UiSelector().text("Search settings")).click() + composeTestRule.onNodeWithContentDescription(getStringResource(R.string.search_settings_menu_item)).performClick() Log.i(TAG, "clickSearchEngineSettings: Clicked the \"Search settings\" button") SettingsSubMenuSearchRobot().interact() @@ -695,19 +548,19 @@ class SearchRobot { Log.i(TAG, "clickSearchSuggestion: Clicked search suggestion: $searchSuggestion and waited for $waitingTimeShort ms for a new window") } - BrowserRobot().interact() - return BrowserRobot.Transition() + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } } } -fun searchScreen(interact: SearchRobot.() -> Unit): SearchRobot.Transition { - SearchRobot().interact() - return SearchRobot.Transition() +fun searchScreen(composeTestRule: ComposeTestRule, interact: SearchRobot.() -> Unit): SearchRobot.Transition { + SearchRobot(composeTestRule).interact() + return SearchRobot.Transition(composeTestRule) } private fun browserToolbarEditView() = - mDevice.findObject(UiSelector().resourceId("$packageName:id/mozac_browser_toolbar_edit_url_view")) + mDevice.findObject(UiSelector().resourceId(ADDRESSBAR_SEARCH_BOX)) private fun pressImeActionOnToolbarEditView() { val context = appContext diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsRobot.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsRobot.kt @@ -443,7 +443,7 @@ class SettingsRobot { assertUIObjectExists(aboutFirefoxHeading()) } - fun verifyGooglePlayRedirect() { + fun verifyGooglePlayRedirect(composeTestRule: ComposeTestRule) { if (isPackageInstalled(GOOGLE_PLAY_SERVICES)) { Log.i(TAG, "verifyGooglePlayRedirect: $GOOGLE_PLAY_SERVICES is installed") try { @@ -457,12 +457,12 @@ class SettingsRobot { Log.i(TAG, "verifyGooglePlayRedirect: Verified intent to: $GOOGLE_PLAY_SERVICES") } catch (e: AssertionFailedError) { Log.i(TAG, "verifyGooglePlayRedirect: AssertionFailedError caught, executing fallback methods") - BrowserRobot().verifyRateOnGooglePlayURL() + BrowserRobot(composeTestRule).verifyRateOnGooglePlayURL() } finally { forceCloseApp(GOOGLE_PLAY_SERVICES) } } else { - BrowserRobot().verifyRateOnGooglePlayURL() + BrowserRobot(composeTestRule).verifyRateOnGooglePlayURL() } } @@ -479,16 +479,16 @@ class SettingsRobot { } class Transition { - fun goBack(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition { + fun goBack(composeTestRule: ComposeTestRule, interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition { Log.i(TAG, "goBack: Trying to click the navigate up button") goBackButton().click() Log.i(TAG, "goBack: Clicked the navigate up button") - HomeScreenRobot().interact() - return HomeScreenRobot.Transition() + HomeScreenRobot(composeTestRule).interact() + return HomeScreenRobot.Transition(composeTestRule) } - fun goBackToOnboardingScreen(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition { + fun goBackToOnboardingScreen(composeTestRule: ComposeTestRule, interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition { Log.i(TAG, "goBackToOnboardingScreen: Trying to click device back button") mDevice.pressBack() Log.i(TAG, "goBackToOnboardingScreen: Clicked device back button") @@ -496,17 +496,17 @@ class SettingsRobot { mDevice.waitForIdle(waitingTimeShort) Log.i(TAG, "goBackToOnboardingScreen: Device was idle for $waitingTimeShort ms") - HomeScreenRobot().interact() - return HomeScreenRobot.Transition() + HomeScreenRobot(composeTestRule).interact() + return HomeScreenRobot.Transition(composeTestRule) } - fun goBackToBrowser(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { + fun goBackToBrowser(composeTestRule: ComposeTestRule, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { Log.i(TAG, "goBackToBrowser: Trying to click the navigate up button") goBackButton().click() Log.i(TAG, "goBackToBrowser: Clicked the navigate up button") - BrowserRobot().interact() - return BrowserRobot.Transition() + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } fun openAboutFirefoxPreview(interact: SettingsSubMenuAboutRobot.() -> Unit): SettingsSubMenuAboutRobot.Transition { @@ -716,13 +716,13 @@ class SettingsRobot { return SettingsSubMenuDataCollectionRobot.Transition() } - fun openAddonsManagerMenu(interact: SettingsSubMenuAddonsManagerRobot.() -> Unit): SettingsSubMenuAddonsManagerRobot.Transition { + fun openAddonsManagerMenu(composeTestRule: ComposeTestRule, interact: SettingsSubMenuAddonsManagerRobot.() -> Unit): SettingsSubMenuAddonsManagerRobot.Transition { Log.i(TAG, "openAddonsManagerMenu: Trying to click the \"Add-ons\" button") addonsManagerButton().click() Log.i(TAG, "openAddonsManagerMenu: Clicked the \"Add-ons\" button") - SettingsSubMenuAddonsManagerRobot().interact() - return SettingsSubMenuAddonsManagerRobot.Transition() + SettingsSubMenuAddonsManagerRobot(composeTestRule).interact() + return SettingsSubMenuAddonsManagerRobot.Transition(composeTestRule) } fun openOpenLinksInAppsMenu(interact: SettingsSubMenuOpenLinksInAppsRobot.() -> Unit): SettingsSubMenuOpenLinksInAppsRobot.Transition { diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuAboutRobot.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuAboutRobot.kt @@ -8,6 +8,7 @@ package org.mozilla.fenix.ui.robots import android.os.Build import android.util.Log +import androidx.compose.ui.test.junit4.ComposeTestRule import androidx.core.content.pm.PackageInfoCompat import androidx.test.espresso.Espresso import androidx.test.espresso.Espresso.onView @@ -99,7 +100,7 @@ class SettingsSubMenuAboutRobot { Log.i(TAG, "verifyAboutToolbar: Verified that the \"About $appName\" toolbar title is visible") } - fun verifyWhatIsNewInFirefoxLink() { + fun verifyWhatIsNewInFirefoxLink(composeTestRule: ComposeTestRule) { Log.i(TAG, "verifyWhatIsNewInFirefoxLink: Trying to perform ${LISTS_MAXSWIPES}x a scroll action to the end of the about list") aboutMenuList.scrollToEnd(LISTS_MAXSWIPES) Log.i(TAG, "verifyWhatIsNewInFirefoxLink: Performed ${LISTS_MAXSWIPES}x a scroll action to the end of the about list") @@ -112,11 +113,11 @@ class SettingsSubMenuAboutRobot { onView(withText("What’s new in $firefox")).perform(click()) Log.i(TAG, "verifyWhatIsNewInFirefoxLink: Clicked the \"What’s new in $firefox\" link") - browserScreen { + browserScreen(composeTestRule) { verifyWhatsNewURL() } } - fun verifySupportLink() { + fun verifySupportLink(composeTestRule: ComposeTestRule) { Log.i(TAG, "verifySupport: Trying to perform ${LISTS_MAXSWIPES}x a scroll action to the end of the about list") aboutMenuList.scrollToEnd(LISTS_MAXSWIPES) Log.i(TAG, "verifySupport: Performed ${LISTS_MAXSWIPES}x a scroll action to the end of the about list") @@ -127,7 +128,7 @@ class SettingsSubMenuAboutRobot { onView(withText("Support")).perform(click()) Log.i(TAG, "verifySupport: Clicked the \"Support\" link") - browserScreen { + browserScreen(composeTestRule) { verifyHelpUrl() } } @@ -152,7 +153,7 @@ class SettingsSubMenuAboutRobot { } } - fun verifyPrivacyNoticeLink() { + fun verifyPrivacyNoticeLink(composeTestRule: ComposeTestRule) { Log.i(TAG, "verifyPrivacyNoticeLink: Trying to perform ${LISTS_MAXSWIPES}x a scroll action to the end of the about list") aboutMenuList.scrollToEnd(LISTS_MAXSWIPES) Log.i(TAG, "verifyPrivacyNoticeLink: Performed ${LISTS_MAXSWIPES}x a scroll action to the end of the about list") @@ -163,12 +164,12 @@ class SettingsSubMenuAboutRobot { onView(withText("Privacy notice")).perform(click()) Log.i(TAG, "verifyPrivacyNoticeLink: Clicked the \"Privacy notice\" link") - browserScreen { + browserScreen(composeTestRule) { verifyUrl("/privacy/firefox") } } - fun verifyKnowYourRightsLink() { + fun verifyKnowYourRightsLink(composeTestRule: ComposeTestRule) { Log.i(TAG, "verifyKnowYourRightsLink: Trying to perform ${LISTS_MAXSWIPES}x a scroll action to the end of the about list") aboutMenuList.scrollToEnd(LISTS_MAXSWIPES) Log.i(TAG, "verifyKnowYourRightsLink: Performed ${LISTS_MAXSWIPES}x a scroll action to the end of the about list") @@ -179,12 +180,12 @@ class SettingsSubMenuAboutRobot { onView(withText("Know your rights")).perform(click()) Log.i(TAG, "verifyKnowYourRightsLink: Clicked the \"Know your rights\" link") - browserScreen { + browserScreen(composeTestRule) { verifyUrl(SupportUtils.SumoTopic.YOUR_RIGHTS.topicStr) } } - fun verifyLicensingInformationLink() { + fun verifyLicensingInformationLink(composeTestRule: ComposeTestRule) { Log.i(TAG, "verifyLicensingInformationLink: Trying to perform ${LISTS_MAXSWIPES}x a scroll action to the end of the about list") aboutMenuList.scrollToEnd(LISTS_MAXSWIPES) Log.i(TAG, "verifyLicensingInformationLink: Performed ${LISTS_MAXSWIPES}x a scroll action to the end of the about list") @@ -195,7 +196,7 @@ class SettingsSubMenuAboutRobot { onView(withText("Licensing information")).perform(click()) Log.i(TAG, "verifyLicensingInformationLink: Clicked the \"Licensing information\" link") - browserScreen { + browserScreen(composeTestRule) { verifyUrl("about:license") } } @@ -243,10 +244,10 @@ class SettingsSubMenuAboutRobot { } } -private fun navigateBackToAboutPage() { - navigationToolbar { +private fun navigateBackToAboutPage(composeTestRule: ComposeTestRule) { + browserScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openAboutFirefoxPreview { } } diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuAddonsManagerAddonDetailedMenuRobot.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuAddonsManagerAddonDetailedMenuRobot.kt @@ -7,6 +7,7 @@ package org.mozilla.fenix.ui.robots import android.util.Log import android.view.View +import androidx.compose.ui.test.junit4.ComposeTestRule import androidx.test.espresso.Espresso.onView import androidx.test.espresso.assertion.ViewAssertions.matches import androidx.test.espresso.matcher.ViewMatchers @@ -36,14 +37,14 @@ class SettingsSubMenuAddonsManagerAddonDetailedMenuRobot { Log.i(TAG, "disableExtension: Clicked the enable/disable extension toggle") } - class Transition { + class Transition(private val composeTestRule: ComposeTestRule) { fun goBack(interact: SettingsSubMenuAddonsManagerRobot.() -> Unit): SettingsSubMenuAddonsManagerRobot.Transition { Log.i(TAG, "goBack: Trying to click the navigate up button") onView(allOf(withContentDescription("Navigate up"))).click() Log.i(TAG, "goBack: Clicked the navigate up button") - SettingsSubMenuAddonsManagerRobot().interact() - return SettingsSubMenuAddonsManagerRobot.Transition() + SettingsSubMenuAddonsManagerRobot(composeTestRule).interact() + return SettingsSubMenuAddonsManagerRobot.Transition(composeTestRule) } fun removeAddon(activityTestRule: ActivityTestRule<HomeActivity>, interact: SettingsSubMenuAddonsManagerRobot.() -> Unit): SettingsSubMenuAddonsManagerRobot.Transition { @@ -61,8 +62,8 @@ class SettingsSubMenuAddonsManagerAddonDetailedMenuRobot { Log.i(TAG, "removeAddon: Clicked the remove add-on button") } - SettingsSubMenuAddonsManagerRobot().interact() - return SettingsSubMenuAddonsManagerRobot.Transition() + SettingsSubMenuAddonsManagerRobot(composeTestRule).interact() + return SettingsSubMenuAddonsManagerRobot.Transition(composeTestRule) } } } diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuAddonsManagerRobot.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuAddonsManagerRobot.kt @@ -69,7 +69,7 @@ import mozilla.components.feature.addons.R as addonsR * Implementation of Robot Pattern for the Addons Management Settings. */ -class SettingsSubMenuAddonsManagerRobot { +class SettingsSubMenuAddonsManagerRobot(private val composeTestRule: ComposeTestRule) { fun verifyAddonsListIsDisplayed(shouldBeDisplayed: Boolean) = assertUIObjectExists(addonsList(), exists = shouldBeDisplayed) @@ -140,10 +140,10 @@ class SettingsSubMenuAddonsManagerRobot { break } catch (e: NoMatchingViewException) { Log.i(TAG, "clickInstallAddon: NoMatchingViewException caught, executing fallback methods") - addonsMenu { + addonsMenu(composeTestRule) { }.goBackToHomeScreen { }.openThreeDotMenu { - }.openAddonsManagerMenu { + }.clickExtensionsButton { } } } @@ -171,9 +171,9 @@ class SettingsSubMenuAddonsManagerRobot { throw e } else { restartApp(activityTestRule) - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openAddonsManagerMenu { + }.clickExtensionsButton { waitForAddonsListProgressBarToBeGone() scrollToAddon(addonName) clickInstallAddon(addonName) @@ -273,9 +273,9 @@ class SettingsSubMenuAddonsManagerRobot { } fun installAddon(addonName: String, activityTestRule: HomeActivityIntentTestRule) { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openAddonsManagerMenu { + }.clickExtensionsButton { waitForAddonsListProgressBarToBeGone() clickInstallAddon(addonName) verifyAddonPermissionPrompt(addonName) @@ -285,9 +285,9 @@ class SettingsSubMenuAddonsManagerRobot { } fun installAddonInPrivateMode(addonName: String, activityTestRule: HomeActivityIntentTestRule) { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openAddonsManagerMenu { + }.clickExtensionsButton { waitForAddonsListProgressBarToBeGone() clickInstallAddon(addonName) verifyAddonPermissionPrompt(addonName) @@ -382,10 +382,10 @@ class SettingsSubMenuAddonsManagerRobot { mDevice.pressBack() Log.i(TAG, "verifyTheRecommendedAddons: Clicked device back button to dismiss the main menu") waitForAppWindowToBeUpdated() - browserScreen { - }.openThreeDotMenu(composeTestRule) { + browserScreen(composeTestRule) { + }.openThreeDotMenu { verifyTryRecommendedExtensionButton() - }.openExtensionsFromMainMenu { + }.clickExtensionsButton { } } } @@ -415,10 +415,10 @@ class SettingsSubMenuAddonsManagerRobot { mDevice.pressBack() Log.i(TAG, "installRecommendedAddon: Clicked device back button to dismiss the main menu") waitForAppWindowToBeUpdated() - browserScreen { - }.openThreeDotMenu(composeTestRule) { + browserScreen(composeTestRule) { + }.openThreeDotMenu { verifyTryRecommendedExtensionButton() - }.openExtensionsFromMainMenu { + }.clickExtensionsButton { recommendedExtensionTitle = getRecommendedExtensionTitle(composeTestRule) } } @@ -467,14 +467,14 @@ class SettingsSubMenuAddonsManagerRobot { ).assertIsDisplayed() Log.i(TAG, "verifyInstalledExtension: Verified that extension: $extensionTitle is displayed") } - class Transition { + class Transition(private val composeTestRule: ComposeTestRule) { fun goBackToHomeScreen(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition { Log.i(TAG, "goBackToHomeScreen: Trying to click navigate up toolbar button") onView(allOf(withContentDescription("Navigate up"))).click() Log.i(TAG, "goBackToHomeScreen: Clicked the navigate up toolbar button") - HomeScreenRobot().interact() - return HomeScreenRobot.Transition() + HomeScreenRobot(composeTestRule).interact() + return HomeScreenRobot.Transition(composeTestRule) } fun goBackToBrowser(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { @@ -482,8 +482,8 @@ class SettingsSubMenuAddonsManagerRobot { onView(allOf(withContentDescription("Navigate up"))).click() Log.i(TAG, "goBackToBrowser: Clicked the navigate up toolbar button") - BrowserRobot().interact() - return BrowserRobot.Transition() + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } fun openDetailedMenuForAddon( @@ -503,7 +503,7 @@ class SettingsSubMenuAddonsManagerRobot { Log.i(TAG, "openDetailedMenuForAddon: Clicked the $addonName add-on") SettingsSubMenuAddonsManagerAddonDetailedMenuRobot().interact() - return SettingsSubMenuAddonsManagerAddonDetailedMenuRobot.Transition() + return SettingsSubMenuAddonsManagerAddonDetailedMenuRobot.Transition(composeTestRule) } fun clickExtensionsPromotionBannerLearnMoreLink(composeTestRule: ComposeTestRule, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { @@ -513,8 +513,8 @@ class SettingsSubMenuAddonsManagerRobot { ).performClick() Log.i(TAG, "clickExtensionsPromotionBannerLearnMoreLink: Clicked the \"Learn more\" link") - BrowserRobot().interact() - return BrowserRobot.Transition() + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } fun clickDiscoverMoreExtensionsButton(composeTestRule: ComposeTestRule, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { @@ -522,8 +522,8 @@ class SettingsSubMenuAddonsManagerRobot { composeTestRule.onNode(hasText(getStringResource(R.string.browser_menu_discover_more_extensions)), useUnmergedTree = true).performClick() Log.i(TAG, "clickDiscoverMoreExtensionsButton: Clicked the \"Discover more extensions\" link") - BrowserRobot().interact() - return BrowserRobot.Transition() + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } } @@ -579,9 +579,9 @@ class SettingsSubMenuAddonsManagerRobot { } } -fun addonsMenu(interact: SettingsSubMenuAddonsManagerRobot.() -> Unit): SettingsSubMenuAddonsManagerRobot.Transition { - SettingsSubMenuAddonsManagerRobot().interact() - return SettingsSubMenuAddonsManagerRobot.Transition() +fun addonsMenu(composeTestRule: ComposeTestRule, interact: SettingsSubMenuAddonsManagerRobot.() -> Unit): SettingsSubMenuAddonsManagerRobot.Transition { + SettingsSubMenuAddonsManagerRobot(composeTestRule).interact() + return SettingsSubMenuAddonsManagerRobot.Transition(composeTestRule) } private fun scrollToAddon(addonName: String) { diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuAutofillRobot.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuAutofillRobot.kt @@ -350,6 +350,7 @@ class SettingsSubMenuAutofillRobot(private val composeTestRule: ComposeTestRule) @OptIn(ExperimentalTestApi::class) fun fillAndSaveAddress( + composeTestRule: ComposeTestRule, navigateToAutofillSettings: Boolean, isAddressAutofillEnabled: Boolean = true, userHasSavedAddress: Boolean = false, @@ -363,9 +364,9 @@ class SettingsSubMenuAutofillRobot(private val composeTestRule: ComposeTestRule) emailAddress: String, ) { if (navigateToAutofillSettings) { - homeScreen { + homeScreen(composeTestRule) { }.openThreeDotMenu { - }.openSettings { + }.clickSettingsButton { }.openAutofillSubMenu(composeTestRule) { verifyAddressAutofillSection(isAddressAutofillEnabled, userHasSavedAddress) clickAddAddressButton() @@ -679,13 +680,13 @@ class SettingsSubMenuAutofillRobot(private val composeTestRule: ComposeTestRule) return SettingsSubMenuAutofillRobot.Transition(composeTestRule) } - fun goBackToBrowser(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { + fun goBackToBrowser(composeTestRule: ComposeTestRule, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { Log.i(TAG, "goBackToBrowser: Trying to click the device back button") mDevice.pressBack() Log.i(TAG, "goBackToBrowser: Clicked the device back button") - BrowserRobot().interact() - return BrowserRobot.Transition() + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } } } diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuEnhancedTrackingProtectionRobot.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuEnhancedTrackingProtectionRobot.kt @@ -5,6 +5,7 @@ package org.mozilla.fenix.ui.robots import android.util.Log +import androidx.compose.ui.test.junit4.ComposeTestRule import androidx.recyclerview.widget.RecyclerView import androidx.test.espresso.Espresso.onView import androidx.test.espresso.Espresso.pressBack @@ -270,7 +271,7 @@ class SettingsSubMenuEnhancedTrackingProtectionRobot { } class Transition { - fun goBackToHomeScreen(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition { + fun goBackToHomeScreen(composeTestRule: ComposeTestRule, interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition { // To settings Log.i(TAG, "goBackToHomeScreen: Trying to click the navigate up toolbar button") goBackButton().click() @@ -280,8 +281,8 @@ class SettingsSubMenuEnhancedTrackingProtectionRobot { pressBack() Log.i(TAG, "goBackToHomeScreen: Performed press back action") - HomeScreenRobot().interact() - return HomeScreenRobot.Transition() + HomeScreenRobot(composeTestRule).interact() + return HomeScreenRobot.Transition(composeTestRule) } fun goBack(interact: SettingsRobot.() -> Unit): SettingsRobot.Transition { diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuExperimentsRobot.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuExperimentsRobot.kt @@ -8,6 +8,7 @@ import androidx.test.espresso.Espresso.onView import androidx.test.espresso.matcher.ViewMatchers.withContentDescription import androidx.test.uiautomator.UiSelector import org.mozilla.fenix.R +import org.mozilla.fenix.helpers.HomeActivityComposeTestRule import org.mozilla.fenix.helpers.MatcherHelper.assertUIObjectExists import org.mozilla.fenix.helpers.MatcherHelper.itemContainingText import org.mozilla.fenix.helpers.MatcherHelper.itemWithResId @@ -21,11 +22,11 @@ class SettingsSubMenuExperimentsRobot { class Transition { - fun goBackToHomeScreen(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition { + fun goBackToHomeScreen(composeTestRule: HomeActivityComposeTestRule, interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition { goBackButton().click() - HomeScreenRobot().interact() - return HomeScreenRobot.Transition() + HomeScreenRobot(composeTestRule).interact() + return HomeScreenRobot.Transition(composeTestRule) } fun goBack(interact: SettingsRobot.() -> Unit): SettingsRobot.Transition { diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuHomepageRobot.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuHomepageRobot.kt @@ -5,6 +5,7 @@ package org.mozilla.fenix.ui.robots import android.util.Log +import androidx.compose.ui.test.junit4.ComposeTestRule import androidx.test.espresso.Espresso.onView import androidx.test.espresso.assertion.ViewAssertions.matches import androidx.test.espresso.matcher.ViewMatchers @@ -390,13 +391,13 @@ class SettingsSubMenuHomepageRobot { class Transition { - fun goBackToHomeScreen(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition { + fun goBackToHomeScreen(composeTestRule: ComposeTestRule, interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition { Log.i(TAG, "goBackToHomeScreen: Trying to click the navigate up toolbar button") goBackButton().click() Log.i(TAG, "goBackToHomeScreen: Clicked the navigate up toolbar button") - HomeScreenRobot().interact() - return HomeScreenRobot.Transition() + HomeScreenRobot(composeTestRule).interact() + return HomeScreenRobot.Transition(composeTestRule) } fun goBack(interact: SettingsRobot.() -> Unit): SettingsRobot.Transition { @@ -408,7 +409,7 @@ class SettingsSubMenuHomepageRobot { return SettingsRobot.Transition() } - fun clickSnackBarViewButton(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition { + fun clickSnackBarViewButton(composeTestRule: ComposeTestRule, interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition { Log.i(TAG, "clickSnackBarViewButton: Waiting for $waitingTimeShort ms for \"VIEW\" snackbar button to exist") mDevice.findObject(UiSelector().text("VIEW")).waitForExists(waitingTimeShort) Log.i(TAG, "clickSnackBarViewButton: Waited for $waitingTimeShort ms for \"VIEW\" snackbar button to exist") @@ -416,8 +417,8 @@ class SettingsSubMenuHomepageRobot { mDevice.findObject(UiSelector().text("VIEW")).click() Log.i(TAG, "clickSnackBarViewButton: Clicked the \"VIEW\" snackbar button") - HomeScreenRobot().interact() - return HomeScreenRobot.Transition() + HomeScreenRobot(composeTestRule).interact() + return HomeScreenRobot.Transition(composeTestRule) } } } diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuLoginsAndPasswordRobot.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuLoginsAndPasswordRobot.kt @@ -8,6 +8,7 @@ package org.mozilla.fenix.ui.robots import android.content.Context import android.util.Log +import androidx.compose.ui.test.junit4.ComposeTestRule import androidx.test.espresso.Espresso.onView import androidx.test.espresso.action.ViewActions.click import androidx.test.espresso.assertion.ViewAssertions.matches @@ -136,22 +137,22 @@ class SettingsSubMenuLoginsAndPasswordRobot { return SettingsRobot.Transition() } - fun openSavedLogins(interact: SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot.() -> Unit): SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot.Transition { + fun openSavedLogins(composeTestRule: ComposeTestRule, interact: SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot.() -> Unit): SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot.Transition { Log.i(TAG, "openSavedLogins: Trying to click the \"Saved logins\" button") savedLoginsButton().click() Log.i(TAG, "openSavedLogins: Clicked the \"Saved logins\" button") - SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot().interact() - return SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot.Transition() + SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot(composeTestRule).interact() + return SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot.Transition(composeTestRule) } - fun openLoginExceptions(interact: SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot.() -> Unit): SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot.Transition { + fun openLoginExceptions(composeTestRule: ComposeTestRule, interact: SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot.() -> Unit): SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot.Transition { Log.i(TAG, "openLoginExceptions: Trying to click the \"Exceptions\" button") loginExceptionsButton().click() Log.i(TAG, "openLoginExceptions: Clicked the \"Exceptions\" button") - SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot().interact() - return SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot.Transition() + SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot(composeTestRule).interact() + return SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot.Transition(composeTestRule) } fun openSyncLogins(interact: SettingsTurnOnSyncRobot.() -> Unit): SettingsTurnOnSyncRobot.Transition { diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot.kt @@ -57,7 +57,7 @@ import org.mozilla.fenix.settings.logins.ui.LoginsTestingTags.SAVED_LOGINS_PASSW * Implementation of Robot Pattern for the Privacy Settings > saved logins sub menu */ -class SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot { +class SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot(private val composeTestRule: ComposeTestRule) { fun verifySecurityPromptForLogins() { Log.i(TAG, "verifySecurityPromptForLogins: Trying to verify that the \"Secure your saved passwords\" dialog is visible") onView(withText("Secure your saved passwords")).inRoot(RootMatchers.isDialog()).check( @@ -70,7 +70,7 @@ class SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot { Log.i(TAG, "verifySecurityPromptForLogins: Verified that the \"Secure your saved passwords\" dialog is visible") } - fun verifyEmptySavedLoginsListView(composeTestRule: HomeActivityComposeTestRule) { + fun verifyEmptySavedLoginsListView() { Log.i(TAG, "verifyEmptySavedLoginsListView: Trying to verify that the saved logins section description is displayed") composeTestRule.onNodeWithText(getStringResource(R.string.preferences_passwords_saved_logins_description_empty_text_2)).assertIsDisplayed() Log.i(TAG, "verifyEmptySavedLoginsListView: Verified that the saved logins section description is displayed") @@ -105,7 +105,7 @@ class SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot { Log.i(TAG, "clickAddLoginButton: Clicked the \"Add login\" button") } - fun verifyAddNewLoginView(composeTestRule: ComposeTestRule) { + fun verifyAddNewLoginView() { Log.i(TAG, "verifyAddNewLoginView: Trying to verify the \"Add login\" view items") composeTestRule.onNodeWithText(getStringResource(R.string.preferences_passwords_saved_logins_site), useUnmergedTree = true).assertIsDisplayed() composeTestRule.onNodeWithTag(ADD_LOGIN_HOST_NAME_TEXT_FIELD).assertIsDisplayed() @@ -117,58 +117,58 @@ class SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot { Log.i(TAG, "verifyAddNewLoginView: Verified the \"Add login\" view items") } - fun enterSiteCredentialWhileAddingALogin(composeTestRule: ComposeTestRule, website: String) { + fun enterSiteCredentialWhileAddingALogin(website: String) { Log.i(TAG, "enterSiteCredentialWhileAddingALogin: Trying to set the \"Site\" text box text to: $website") composeTestRule.onNodeWithTag(ADD_LOGIN_HOST_NAME_TEXT_FIELD).performClick() composeTestRule.onNodeWithTag(ADD_LOGIN_HOST_NAME_TEXT_FIELD).clearAndSetText(website) Log.i(TAG, "enterSiteCredentialWhileAddingALogin: The \"Site\" text box text was set to: $website") } - fun verifyHostnameErrorMessage(composeTestRule: ComposeTestRule) { + fun verifyHostnameErrorMessage() { Log.i(TAG, "verifyHostnameErrorMessage: Trying to verify that the host name error message is displayed") composeTestRule.onNodeWithText(getStringResource(R.string.add_login_hostname_invalid_text_2), useUnmergedTree = true).assertIsDisplayed() Log.i(TAG, "verifyHostnameErrorMessage: Verified that the host name error message is displayed") } - fun verifyPasswordErrorMessage(composeTestRule: ComposeTestRule) { + fun verifyPasswordErrorMessage() { Log.i(TAG, "verifyPasswordErrorMessage: Trying to verify that the password error message is displayed") composeTestRule.onNodeWithText(getStringResource(R.string.saved_login_password_required_2), useUnmergedTree = true).assertIsDisplayed() Log.i(TAG, "verifyPasswordErrorMessage: Verified that the password error message is displayed") } - fun verifyPasswordClearButton(composeTestRule: ComposeTestRule) { + fun verifyPasswordClearButton() { Log.i(TAG, "verifyPasswordClearButton: Trying to verify that the clear password button is displayed") composeTestRule.onNodeWithContentDescription(getStringResource(R.string.saved_logins_clear_password)).assertIsDisplayed() Log.i(TAG, "verifyPasswordClearButton: Verified that the clear password button is displayed") } - fun verifyHostnameClearButton(composeTestRule: ComposeTestRule) { + fun verifyHostnameClearButton() { Log.i(TAG, "verifyHostnameClearButton: Trying to verify the clear host name button is displayed") composeTestRule.onNodeWithContentDescription(getStringResource(R.string.saved_login_clear_hostname), useUnmergedTree = true) .assertIsDisplayed() Log.i(TAG, "verifyHostnameClearButton: Verified that the clear host name button is displayed") } - fun clickSearchLoginButton(composeTestRule: ComposeTestRule) { + fun clickSearchLoginButton() { Log.i(TAG, "clickSearchLoginButton: Trying to click the search logins button") composeTestRule.onNodeWithContentDescription(getStringResource(R.string.preferences_passwords_saved_logins_search_2)).performClick() Log.i(TAG, "clickSearchLoginButton: Clicked the search logins button") } - fun clickSortPasswordsButton(composeTestRule: ComposeTestRule) { + fun clickSortPasswordsButton() { Log.i(TAG, "clickSortPasswordsButton: Trying to click the \"Saved logins\" sort button") composeTestRule.onNodeWithContentDescription(getStringResource(R.string.saved_logins_menu_dropdown_chevron_icon_content_description_2)).performClick() Log.i(TAG, "clickSortPasswordsButton: Clicked the \"Saved logins\" sort button") } - fun verifyLoginsSortingOptions(composeTestRule: ComposeTestRule) { + fun verifyLoginsSortingOptions() { Log.i(TAG, "clickSortPasswordsButton: Trying to verify that the logins sorting options are displayed") composeTestRule.onNodeWithText(getStringResource(R.string.saved_logins_sort_strategy_alphabetically)).assertIsDisplayed() composeTestRule.onNodeWithText(getStringResource(R.string.saved_logins_sort_strategy_last_used)).assertIsDisplayed() Log.i(TAG, "clickSortPasswordsButton: Verified that the logins sorting options are displayed") } - fun clickLastUsedSortingOption(composeTestRule: ComposeTestRule) { + fun clickLastUsedSortingOption() { Log.i(TAG, "clickLastUsedSortingOption: Trying to click the \"Last used\" sorting option") composeTestRule.onNodeWithText(getStringResource(R.string.saved_logins_sort_strategy_last_used)).performClick() Log.i(TAG, "clickLastUsedSortingOption: Clicked the \"Last used\" sorting option") @@ -187,7 +187,7 @@ class SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot { ) } - fun searchLogin(composeTestRule: ComposeTestRule, searchTerm: String) { + fun searchLogin(searchTerm: String) { Log.i(TAG, "searchLogin: Trying to set the search bar text to: $searchTerm") composeTestRule.onNodeWithTag(SAVED_LOGINS_PASSWORD_SEARCH_FIELD).performClick() composeTestRule.onNodeWithTag(SAVED_LOGINS_PASSWORD_SEARCH_FIELD).clearAndSetText(searchTerm) @@ -197,13 +197,13 @@ class SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot { fun verifySavedLoginsSectionUsername(username: String) = mDevice.waitNotNull(Until.findObjects(By.text(username))) - fun verifyLoginItemUsername(composeTestRule: ComposeTestRule, loginUserName: String) = { + fun verifyLoginItemUsername(loginUserName: String) = { Log.i(TAG, "verifyLoginItemUsername: Trying to verify that the login item with user name: $loginUserName is displayed") composeTestRule.onNodeWithText(loginUserName, useUnmergedTree = true).assertIsDisplayed() Log.i(TAG, "verifyLoginItemUsername: Verified that the login item with user name: $loginUserName is displayed") } - fun verifyNotSavedLoginFromPrompt(composeTestRule: ComposeTestRule) { + fun verifyNotSavedLoginFromPrompt() { Log.i(TAG, "verifyNotSavedLoginFromPrompt: Trying to verify that \"test@example.com\" does not exist in the saved logins list") composeTestRule.onNodeWithText("test@example.com", useUnmergedTree = true).assertIsNotDisplayed() Log.i(TAG, "verifyNotSavedLoginFromPrompt: Verified that \"test@example.com\" does not exist in the saved logins list") @@ -216,21 +216,21 @@ class SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot { Log.i(TAG, "verifyLocalhostExceptionAdded: Verified that \"localhost\" is visible in the exceptions list") } - fun viewSavedLoginDetails(composeTestRule: ComposeTestRule, loginDetail: String) { + fun viewSavedLoginDetails(loginDetail: String) { waitForAppWindowToBeUpdated() Log.i(TAG, "viewSavedLoginDetails: Trying to click $loginDetail saved login") composeTestRule.onNodeWithText(loginDetail, useUnmergedTree = true).performClick() Log.i(TAG, "viewSavedLoginDetails: Clicked $loginDetail saved login") } - fun clickThreeDotButton(composeTestRule: ComposeTestRule) { + fun clickThreeDotButton() { Log.i(TAG, "clickThreeDotButton: Trying to click the three dot button") composeTestRule.onNodeWithContentDescription(getStringResource(R.string.login_detail_menu_button_content_description)) .performClick() Log.i(TAG, "clickThreeDotButton: Clicked the three dot button") } - fun clickEditLoginButton(composeTestRule: ComposeTestRule) { + fun clickEditLoginButton() { Log.i(TAG, "clickEditLoginButton: Trying to click the \"Edit\" button") composeTestRule.onNodeWithText( getStringResource(R.string.login_detail_menu_edit_button), @@ -239,7 +239,7 @@ class SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot { Log.i(TAG, "clickEditLoginButton: Clicked the \"Edit\" button") } - fun clickDeleteLoginButton(composeTestRule: ComposeTestRule) { + fun clickDeleteLoginButton() { Log.i(TAG, "clickDeleteLoginButton: Trying to click the \"Delete\" button") composeTestRule.onNodeWithText( getStringResource(R.string.login_detail_menu_delete_button), @@ -248,7 +248,7 @@ class SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot { Log.i(TAG, "clickDeleteLoginButton: Clicked the \"Delete\" button") } - fun verifyLoginDeletionPrompt(composeTestRule: ComposeTestRule) { + fun verifyLoginDeletionPrompt() { Log.i(TAG, "clickDeleteLoginButton: Trying to verify that the login deletion prompt is displayed") composeTestRule.onNodeWithText( getStringResource(R.string.login_deletion_confirmation_2), @@ -257,70 +257,70 @@ class SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot { Log.i(TAG, "clickDeleteLoginButton: Verified that the login deletion prompt is displayed") } - fun clickConfirmDeleteLogin(composeTestRule: ComposeTestRule) { + fun clickConfirmDeleteLogin() { Log.i(TAG, "clickConfirmDeleteLogin: Trying to click the \"Delete\" dialog button") composeTestRule.onNodeWithText(getStringResource(R.string.dialog_delete_positive)) .performClick() Log.i(TAG, "clickConfirmDeleteLogin: Clicked the \"Delete\" dialog button") } - fun clickCancelDeleteLogin(composeTestRule: ComposeTestRule) { + fun clickCancelDeleteLogin() { Log.i(TAG, "clickCancelDeleteLogin: Trying to click the \"Cancel\" dialog button") composeTestRule.onNodeWithText(getStringResource(R.string.dialog_delete_negative)) .performClick() Log.i(TAG, "clickCancelDeleteLogin: Clicked the \"Cancel\" dialog button") } - fun setNewUserNameWhileEditingALogin(composeTestRule: ComposeTestRule, userName: String) { + fun setNewUserNameWhileEditingALogin(userName: String) { Log.i(TAG, "setNewUserNameWhileEditingALogin: Trying to set \"Username\" text box to: $userName") composeTestRule.onNodeWithTag(EDIT_LOGIN_USERNAME_TEXT_FIELD).performClick() composeTestRule.onNodeWithTag(EDIT_LOGIN_USERNAME_TEXT_FIELD).clearAndSetText(userName) Log.i(TAG, "setNewUserNameWhileEditingALogin: \"Username\" text box was set to: $userName") } - fun setUserNameWhileAddingANewLogin(composeTestRule: ComposeTestRule, userName: String) { + fun setUserNameWhileAddingANewLogin(userName: String) { Log.i(TAG, "setUserNameWhileAddingANewLogin: Trying to set \"Username\" text box to: $userName") composeTestRule.onNodeWithTag(ADD_LOGIN_USER_NAME_TEXT_FIELD).performClick() composeTestRule.onNodeWithTag(ADD_LOGIN_USER_NAME_TEXT_FIELD).clearAndSetText(userName) Log.i(TAG, "setUserNameWhileAddingANewLogin: \"Username\" text box was set to: $userName") } - fun clickClearUserNameButton(composeTestRule: ComposeTestRule) { + fun clickClearUserNameButton() { Log.i(TAG, "clickClearUserNameButton: Trying to click the clear username button") composeTestRule.onNodeWithContentDescription(getStringResource(R.string.saved_login_clear_username)) .performClick() Log.i(TAG, "clickClearUserNameButton: Clicked the clear username button") } - fun setNewPasswordWhileEditingALogin(composeTestRule: ComposeTestRule, password: String) { + fun setNewPasswordWhileEditingALogin(password: String) { Log.i(TAG, "setNewPasswordWhileEditingALogin: Trying to set \"Password\" text box to: $password") composeTestRule.onNodeWithTag(EDIT_LOGIN_PASSWORD_TEXT_FIELD).performClick() composeTestRule.onNodeWithTag(EDIT_LOGIN_PASSWORD_TEXT_FIELD).clearAndSetText(password) Log.i(TAG, "setNewPasswordWhileEditingALogin: \"Password\" text box was set to: $password") } - fun setNewPasswordWhileAddingANewLogin(composeTestRule: ComposeTestRule, password: String) { + fun setNewPasswordWhileAddingANewLogin(password: String) { Log.i(TAG, "setNewPasswordWhileAddingANewLogin: Trying to set \"Password\" text box to: $password") composeTestRule.onNodeWithTag(ADD_LOGIN_PASSWORD_TEXT_FIELD).performClick() composeTestRule.onNodeWithTag(ADD_LOGIN_PASSWORD_TEXT_FIELD).clearAndSetText(password) Log.i(TAG, "setNewPasswordWhileAddingANewLogin: \"Password\" text box was set to: $password") } - fun clickClearPasswordButton(composeTestRule: ComposeTestRule) { + fun clickClearPasswordButton() { Log.i(TAG, "clickClearPasswordButton: Trying to click the clear password button") composeTestRule.onNodeWithContentDescription(getStringResource(R.string.saved_logins_clear_password)) .performClick() Log.i(TAG, "clickClearPasswordButton: Clicked the clear password button") } - fun saveEditedLogin(composeTestRule: ComposeTestRule) { + fun saveEditedLogin() { Log.i(TAG, "saveEditedLogin: Trying to click the toolbar save button") composeTestRule.onNodeWithContentDescription(getStringResource(R.string.edit_login_button_content_description)).performClick() Log.i(TAG, "saveEditedLogin: Clicked the toolbar save button") waitForAppWindowToBeUpdated() } - fun saveNewLogin(composeTestRule: ComposeTestRule) { + fun saveNewLogin() { Log.i(TAG, "saveNewLogin: Trying to click the toolbar save button") composeTestRule.onNodeWithContentDescription(getStringResource(R.string.add_login_save_new_login_button_content_description)) .performClick() @@ -328,7 +328,7 @@ class SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot { waitForAppWindowToBeUpdated() } - fun verifySaveLoginButtonIsEnabled(composeTestRule: ComposeTestRule, isEnabled: Boolean) { + fun verifySaveLoginButtonIsEnabled(isEnabled: Boolean) { if (isEnabled) { Log.i(TAG, "verifySaveLoginButtonIsEnabled: Trying to verify that the save login button is enabled") composeTestRule.onNodeWithContentDescription(getStringResource(R.string.edit_login_button_content_description)) @@ -342,40 +342,40 @@ class SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot { } } - fun revealPassword(composeTestRule: ComposeTestRule) { + fun revealPassword() { Log.i(TAG, "revealPassword: Trying to click the reveal password button") composeTestRule.onNodeWithContentDescription(getStringResource(R.string.saved_login_reveal_password), useUnmergedTree = true) .performClick() Log.i(TAG, "revealPassword: Clicked the reveal password button") } - fun verifyPasswordSaved(composeTestRule: ComposeTestRule, password: String) { + fun verifyPasswordSaved(password: String) { Log.i(TAG, "verifyPasswordSaved: Trying to verify that the saved login password is set to: $password") composeTestRule.onNodeWithTag(LOGIN_DETAILS_PASSWORD_TEXT_FIELD).assert(hasText(password)) Log.i(TAG, "verifyPasswordSaved: Verified that the saved login password is set to: $password") } - fun verifyPasswordWhileEditingALogin(composeTestRule: ComposeTestRule, password: String) { + fun verifyPasswordWhileEditingALogin(password: String) { Log.i(TAG, "verifyPasswordWhileEditingALogin: Trying to verify that the saved login password while editing a login is set to: $password") composeTestRule.onNodeWithTag(EDIT_LOGIN_PASSWORD_TEXT_FIELD).assert(hasText(password)) Log.i(TAG, "verifyPasswordWhileEditingALogin: Verified that the saved login password while editing a login is set to: $password") } - fun verifyUserNameRequiredErrorMessage(composeTestRule: ComposeTestRule) { + fun verifyUserNameRequiredErrorMessage() { Log.i(TAG, "verifyUserNameRequiredErrorMessage: Trying to verify the user name required error message is displayed") composeTestRule.onNodeWithText(getStringResource(R.string.saved_login_username_required_2)) .assertIsDisplayed() Log.i(TAG, "verifyUserNameRequiredErrorMessage: Verified the user name required error message is displayed") } - fun verifyPasswordRequiredErrorMessage(composeTestRule: ComposeTestRule) { + fun verifyPasswordRequiredErrorMessage() { Log.i(TAG, "verifyUserNameRequiredErrorMessage: Trying to verify the password required error message is displayed") composeTestRule.onNodeWithText(getStringResource(R.string.saved_login_password_required_2)) .assertIsDisplayed() Log.i(TAG, "verifyUserNameRequiredErrorMessage: Verified the password required error message is displayed") } - fun clickGoBackButton(composeTestRule: ComposeTestRule) { + fun clickGoBackButton() { Log.i(TAG, "clickGoBackButton: Trying to click the go back button") composeTestRule.onNodeWithContentDescription(getStringResource(R.string.edit_login_navigate_back_button_content_description)) .performClick() @@ -383,39 +383,39 @@ class SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot { waitForAppWindowToBeUpdated() } - fun clickCopyUserNameButton(composeTestRule: ComposeTestRule) { + fun clickCopyUserNameButton() { Log.i(TAG, "clickCopyUserNameButton: Trying to click the copy username button") composeTestRule.onNodeWithContentDescription(getStringResource(R.string.saved_login_copy_username)).performClick() Log.i(TAG, "clickCopyUserNameButton:Clicked the copy username button") } - fun clickCopyPasswordButton(composeTestRule: ComposeTestRule) { + fun clickCopyPasswordButton() { Log.i(TAG, "clickCopyPasswordButton: Trying to click the copy password button") composeTestRule.onNodeWithContentDescription(getStringResource(R.string.saved_logins_copy_password)).performClick() Log.i(TAG, "clickCopyPasswordButton:Clicked the copy password button") } - fun verifyCopyUserNameLoginCredentialsSnackBar(composeTestRule: ComposeTestRule) { + fun verifyCopyUserNameLoginCredentialsSnackBar() { Log.i(TAG, "verifyCopyUserNameLoginCredentialsSnackBar: Trying to verify that the \"Username copied to clipboard\" snackbar is displayed") composeTestRule.onNodeWithText(getStringResource(R.string.logins_username_copied), useUnmergedTree = true).assertIsDisplayed() Log.i(TAG, "verifyCopyUserNameLoginCredentialsSnackBar: Verified that the \"Username copied to clipboard\" snackbar is displayed") } - fun verifyCopyPasswordLoginCredentialsSnackBar(composeTestRule: ComposeTestRule) { + fun verifyCopyPasswordLoginCredentialsSnackBar() { Log.i(TAG, "verifyCopyPasswordLoginCredentialsSnackBar: Trying to verify that the \"Password copied to clipboard\" snackbar is displayed") composeTestRule.onNodeWithText(getStringResource(R.string.logins_password_copied), useUnmergedTree = true).assertIsDisplayed() Log.i(TAG, "verifyCopyPasswordLoginCredentialsSnackBar: Verified that the \"Password copied to clipboard\" snackbar is displayed") } @OptIn(ExperimentalTestApi::class) - fun waitUntilCopyLoginCredentialsSnackBarIsGone(composeTestRule: ComposeTestRule) { + fun waitUntilCopyLoginCredentialsSnackBarIsGone() { Log.i(TAG, "waitUntilCopyLoginCredentialsSnackBarIsGone: Waiting for $waitingTime until the snackbar does not exist") composeTestRule.waitUntilDoesNotExist(hasTestTag(SNACKBAR_TEST_TAG), waitingTime) Log.i(TAG, "waitUntilCopyLoginCredentialsSnackBarIsGone: Waited for $waitingTime until the snackbar does not exist") } - class Transition { - fun goBack(composeTestRule: ComposeTestRule, interact: SettingsSubMenuLoginsAndPasswordRobot.() -> Unit): SettingsSubMenuLoginsAndPasswordRobot.Transition { + class Transition(private val composeTestRule: ComposeTestRule) { + fun goBack(interact: SettingsSubMenuLoginsAndPasswordRobot.() -> Unit): SettingsSubMenuLoginsAndPasswordRobot.Transition { Log.i(TAG, "goBack: Trying to click the navigate up button") composeTestRule.onNodeWithContentDescription(getStringResource(R.string.logins_navigate_back_button_content_description)) .performClick() @@ -427,21 +427,22 @@ class SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot { fun goBackToHomeScreen(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition { Log.i(TAG, "goBackToHomeScreen: Trying to click the navigate up button") - goBackButton().perform(ViewActions.click()) + composeTestRule.onNodeWithContentDescription(getStringResource(R.string.logins_navigate_back_button_content_description)) + .performClick() Log.i(TAG, "goBackToHomeScreen: Clicked the navigate up button") - HomeScreenRobot().interact() - return HomeScreenRobot.Transition() + HomeScreenRobot(composeTestRule).interact() + return HomeScreenRobot.Transition(composeTestRule) } - fun goToSavedWebsite(composeTestRule: ComposeTestRule, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { + fun goToSavedWebsite(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { Log.i(TAG, "goToSavedWebsite: Trying to click the open web site button") composeTestRule.onNodeWithContentDescription(getStringResource(R.string.saved_login_open_site)) .performClick() Log.i(TAG, "goToSavedWebsite: Clicked the open web site button") - BrowserRobot().interact() - return BrowserRobot.Transition() + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } } } diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuPrivateBrowsingRobot.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuPrivateBrowsingRobot.kt @@ -5,6 +5,7 @@ package org.mozilla.fenix.ui.robots import android.util.Log +import androidx.compose.ui.test.junit4.ComposeTestRule import androidx.test.espresso.Espresso.onView import androidx.test.espresso.action.ViewActions import androidx.test.espresso.assertion.ViewAssertions.matches @@ -132,13 +133,13 @@ class SettingsSubMenuPrivateBrowsingRobot { return SettingsRobot.Transition() } - fun openPrivateBrowsingShortcut(interact: SearchRobot.() -> Unit): SearchRobot.Transition { + fun openPrivateBrowsingShortcut(composeTestRule: ComposeTestRule, interact: SearchRobot.() -> Unit): SearchRobot.Transition { Log.i(TAG, "openPrivateBrowsingShortcut: Trying to click the \"Private $appName\" shortcut icon") privateBrowsingShortcutIcon().click() Log.i(TAG, "openPrivateBrowsingShortcut: Clicked the \"Private $appName\" shortcut icon") - SearchRobot().interact() - return SearchRobot.Transition() + SearchRobot(composeTestRule).interact() + return SearchRobot.Transition(composeTestRule) } } } diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuSearchRobot.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuSearchRobot.kt @@ -514,22 +514,22 @@ class SettingsSubMenuSearchRobot { return SettingsSubMenuSearchRobot.Transition() } - fun clickCustomSearchStringLearnMoreLink(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { + fun clickCustomSearchStringLearnMoreLink(composeTestRule: ComposeTestRule, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { Log.i(TAG, "clickCustomSearchStringLearnMoreLink: Trying to click the \"Search string URL\" learn more link") onView(withId(R.id.custom_search_engines_learn_more)).click() Log.i(TAG, "clickCustomSearchStringLearnMoreLink: Clicked the \"Search string URL\" learn more link") - BrowserRobot().interact() - return BrowserRobot.Transition() + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } - fun clickCustomSearchSuggestionsLearnMoreLink(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { + fun clickCustomSearchSuggestionsLearnMoreLink(composeTestRule: ComposeTestRule, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { Log.i(TAG, "clickCustomSearchSuggestionsLearnMoreLink: Trying to click the \"Search suggestions API\" learn more link") onView(withId(R.id.custom_search_suggestions_learn_more)).click() Log.i(TAG, "clickCustomSearchSuggestionsLearnMoreLink: Clicked the \"Search suggestions API\" learn more link") - BrowserRobot().interact() - return BrowserRobot.Transition() + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } } } diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ShareOverlayRobot.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ShareOverlayRobot.kt @@ -7,6 +7,7 @@ package org.mozilla.fenix.ui.robots import android.content.Intent import android.net.Uri import android.util.Log +import androidx.compose.ui.test.junit4.ComposeTestRule import androidx.test.espresso.Espresso.onView import androidx.test.espresso.assertion.ViewAssertions.matches import androidx.test.espresso.intent.Intents @@ -185,23 +186,23 @@ class ShareOverlayRobot { } class Transition { - fun clickSaveAsPDF(interact: DownloadRobot.() -> Unit): DownloadRobot.Transition { + fun clickSaveAsPDF(composeTestRule: ComposeTestRule, interact: DownloadRobot.() -> Unit): DownloadRobot.Transition { Log.i(TAG, "clickSaveAsPDF: Trying to click the \"SAVE AS PDF\" share overlay button") itemContainingText("Save as PDF").click() Log.i(TAG, "clickSaveAsPDF: Clicked the \"SAVE AS PDF\" share overlay button") - DownloadRobot().interact() - return DownloadRobot.Transition() + DownloadRobot(composeTestRule).interact() + return DownloadRobot.Transition(composeTestRule) } - fun clickPrintButton(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { + fun clickPrintButton(composeTestRule: ComposeTestRule, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { itemWithText("Print").waitForExists(waitingTime) Log.i(TAG, "clickPrintButton: Trying to click the \"Print\" share overlay button") itemWithText("Print").click() Log.i(TAG, "clickPrintButton: Clicked the \"Print\" share overlay button") - BrowserRobot().interact() - return BrowserRobot.Transition() + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } } } diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SitePermissionsRobot.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SitePermissionsRobot.kt @@ -5,13 +5,13 @@ package org.mozilla.fenix.ui.robots import android.util.Log +import androidx.compose.ui.test.junit4.ComposeTestRule import androidx.test.espresso.Espresso.onView import androidx.test.espresso.assertion.ViewAssertions.matches import androidx.test.espresso.matcher.ViewMatchers import androidx.test.espresso.matcher.ViewMatchers.isDisplayed import androidx.test.espresso.matcher.ViewMatchers.withId import androidx.test.uiautomator.UiSelector -import org.mozilla.fenix.R import org.mozilla.fenix.helpers.Constants.TAG import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource import org.mozilla.fenix.helpers.MatcherHelper.assertItemTextEquals @@ -24,7 +24,7 @@ import org.mozilla.fenix.helpers.TestHelper.packageName import org.mozilla.fenix.helpers.click import mozilla.components.feature.sitepermissions.R as sitepermissionsR -class SitePermissionsRobot { +class SitePermissionsRobot(private val composeTestRule: ComposeTestRule) { fun verifyMicrophonePermissionPrompt(host: String) { try { assertUIObjectExists(itemWithText("Allow $host to use your microphone?")) @@ -32,9 +32,9 @@ class SitePermissionsRobot { assertItemTextEquals(allowPagePermissionButton(), expectedText = "Allow") } catch (e: AssertionError) { Log.i(TAG, "verifyMicrophonePermissionPrompt: AssertionError caught, executing fallback methods") - browserScreen { + browserScreen(composeTestRule) { }.openThreeDotMenu { - }.refreshPage { + }.clickRefreshButton { }.clickStartMicrophoneButton { assertUIObjectExists(itemWithText("Allow $host to use your microphone?")) assertItemTextEquals(denyPagePermissionButton(), expectedText = "Don’t allow") @@ -50,9 +50,9 @@ class SitePermissionsRobot { assertItemTextEquals(allowPagePermissionButton(), expectedText = "Allow") } catch (e: AssertionError) { Log.i(TAG, "verifyCameraPermissionPrompt: AssertionError caught, executing fallback methods") - browserScreen { + browserScreen(composeTestRule) { }.openThreeDotMenu { - }.refreshPage { + }.clickRefreshButton { }.clickStartCameraButton { assertUIObjectExists(itemWithText("Allow $host to use your camera?")) assertItemTextEquals(denyPagePermissionButton(), expectedText = "Don’t allow") @@ -74,9 +74,9 @@ class SitePermissionsRobot { assertItemTextEquals(allowPagePermissionButton(), expectedText = "Allow") } catch (e: AssertionError) { Log.i(TAG, "verifyLocationPermissionPrompt: AssertionError caught, executing fallback methods") - browserScreen { + browserScreen(composeTestRule) { }.openThreeDotMenu { - }.refreshPage { + }.clickRefreshButton { }.clickGetLocationButton { assertUIObjectExists(itemWithText("Allow $host to use your location?")) assertItemTextEquals(denyPagePermissionButton(), expectedText = "Don’t allow") @@ -99,9 +99,9 @@ class SitePermissionsRobot { assertItemTextEquals(allowPagePermissionButton(), expectedText = "Always") } catch (e: AssertionError) { Log.i(TAG, "verifyNotificationsPermissionPrompt: AssertionError caught, executing fallback methods") - browserScreen { + browserScreen(composeTestRule) { }.openThreeDotMenu { - }.refreshPage { + }.clickRefreshButton { }.clickOpenNotificationButton { assertUIObjectExists(itemWithText("Allow $host to send notifications?")) assertItemTextEquals(denyPagePermissionButton(), expectedText = "Never") @@ -122,9 +122,9 @@ class SitePermissionsRobot { assertItemTextEquals(allowPagePermissionButton(), expectedText = "Allow") } catch (e: AssertionError) { Log.i(TAG, "verifyPersistentStoragePermissionPrompt: AssertionError caught, executing fallback methods") - browserScreen { + browserScreen(composeTestRule) { }.openThreeDotMenu { - }.refreshPage { + }.clickRefreshButton { }.clickRequestPersistentStorageAccessButton { assertUIObjectExists(itemWithText("Allow $host to store data in persistent storage?")) assertItemTextEquals(denyPagePermissionButton(), expectedText = "Don’t allow") @@ -140,9 +140,9 @@ class SitePermissionsRobot { assertItemTextEquals(allowPagePermissionButton(), expectedText = "Allow") } catch (e: AssertionError) { Log.i(TAG, "verifyDRMContentPermissionPrompt: AssertionError caught, executing fallback methods") - browserScreen { + browserScreen(composeTestRule) { }.openThreeDotMenu { - }.refreshPage { + }.clickRefreshButton { }.clickRequestDRMControlledContentAccessButton { assertUIObjectExists(itemWithText("Allow $host to play DRM-controlled content?")) assertItemTextEquals(denyPagePermissionButton(), expectedText = "Don’t allow") @@ -185,7 +185,7 @@ class SitePermissionsRobot { Log.i(TAG, "selectRememberPermissionDecision: Clicked the \"Remember decision for this site\" check box") } - class Transition { + class Transition(private val composeTestRule: ComposeTestRule) { fun clickLearnMore(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { Log.i(TAG, "clickLearnMore: Waiting for $waitingTime ms for the Learn more link to exist") @@ -194,10 +194,9 @@ class SitePermissionsRobot { Log.i(TAG, "clickLearnMore: Trying to click the Learn more link") learnMoreText().click() Log.i(TAG, "clickLearnMore: Clicked the Learn more link") - BrowserRobot().interact() - return BrowserRobot.Transition() + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } - fun clickPagePermissionButton(allow: Boolean, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { if (allow) { Log.i(TAG, "clickPagePermissionButton: Waiting for $waitingTime ms for the \"Allow\" prompt button to exist") @@ -233,8 +232,8 @@ class SitePermissionsRobot { Log.i(TAG, "clickPagePermissionButton: Waited for $waitingTime ms for the \"Don’t allow\" prompt button to be gone") } - BrowserRobot().interact() - return BrowserRobot.Transition() + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } } } diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SiteSecurityRobot.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SiteSecurityRobot.kt @@ -7,13 +7,18 @@ package org.mozilla.fenix.ui.robots import android.util.Log +import androidx.compose.ui.test.junit4.ComposeTestRule import androidx.test.espresso.Espresso.onView import androidx.test.espresso.assertion.ViewAssertions.matches import androidx.test.espresso.matcher.RootMatchers +import androidx.test.espresso.matcher.ViewMatchers import androidx.test.espresso.matcher.ViewMatchers.isDisplayed import androidx.test.espresso.matcher.ViewMatchers.withId +import androidx.test.uiautomator.By import androidx.test.uiautomator.UiSelector +import androidx.test.uiautomator.Until import mozilla.components.support.ktx.kotlin.tryGetHostFromUrl +import org.hamcrest.Matchers.not import org.mozilla.fenix.R import org.mozilla.fenix.helpers.Constants.TAG import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource @@ -22,6 +27,11 @@ import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime import org.mozilla.fenix.helpers.TestAssetHelper.waitingTimeShort import org.mozilla.fenix.helpers.TestHelper.mDevice import org.mozilla.fenix.helpers.TestHelper.packageName +import org.mozilla.fenix.helpers.TestHelper.waitForAppWindowToBeUpdated +import org.mozilla.fenix.helpers.click +import org.mozilla.fenix.helpers.ext.waitNotNull +import org.mozilla.fenix.helpers.isChecked +import org.mozilla.fenix.ui.robots.EnhancedTrackingProtectionRobot.Transition /** * Implementation of Robot Pattern for Site Security UI. @@ -74,7 +84,67 @@ class SiteSecurityRobot { Log.i(TAG, "verifyClearSiteDataPrompt: Verified that the \"Delete\" dialog button is displayed") } - class Transition + fun verifyETPSwitchVisibility(visible: Boolean) { + waitForAppWindowToBeUpdated() + if (visible) { + Log.i(TAG, "verifyETPSwitchVisibility: Trying to verify ETP toggle is displayed") + enhancedTrackingProtectionSwitch() + .check(matches(isDisplayed())) + Log.i(TAG, "verifyETPSwitchVisibility: Verified ETP toggle is displayed") + } else { + Log.i(TAG, "verifyETPSwitchVisibility: Trying to verify ETP toggle is not displayed") + enhancedTrackingProtectionSwitch() + .check(matches(not(isDisplayed()))) + Log.i(TAG, "verifyETPSwitchVisibility: Verified ETP toggle is not displayed") + } + } + + fun verifyEnhancedTrackingProtectionSheetStatus(status: String, state: Boolean) { + mDevice.waitNotNull(Until.findObjects(By.text("Protections are $status for this site"))) + Log.i(TAG, "verifyEnhancedTrackingProtectionSheetStatus: Trying to check ETP toggle is checked: $state") + onView(ViewMatchers.withResourceName("switch_widget")).check( + matches( + isChecked( + state, + ), + ), + ) + Log.i(TAG, "verifyEnhancedTrackingProtectionSheetStatus: Verified ETP toggle is checked: $state") + } + + class Transition { + fun closeSiteSecuritySheet(composeTestRule: ComposeTestRule, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { + // Back out of the Enhanced Tracking Protection sheet + Log.i(TAG, "closeSiteSecuritySheet: Trying to click device back button") + mDevice.pressBack() + Log.i(TAG, "closeSiteSecuritySheet: Clicked device back button") + + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) + } + + fun toggleEnhancedTrackingProtectionFromSheet(interact: SiteSecurityRobot.() -> Unit): SiteSecurityRobot.Transition { + waitForAppWindowToBeUpdated() + Log.i(TAG, "toggleEnhancedTrackingProtectionFromSheet: Trying to click ETP switch") + enhancedTrackingProtectionSwitch().click() + Log.i(TAG, "toggleEnhancedTrackingProtectionFromSheet: Clicked ETP switch") + + SiteSecurityRobot().interact() + return Transition() + } + + fun openDetails(interact: EnhancedTrackingProtectionRobot.() -> Unit): EnhancedTrackingProtectionRobot.Transition { + Log.i(TAG, "openDetails: Waiting for $waitingTime ms for ETP sheet \"Details\" button to exist") + openEnhancedTrackingProtectionDetails().waitForExists(waitingTime) + Log.i(TAG, "openDetails: Waited for $waitingTime ms for ETP sheet \"Details\" button to exist") + Log.i(TAG, "openDetails: Trying to click ETP sheet \"Details\" button") + openEnhancedTrackingProtectionDetails().click() + Log.i(TAG, "openDetails: Clicked ETP sheet \"Details\" button") + + EnhancedTrackingProtectionRobot().interact() + return EnhancedTrackingProtectionRobot.Transition() + } + } } private fun quickActionSheet() = @@ -170,3 +240,9 @@ private fun clearSiteDataPrompt(url: String) = private fun cancelClearSiteDataButton() = onView(withId(android.R.id.button2)).inRoot(RootMatchers.isDialog()) private fun deleteSiteDataButton() = onView(withId(android.R.id.button1)).inRoot(RootMatchers.isDialog()) + +private fun enhancedTrackingProtectionSwitch() = + onView(ViewMatchers.withResourceName("switch_widget")) + +private fun openEnhancedTrackingProtectionDetails() = + mDevice.findObject(UiSelector().resourceId("$packageName:id/trackingProtectionDetails")) diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SyncSignInRobot.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SyncSignInRobot.kt @@ -5,6 +5,7 @@ package org.mozilla.fenix.ui.robots import android.util.Log +import androidx.compose.ui.test.junit4.ComposeTestRule import androidx.test.espresso.Espresso.onView import androidx.test.espresso.matcher.ViewMatchers.withContentDescription import androidx.test.uiautomator.UiSelector @@ -32,14 +33,14 @@ class SyncSignInRobot { ) } - class Transition { + class Transition(private val composeTestRule: ComposeTestRule) { fun goBack(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { Log.i(TAG, "goBack: Trying to click the navigate up button") goBackButton().click() Log.i(TAG, "goBack: Clicked the navigate up button") - BrowserRobot().interact() - return BrowserRobot.Transition() + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } fun goBackToHomeScreen(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition { @@ -47,8 +48,8 @@ class SyncSignInRobot { goBackButton().click() Log.i(TAG, "goBackToHomeScreen: Clicked the navigate up button") - HomeScreenRobot().interact() - return HomeScreenRobot.Transition() + HomeScreenRobot(composeTestRule).interact() + return HomeScreenRobot.Transition(composeTestRule) } } } diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/TabDrawerRobot.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/TabDrawerRobot.kt @@ -430,8 +430,8 @@ class TabDrawerRobot(private val composeTestRule: ComposeTestRule) { Log.i(TAG, "openNewTab: Trying to click the new tab FAB button") composeTestRule.tabsTrayFab().performClick() Log.i(TAG, "openNewTab: Clicked the new tab FAB button") - SearchRobot().interact() - return SearchRobot.Transition() + SearchRobot(composeTestRule).interact() + return SearchRobot.Transition(composeTestRule) } fun toggleToNormalTabs(interact: TabDrawerRobot.() -> Unit): Transition { @@ -464,7 +464,7 @@ class TabDrawerRobot(private val composeTestRule: ComposeTestRule) { .clickAndWaitForNewWindow(waitingTimeShort) Log.i(TAG, "clickSignInToSyncButton: Clicked the sign in to sync button and waited for $waitingTimeShort ms for a new window") SyncSignInRobot().interact() - return SyncSignInRobot.Transition() + return SyncSignInRobot.Transition(composeTestRule) } fun openThreeDotMenu(interact: TabDrawerRobot.() -> Unit): Transition { @@ -489,8 +489,8 @@ class TabDrawerRobot(private val composeTestRule: ComposeTestRule) { .performClick() Log.i(TAG, "closeAllTabs: Clicked the \"$confirmButtonText\" dialog button") - HomeScreenRobot().interact() - return HomeScreenRobot.Transition() + HomeScreenRobot(composeTestRule).interact() + return HomeScreenRobot.Transition(composeTestRule) } fun openTab(title: String, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { @@ -501,8 +501,8 @@ class TabDrawerRobot(private val composeTestRule: ComposeTestRule) { composeTestRule.tabItem(title).performClick() Log.i(TAG, "openTab: Clicked tab with title: $title") - BrowserRobot().interact() - return BrowserRobot.Transition() + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } fun openPrivateTab(position: Int, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { @@ -512,8 +512,8 @@ class TabDrawerRobot(private val composeTestRule: ComposeTestRule) { .performClick() Log.i(TAG, "openPrivateTab: Clicked private tab at position: ${position + 1}") - BrowserRobot().interact() - return BrowserRobot.Transition() + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } fun openNormalTab(position: Int, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { @@ -523,8 +523,8 @@ class TabDrawerRobot(private val composeTestRule: ComposeTestRule) { .performClick() Log.i(TAG, "openNormalTab: Clicked tab at position: ${position + 1}") - BrowserRobot().interact() - return BrowserRobot.Transition() + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } fun clickTopBar(interact: TabDrawerRobot.() -> Unit): Transition { @@ -548,8 +548,8 @@ class TabDrawerRobot(private val composeTestRule: ComposeTestRule) { Log.i(TAG, "closeTabDrawer: Closed the tabs tray by clicking the handle") } - BrowserRobot().interact() - return BrowserRobot.Transition() + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } fun clickSaveCollection(interact: CollectionRobot.() -> Unit): CollectionRobot.Transition { @@ -557,8 +557,8 @@ class TabDrawerRobot(private val composeTestRule: ComposeTestRule) { composeTestRule.collectionsButton().performClick() Log.i(TAG, "clickSaveCollection: Clicked collections button") - CollectionRobot().interact() - return CollectionRobot.Transition() + CollectionRobot(composeTestRule).interact() + return CollectionRobot.Transition(composeTestRule) } fun clickSelectTabsButton(interact: TabDrawerRobot.() -> Unit): Transition { @@ -597,8 +597,8 @@ private fun clickCollectionsButton(composeTestRule: ComposeTestRule, interact: C composeTestRule.collectionsButton().performClick() Log.i(TAG, "clickCollectionsButton: Clicked the collections button") - CollectionRobot().interact() - return CollectionRobot.Transition() + CollectionRobot(composeTestRule).interact() + return CollectionRobot.Transition(composeTestRule) } /** diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ThreeDotMenuMainRobot.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ThreeDotMenuMainRobot.kt @@ -7,114 +7,101 @@ package org.mozilla.fenix.ui.robots import android.util.Log +import androidx.compose.ui.test.ExperimentalTestApi +import androidx.compose.ui.test.assert +import androidx.compose.ui.test.assertIsDisplayed +import androidx.compose.ui.test.assertIsEnabled +import androidx.compose.ui.test.assertIsNotDisplayed +import androidx.compose.ui.test.assertIsNotEnabled +import androidx.compose.ui.test.hasContentDescription +import androidx.compose.ui.test.hasTestTag import androidx.compose.ui.test.junit4.ComposeTestRule -import androidx.recyclerview.widget.RecyclerView +import androidx.compose.ui.test.onNodeWithContentDescription +import androidx.compose.ui.test.onNodeWithTag +import androidx.compose.ui.test.onNodeWithText +import androidx.compose.ui.test.performClick import androidx.test.espresso.Espresso.onView -import androidx.test.espresso.action.ViewActions.swipeDown import androidx.test.espresso.action.ViewActions.swipeUp import androidx.test.espresso.assertion.ViewAssertions.matches -import androidx.test.espresso.contrib.RecyclerViewActions import androidx.test.espresso.matcher.RootMatchers import androidx.test.espresso.matcher.ViewMatchers.Visibility -import androidx.test.espresso.matcher.ViewMatchers.hasDescendant import androidx.test.espresso.matcher.ViewMatchers.isDisplayed import androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility import androidx.test.espresso.matcher.ViewMatchers.withId import androidx.test.espresso.matcher.ViewMatchers.withText import androidx.test.uiautomator.By -import androidx.test.uiautomator.UiObjectNotFoundException import androidx.test.uiautomator.UiSelector -import androidx.test.uiautomator.Until import org.hamcrest.Matchers.allOf -import org.junit.Assert.assertTrue import org.mozilla.fenix.R +import org.mozilla.fenix.components.menu.MenuDialogTestTag.DESKTOP_SITE_OFF +import org.mozilla.fenix.components.menu.MenuDialogTestTag.DESKTOP_SITE_ON +import org.mozilla.fenix.components.menu.MenuDialogTestTag.EXTENSIONS +import org.mozilla.fenix.components.menu.MenuDialogTestTag.EXTENSIONS_OPTION_CHEVRON +import org.mozilla.fenix.components.menu.MenuDialogTestTag.MORE_OPTION_CHEVRON import org.mozilla.fenix.helpers.Constants.LONG_CLICK_DURATION -import org.mozilla.fenix.helpers.Constants.RETRY_COUNT import org.mozilla.fenix.helpers.Constants.TAG import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource import org.mozilla.fenix.helpers.MatcherHelper.assertUIObjectExists -import org.mozilla.fenix.helpers.MatcherHelper.checkedItemWithResIdAndText import org.mozilla.fenix.helpers.MatcherHelper.itemContainingText import org.mozilla.fenix.helpers.MatcherHelper.itemWithDescription import org.mozilla.fenix.helpers.MatcherHelper.itemWithResId -import org.mozilla.fenix.helpers.MatcherHelper.itemWithResIdAndText -import org.mozilla.fenix.helpers.MatcherHelper.itemWithText import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime -import org.mozilla.fenix.helpers.TestAssetHelper.waitingTimeLong +import org.mozilla.fenix.helpers.TestAssetHelper.waitingTimeShort +import org.mozilla.fenix.helpers.TestHelper.appName import org.mozilla.fenix.helpers.TestHelper.mDevice import org.mozilla.fenix.helpers.TestHelper.packageName +import org.mozilla.fenix.helpers.TestHelper.waitForAppWindowToBeUpdated import org.mozilla.fenix.helpers.click -import org.mozilla.fenix.helpers.ext.waitNotNull -import org.mozilla.fenix.nimbus.FxNimbus import mozilla.components.browser.menu.R as menuR /** * Implementation of Robot Pattern for the three dot (main) menu. */ @Suppress("ForbiddenComment") -class ThreeDotMenuMainRobot { +class ThreeDotMenuMainRobot(private val composeTestRule: ComposeTestRule) { fun verifyShareAllTabsButton() { Log.i(TAG, "verifyShareAllTabsButton: Trying to verify that the \"Share all tabs\" menu button is displayed") shareAllTabsButton().check(matches(isDisplayed())) Log.i(TAG, "verifyShareAllTabsButton: Verified that the \"Share all tabs\" menu button is displayed") } - fun verifySettingsButton() = assertUIObjectExists(settingsButton()) - fun verifyHistoryButton() = assertUIObjectExists(historyButton()) + fun verifyThreeDotMenuExists() { Log.i(TAG, "verifyThreeDotMenuExists: Trying to verify that the three dot menu is displayed") threeDotMenuRecyclerView().check(matches(isDisplayed())) Log.i(TAG, "verifyThreeDotMenuExists: Verified that the three dot menu is displayed") } - fun verifyAddBookmarkButton() = assertUIObjectExists(addBookmarkButton()) + fun verifyBookmarkThisPageButton() { + Log.i(TAG, "verifyEditBookmarkButton: Trying to verify that the \"Bookmark this page\" button is visible") + composeTestRule.bookmarkPageButton().assertIsDisplayed() + Log.i(TAG, "verifyEditBookmarkButton: Verified that the \"Bookmark this page\" button is visible") + } fun verifyEditBookmarkButton() { - Log.i(TAG, "verifyEditBookmarkButton: Trying to verify that the \"Edit\" button is visible") - editBookmarkButton().check(matches(withEffectiveVisibility(Visibility.VISIBLE))) - Log.i(TAG, "verifyEditBookmarkButton: Verified that the \"Edit\" button is visible") + Log.i(TAG, "clickEditBookmarkButton: Trying to verify the \"Edit bookmark\" button is displayed.") + composeTestRule.editBookmarkButton().assertIsDisplayed() + Log.i(TAG, "clickEditBookmarkButton: Verified the \"Edit bookmark\" button is displayed.") } fun verifyCloseAllTabsButton() { Log.i(TAG, "verifyCloseAllTabsButton: Trying to verify that the \"Close all tabs\" button is visible") closeAllTabsButton().check(matches(withEffectiveVisibility(Visibility.VISIBLE))) Log.i(TAG, "verifyCloseAllTabsButton: Verified that the \"Close all tabs\" button is visible") } - fun verifyReaderViewAppearance(visible: Boolean) { - var maxSwipes = 3 - if (visible) { - while (!readerViewAppearanceToggle().exists() && maxSwipes != 0) { - Log.i(TAG, "verifyReaderViewAppearance: The \"Customize reader view\" button does not exist") - Log.i(TAG, "verifyReaderViewAppearance: Trying to perform swipe up action on the three dot menu") - threeDotMenuRecyclerView().perform(swipeUp()) - Log.i(TAG, "verifyReaderViewAppearance: Performed swipe up action on the three dot menu") - maxSwipes-- - } - assertUIObjectExists(readerViewAppearanceToggle()) + fun verifyCustomizeReaderViewButton(isDisplayed: Boolean) { + waitForAppWindowToBeUpdated() + if (isDisplayed) { + Log.i(TAG, "verifyCloseAllTabsButton: Trying to verify that the \"Customize Reader view\" button is displayed") + composeTestRule.onNodeWithContentDescription(getStringResource(R.string.browser_menu_customize_reader_view_2), useUnmergedTree = true).assertIsDisplayed() + Log.i(TAG, "verifyCloseAllTabsButton: Verified that the \"Customize Reader view\" button is displayed") } else { - while (!readerViewAppearanceToggle().exists() && maxSwipes != 0) { - Log.i(TAG, "verifyReaderViewAppearance: The \"Customize reader view\" button does not exist") - Log.i(TAG, "verifyReaderViewAppearance: Trying to perform swipe up action on the three dot menu") - threeDotMenuRecyclerView().perform(swipeUp()) - Log.i(TAG, "verifyReaderViewAppearance: Performed swipe up action on the three dot menu") - maxSwipes-- - } - assertUIObjectExists(readerViewAppearanceToggle(), exists = false) + Log.i(TAG, "verifyCloseAllTabsButton: Trying to verify that the \"Customize Reader view\" button is not displayed") + composeTestRule.onNodeWithContentDescription(getStringResource(R.string.browser_menu_customize_reader_view_2), useUnmergedTree = true).assertIsNotDisplayed() + Log.i(TAG, "verifyCloseAllTabsButton: Verified that the \"Customize Reader view\" button is not displayed") } } fun verifyQuitButtonExists() { - expandMenuFully() - assertUIObjectExists(itemWithText("Quit")) - } - - fun expandMenuFully() { - // Need to double swipe the menu, to make some buttons. - // In case it reaches the end, the second swipe is no-op. - expandMenu() - expandMenu() - } - - fun expandMenu() { - Log.i(TAG, "expandMenu: Trying to perform swipe up action on the three dot menu") - onView(withId(menuR.id.mozac_browser_menu_menuView)).perform(swipeUp()) - Log.i(TAG, "expandMenu: Performed swipe up action on the three dot menu") + Log.i(TAG, "verifyShareTabButton: Trying to verify that the \"Quit $appName\" button is visible") + composeTestRule.onNodeWithContentDescription(getStringResource(R.string.browser_menu_delete_browsing_data_on_quit, appName)).assertIsDisplayed() + Log.i(TAG, "verifyShareTabButton: Verified that the \"Quit $appName\" button is visible") } fun verifyShareTabButton() { @@ -128,18 +115,10 @@ class ThreeDotMenuMainRobot { Log.i(TAG, "verifySelectTabs: Verified that the \"Select tabs\" button is visible") } - fun verifyFindInPageButton() = assertUIObjectExists(findInPageButton()) - fun verifyAddToShortcutsButton(shouldExist: Boolean) = - assertUIObjectExists(addToShortcutsButton(), exists = shouldExist) fun verifyRemoveFromShortcutsButton() { - Log.i(TAG, "verifyRemoveFromShortcutsButton: Trying to perform scroll action to the \"Settings\" button") - onView(withId(menuR.id.mozac_browser_menu_recyclerView)) - .perform( - RecyclerViewActions.scrollTo<RecyclerView.ViewHolder>( - hasDescendant(withText(R.string.browser_menu_settings)), - ), - ).check(matches(withEffectiveVisibility(Visibility.VISIBLE))) - Log.i(TAG, "verifyRemoveFromShortcutsButton: Performed scroll action to the \"Settings\" button") + Log.i(TAG, "clickRemoveFromShortcutsButton: Trying to verify that the \"Remove from shortcuts\" button is displayed.") + composeTestRule.removeFromShortcutsButton().assertIsDisplayed() + Log.i(TAG, "clickRemoveFromShortcutsButton: Clicked the \"Remove from shortcuts\" button is displayed.") } fun verifyShareTabsOverlay() { @@ -157,322 +136,417 @@ class ThreeDotMenuMainRobot { Log.i(TAG, "verifyShareTabsOverlay: Verified that the shared tab url is displayed") } - fun verifyDesktopSiteModeEnabled(isRequestDesktopSiteEnabled: Boolean) { - expandMenu() - assertUIObjectExists(desktopSiteToggle(isRequestDesktopSiteEnabled)) - } - - fun verifyPageThreeDotMainMenuItems(isRequestDesktopSiteEnabled: Boolean) { - expandMenu() - assertUIObjectExists( - normalBrowsingNewTabButton(), - bookmarksButton(), - addBookmarkButton(), - historyButton(), - downloadsButton(), - passwordsButton(), - extensionsButton(), - syncAndSaveDataButton(), - findInPageButton(), - translateButton(), - desktopSiteButton(), - reportSiteIssueButton(), - desktopSiteToggle(isRequestDesktopSiteEnabled), - ) - // Swipe to second part of menu - expandMenu() - assertUIObjectExists( - addToHomeScreenButton(), - addToShortcutsButton(), - saveToCollectionButton(), - settingsButton(), - ) - if (FxNimbus.features.print.value().browserPrintEnabled) { - assertUIObjectExists(printContentButton()) - } - assertUIObjectExists( - backButton(), - forwardButton(), - shareButton(), - refreshButton(), - ) - } - - fun verifyHomeThreeDotMainMenuItems() { - assertUIObjectExists( - bookmarksButton(), - historyButton(), - downloadsButton(), - passwordsButton(), - extensionsButton(), - syncAndSaveDataButton(), - helpButton(), - customizeHomeButton(), - settingsButton(), - ) - } - - 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) { - for (i in 1..RETRY_COUNT) { - Log.i(TAG, "verifyAddonAvailableInMainMenu: Started try #$i") - try { - assertUIObjectExists(itemContainingText(addonName)) - break - } catch (e: AssertionError) { - Log.i(TAG, "verifyAddonAvailableInMainMenu: AssertionError caught, executing fallback methods") - if (i == RETRY_COUNT) { - throw e - } else { - mDevice.pressBack() - browserScreen { - }.openThreeDotMenu { - openAddonsSubList() - } - } - } + fun verifySwitchToDesktopSiteButton() { + Log.i(TAG, "verifySwitchToDesktopSiteButton: Trying to verify that the \"Switch to desktop site\" button is displayed.") + composeTestRule.desktopSiteButton().assertIsDisplayed() + Log.i(TAG, "verifySwitchToDesktopSiteButton: Verified that the \"Switch to desktop site\" button is displayed.") + } + + @OptIn(ExperimentalTestApi::class) + fun verifySwitchToDesktopSiteButtonIsEnabled(isEnabled: Boolean) { + Log.i(TAG, "verifySuggestedUserName: Waiting for the \"Desktop site\" button to exist") + composeTestRule.waitUntilAtLeastOneExists(hasContentDescription(getStringResource(R.string.browser_menu_desktop_site), substring = true)) + Log.i(TAG, "verifySuggestedUserName: Waited for the \"Desktop site\" button to exist") + Log.i(TAG, "verifySwitchToDesktopSiteButtonIsEnabled: Trying to verify the Switch to Desktop Site button from the new main menu design is enabled.") + if (isEnabled) { + composeTestRule.desktopSiteButton().assertIsEnabled() + Log.i(TAG, "verifySwitchToDesktopSiteButtonIsEnabled: Verified the Switch to Desktop Site button from the new main menu design is enabled.") + } else { + composeTestRule.desktopSiteButton().assertIsNotEnabled() + Log.i(TAG, "verifySwitchToDesktopSiteButtonIsEnabled: Verified the Switch to Desktop Site button from the new main menu design is disabled.") } } - fun verifyTrackersBlockedByUblock() { - for (i in 1..RETRY_COUNT) { - Log.i(TAG, "verifyTrackersBlockedByUblock: Started try #$i") - try { - assertUIObjectExists(itemWithResId("$packageName:id/badge_text")) - Log.i(TAG, "verifyTrackersBlockedByUblock: Trying to verify that the count of trackers blocked is greater than 0") - assertTrue("$TAG: The count of trackers blocked is not greater than 0", itemWithResId("$packageName:id/badge_text").text.toInt() > 0) - Log.i(TAG, "verifyTrackersBlockedByUblock: Verified that the count of trackers blocked is greater than 0") - - break - } catch (e: NumberFormatException) { - Log.i(TAG, "verifyTrackersBlockedByUblock: NumberFormatException caught, executing fallback methods") - Log.i(TAG, "verifyTrackersBlockedByUblock: Trying to click the device back button") - mDevice.pressBack() - Log.i(TAG, "verifyTrackersBlockedByUblock: Clicked the device back button") - browserScreen { - }.openThreeDotMenu { - openAddonsSubList() - } - } + fun verifyDesktopSiteButtonState(isEnabled: Boolean) { + if (isEnabled) { + Log.i(TAG, "verifyDesktopSiteButtonState: Trying to verify that the \"Desktop site\" button is set to \"On\".") + composeTestRule.enabledDesktopSiteButton().assertIsDisplayed() + Log.i(TAG, "verifyDesktopSiteButtonState: Verified that the \"Desktop site\" button is set to \"On\".") + } else { + Log.i(TAG, "verifyDesktopSiteButtonState: Trying to verify that the \"Desktop site\" button is set to \"Off\".") + composeTestRule.disabledDesktopSiteButton().assertIsDisplayed() + Log.i(TAG, "verifyDesktopSiteButtonState: Verified that the \"Desktop site\" button is set to \"Off\".") } } - fun clickQuit() { - expandMenu() - Log.i(TAG, "clickQuit: Trying to click the \"Quit\" button") - onView(withText("Quit")).click() - Log.i(TAG, "clickQuit: Clicked the \"Quit\" button") - } - - class Transition { - fun openSettings( - localizedText: String = getStringResource(R.string.browser_menu_settings), - interact: SettingsRobot.() -> Unit, - ): SettingsRobot.Transition { - // We require one swipe to display the full size 3-dot menu. On smaller devices - // such as the Pixel 2, we require two swipes to display the "Settings" menu item - // at the bottom. On larger devices, the second swipe is a no-op. - Log.i(TAG, "openSettings: Trying to perform swipe up action on the three dot menu") - threeDotMenuRecyclerView().perform(swipeUp()) - Log.i(TAG, "openSettings: Performed swipe up action on the three dot menu") - Log.i(TAG, "openSettings: Trying to perform swipe up action on the three dot menu") - threeDotMenuRecyclerView().perform(swipeUp()) - Log.i(TAG, "openSettings: Performed swipe up action on the three dot menu") - Log.i(TAG, "openSettings: Trying to click the $localizedText button") - settingsButton(localizedText).click() - Log.i(TAG, "openSettings: Clicked the $localizedText button") + fun verifyPageMainMenuItems() { + Log.i(TAG, "verifyPageMainMenuItems: Trying to verify the main menu items on the web page.") + Log.i(TAG, "verifyPageMainMenuItems: Trying to verify that the \"Back\" button exists.") + composeTestRule.backButton().assertIsDisplayed() + Log.i(TAG, "verifyPageMainMenuItems: Verified that the \"Back\" button exists.") + Log.i(TAG, "verifyPageMainMenuItems: Trying to verify that the \"Forward\" button exists.") + composeTestRule.forwardButton().assertIsDisplayed() + Log.i(TAG, "verifyPageMainMenuItems: Verified that the \"Forward\" button exists.") + Log.i(TAG, "verifyPageMainMenuItems: Trying to verify that the \"Refresh\" button exists.") + composeTestRule.refreshButton().assertIsDisplayed() + Log.i(TAG, "verifyPageMainMenuItems: Verified that the \"Refresh\" button exists.") + Log.i(TAG, "verifyPageMainMenuItems: Trying to verify that the \"Share\" button exists.") + composeTestRule.shareButton().assertIsDisplayed() + Log.i(TAG, "verifyPageMainMenuItems: Verified that the \"Share\" button exists.") + Log.i(TAG, "verifyPageMainMenuItems: Trying to verify that the \"Bookmark page\" button exists.") + composeTestRule.bookmarkPageButton().assertIsDisplayed() + Log.i(TAG, "verifyPageMainMenuItems: Verified that the \"Bookmark page\" button exists.") + Log.i(TAG, "verifyPageMainMenuItems: Trying to verify that the \"Find in page\" button exists.") + composeTestRule.findInPageButton().assertIsDisplayed() + Log.i(TAG, "verifyPageMainMenuItems: Verified that the \"Find in page\" button exists.") + Log.i(TAG, "verifyPageMainMenuItems: Trying to verify that the \"Desktop site\" button exists.") + composeTestRule.desktopSiteButton().assertIsDisplayed() + Log.i(TAG, "verifyPageMainMenuItems: Verified that the \"Desktop site\" button exists.") + Log.i(TAG, "verifyPageMainMenuItems: Trying to verify that the \"Extensions\" button exists.") + composeTestRule.extensionsButton().assertIsDisplayed() + Log.i(TAG, "verifyPageMainMenuItems: Verified that the \"Extensions\" button exists.") + Log.i(TAG, "verifyPageMainMenuItems: Trying to verify that the \"More\" button exists.") + composeTestRule.moreButton().assertIsDisplayed() + Log.i(TAG, "verifyPageMainMenuItems: Verified that the \"More\" button exists.") + Log.i(TAG, "verifyPageMainMenuItems: Trying to verify that the \"History\" button exists.") + composeTestRule.historyButton().assertIsDisplayed() + Log.i(TAG, "verifyPageMainMenuItems: Verified that the \"History\" button exists.") + Log.i(TAG, "verifyPageMainMenuItems: Trying to verify that the \"Bookmarks\" button exists.") + composeTestRule.bookmarksButton().assertIsDisplayed() + Log.i(TAG, "verifyPageMainMenuItems: Verified that the \"Bookmarks\" button exists.") + Log.i(TAG, "verifyPageMainMenuItems: Trying to verify that the \"Downloads\" button exists.") + composeTestRule.downloadsButton().assertIsDisplayed() + Log.i(TAG, "verifyPageMainMenuItems: Verified that the \"Downloads\" button exists.") + Log.i(TAG, "verifyPageMainMenuItems: Trying to verify that the \"Passwords\" button exists.") + composeTestRule.passwordsButton().assertIsDisplayed() + Log.i(TAG, "verifyPageMainMenuItems: Verified that the \"Passwords\" button exists.") + Log.i(TAG, "verifyPageMainMenuItems: Trying to verify that the \"Sign in\" button exists.") + composeTestRule.signInButton().assertIsDisplayed() + Log.i(TAG, "verifyPageMainMenuItems: Verified that the \"Sign in\" button exists.") + Log.i(TAG, "verifyPageMainMenuItems: Trying to verify that the \"Settings\" button exists.") + composeTestRule.settingsButton().assertIsDisplayed() + Log.i(TAG, "verifyPageMainMenuItems: Verified that the \"Settings\" button exists.") + Log.i(TAG, "verifyPageMainMenuItems: Verified the main menu items on the web page.") + } - SettingsRobot().interact() - return SettingsRobot.Transition() - } + fun verifyHomeMainMenuItems() { + Log.i(TAG, "verifyHomeMainMenuItems: Trying to verify that the \"Make Firefox your default\" button exists.") + verifyMakeFirefoxYourDefaultBrowserPromotionBanner() + Log.i(TAG, "verifyHomeMainMenuItems: Verified that the \"Make Firefox your default\" button exists.") + Log.i(TAG, "verifyHomeMainMenuItems: Trying to verify that the \"Extensions\" button exists.") + composeTestRule.extensionsButton().assertIsDisplayed() + Log.i(TAG, "verifyHomeMainMenuItems: Verified that the \"Extensions\" button exists.") + Log.i(TAG, "verifyHomeMainMenuItems: Trying to verify that the \"History\" button exists.") + composeTestRule.historyButton().assertIsDisplayed() + Log.i(TAG, "verifyHomeMainMenuItems: Verified that the \"History\" button exists.") + Log.i(TAG, "verifyHomeMainMenuItems: Trying to verify that the \"Bookmarks\" button exists.") + composeTestRule.bookmarksButton().assertIsDisplayed() + Log.i(TAG, "verifyHomeMainMenuItems: Verified that the \"Bookmarks\" button exists.") + Log.i(TAG, "verifyHomeMainMenuItems: Trying to verify that the \"Downloads\" button exists.") + composeTestRule.downloadsButton().assertIsDisplayed() + Log.i(TAG, "verifyHomeMainMenuItems: Verified that the \"Downloads\" button exists.") + Log.i(TAG, "verifyHomeMainMenuItems: Trying to verify that the \"Passwords\" button exists.") + composeTestRule.passwordsButton().assertIsDisplayed() + Log.i(TAG, "verifyHomeMainMenuItems: Verified that the \"Passwords\" button exists.") + Log.i(TAG, "verifyHomeMainMenuItems: Trying to verify that the \"Sign in\" button exists.") + composeTestRule.signInButton().assertIsDisplayed() + Log.i(TAG, "verifyHomeMainMenuItems: Verified that the \"Sign in\" button exists.") + Log.i(TAG, "verifyHomeMainMenuItems: Trying to verify that the \"Settings\" button exists.") + composeTestRule.settingsButton().assertIsDisplayed() + Log.i(TAG, "verifyHomeMainMenuItems: Verified that the \"Settings\" button exists.") + Log.i(TAG, "verifyHomeMainMenuItems: Verified the main menu items on the home page.") + } - fun openDownloadsManager(interact: DownloadRobot.() -> Unit): DownloadRobot.Transition { - Log.i(TAG, "openDownloadsManager: Trying to perform swipe down action on the three dot menu") - threeDotMenuRecyclerView().perform(swipeDown()) - Log.i(TAG, "openDownloadsManager: Performed swipe down action on the three dot menu") - Log.i(TAG, "openDownloadsManager: Trying to click the \"DOWNLOADS\" button") - downloadsButton().click() - Log.i(TAG, "openDownloadsManager: Clicked the \"DOWNLOADS\" button") + fun verifyMainMenuCFR() { + Log.i(TAG, "verifyMainMenuCFR: Trying to verify the main menu CFR title is displayed.") + composeTestRule.mainMenuCFRTitle().assertIsDisplayed() + Log.i(TAG, "verifyMainMenuCFR: Verified the main menu CFR title is displayed.") + Log.i(TAG, "verifyMainMenuCFR: Trying to verify the main menu CFR message is displayed.") + composeTestRule.mainMenuCFRMessage().assertIsDisplayed() + Log.i(TAG, "verifyMainMenuCFR: Verified the main menu CFR message is displayed.") + Log.i(TAG, "verifyMainMenuCFR: Trying to verify the main menu CFR dismiss button is displayed.") + composeTestRule.closeMainMenuCFRButton().assertIsDisplayed() + Log.i(TAG, "verifyMainMenuCFR: Verified the main menu CFR dismiss button is displayed.") + } - DownloadRobot().interact() - return DownloadRobot.Transition() - } + fun clickTheQuitFirefoxButton() { + Log.i(TAG, "clickTheQuitFirefoxButton: Trying to click the \"Quit $appName\" button from the new main menu design.") + composeTestRule.quitFirefoxButton().performClick() + Log.i(TAG, "clickTheQuitFirefoxButton: Clicked the \"Quit $appName\" button from the new main menu design.") + } + + fun verifyTranslatePageButton() { + Log.i(TAG, "verifyTranslatePageButton: Trying to verify that the \"Translate page\" button exists.") + composeTestRule.translatePageButton().assertIsDisplayed() + Log.i(TAG, "verifyTranslatePageButton: Verified that the \"Translate page\" button exists.") + } + + fun verifyMakeFirefoxYourDefaultBrowserPromotionBanner() { + composeTestRule.onNodeWithText(getStringResource(R.string.browser_menu_default_banner_title, appName)).assertIsDisplayed() + composeTestRule.onNodeWithText(getStringResource(R.string.browser_menu_default_banner_subtitle_2)).assertIsDisplayed() + composeTestRule.onNodeWithContentDescription(getStringResource(R.string.browser_menu_default_banner_dismiss_promotion)).assertIsDisplayed() + } + + fun verifyMoreMainMenuItems() { + Log.i(TAG, "verifyMoreMainMenuItems: Trying to verify the more main menu items on the web page.") + Log.i(TAG, "verifyMoreMainMenuItems: Trying to verify that the \"Translate page\" button exists.") + composeTestRule.translatePageButton().assertIsDisplayed() + Log.i(TAG, "verifyMoreMainMenuItems: Verified that the \"Translate page\" button exists.") + Log.i(TAG, "verifyMoreMainMenuItems: Trying to verify that the \"Report broken site\" button exists.") + composeTestRule.reportBrokenSiteButton().assertIsDisplayed() + Log.i(TAG, "verifyMoreMainMenuItems: Verified that the \"Report broken site\" button exists.") + Log.i(TAG, "verifyMoreMainMenuItems: Trying to verify that the \"Add to shortcuts\" button exists.") + composeTestRule.addToShortcutsButton().assertIsDisplayed() + Log.i(TAG, "verifyMoreMainMenuItems: Verified that the \"Add to shortcuts\" button exists.") + Log.i(TAG, "verifyMoreMainMenuItems: Trying to verify that the \"Add app to Home screen\" button exists.") + composeTestRule.addToHomeScreenButton().assertIsDisplayed() + Log.i(TAG, "verifyMoreMainMenuItems: Verified that the \"Add app to Home screen\" button exists.") + Log.i(TAG, "verifyMoreMainMenuItems: Trying to verify that the \"Save to collection\" button exists.") + composeTestRule.saveToCollectionButton().assertIsDisplayed() + Log.i(TAG, "verifyMoreMainMenuItems: Verified that the \"Save to collection\" button exists.") + Log.i(TAG, "verifyMoreMainMenuItems: Trying to verify that the \"Open in app\" button exists.") + composeTestRule.defaultOpenInAppButton().assertIsDisplayed() + Log.i(TAG, "verifyMoreMainMenuItems: Verified that the \"Open in app\" button exists.") + Log.i(TAG, "verifyMoreMainMenuItems: Trying to verify that the \"Save as PDF\" button exists.") + composeTestRule.saveAsPDFButton().assertIsDisplayed() + Log.i(TAG, "verifyMoreMainMenuItems: Verified that the \"Save as PDF\" button exists.") + Log.i(TAG, "verifyMoreMainMenuItems: Trying to verify that the \"Print\" button exists.") + composeTestRule.printContentButton().assertIsDisplayed() + Log.i(TAG, "verifyMoreMainMenuItems: Verified that the \"Print\" button exists.") + Log.i(TAG, "verifyMoreMainMenuItems: Verified the more main menu items on the web page.") + } + + fun clickTheMoreButton() { + Log.i(TAG, "clickTheMoreButton: Trying to click the \"More\" button from the new main menu design.") + composeTestRule.moreButton().performClick() + Log.i(TAG, "clickTheMoreButton: Clicked the \"More\" button from the new main menu design.") + waitForAppWindowToBeUpdated() + } + + fun clickMoreOptionChevron() { + Log.i(TAG, "clickMoreOptionChevron: Trying to click the \"More option chevron\" button from the new main menu design.") + composeTestRule.moreChevronButton().performClick() + Log.i(TAG, "clickMoreOptionChevron: Clicked the \"More option chevron\" button from the new main menu design.") + waitForAppWindowToBeUpdated() + } - fun openPasswords(interact: SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot.() -> Unit): SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot.Transition { - Log.i(TAG, "openPasswords: Trying to perform swipe down action on the three dot menu") - threeDotMenuRecyclerView().perform(swipeDown()) - Log.i(TAG, "openPasswords: Performed swipe down action on the three dot menu") - Log.i(TAG, "openPasswords: Trying to click the \"Passwords\" button") - passwordsButton().click() - Log.i(TAG, "openPasswords: Clicked the \"Passwords\" button") + fun clickSaveButton() { + Log.i(TAG, "clickSaveButton: Trying to click the \"Save\" button from the new main menu design.") + composeTestRule.saveMenuButton().performClick() + Log.i(TAG, "clickSaveButton: Clicked the \"Save\" button from the new main menu design.") + } + + fun verifyOpenInAppButtonIsEnabled(appName: String = "", isEnabled: Boolean) { + Log.i(TAG, "verifyOpenInAppButtonIsEnabled: Trying to verify the Open in App button from the new main menu design is enabled.") + when (appName) { + "" -> composeTestRule.defaultOpenInAppButton().apply { + if (isEnabled) assertIsEnabled() else assertIsNotEnabled() + Log.i( + TAG, + "verifyOpenInAppButtonIsEnabled: Open in App button from the new main menu design is enabled = $isEnabled.", + ) + } + else -> composeTestRule.openInAppNameButton(appName).apply { + if (isEnabled) assertIsEnabled() else assertIsNotEnabled() + Log.i(TAG, "verifyOpenInAppButtonIsEnabled: Open in App button from the new main menu design is enabled = $isEnabled.") + } + } + } - SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot().interact() - return SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot.Transition() + fun clickOpenInAppButton(appName: String = "") { + Log.i(TAG, "clickOpenInAppButton: Trying to click the Open in App button from the new main menu design.") + when (appName) { + "" -> composeTestRule.defaultOpenInAppButton().performClick() + else -> composeTestRule.openInAppNameButton(appName).performClick() } + Log.i(TAG, "clickOpenInAppButton: Clicked the Open in App button from the new main menu design.") + mDevice.waitForIdle() + } - fun openSyncSignIn(interact: SyncSignInRobot.() -> Unit): SyncSignInRobot.Transition { - Log.i(TAG, "openSyncSignIn: Trying to perform swipe down action on the three dot menu") - threeDotMenuRecyclerView().perform(swipeDown()) - Log.i(TAG, "openSyncSignIn: Performed swipe down action on the three dot menu") - mDevice.waitNotNull(Until.findObject(By.text("Sign in")), waitingTime) - Log.i(TAG, "openSyncSignIn: Trying to click the \"Sync and save data\" button") - syncAndSaveDataButton().click() - Log.i(TAG, "openSyncSignIn: Clicked the \"Sync and save data\" button") + fun clickSwitchToDesktopSiteButton() { + Log.i(TAG, "clickSwitchToDesktopSiteButton: Trying to click the \"Switch to desktop site\" button.") + composeTestRule.desktopSiteButton().performClick() + Log.i(TAG, "clickSwitchToDesktopSiteButton: Clicked the \"Switch to desktop site\" button.") + } - SyncSignInRobot().interact() - return SyncSignInRobot.Transition() + fun clickPrintContentButton() { + Log.i(TAG, "clickPrintContentButton: Trying to click the \"Print…\" button.") + composeTestRule.printContentButton().performClick() + Log.i(TAG, "clickPrintContentButton: Clicked the \"Print…\" button.") + } + + fun clickTheToolsButton() { + Log.i(TAG, "clickTheToolsButton: Trying to click the Tools menu button from the new main menu design.") + composeTestRule.toolsMenuButton().performClick() + composeTestRule.waitForIdle() + Log.i(TAG, "clickTheToolsButton: Clicked the Tools menu button from the new main menu design.") + } + + @OptIn(ExperimentalTestApi::class) + fun verifyExtensionsButtonWithInstalledExtension(extensionTitle: String) { + Log.i(TAG, "verifyExtensionsButtonWithInstalledExtension: Waiting for $waitingTime for the collapsed \"Extensions\" button with installed $extensionTitle to exist.") + composeTestRule.waitUntilAtLeastOneExists(hasContentDescription(extensionTitle, substring = true, ignoreCase = true), waitingTime) + Log.i(TAG, "verifyExtensionsButtonWithInstalledExtension: Waited for $waitingTime for the collapsed \"Extensions\" button with installed $extensionTitle to exist.") + Log.i(TAG, "verifyExtensionsButtonWithInstalledExtension: Trying to verify that the collapsed \"Extensions\" button with installed $extensionTitle exists.") + composeTestRule.onNode( + hasTestTag("mainMenu.extensions"), + ).assert( + hasContentDescription(extensionTitle, substring = true, ignoreCase = true), + ).assertIsDisplayed() + Log.i(TAG, "verifyExtensionsButtonWithInstalledExtension: Verified that the collapsed \"Extensions\" button with installed $extensionTitle exists.") + } + + @OptIn(ExperimentalTestApi::class) + fun verifyTryRecommendedExtensionButton() { + Log.i(TAG, "verifyTryRecommendedExtensionButton: Waiting for $waitingTime for the \"Extensions - Try a recommended extension\" button to exists.") + composeTestRule.waitUntilAtLeastOneExists(hasContentDescription("Extensions Try a recommended extension", substring = true), waitingTime) + Log.i(TAG, "verifyTryRecommendedExtensionButton: Waited for $waitingTime for the \"Extensions - Try a recommended extension\" button to exists.") + Log.i(TAG, "verifyTryRecommendedExtensionButton: Trying to verify that the \"Extensions - Try a recommended extension\" button exists.") + composeTestRule.tryRecommendedExtensionButton().assertExists() + Log.i(TAG, "verifyTryRecommendedExtensionButton: Verified that the \"Extensions - Try a recommended extension\" button exists.") + } + + fun verifyNoExtensionsEnabledButton() { + Log.i(TAG, "verifyNoExtensionsEnabledButton: Trying to verify that the \"Extensions - Try a recommended extension\" button exists.") + composeTestRule.noExtensionsEnabledButton().assertExists() + Log.i(TAG, "verifyNoExtensionsEnabledButton: Verified that the \"Extensions - Try a recommended extension\" button exists.") + } + + fun verifySettingsButton() { + Log.i(TAG, "verifySettingsButton: Trying to verify that the \"Settings\" button exists.") + composeTestRule.settingsButton().assertIsDisplayed() + Log.i(TAG, "verifySettingsButton: Verified that the \"Settings\" button exists.") + } + fun verifyHistoryButton() { + Log.i(TAG, "verifyHistoryButton: Trying to verify that the \"History\" button exists.") + composeTestRule.historyButton().assertIsDisplayed() + Log.i(TAG, "verifyHistoryButton: Verified that the \"History\" button exists.") + } + + fun verifyFindInPageButton() { + Log.i(TAG, "verifyFindInPageButton: Trying to verify that the \"Find in page\" button exists.") + composeTestRule.findInPageButton().assertIsDisplayed() + Log.i(TAG, "verifyFindInPageButton: Verified that the \"Find in page\" button exists.") + } + + fun verifyAddToShortcutsButton(isDisplayed: Boolean) { + if (isDisplayed) { + Log.i(TAG, "verifyAddToShortcutsButton: Trying to verify that the \"Add to shortcuts\" button is displayed.") + composeTestRule.addToShortcutsButton().assertIsDisplayed() + Log.i(TAG, "verifyAddToShortcutsButton: Verified that the \"Add to shortcuts\" button is displayed.") + } else { + Log.i(TAG, "verifyAddToShortcutsButton: Trying to verify that the \"Add to shortcuts\" button is not displayed.") + composeTestRule.addToShortcutsButton().assertIsDisplayed() + Log.i(TAG, "verifyAddToShortcutsButton: Verified that the \"Add to shortcuts\" button is not displayed.") } + } - fun openBookmarksMenu(composeTestRule: ComposeTestRule, interact: BookmarksRobot.() -> Unit): BookmarksRobot.Transition { - Log.i(TAG, "openBookmarksMenu: Trying to perform swipe down action on the three dot menu") - threeDotMenuRecyclerView().perform(swipeDown()) - Log.i(TAG, "openBookmarksMenu: Performed swipe down action on the three dot menu") - mDevice.waitNotNull(Until.findObject(By.text("Bookmarks")), waitingTime) - Log.i(TAG, "openBookmarksMenu: Trying to click the \"Bookmarks\" button") - bookmarksButton().click() - Log.i(TAG, "openBookmarksMenu: Clicked the \"Bookmarks\" button") + class Transition(private val composeTestRule: ComposeTestRule) { + fun clickSettingsButton(localizedText: String = getStringResource(R.string.browser_menu_settings), interact: SettingsRobot.() -> Unit): SettingsRobot.Transition { + Log.i(TAG, "clickSettingsButton: Trying to click the Settings button from the new main menu design.") + composeTestRule.settingsButton(localizedText).performClick() + Log.i(TAG, "clickSettingsButton: Clicked the Settings button from the new main menu design.") - BookmarksRobot(composeTestRule).interact() - return BookmarksRobot.Transition(composeTestRule) + SettingsRobot().interact() + return SettingsRobot.Transition() } - fun clickNewTabButton(interact: SearchRobot.() -> Unit): SearchRobot.Transition { - Log.i(TAG, "clickNewTabButton: Trying to click the \"New tab\" button") - normalBrowsingNewTabButton().click() - Log.i(TAG, "clickNewTabButton: Clicked the \"New tab\" button") + fun clickDownloadsButton(interact: DownloadRobot.() -> Unit): DownloadRobot.Transition { + Log.i(TAG, "clickDownloadsButton: Trying to click the \"Download\" button from the new main menu design.") + composeTestRule.downloadsButton().performClick() + Log.i(TAG, "clickDownloadsButton: Clicked the \"Download\" button from the new main menu design.") - SearchRobot().interact() - return SearchRobot.Transition() + DownloadRobot(composeTestRule).interact() + return DownloadRobot.Transition(composeTestRule) } - fun openHistory(interact: HistoryRobot.() -> Unit): HistoryRobot.Transition { - Log.i(TAG, "openHistory: Trying to perform swipe down action on the three dot menu") - threeDotMenuRecyclerView().perform(swipeDown()) - Log.i(TAG, "openHistory: Performed swipe down action on the three dot menu") - mDevice.waitNotNull(Until.findObject(By.text("History")), waitingTime) - Log.i(TAG, "openHistory: Trying to click the \"History\" button") - historyButton().click() - Log.i(TAG, "openHistory: Clicked the \"History\" button") + fun clickPasswordsButton(interact: SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot.() -> Unit): SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot.Transition { + Log.i(TAG, "clickPasswordsButton: Trying to click the \"Passwords\" button from the new main menu design.") + composeTestRule.passwordsButton().performClick() + Log.i(TAG, "clickPasswordsButton: Clicked the \"Passwords\" button from the new main menu design.") - HistoryRobot().interact() - return HistoryRobot.Transition() + SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot(composeTestRule).interact() + return SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot.Transition(composeTestRule) } - fun bookmarkPage(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { - mDevice.waitNotNull(Until.findObject(By.text("Bookmarks")), waitingTime) - Log.i(TAG, "bookmarkPage: Trying to click the \"Add\" button") - addBookmarkButton().click() - Log.i(TAG, "bookmarkPage: Clicked the \"Add\" button") + fun clickSignInToSyncButton(interact: SyncSignInRobot.() -> Unit): SyncSignInRobot.Transition { + Log.i(TAG, "clickSignInToSyncButton: Trying to click \"Sign in\" main menu button") + composeTestRule.onNodeWithContentDescription("Sign in Sync passwords, bookmarks, and more").performClick() + Log.i(TAG, "clickSignInToSyncButton: Clicked \"Sign in\" main menu button") - BrowserRobot().interact() - return BrowserRobot.Transition() + SyncSignInRobot().interact() + return SyncSignInRobot.Transition(composeTestRule) } - fun editBookmarkPage(composeTestRule: ComposeTestRule, interact: BookmarksRobot.() -> Unit): BookmarksRobot.Transition { - mDevice.waitNotNull(Until.findObject(By.text("Bookmarks")), waitingTime) - Log.i(TAG, "editBookmarkPage: Trying to click the \"Edit\" button") - editBookmarkButton().click() - Log.i(TAG, "editBookmarkPage: Clicked the \"Edit\" button") + fun clickBookmarksButton(interact: BookmarksRobot.() -> Unit): BookmarksRobot.Transition { + Log.i(TAG, "clickBookmarksButton: Trying to click the Bookmarks button from the new main menu design.") + composeTestRule.bookmarksButton().performClick() + Log.i(TAG, "clickBookmarksButton: Clicked the Bookmarks button from the new main menu design.") BookmarksRobot(composeTestRule).interact() return BookmarksRobot.Transition(composeTestRule) } - fun openHelp(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { - mDevice.waitNotNull(Until.findObject(By.text("Help")), waitingTime) - Log.i(TAG, "openHelp: Trying to click the \"Help\" button") - helpButton().click() - Log.i(TAG, "openHelp: Clicked the \"Help\" button") + fun clickHistoryButton(interact: HistoryRobot.() -> Unit): HistoryRobot.Transition { + Log.i(TAG, "clickHistoryButton: Trying to click the History button from the new main menu design.") + composeTestRule.historyButton().performClick() + Log.i(TAG, "clickHistoryButton: Clicked the History button from the new main menu design.") - BrowserRobot().interact() - return BrowserRobot.Transition() + HistoryRobot().interact() + return HistoryRobot.Transition(composeTestRule) } - fun openCustomizeHome(interact: SettingsSubMenuHomepageRobot.() -> Unit): SettingsSubMenuHomepageRobot.Transition { - Log.i(TAG, "openCustomizeHome: Waiting for $waitingTime ms until finding the \"Customize homepage\" button") - mDevice.wait( - Until - .findObject( - By.textContains("$packageName:id/browser_menu_customize_home_1"), - ), - waitingTime, - ) - Log.i(TAG, "openCustomizeHome: Waited for $waitingTime ms until the \"Customize homepage\" button was found") - Log.i(TAG, "openCustomizeHome: Trying to click the \"Customize homepage\" button") - customizeHomeButton().click() - Log.i(TAG, "openCustomizeHome: Clicked the \"Customize homepage\" button") - Log.i(TAG, "openCustomizeHome: Waiting for $waitingTime ms for \"Customize homepage\" settings menu to exist") - mDevice.findObject( - UiSelector().resourceId("$packageName:id/recycler_view"), - ).waitForExists(waitingTime) - Log.i(TAG, "openCustomizeHome: Waited for $waitingTime ms for \"Customize homepage\" settings menu to exist") + fun clickBookmarkThisPageButton(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { + Log.i(TAG, "clickBookmarkThisPageButton: Trying to click the \"Bookmark this page\" button from the new main menu design.") + composeTestRule.bookmarkPageButton().performClick() + Log.i(TAG, "clickBookmarkThisPageButton: Clicked the \"Bookmark this page\" button from the new main menu design.") - SettingsSubMenuHomepageRobot().interact() - return SettingsSubMenuHomepageRobot.Transition() + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } - fun goForward(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { - Log.i(TAG, "goForward: Trying to click the \"Forward\" button") - forwardButton().click() - Log.i(TAG, "goForward: Clicked the \"Forward\" button") + fun clickEditBookmarkButton(interact: BookmarksRobot.() -> Unit): BookmarksRobot.Transition { + Log.i(TAG, "clickEditBookmarkButton: Trying to click the \"Edit bookmark\" button from the new main menu design.") + composeTestRule.editBookmarkButton().performClick() + Log.i(TAG, "clickEditBookmarkButton: Clicked the \"Edit bookmark\" button from the new main menu design.") - BrowserRobot().interact() - return BrowserRobot.Transition() + BookmarksRobot(composeTestRule).interact() + return BookmarksRobot.Transition(composeTestRule) } - fun goToPreviousPage(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { - Log.i(TAG, "goToPreviousPage: Trying to click the \"Back\" button") - backButton().click() - Log.i(TAG, "goToPreviousPage: Clicked the \"Back\" button") + fun clickForwardButton(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { + Log.i(TAG, "clickForwardButton: Trying to click the \"Forward\" button") + composeTestRule.forwardButton().performClick() + Log.i(TAG, "clickForwardButton: Clicked the \"Forward\" button") - BrowserRobot().interact() - return BrowserRobot.Transition() + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) + } + + fun clickPreviousPageButton(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { + Log.i(TAG, "clickPreviousPageButton: Trying to click the \"Back\" button") + composeTestRule.backButton().performClick() + Log.i(TAG, "clickPreviousPageButton: Clicked the \"Back\" button") + + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } fun clickShareButton(interact: ShareOverlayRobot.() -> Unit): ShareOverlayRobot.Transition { - Log.i(TAG, "clickShareButton: Trying to click the \"Share\" button") - shareButton().click() - Log.i(TAG, "clickShareButton: Clicked the \"Share\" button") - mDevice.waitNotNull(Until.findObject(By.text("ALL ACTIONS")), waitingTime) + Log.i(TAG, "clickShareButton: Trying to click the Share button from the new main menu design.") + composeTestRule.shareButton().performClick() + Log.i(TAG, "clickShareButton: Clicked the Share button from the new main menu design.") ShareOverlayRobot().interact() return ShareOverlayRobot.Transition() } - fun closeBrowserMenuToBrowser(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { - Log.i(TAG, "closeBrowserMenuToBrowser: Trying to click device back button") - // Close three dot + fun closeMainMenuAndExitToBrowserView(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { + Log.i(TAG, "closeMainMenuAndExitToBrowserView: Trying to click device back button") mDevice.pressBack() - Log.i(TAG, "closeBrowserMenuToBrowser: Clicked the device back button") + Log.i(TAG, "closeMainMenuAndExitToBrowserView: Clicked the device back button") - BrowserRobot().interact() - return BrowserRobot.Transition() + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } - fun refreshPage(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { - if (stopLoadingButton().exists()) { - Log.i(TAG, "refreshPage: Trying to click the \"Stop\" button") - stopLoadingButton().click() - Log.i(TAG, "refreshPage: Clicked the \"Stop\" button") - browserScreen { - }.openThreeDotMenu {} - } - refreshButton().also { - Log.i(TAG, "refreshPage: Waiting for $waitingTime ms for the \"Refresh\" button to exist") - it.waitForExists(waitingTime) - Log.i(TAG, "refreshPage: Waited for $waitingTime ms for the \"Refresh\" button to exist") - Log.i(TAG, "refreshPage: Trying to click the \"Refresh\" button") - it.click() - Log.i(TAG, "refreshPage: Clicked the \"Refresh\" button") - } + fun clickRefreshButton(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { + Log.i(TAG, "clickRefreshButton: Trying to click the \"Refresh\" button") + composeTestRule.refreshButton().performClick() + Log.i(TAG, "clickRefreshButton: Clicked the \"Refresh\" button") - BrowserRobot().interact() - return BrowserRobot.Transition() + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } fun forceRefreshPage(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { @@ -481,8 +555,8 @@ class ThreeDotMenuMainRobot { .click(LONG_CLICK_DURATION) Log.i(TAG, "forceRefreshPage: Long clicked the \"Refresh\" button") - BrowserRobot().interact() - return BrowserRobot.Transition() + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } fun closeAllTabs(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition { @@ -490,182 +564,92 @@ class ThreeDotMenuMainRobot { closeAllTabsButton().click() Log.i(TAG, "closeAllTabs: Clicked the \"Close all tabs\" button") - HomeScreenRobot().interact() - return HomeScreenRobot.Transition() - } - - fun openReportBrokenSite(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { - Log.i(TAG, "openReportBrokenSite: Trying to perform swipe up action on the three dot menu") - threeDotMenuRecyclerView().perform(swipeUp()) - Log.i(TAG, "openReportBrokenSite: Performed swipe up action on the three dot menu") - Log.i(TAG, "openReportBrokenSite: Trying to perform swipe up action on the three dot menu") - threeDotMenuRecyclerView().perform(swipeUp()) - Log.i(TAG, "openReportBrokenSite: Performed swipe up action on the three dot menu") - Log.i(TAG, "openReportBrokenSite: Trying to click the \"Report broke site\" button") - reportSiteIssueButton().click() - Log.i(TAG, "openReportBrokenSite: Clicked the \"Report broke site\" button") - - BrowserRobot().interact() - return BrowserRobot.Transition() - } - - fun openFindInPage(interact: FindInPageRobot.() -> Unit): FindInPageRobot.Transition { - Log.i(TAG, "openFindInPage: Trying to perform swipe up action on the three dot menu") - threeDotMenuRecyclerView().perform(swipeUp()) - Log.i(TAG, "openFindInPage: Performed swipe up action on the three dot menu") - Log.i(TAG, "openFindInPage: Trying to perform swipe up action on the three dot menu") - threeDotMenuRecyclerView().perform(swipeUp()) - Log.i(TAG, "openFindInPage: Performed swipe up action on the three dot menu") - mDevice.waitNotNull(Until.findObject(By.text("Find in page")), waitingTime) - Log.i(TAG, "openFindInPage: Trying to click the \"Find in page\" button") - findInPageButton().click() - Log.i(TAG, "openFindInPage: Clicked the \"Find in page\" button") - - FindInPageRobot().interact() - return FindInPageRobot.Transition() + HomeScreenRobot(composeTestRule).interact() + return HomeScreenRobot.Transition(composeTestRule) } - fun openReaderViewAppearance(interact: ReaderViewRobot.() -> Unit): ReaderViewRobot.Transition { - Log.i(TAG, "openReaderViewAppearance: Trying to perform swipe up action on the three dot menu") - threeDotMenuRecyclerView().perform(swipeUp()) - Log.i(TAG, "openReaderViewAppearance: Performed swipe up action on the three dot menu") - Log.i(TAG, "openReaderViewAppearance: Trying to perform swipe up action on the three dot menu") - threeDotMenuRecyclerView().perform(swipeUp()) - Log.i(TAG, "openReaderViewAppearance: Performed swipe up action on the three dot menu") - Log.i(TAG, "openReaderViewAppearance: Trying to click the \"Customize reader view\" button") - readerViewAppearanceToggle().click() - Log.i(TAG, "openReaderViewAppearance: Clicked the \"Customize reader view\" button") + fun clickReportBrokenSiteButton(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { + Log.i(TAG, "openReportSiteIssue: Trying to click the \"Report Site Issue\" button") + composeTestRule.reportBrokenSiteButton().performClick() + Log.i(TAG, "openReportSiteIssue: Clicked the \"Report Site Issue\" button") - ReaderViewRobot().interact() - return ReaderViewRobot.Transition() + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } - fun addToFirefoxHome(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { - for (i in 1..RETRY_COUNT) { - Log.i(TAG, "addToFirefoxHome: Started try #$i") - try { - addToShortcutsButton().also { - Log.i(TAG, "addToFirefoxHome: Waiting for $waitingTime ms for the \"Add to shortcuts\" button to exist") - it.waitForExists(waitingTime) - Log.i(TAG, "addToFirefoxHome: Waited for $waitingTime ms for the \"Add to shortcuts\" button to exist") - Log.i(TAG, "addToFirefoxHome: Trying to click the \"Add to shortcuts\" button") - it.click() - Log.i(TAG, "addToFirefoxHome: Clicked the \"Add to shortcuts\" button") - } - - break - } catch (e: UiObjectNotFoundException) { - Log.i(TAG, "addToFirefoxHome: UiObjectNotFoundException caught, executing fallback methods") - if (i == RETRY_COUNT) { - throw e - } else { - Log.i(TAG, "addToFirefoxHome: Trying to click the device back button") - mDevice.pressBack() - Log.i(TAG, "addToFirefoxHome: Clicked the device back button") - navigationToolbar { - }.openThreeDotMenu { - expandMenu() - } - } - } - } + fun clickFindInPageButton(interact: FindInPageRobot.() -> Unit): FindInPageRobot.Transition { + Log.i(TAG, "clickFindInPageButton: Trying to click the FindInPage button from the new main menu design.") + composeTestRule.findInPageButton().performClick() + Log.i(TAG, "clickFindInPageButton: Clicked the FindInPage button from the new main menu design.") - BrowserRobot().interact() - return BrowserRobot.Transition() + FindInPageRobot().interact() + return FindInPageRobot.Transition() } - fun clickRemoveFromShortcuts(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { - Log.i(TAG, "clickRemoveFromShortcuts: Trying to click the \"Remove from shortcuts\" button") - removeFromShortcutsButton().click() - Log.i(TAG, "clickRemoveFromShortcuts: Clicked the \"Remove from shortcuts\" button") + fun clickCustomizeReaderViewButton(interact: ReaderViewRobot.() -> Unit): ReaderViewRobot.Transition { + Log.i(TAG, "clickCustomizeReaderViewButton: Trying to click the \"Customize reader view\" button") + composeTestRule.onNodeWithContentDescription(getStringResource(R.string.browser_menu_customize_reader_view_2), useUnmergedTree = true).performClick() + Log.i(TAG, "clickCustomizeReaderViewButton: Clicked the \"Customize reader view\" button") - BrowserRobot().interact() - return BrowserRobot.Transition() + ReaderViewRobot().interact() + return ReaderViewRobot.Transition() } - fun openAddToHomeScreen(interact: AddToHomeScreenRobot.() -> Unit): AddToHomeScreenRobot.Transition { - Log.i(TAG, "openAddToHomeScreen: Trying to click the \"Add to Home screen\" button and wait for $waitingTime ms for a new window") - addToHomeScreenButton().clickAndWaitForNewWindow(waitingTime) - Log.i(TAG, "openAddToHomeScreen: Clicked the \"Add to Home screen\" button and waited for $waitingTime ms for a new window") + fun clickAddToShortcutsButton(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { + Log.i(TAG, "clickAddToShortcutsButton: Trying to click the \"Add to shortcuts\" button from the new main menu design.") + composeTestRule.addToShortcutsButton().performClick() + Log.i(TAG, "clickAddToShortcutsButton: Clicked the \"Add to shortcuts\" button from the new main menu design.") - AddToHomeScreenRobot().interact() - return AddToHomeScreenRobot.Transition() + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } - fun clickAddAppToHomeScreen(interact: AddToHomeScreenRobot.() -> Unit): AddToHomeScreenRobot.Transition { - Log.i(TAG, "clickInstall: Trying to perform swipe up action on the three dot menu") - threeDotMenuRecyclerView().perform(swipeUp()) - Log.i(TAG, "clickInstall: Performed swipe up action on the three dot menu") - Log.i(TAG, "clickInstall: Trying to perform swipe up action on the three dot menu") - threeDotMenuRecyclerView().perform(swipeUp()) - Log.i(TAG, "clickInstall: Performed swipe up action on the three dot menu") - Log.i(TAG, "clickInstall: Trying to click the \"Add app to Home screen\" button") - addAppToHomeScreenButton().click() - Log.i(TAG, "clickInstall: Clicked the \"Add app to Home screen\" button") + fun clickRemoveFromShortcutsButton(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { + Log.i(TAG, "clickRemoveFromShortcutsButton: Trying to click the \"Remove from shortcuts\" button from the new main menu design.") + composeTestRule.removeFromShortcutsButton().performClick() + Log.i(TAG, "clickRemoveFromShortcutsButton: Clicked the \"Remove from shortcuts\" button from the new main menu design.") - AddToHomeScreenRobot().interact() - return AddToHomeScreenRobot.Transition() + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } - fun openSaveToCollection(interact: CollectionRobot.() -> Unit): CollectionRobot.Transition { - // Ensure the menu is expanded and fully scrolled to the bottom. - Log.i(TAG, "openSaveToCollection: Trying to perform swipe up action on the three dot menu") - threeDotMenuRecyclerView().perform(swipeUp()) - Log.i(TAG, "openSaveToCollection: Performed swipe up action on the three dot menu") - Log.i(TAG, "openSaveToCollection: Trying to perform swipe up action on the three dot menu") - threeDotMenuRecyclerView().perform(swipeUp()) - Log.i(TAG, "openSaveToCollection: Performed swipe up action on the three dot menu") + fun clickAddToHomeScreenButton(interact: AddToHomeScreenRobot.() -> Unit): AddToHomeScreenRobot.Transition { + Log.i(TAG, "clickAddToHomeScreenButton: Trying to click the \"Add to Home screen…\" button from the new main menu design.") + composeTestRule.addToHomeScreenButton().performClick() + Log.i(TAG, "clickAddToHomeScreenButton: Clicked the \"Add to Home screen…\" button from the new main menu design.") - mDevice.waitNotNull(Until.findObject(By.text("Save to collection")), waitingTime) - Log.i(TAG, "openSaveToCollection: Trying to click the \"Save to collection\" button") - saveToCollectionButton().click() - Log.i(TAG, "openSaveToCollection: Clicked the \"Save to collection\" button") - CollectionRobot().interact() - return CollectionRobot.Transition() + AddToHomeScreenRobot(composeTestRule).interact() + return AddToHomeScreenRobot.Transition(composeTestRule) } - fun openAddonsManagerMenu(interact: SettingsSubMenuAddonsManagerRobot.() -> Unit): SettingsSubMenuAddonsManagerRobot.Transition { - clickAddonsManagerButton() - Log.i(TAG, "openAddonsManagerMenu: Waiting for $waitingTimeLong ms for the addons list to exist") - mDevice.findObject(UiSelector().resourceId("$packageName:id/add_ons_list")) - .waitForExists(waitingTimeLong) - Log.i(TAG, "openAddonsManagerMenu: Waited for $waitingTimeLong ms for the addons list to exist") + fun clickAddAppToHomeScreenButton(interact: AddToHomeScreenRobot.() -> Unit): AddToHomeScreenRobot.Transition { + Log.i(TAG, "clickAddToHomeScreenButton: Trying to click the \"Add app to Home screen…\" button from the new main menu design.") + composeTestRule.addAppToHomeScreenButton().performClick() + Log.i(TAG, "clickAddToHomeScreenButton: Clicked the \"Add app to Home screen…\" button from the new main menu design.") - SettingsSubMenuAddonsManagerRobot().interact() - return SettingsSubMenuAddonsManagerRobot.Transition() + AddToHomeScreenRobot(composeTestRule).interact() + return AddToHomeScreenRobot.Transition(composeTestRule) } - fun clickOpenInApp(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { - Log.i(TAG, "clickOpenInApp: Trying to perform swipe up action on the three dot menu") - threeDotMenuRecyclerView().perform(swipeUp()) - Log.i(TAG, "clickOpenInApp: Performed swipe up action on the three dot menu") - Log.i(TAG, "clickOpenInApp: Trying to perform swipe up action on the three dot menu") - threeDotMenuRecyclerView().perform(swipeUp()) - Log.i(TAG, "clickOpenInApp: Performed swipe up action on the three dot menu") - Log.i(TAG, "clickOpenInApp: Trying to click the \"Open in app\" button") - openInAppButton().click() - Log.i(TAG, "clickOpenInApp: Clicked the \"Open in app\" button") - Log.i(TAG, "clickOpenInApp: Waiting for device to be idle") - mDevice.waitForIdle() - Log.i(TAG, "clickOpenInApp: Waited for device to be idle") + fun clickSaveToCollectionButton(interact: CollectionRobot.() -> Unit): CollectionRobot.Transition { + Log.i(TAG, "clickSaveToCollectionButton: Trying to click the \"Save to collection…\" button from the new main menu design.") + composeTestRule.saveToCollectionButton().performClick() + Log.i(TAG, "clickSaveToCollectionButton: Clicked the \"Save to collection…\" button from the new main menu design.") - BrowserRobot().interact() - return BrowserRobot.Transition() + CollectionRobot(composeTestRule).interact() + return CollectionRobot.Transition(composeTestRule) } - fun switchDesktopSiteMode(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { - Log.i(TAG, "switchDesktopSiteMode: Trying to perform swipe up action on the three dot menu") - threeDotMenuRecyclerView().perform(swipeUp()) - Log.i(TAG, "switchDesktopSiteMode: Performed swipe up action on the three dot menu") - Log.i(TAG, "switchDesktopSiteMode: Trying to perform swipe up action on the three dot menu") - threeDotMenuRecyclerView().perform(swipeUp()) - Log.i(TAG, "switchDesktopSiteMode: Performed swipe up action on the three dot menu") - Log.i(TAG, "switchDesktopSiteMode: Trying to click the \"Desktop site\" button") - desktopSiteButton().click() - Log.i(TAG, "switchDesktopSiteMode: Clicked the \"Desktop site\" button") + fun clickExtensionsButton(interact: SettingsSubMenuAddonsManagerRobot.() -> Unit): SettingsSubMenuAddonsManagerRobot.Transition { + Log.i(TAG, "clickExtensionsButton: Trying to click the \"Extensions\" button") + assertUIObjectExists(itemWithResId("mainMenu.extensions")) + itemWithResId("mainMenu.extensions").clickAndWaitForNewWindow(waitingTimeShort) + Log.i(TAG, "clickExtensionsButton: Clicked the \"Extensions\" button") + composeTestRule.waitForIdle() + waitForAppWindowToBeUpdated() - BrowserRobot().interact() - return BrowserRobot.Transition() + SettingsSubMenuAddonsManagerRobot(composeTestRule).interact() + return SettingsSubMenuAddonsManagerRobot.Transition(composeTestRule) } fun clickShareAllTabsButton(interact: ShareOverlayRobot.() -> Unit): ShareOverlayRobot.Transition { @@ -677,34 +661,62 @@ class ThreeDotMenuMainRobot { return ShareOverlayRobot.Transition() } - fun clickPrintButton(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { - Log.i(TAG, "clickPrintButton: Trying to perform swipe up action on the three dot menu") - threeDotMenuRecyclerView().perform(swipeUp()) - Log.i(TAG, "clickPrintButton: Performed swipe up action on the three dot menu") - Log.i(TAG, "clickPrintButton: Trying to perform swipe up action on the three dot menu") - threeDotMenuRecyclerView().perform(swipeUp()) - Log.i(TAG, "clickPrintButton: Performed swipe up action on the three dot menu") - Log.i(TAG, "clickPrintButton: Waiting for $waitingTime ms for the \"Print\" button to exist") - printButton().waitForExists(waitingTime) - Log.i(TAG, "clickPrintButton: Waited for $waitingTime ms for the \"Print\" button to exist") - Log.i(TAG, "clickPrintButton: Trying to click the \"Print\" button") - printButton().click() - Log.i(TAG, "clickPrintButton: Clicked the \"Print\" button") + fun clickTranslateButton(interact: TranslationsRobot.() -> Unit): TranslationsRobot.Transition { + Log.i(TAG, "clickTranslateButton: Trying to click the Translate button from the new main menu design.") + composeTestRule.translatePageButton().performClick() + Log.i(TAG, "clickTranslateButton: Clicked the Translate button from the new main menu design.") + Log.i(TAG, "clickTranslateButton: Waiting for compose test rule to be idle") + composeTestRule.waitForIdle() + Log.i(TAG, "clickTranslateButton: Waited for compose test rule to be idle") - BrowserRobot().interact() - return BrowserRobot.Transition() + TranslationsRobot(composeTestRule).interact() + return TranslationsRobot.Transition(composeTestRule) } - fun clickTranslateButton(composeTestRule: ComposeTestRule, interact: TranslationsRobot.() -> Unit): TranslationsRobot.Transition { - Log.i(TAG, "clickTranslateButton: Trying to click the \"Translate page\" button") - translateButton().click() - Log.i(TAG, "clickTranslateButton: Clicked the \"Translate page\" button") - + fun clickTranslatedButton(interact: TranslationsRobot.() -> Unit): TranslationsRobot.Transition { + Log.i(TAG, "clickTranslateButton: Trying to click the Translate button from the new main menu design.") + composeTestRule.translatedButton().assertIsDisplayed() + composeTestRule.translatedButton().performClick() + Log.i(TAG, "clickTranslateButton: Clicked the Translate button from the new main menu design.") TranslationsRobot(composeTestRule).interact() return TranslationsRobot.Transition(composeTestRule) } + + fun clickOutsideTheMainMenu(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { + Log.i(TAG, "clickOutsideTheMainMenu: Trying to click outside the main menu.") + itemWithResId("$packageName:id/touch_outside").clickTopLeft() + Log.i(TAG, "clickOutsideTheMainMenu: Clicked click outside the main menu.") + + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) + } + + fun clickSaveAsPDFButton(interact: DownloadRobot.() -> Unit): DownloadRobot.Transition { + Log.i(TAG, "clickSaveAsPDFButton: Trying to click the \"Save as PDF…\" button from the new main menu design.") + composeTestRule.saveAsPDFButton().performClick() + Log.i(TAG, "clickSaveAsPDFButton: Clicked the \"Save as PDF…\" button from the new main menu design.") + + DownloadRobot(composeTestRule).interact() + return DownloadRobot.Transition(composeTestRule) + } + + @OptIn(ExperimentalTestApi::class) + fun clickExtensionsChevronFromMainMenu(interact: SettingsSubMenuAddonsManagerRobot.() -> Unit): SettingsSubMenuAddonsManagerRobot.Transition { + Log.i(TAG, "clickExtensionsChevronFromMainMenu: Trying to click the \"Extensions chevron\" button from the new main menu design.") + composeTestRule.extensionsChevronButton().performClick() + Log.i(TAG, "clickExtensionsChevronFromMainMenu: Clicked the \"Extensions chevron\" button from the new main menu design.") + + SettingsSubMenuAddonsManagerRobot(composeTestRule).interact() + return SettingsSubMenuAddonsManagerRobot.Transition(composeTestRule) + } } } + +fun mainMenuScreen(composeTestRule: ComposeTestRule, interact: ThreeDotMenuMainRobot.() -> Unit): ThreeDotMenuMainRobot.Transition { + ThreeDotMenuMainRobot(composeTestRule).interact() + return ThreeDotMenuMainRobot.Transition(composeTestRule) +} + private fun threeDotMenuRecyclerView() = onView(withId(menuR.id.mozac_browser_menu_recyclerView)) @@ -735,60 +747,92 @@ private fun openInAppButton() = ), ) -private fun clickAddonsManagerButton() { - Log.i(TAG, "clickAddonsManagerButton: Trying to perform swipe down action on the three dot menu") - onView(withId(menuR.id.mozac_browser_menu_menuView)).perform(swipeDown()) - Log.i(TAG, "clickAddonsManagerButton: Performed swipe down action on the three dot menu") - Log.i(TAG, "clickAddonsManagerButton: Trying to click the \"Add-ons\" button") - extensionsButton().click() - Log.i(TAG, "clickAddonsManagerButton: Clicked the \"Add-ons\" button") -} - private fun shareAllTabsButton() = onView(allOf(withText("Share all tabs"))).inRoot(RootMatchers.isPlatformPopup()) -private fun bookmarksButton() = - itemContainingText(getStringResource(R.string.library_bookmarks)) -private fun historyButton() = - itemContainingText(getStringResource(R.string.library_history)) -private fun downloadsButton() = - itemContainingText(getStringResource(R.string.library_downloads)) -private fun passwordsButton() = - itemContainingText(getStringResource(R.string.browser_menu_passwords)) -private fun extensionsButton() = - itemContainingText(getStringResource(R.string.browser_menu_extensions)) -private fun desktopSiteButton() = - itemContainingText(getStringResource(R.string.browser_menu_desktop_site)) -private fun desktopSiteToggle(state: Boolean) = - checkedItemWithResIdAndText( - "$packageName:id/switch_widget", - getStringResource(R.string.browser_menu_desktop_site), - state, - ) -private fun helpButton() = - itemContainingText(getStringResource(R.string.browser_menu_help)) -private fun customizeHomeButton() = - itemContainingText(getStringResource(R.string.browser_menu_customize_home_1)) -private fun settingsButton(localizedText: String = getStringResource(R.string.browser_menu_settings)) = - itemContainingText(localizedText) -private fun syncAndSaveDataButton() = - itemContainingText(getStringResource(R.string.sync_menu_sign_in)) -private fun normalBrowsingNewTabButton() = - itemContainingText(getStringResource(R.string.library_new_tab)) -private fun addBookmarkButton() = - itemWithResIdAndText( - "$packageName:id/checkbox", - getStringResource(R.string.browser_menu_add), - ) -private fun findInPageButton() = itemContainingText(getStringResource(R.string.browser_menu_find_in_page)) -private fun translateButton() = itemContainingText(getStringResource(R.string.browser_menu_translations)) -private fun reportSiteIssueButton() = itemContainingText("Report broken site") -private fun addToHomeScreenButton() = itemContainingText(getStringResource(R.string.browser_menu_add_to_homescreen)) -private fun addToShortcutsButton() = itemContainingText(getStringResource(R.string.browser_menu_add_to_shortcuts)) -private fun saveToCollectionButton() = itemContainingText(getStringResource(R.string.browser_menu_save_to_collection_2)) -private fun printContentButton() = itemContainingText(getStringResource(R.string.menu_print)) -private fun backButton() = itemWithDescription(getStringResource(R.string.browser_menu_back)) -private fun forwardButton() = itemWithDescription(getStringResource(R.string.browser_menu_forward)) -private fun shareButton() = itemWithDescription(getStringResource(R.string.share_button_content_description)) -private fun refreshButton() = itemWithDescription(getStringResource(R.string.browser_menu_refresh)) -private fun printButton() = itemWithText("Print") +// ComposeMainMenu + +private fun ComposeTestRule.mainMenuCFRTitle() = onNodeWithText(getStringResource(R.string.menu_cfr_title)) + +private fun ComposeTestRule.mainMenuCFRMessage() = onNodeWithText(getStringResource(R.string.menu_cfr_body)) + +private fun ComposeTestRule.closeMainMenuCFRButton() = onNodeWithTag("cfr.dismiss") + +private fun ComposeTestRule.backButton() = onNodeWithText("Back") + +private fun ComposeTestRule.forwardButton() = onNodeWithText("Forward") + +private fun ComposeTestRule.refreshButton() = onNodeWithText("Refresh") + +private fun ComposeTestRule.shareButton() = onNodeWithText("Share") + +private fun ComposeTestRule.signInButton() = onNodeWithContentDescription("Sign in Sync passwords, bookmarks, and more") + +private fun ComposeTestRule.settingsButton(localizedText: String = getStringResource(R.string.browser_menu_settings)) = + onNodeWithContentDescription(localizedText) + +private fun ComposeTestRule.extensionsButton() = onNodeWithTag(EXTENSIONS) + +private fun ComposeTestRule.tryRecommendedExtensionButton() = onNodeWithContentDescription("Extensions Try a recommended extension", substring = true) + +private fun ComposeTestRule.noExtensionsEnabledButton() = onNodeWithContentDescription("Extensions No extensions enabled", substring = true) + +private fun ComposeTestRule.moreButton() = onNodeWithContentDescription("More Collapsed") + +private fun ComposeTestRule.moreChevronButton() = onNodeWithTag(MORE_OPTION_CHEVRON, useUnmergedTree = true) + +private fun ComposeTestRule.bookmarksButton() = onNodeWithContentDescription(getStringResource(R.string.library_bookmarks), substring = true) + +private fun ComposeTestRule.historyButton() = onNodeWithContentDescription(getStringResource(R.string.library_history), substring = true) + +private fun ComposeTestRule.downloadsButton() = onNodeWithContentDescription(getStringResource(R.string.library_downloads), substring = true) + +private fun ComposeTestRule.passwordsButton() = onNodeWithContentDescription(getStringResource(R.string.browser_menu_passwords), substring = true) + +private fun ComposeTestRule.quitFirefoxButton() = onNodeWithContentDescription("Quit $appName") + +// Page main menu items + +private fun ComposeTestRule.findInPageButton() = onNodeWithContentDescription(getStringResource(R.string.browser_menu_find_in_page), substring = true) + +private fun ComposeTestRule.toolsMenuButton() = onNodeWithTag("mainMenu.tools") + +private fun ComposeTestRule.saveMenuButton() = onNodeWithTag("mainMenu.save") + +private fun ComposeTestRule.bookmarkPageButton() = onNodeWithContentDescription(getStringResource(R.string.browser_menu_bookmark_this_page_2)) + +private fun ComposeTestRule.desktopSiteButton() = onNodeWithContentDescription(getStringResource(R.string.browser_menu_desktop_site), substring = true) + +private fun ComposeTestRule.enabledDesktopSiteButton() = onNodeWithTag(DESKTOP_SITE_ON) + +private fun ComposeTestRule.disabledDesktopSiteButton() = onNodeWithTag(DESKTOP_SITE_OFF) + +// Save sub menu items + +private fun ComposeTestRule.editBookmarkButton() = onNodeWithContentDescription(getStringResource(R.string.browser_menu_edit_bookmark)) + +private fun ComposeTestRule.addToShortcutsButton() = onNodeWithContentDescription(getStringResource(R.string.browser_menu_add_to_shortcuts)) + +private fun ComposeTestRule.removeFromShortcutsButton() = onNodeWithContentDescription(getStringResource(R.string.browser_menu_remove_from_shortcuts)) + +private fun ComposeTestRule.addToHomeScreenButton() = onNodeWithContentDescription(getStringResource(R.string.browser_menu_add_to_homescreen)) + +private fun ComposeTestRule.addAppToHomeScreenButton() = onNodeWithContentDescription(getStringResource(R.string.browser_menu_add_app_to_homescreen)) + +private fun ComposeTestRule.saveToCollectionButton() = onNodeWithContentDescription(getStringResource(R.string.browser_menu_save_to_collection_2)) + +private fun ComposeTestRule.saveAsPDFButton() = onNodeWithContentDescription(getStringResource(R.string.browser_menu_save_as_pdf_2)) + +private fun ComposeTestRule.translatePageButton() = onNodeWithContentDescription(getStringResource(R.string.browser_menu_translations)) + +private fun ComposeTestRule.translatedButton() = onNodeWithContentDescription(getStringResource(R.string.browser_menu_translated)) + +private fun ComposeTestRule.reportBrokenSiteButton() = onNodeWithContentDescription(getStringResource(R.string.browser_menu_webcompat_reporter_2)) + +private fun ComposeTestRule.printContentButton() = onNodeWithContentDescription(getStringResource(R.string.browser_menu_print_2)) + +private fun ComposeTestRule.defaultOpenInAppButton() = onNodeWithContentDescription(getStringResource(R.string.browser_menu_open_app_link)) + +private fun ComposeTestRule.openInAppNameButton(appName: String) = onNodeWithContentDescription(getStringResource(R.string.browser_menu_open_in_fenix, appName)) + +private fun ComposeTestRule.extensionsChevronButton() = onNodeWithTag(EXTENSIONS_OPTION_CHEVRON, useUnmergedTree = true) diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ThreeDotMenuMainRobotCompose.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ThreeDotMenuMainRobotCompose.kt @@ -1,692 +0,0 @@ -/* 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.util.Log -import androidx.compose.ui.test.ExperimentalTestApi -import androidx.compose.ui.test.assert -import androidx.compose.ui.test.assertIsDisplayed -import androidx.compose.ui.test.assertIsEnabled -import androidx.compose.ui.test.assertIsNotEnabled -import androidx.compose.ui.test.hasContentDescription -import androidx.compose.ui.test.hasTestTag -import androidx.compose.ui.test.junit4.ComposeTestRule -import androidx.compose.ui.test.onNodeWithContentDescription -import androidx.compose.ui.test.onNodeWithTag -import androidx.compose.ui.test.onNodeWithText -import androidx.compose.ui.test.performClick -import org.mozilla.fenix.R -import org.mozilla.fenix.components.menu.MenuDialogTestTag.DESKTOP_SITE_OFF -import org.mozilla.fenix.components.menu.MenuDialogTestTag.DESKTOP_SITE_ON -import org.mozilla.fenix.components.menu.MenuDialogTestTag.EXTENSIONS -import org.mozilla.fenix.components.menu.MenuDialogTestTag.EXTENSIONS_OPTION_CHEVRON -import org.mozilla.fenix.components.menu.MenuDialogTestTag.MORE_OPTION_CHEVRON -import org.mozilla.fenix.helpers.Constants.TAG -import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource -import org.mozilla.fenix.helpers.MatcherHelper.assertUIObjectExists -import org.mozilla.fenix.helpers.MatcherHelper.itemWithResId -import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime -import org.mozilla.fenix.helpers.TestAssetHelper.waitingTimeShort -import org.mozilla.fenix.helpers.TestHelper.appName -import org.mozilla.fenix.helpers.TestHelper.mDevice -import org.mozilla.fenix.helpers.TestHelper.packageName -import org.mozilla.fenix.helpers.TestHelper.waitForAppWindowToBeUpdated - -class ThreeDotMenuMainRobotCompose(private val composeTestRule: ComposeTestRule) { - - fun verifyMainMenuCFR() { - Log.i(TAG, "verifyMainMenuCFR: Trying to verify the main menu CFR title is displayed.") - composeTestRule.mainMenuCFRTitle().assertIsDisplayed() - Log.i(TAG, "verifyMainMenuCFR: Verified the main menu CFR title is displayed.") - Log.i(TAG, "verifyMainMenuCFR: Trying to verify the main menu CFR message is displayed.") - composeTestRule.mainMenuCFRMessage().assertIsDisplayed() - Log.i(TAG, "verifyMainMenuCFR: Verified the main menu CFR message is displayed.") - Log.i(TAG, "verifyMainMenuCFR: Trying to verify the main menu CFR dismiss button is displayed.") - composeTestRule.closeMainMenuCFRButton().assertIsDisplayed() - Log.i(TAG, "verifyMainMenuCFR: Verified the main menu CFR dismiss button is displayed.") - } - - fun verifyHomeMainMenuItems() { - Log.i(TAG, "verifyHomeMainMenuItems: Trying to verify that the \"Make Firefox your default\" button exists.") - verifyMakeFirefoxYourDefaultBrowserPromotionBanner() - Log.i(TAG, "verifyHomeMainMenuItems: Verified that the \"Make Firefox your default\" button exists.") - Log.i(TAG, "verifyHomeMainMenuItems: Trying to verify that the \"Extensions\" button exists.") - composeTestRule.extensionsButton().assertIsDisplayed() - Log.i(TAG, "verifyHomeMainMenuItems: Verified that the \"Extensions\" button exists.") - Log.i(TAG, "verifyHomeMainMenuItems: Trying to verify that the \"History\" button exists.") - composeTestRule.historyButton().assertIsDisplayed() - Log.i(TAG, "verifyHomeMainMenuItems: Verified that the \"History\" button exists.") - Log.i(TAG, "verifyHomeMainMenuItems: Trying to verify that the \"Bookmarks\" button exists.") - composeTestRule.bookmarksButton().assertIsDisplayed() - Log.i(TAG, "verifyHomeMainMenuItems: Verified that the \"Bookmarks\" button exists.") - Log.i(TAG, "verifyHomeMainMenuItems: Trying to verify that the \"Downloads\" button exists.") - composeTestRule.downloadsButton().assertIsDisplayed() - Log.i(TAG, "verifyHomeMainMenuItems: Verified that the \"Downloads\" button exists.") - Log.i(TAG, "verifyHomeMainMenuItems: Trying to verify that the \"Passwords\" button exists.") - composeTestRule.passwordsButton().assertIsDisplayed() - Log.i(TAG, "verifyHomeMainMenuItems: Verified that the \"Passwords\" button exists.") - Log.i(TAG, "verifyHomeMainMenuItems: Trying to verify that the \"Sign in\" button exists.") - composeTestRule.signInButton().assertIsDisplayed() - Log.i(TAG, "verifyHomeMainMenuItems: Verified that the \"Sign in\" button exists.") - Log.i(TAG, "verifyHomeMainMenuItems: Trying to verify that the \"Settings\" button exists.") - composeTestRule.settingsButton().assertIsDisplayed() - Log.i(TAG, "verifyHomeMainMenuItems: Verified that the \"Settings\" button exists.") - Log.i(TAG, "verifyHomeMainMenuItems: Verified the main menu items on the home page.") - } - - fun verifyPageMainMenuItems() { - Log.i(TAG, "verifyPageMainMenuItems: Trying to verify the main menu items on the web page.") - Log.i(TAG, "verifyPageMainMenuItems: Trying to verify that the \"Back\" button exists.") - composeTestRule.backButton().assertIsDisplayed() - Log.i(TAG, "verifyPageMainMenuItems: Verified that the \"Back\" button exists.") - Log.i(TAG, "verifyPageMainMenuItems: Trying to verify that the \"Forward\" button exists.") - composeTestRule.forwardButton().assertIsDisplayed() - Log.i(TAG, "verifyPageMainMenuItems: Verified that the \"Forward\" button exists.") - Log.i(TAG, "verifyPageMainMenuItems: Trying to verify that the \"Refresh\" button exists.") - composeTestRule.refreshButton().assertIsDisplayed() - Log.i(TAG, "verifyPageMainMenuItems: Verified that the \"Refresh\" button exists.") - Log.i(TAG, "verifyPageMainMenuItems: Trying to verify that the \"Share\" button exists.") - composeTestRule.shareButton().assertIsDisplayed() - Log.i(TAG, "verifyPageMainMenuItems: Verified that the \"Share\" button exists.") - Log.i(TAG, "verifyPageMainMenuItems: Trying to verify that the \"Bookmark page\" button exists.") - composeTestRule.bookmarkPageButton().assertIsDisplayed() - Log.i(TAG, "verifyPageMainMenuItems: Verified that the \"Bookmark page\" button exists.") - Log.i(TAG, "verifyPageMainMenuItems: Trying to verify that the \"Find in page\" button exists.") - composeTestRule.findInPageButton().assertIsDisplayed() - Log.i(TAG, "verifyPageMainMenuItems: Verified that the \"Find in page\" button exists.") - Log.i(TAG, "verifyPageMainMenuItems: Trying to verify that the \"Desktop site\" button exists.") - composeTestRule.desktopSiteButton().assertIsDisplayed() - Log.i(TAG, "verifyPageMainMenuItems: Verified that the \"Desktop site\" button exists.") - Log.i(TAG, "verifyPageMainMenuItems: Trying to verify that the \"Extensions\" button exists.") - composeTestRule.extensionsButton().assertIsDisplayed() - Log.i(TAG, "verifyPageMainMenuItems: Verified that the \"Extensions\" button exists.") - Log.i(TAG, "verifyPageMainMenuItems: Trying to verify that the \"More\" button exists.") - composeTestRule.moreButton().assertIsDisplayed() - Log.i(TAG, "verifyPageMainMenuItems: Verified that the \"More\" button exists.") - Log.i(TAG, "verifyPageMainMenuItems: Trying to verify that the \"History\" button exists.") - composeTestRule.historyButton().assertIsDisplayed() - Log.i(TAG, "verifyPageMainMenuItems: Verified that the \"History\" button exists.") - Log.i(TAG, "verifyPageMainMenuItems: Trying to verify that the \"Bookmarks\" button exists.") - composeTestRule.bookmarksButton().assertIsDisplayed() - Log.i(TAG, "verifyPageMainMenuItems: Verified that the \"Bookmarks\" button exists.") - Log.i(TAG, "verifyPageMainMenuItems: Trying to verify that the \"Downloads\" button exists.") - composeTestRule.downloadsButton().assertIsDisplayed() - Log.i(TAG, "verifyPageMainMenuItems: Verified that the \"Downloads\" button exists.") - Log.i(TAG, "verifyPageMainMenuItems: Trying to verify that the \"Passwords\" button exists.") - composeTestRule.passwordsButton().assertIsDisplayed() - Log.i(TAG, "verifyPageMainMenuItems: Verified that the \"Passwords\" button exists.") - Log.i(TAG, "verifyPageMainMenuItems: Trying to verify that the \"Sign in\" button exists.") - composeTestRule.signInButton().assertIsDisplayed() - Log.i(TAG, "verifyPageMainMenuItems: Verified that the \"Sign in\" button exists.") - Log.i(TAG, "verifyPageMainMenuItems: Trying to verify that the \"Settings\" button exists.") - composeTestRule.settingsButton().assertIsDisplayed() - Log.i(TAG, "verifyPageMainMenuItems: Verified that the \"Settings\" button exists.") - Log.i(TAG, "verifyPageMainMenuItems: Verified the main menu items on the web page.") - } - - fun openToolsMenu() { - Log.i( - TAG, - "openToolsMenu: Trying to click the Tools menu button from the new main menu design.", - ) - composeTestRule.toolsMenuButton().performClick() - composeTestRule.waitForIdle() - Log.i(TAG, "openToolsMenu: Clicked the Tools menu button from the new main menu design.") - } - - fun clickPrintContentButton() { - Log.i(TAG, "clickPrintContentButton: Trying to click the \"Print…\" button.") - composeTestRule.printContentButton().performClick() - Log.i(TAG, "clickPrintContentButton: Clicked the \"Print…\" button.") - } - - @OptIn(ExperimentalTestApi::class) - fun verifySwitchToDesktopSiteButtonIsEnabled(isEnabled: Boolean) { - Log.i(TAG, "verifySuggestedUserName: Waiting for the \"Desktop site\" button to exist") - composeTestRule.waitUntilAtLeastOneExists(hasContentDescription(getStringResource(R.string.browser_menu_desktop_site), substring = true)) - Log.i(TAG, "verifySuggestedUserName: Waited for the \"Desktop site\" button to exist") - Log.i(TAG, "verifySwitchToDesktopSiteButtonIsEnabled: Trying to verify the Switch to Desktop Site button from the new main menu design is enabled.") - if (isEnabled) { - composeTestRule.desktopSiteButton().assertIsEnabled() - Log.i(TAG, "verifySwitchToDesktopSiteButtonIsEnabled: Verified the Switch to Desktop Site button from the new main menu design is enabled.") - } else { - composeTestRule.desktopSiteButton().assertIsNotEnabled() - Log.i(TAG, "verifySwitchToDesktopSiteButtonIsEnabled: Verified the Switch to Desktop Site button from the new main menu design is disabled.") - } - } - - fun verifySwitchToDesktopSiteButton() { - Log.i(TAG, "verifySwitchToDesktopSiteButton: Trying to verify that the \"Switch to desktop site\" button is displayed.") - composeTestRule.desktopSiteButton().assertIsDisplayed() - Log.i(TAG, "verifySwitchToDesktopSiteButton: Verified that the \"Switch to desktop site\" button is displayed.") - } - - fun verifyDesktopSiteButtonState(isEnabled: Boolean) { - if (isEnabled) { - Log.i(TAG, "verifyDesktopSiteButtonState: Trying to verify that the \"Desktop site\" button is set to \"On\".") - composeTestRule.enabledDesktopSiteButton().assertIsDisplayed() - Log.i(TAG, "verifyDesktopSiteButtonState: Verified that the \"Desktop site\" button is set to \"On\".") - } else { - Log.i(TAG, "verifyDesktopSiteButtonState: Trying to verify that the \"Desktop site\" button is set to \"Off\".") - composeTestRule.disabledDesktopSiteButton().assertIsDisplayed() - Log.i(TAG, "verifyDesktopSiteButtonState: Verified that the \"Desktop site\" button is set to \"Off\".") - } - } - - fun clickSwitchToDesktopSiteButton() { - Log.i(TAG, "clickSwitchToDesktopSiteButton: Trying to click the \"Switch to desktop site\" button.") - composeTestRule.desktopSiteButton().performClick() - Log.i(TAG, "clickSwitchToDesktopSiteButton: Clicked the \"Switch to desktop site\" button.") - } - - fun verifyOpenInAppButtonIsEnabled(appName: String = "", isEnabled: Boolean) { - Log.i( - TAG, - "verifyOpenInAppButtonIsEnabled: Trying to verify the Open in App button from the new main menu design is enabled.", - ) - when (appName) { - "" -> composeTestRule.defaultOpenInAppButton().apply { - if (isEnabled) assertIsEnabled() else assertIsNotEnabled() - Log.i( - TAG, - "verifyOpenInAppButtonIsEnabled: Open in App button from the new main menu design is enabled = $isEnabled.", - ) - } - else -> composeTestRule.openInAppNameButton(appName).apply { - if (isEnabled) assertIsEnabled() else assertIsNotEnabled() - Log.i( - TAG, - "verifyOpenInAppButtonIsEnabled: Open in App button from the new main menu design is enabled = $isEnabled.", - ) - } - } - } - - fun clickOpenInAppButton(appName: String = "") { - Log.i( - TAG, - "clickOpenInAppButton: Trying to click the Open in App button from the new main menu design.", - ) - when (appName) { - "" -> composeTestRule.defaultOpenInAppButton().performClick() - else -> composeTestRule.openInAppNameButton(appName).performClick() - } - Log.i( - TAG, - "clickOpenInAppButton: Clicked the Open in App button from the new main menu design.", - ) - mDevice.waitForIdle() - } - - @OptIn(ExperimentalTestApi::class) - fun verifyExtensionsButtonWithInstalledExtension(extensionTitle: String) { - Log.i(TAG, "verifyExtensionsButtonWithInstalledExtension: Waiting for $waitingTime for the collapsed \"Extensions\" button with installed $extensionTitle to exist.") - composeTestRule.waitUntilAtLeastOneExists(hasContentDescription(extensionTitle, substring = true, ignoreCase = true), waitingTime) - Log.i(TAG, "verifyExtensionsButtonWithInstalledExtension: Waited for $waitingTime for the collapsed \"Extensions\" button with installed $extensionTitle to exist.") - Log.i(TAG, "verifyExtensionsButtonWithInstalledExtension: Trying to verify that the collapsed \"Extensions\" button with installed $extensionTitle exists.") - composeTestRule.onNode( - hasTestTag("mainMenu.extensions"), - ).assert( - hasContentDescription(extensionTitle, substring = true, ignoreCase = true), - ).assertIsDisplayed() - Log.i(TAG, "verifyExtensionsButtonWithInstalledExtension: Verified that the collapsed \"Extensions\" button with installed $extensionTitle exists.") - } - - @OptIn(ExperimentalTestApi::class) - fun verifyTryRecommendedExtensionButton() { - Log.i(TAG, "verifyTryRecommendedExtensionButton: Waiting for $waitingTime for the \"Extensions - Try a recommended extension\" button to exists.") - composeTestRule.waitUntilAtLeastOneExists(hasContentDescription("Extensions Try a recommended extension", substring = true), waitingTime) - Log.i(TAG, "verifyTryRecommendedExtensionButton: Waited for $waitingTime for the \"Extensions - Try a recommended extension\" button to exists.") - Log.i(TAG, "verifyTryRecommendedExtensionButton: Trying to verify that the \"Extensions - Try a recommended extension\" button exists.") - composeTestRule.tryRecommendedExtensionButton().assertExists() - Log.i(TAG, "verifyTryRecommendedExtensionButton: Verified that the \"Extensions - Try a recommended extension\" button exists.") - } - - fun verifyNoExtensionsEnabledButton() { - Log.i(TAG, "verifyNoExtensionsEnabledButton: Trying to verify that the \"Extensions - Try a recommended extension\" button exists.") - composeTestRule.noExtensionsEnabledButton().assertExists() - Log.i(TAG, "verifyNoExtensionsEnabledButton: Verified that the \"Extensions - Try a recommended extension\" button exists.") - } - - fun clickSaveButton() { - Log.i(TAG, "clickSaveButton: Trying to click the \"Save\" button from the new main menu design.") - composeTestRule.saveMenuButton().performClick() - Log.i(TAG, "clickSaveButton: Clicked the \"Save\" button from the new main menu design.") - } - - fun openMoreMenu() { - Log.i(TAG, "openMoreMenu: Trying to click the \"More\" button from the new main menu design.") - composeTestRule.moreButton().performClick() - Log.i(TAG, "openMoreMenu: Clicked the \"More\" button from the new main menu design.") - waitForAppWindowToBeUpdated() - } - - fun clickMoreOptionChevron() { - Log.i(TAG, "clickMoreOptionChevron: Trying to click the \"More option chevron\" button from the new main menu design.") - composeTestRule.moreChevronButton().performClick() - Log.i(TAG, "clickMoreOptionChevron: Clicked the \"More option chevron\" button from the new main menu design.") - waitForAppWindowToBeUpdated() - } - - fun verifyBookmarkThisPageButton() { - composeTestRule.bookmarkPageButton().assertIsDisplayed() - } - - fun clickQuitFirefoxButton() { - Log.i(TAG, "clickQuitFirefoxButton: Trying to click the \"Quit $appName\" button from the new main menu design.") - composeTestRule.quitFirefoxButton().performClick() - Log.i(TAG, "clickQuitFirefoxButton: Clicked the \"Quit $appName\" button from the new main menu design.") - } - - fun verifyTranslatePageButton() { - Log.i(TAG, "verifyTranslatePageButton: Trying to verify that the \"Translate page\" button exists.") - composeTestRule.translatePageButton().assertIsDisplayed() - Log.i(TAG, "verifyTranslatePageButton: Verified that the \"Translate page\" button exists.") - } - - fun verifyMakeFirefoxYourDefaultBrowserPromotionBanner() { - composeTestRule.onNodeWithText(getStringResource(R.string.browser_menu_default_banner_title, appName)).assertIsDisplayed() - composeTestRule.onNodeWithText(getStringResource(R.string.browser_menu_default_banner_subtitle_2)).assertIsDisplayed() - composeTestRule.onNodeWithContentDescription(getStringResource(R.string.browser_menu_default_banner_dismiss_promotion)).assertIsDisplayed() - } - - fun verifyMoreMainMenuItems() { - Log.i(TAG, "verifyMoreMainMenuItems: Trying to verify the more main menu items on the web page.") - Log.i(TAG, "verifyMoreMainMenuItems: Trying to verify that the \"Translate page\" button exists.") - composeTestRule.translatePageButton().assertIsDisplayed() - Log.i(TAG, "verifyMoreMainMenuItems: Verified that the \"Translate page\" button exists.") - Log.i(TAG, "verifyMoreMainMenuItems: Trying to verify that the \"Report broken site\" button exists.") - composeTestRule.reportBrokenSiteButton().assertIsDisplayed() - Log.i(TAG, "verifyMoreMainMenuItems: Verified that the \"Report broken site\" button exists.") - Log.i(TAG, "verifyMoreMainMenuItems: Trying to verify that the \"Add to shortcuts\" button exists.") - composeTestRule.addToShortcutsButton().assertIsDisplayed() - Log.i(TAG, "verifyMoreMainMenuItems: Verified that the \"Add to shortcuts\" button exists.") - Log.i(TAG, "verifyMoreMainMenuItems: Trying to verify that the \"Add app to Home screen\" button exists.") - composeTestRule.addToHomeScreenButton().assertIsDisplayed() - Log.i(TAG, "verifyMoreMainMenuItems: Verified that the \"Add app to Home screen\" button exists.") - Log.i(TAG, "verifyMoreMainMenuItems: Trying to verify that the \"Save to collection\" button exists.") - composeTestRule.saveToCollectionButton().assertIsDisplayed() - Log.i(TAG, "verifyMoreMainMenuItems: Verified that the \"Save to collection\" button exists.") - Log.i(TAG, "verifyMoreMainMenuItems: Trying to verify that the \"Open in app\" button exists.") - composeTestRule.defaultOpenInAppButton().assertIsDisplayed() - Log.i(TAG, "verifyMoreMainMenuItems: Verified that the \"Open in app\" button exists.") - Log.i(TAG, "verifyMoreMainMenuItems: Trying to verify that the \"Save as PDF\" button exists.") - composeTestRule.saveAsPDFButton().assertIsDisplayed() - Log.i(TAG, "verifyMoreMainMenuItems: Verified that the \"Save as PDF\" button exists.") - Log.i(TAG, "verifyMoreMainMenuItems: Trying to verify that the \"Print\" button exists.") - composeTestRule.printContentButton().assertIsDisplayed() - Log.i(TAG, "verifyMoreMainMenuItems: Verified that the \"Print\" button exists.") - Log.i(TAG, "verifyMoreMainMenuItems: Verified the more main menu items on the web page.") - } - - class Transition(private val composeTestRule: ComposeTestRule) { - fun openSettings( - interact: SettingsRobot.() -> Unit, - ): SettingsRobot.Transition { - Log.i( - TAG, - "openSettings: Trying to click the Settings button from the new main menu design.", - ) - composeTestRule.settingsButton().performClick() - Log.i(TAG, "openSettings: Clicked the Settings button from the new main menu design.") - - SettingsRobot().interact() - return SettingsRobot.Transition() - } - - fun clickFindInPageButton( - interact: FindInPageRobot.() -> Unit, - ): FindInPageRobot.Transition { - Log.i( - TAG, - "clickFindInPageButton: Trying to click the FindInPage button from the new main menu design.", - ) - composeTestRule.findInPageButton().performClick() - Log.i(TAG, "clickFindInPageButton: Clicked the FindInPage button from the new main menu design.") - - FindInPageRobot().interact() - return FindInPageRobot.Transition() - } - - fun openBookmarks( - composeTestRule: ComposeTestRule, - interact: BookmarksRobot.() -> Unit, - ): BookmarksRobot.Transition { - Log.i( - TAG, - "openBookmarks: Trying to click the Bookmarks button from the new main menu design.", - ) - composeTestRule.bookmarksButton().performClick() - Log.i(TAG, "openBookmarks: Clicked the Bookmarks button from the new main menu design.") - - BookmarksRobot(composeTestRule).interact() - return BookmarksRobot.Transition(composeTestRule) - } - - fun clickSignInMainMenuButton( - composeTestRule: ComposeTestRule, - interact: SyncSignInRobot.() -> Unit, - ): SyncSignInRobot.Transition { - Log.i(TAG, "clickSignInMainMenuButton: Trying to click \"Sign in\" main menu button") - composeTestRule.onNodeWithContentDescription("Sign in Sync passwords, bookmarks, and more").performClick() - Log.i(TAG, "clickSignInMainMenuButton: Clicked \"Sign in\" main menu button") - - SyncSignInRobot().interact() - return SyncSignInRobot.Transition() - } - - fun openHistory( - interact: HistoryRobot.() -> Unit, - ): HistoryRobot.Transition { - Log.i( - TAG, - "openHistory: Trying to click the History button from the new main menu design.", - ) - composeTestRule.historyButton().performClick() - Log.i(TAG, "openHistory: Clicked the History button from the new main menu design.") - - HistoryRobot().interact() - return HistoryRobot.Transition() - } - - fun openDownloads( - interact: DownloadRobot.() -> Unit, - ): DownloadRobot.Transition { - Log.i( - TAG, - "openDownloads: Trying to click the Download button from the new main menu design.", - ) - composeTestRule.downloadsButton().performClick() - Log.i(TAG, "openDownloads: Clicked the Download button from the new main menu design.") - - DownloadRobot().interact() - return DownloadRobot.Transition() - } - - fun openPasswords( - interact: SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot.() -> Unit, - ): SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot.Transition { - Log.i( - TAG, - "openPasswords: Trying to click the Download button from the new main menu design.", - ) - composeTestRule.passwordsButton().performClick() - Log.i(TAG, "openPasswords: Clicked the Download button from the new main menu design.") - - SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot().interact() - return SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot.Transition() - } - - fun openExtensionsFromMainMenu(interact: SettingsSubMenuAddonsManagerRobot.() -> Unit): SettingsSubMenuAddonsManagerRobot.Transition { - Log.i(TAG, "openExtensionsFromMainMenu: Trying to click the \"Extensions\" button") - assertUIObjectExists(itemWithResId("mainMenu.extensions")) - itemWithResId("mainMenu.extensions").clickAndWaitForNewWindow(waitingTimeShort) - Log.i(TAG, "openExtensionsFromMainMenu: Clicked the \"Extensions\" button") - composeTestRule.waitForIdle() - waitForAppWindowToBeUpdated() - - SettingsSubMenuAddonsManagerRobot().interact() - return SettingsSubMenuAddonsManagerRobot.Transition() - } - - @OptIn(ExperimentalTestApi::class) - fun clickExtensionsChevronFromMainMenu(interact: SettingsSubMenuAddonsManagerRobot.() -> Unit): SettingsSubMenuAddonsManagerRobot.Transition { - Log.i(TAG, "clickExtensionsChevronFromMainMenu: Trying to click the \"Extensions chevron\" button from the new main menu design.") - composeTestRule.extensionsChevronButton().performClick() - Log.i(TAG, "clickExtensionsChevronFromMainMenu: Clicked the \"Extensions chevron\" button from the new main menu design.") - - SettingsSubMenuAddonsManagerRobot().interact() - return SettingsSubMenuAddonsManagerRobot.Transition() - } - - fun clickBookmarkThisPageButton(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { - Log.i(TAG, "clickBookmarkThisPageButton: Trying to click the \"Bookmark this page\" button from the new main menu design.") - composeTestRule.bookmarkPageButton().performClick() - Log.i(TAG, "clickBookmarkThisPageButton: Clicked the \"Bookmark this page\" button from the new main menu design.") - - BrowserRobot().interact() - return BrowserRobot.Transition() - } - - fun clickAddToShortcutsButton(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { - Log.i(TAG, "clickAddToShortcutsButton: Trying to click the \"Add to shortcuts\" button from the new main menu design.") - composeTestRule.addToShortcutsButton().performClick() - Log.i(TAG, "clickAddToShortcutsButton: Clicked the \"Add to shortcuts\" button from the new main menu design.") - - BrowserRobot().interact() - return BrowserRobot.Transition() - } - - fun clickRemoveFromShortcutsButton(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { - Log.i(TAG, "clickRemoveFromShortcutsButton: Trying to click the \"Remove from shortcuts\" button from the new main menu design.") - composeTestRule.removeFromShortcutsButton().performClick() - Log.i(TAG, "clickRemoveFromShortcutsButton: Clicked the \"Remove from shortcuts\" button from the new main menu design.") - - BrowserRobot().interact() - return BrowserRobot.Transition() - } - - fun clickEditBookmarkButton(composeTestRule: ComposeTestRule, interact: BookmarksRobot.() -> Unit): BookmarksRobot.Transition { - Log.i(TAG, "clickEditBookmarkButton: Trying to click the \"Edit bookmark\" button from the new main menu design.") - composeTestRule.editBookmarkButton().performClick() - Log.i(TAG, "clickEditBookmarkButton: Clicked the \"Edit bookmark\" button from the new main menu design.") - - BookmarksRobot(composeTestRule).interact() - return BookmarksRobot.Transition(composeTestRule) - } - - fun clickAddToHomeScreenButton(interact: AddToHomeScreenRobot.() -> Unit): AddToHomeScreenRobot.Transition { - Log.i(TAG, "clickAddToHomeScreenButton: Trying to click the \"Add to Home screen…\" button from the new main menu design.") - composeTestRule.addToHomeScreenButton().performClick() - Log.i(TAG, "clickAddToHomeScreenButton: Clicked the \"Add to Home screen…\" button from the new main menu design.") - - AddToHomeScreenRobot().interact() - return AddToHomeScreenRobot.Transition() - } - - fun clickSaveToCollectionButton(interact: CollectionRobot.() -> Unit): CollectionRobot.Transition { - Log.i(TAG, "clickSaveToCollectionButton: Trying to click the \"Save to collection…\" button from the new main menu design.") - composeTestRule.saveToCollectionButton().performClick() - Log.i(TAG, "clickSaveToCollectionButton: Clicked the \"Save to collection…\" button from the new main menu design.") - - CollectionRobot().interact() - return CollectionRobot.Transition() - } - - fun clickSaveAsPDFButton(interact: DownloadRobot.() -> Unit): DownloadRobot.Transition { - Log.i(TAG, "clickSaveAsPDFButton: Trying to click the \"Save as PDF…\" button from the new main menu design.") - composeTestRule.saveAsPDFButton().performClick() - Log.i(TAG, "clickSaveAsPDFButton: Clicked the \"Save as PDF…\" button from the new main menu design.") - - DownloadRobot().interact() - return DownloadRobot.Transition() - } - - fun clickTranslateButton(interact: TranslationsRobot.() -> Unit): TranslationsRobot.Transition { - Log.i(TAG, "clickTranslateButton: Trying to click the Translate button from the new main menu design.") - composeTestRule.translatePageButton().performClick() - Log.i(TAG, "clickTranslateButton: Clicked the Translate button from the new main menu design.") - Log.i(TAG, "clickTranslateButton: Waiting for compose test rule to be idle") - composeTestRule.waitForIdle() - Log.i(TAG, "clickTranslateButton: Waited for compose test rule to be idle") - - TranslationsRobot(composeTestRule).interact() - return TranslationsRobot.Transition(composeTestRule) - } - - fun clickTranslatedButton(interact: TranslationsRobot.() -> Unit): TranslationsRobot.Transition { - Log.i( - TAG, - "clickTranslateButton: Trying to click the Translate button from the new main menu design.", - ) - composeTestRule.translatedButton().assertIsDisplayed() - composeTestRule.translatedButton().performClick() - Log.i( - TAG, - "clickTranslateButton: Clicked the Translate button from the new main menu design.", - ) - TranslationsRobot(composeTestRule).interact() - return TranslationsRobot.Transition(composeTestRule) - } - - fun clickShareButton(interact: ShareOverlayRobot.() -> Unit): ShareOverlayRobot.Transition { - Log.i(TAG, "clickShareButton: Trying to click the Share button from the new main menu design.") - composeTestRule.shareButton().performClick() - Log.i(TAG, "clickShareButton: Clicked the Share button from the new main menu design.") - - ShareOverlayRobot().interact() - return ShareOverlayRobot.Transition() - } - - fun clickOutsideTheMainMenu(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { - Log.i(TAG, "clickOutsideTheMainMenu: Trying to click outside the main menu.") - itemWithResId("$packageName:id/touch_outside").clickTopLeft() - Log.i(TAG, "clickOutsideTheMainMenu: Clicked click outside the main menu.") - - BrowserRobot().interact() - return BrowserRobot.Transition() - } - - fun clickReportBrokenSiteButton(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { - Log.i(TAG, "openReportSiteIssue: Trying to click the \"Report Site Issue\" button") - composeTestRule.reportBrokenSiteButton().performClick() - Log.i(TAG, "openReportSiteIssue: Clicked the \"Report Site Issue\" button") - - BrowserRobot().interact() - return BrowserRobot.Transition() - } - - fun openReportBrokenSite(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { - Log.i(TAG, "openReportBrokenSite: Trying to click the \"Report broken site\" button") - composeTestRule.reportBrokenSiteButton().performClick() - Log.i(TAG, "openReportBrokenSite: Clicked the \"Report broken site\" button") - - BrowserRobot().interact() - return BrowserRobot.Transition() - } - - fun closeMainMenu(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition { - Log.i(TAG, "closeMainMenu: Trying to click the device back button") - mDevice.pressBack() - Log.i(TAG, "closeMainMenu: Clicked the device back button") - - HomeScreenRobot().interact() - return HomeScreenRobot.Transition() - } - - fun goForward(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { - Log.i(TAG, "goForward: Trying to click the \"Forward\" button") - composeTestRule.forwardButton().performClick() - Log.i(TAG, "goForward: Clicked the \"Forward\" button") - - BrowserRobot().interact() - return BrowserRobot.Transition() - } - - fun goToPreviousPage(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { - Log.i(TAG, "goToPreviousPage: Trying to click the \"Back\" button") - composeTestRule.backButton().performClick() - Log.i(TAG, "goToPreviousPage: Clicked the \"Back\" button") - - BrowserRobot().interact() - return BrowserRobot.Transition() - } - - fun clickRefreshButton(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { - Log.i(TAG, "clickRefreshButton: Trying to click the \"Refresh\" button") - composeTestRule.refreshButton().performClick() - Log.i(TAG, "clickRefreshButton: Clicked the \"Refresh\" button") - - BrowserRobot().interact() - return BrowserRobot.Transition() - } - } -} - -fun mainMenuScreen(composeTestRule: ComposeTestRule, interact: ThreeDotMenuMainRobotCompose.() -> Unit): ThreeDotMenuMainRobotCompose.Transition { - ThreeDotMenuMainRobotCompose(composeTestRule).interact() - return ThreeDotMenuMainRobotCompose.Transition(composeTestRule) -} - -private fun ComposeTestRule.mainMenuCFRTitle() = onNodeWithText(getStringResource(R.string.menu_cfr_title)) - -private fun ComposeTestRule.mainMenuCFRMessage() = onNodeWithText(getStringResource(R.string.menu_cfr_body)) - -private fun ComposeTestRule.closeMainMenuCFRButton() = onNodeWithTag("cfr.dismiss") - -private fun ComposeTestRule.backButton() = onNodeWithText("Back") - -private fun ComposeTestRule.forwardButton() = onNodeWithText("Forward") - -private fun ComposeTestRule.refreshButton() = onNodeWithText("Refresh") - -private fun ComposeTestRule.shareButton() = onNodeWithText("Share") - -private fun ComposeTestRule.signInButton() = onNodeWithContentDescription("Sign in Sync passwords, bookmarks, and more") - -private fun ComposeTestRule.settingsButton() = onNodeWithContentDescription("Settings") - -private fun ComposeTestRule.extensionsButton() = onNodeWithTag(EXTENSIONS) - -private fun ComposeTestRule.tryRecommendedExtensionButton() = onNodeWithContentDescription("Extensions Try a recommended extension", substring = true) - -private fun ComposeTestRule.noExtensionsEnabledButton() = onNodeWithContentDescription("Extensions No extensions enabled", substring = true) - -private fun ComposeTestRule.moreButton() = onNodeWithContentDescription(getStringResource(R.string.browser_menu_more_settings), substring = true) - -private fun ComposeTestRule.moreChevronButton() = onNodeWithTag(MORE_OPTION_CHEVRON, useUnmergedTree = true) - -private fun ComposeTestRule.bookmarksButton() = onNodeWithContentDescription(getStringResource(R.string.library_bookmarks), substring = true) - -private fun ComposeTestRule.historyButton() = onNodeWithContentDescription(getStringResource(R.string.library_history), substring = true) - -private fun ComposeTestRule.downloadsButton() = onNodeWithContentDescription(getStringResource(R.string.library_downloads), substring = true) - -private fun ComposeTestRule.passwordsButton() = onNodeWithContentDescription(getStringResource(R.string.browser_menu_passwords), substring = true) - -private fun ComposeTestRule.quitFirefoxButton() = onNodeWithContentDescription("Quit $appName") - -// Page main menu items - -private fun ComposeTestRule.findInPageButton() = onNodeWithContentDescription(getStringResource(R.string.browser_menu_find_in_page), substring = true) - -private fun ComposeTestRule.toolsMenuButton() = onNodeWithTag("mainMenu.tools") - -private fun ComposeTestRule.saveMenuButton() = onNodeWithTag("mainMenu.save") - -private fun ComposeTestRule.bookmarkPageButton() = onNodeWithContentDescription(getStringResource(R.string.browser_menu_bookmark_this_page_2)) - -private fun ComposeTestRule.desktopSiteButton() = onNodeWithContentDescription(getStringResource(R.string.browser_menu_desktop_site), substring = true) - -private fun ComposeTestRule.enabledDesktopSiteButton() = onNodeWithTag(DESKTOP_SITE_ON) - -private fun ComposeTestRule.disabledDesktopSiteButton() = onNodeWithTag(DESKTOP_SITE_OFF) - -// Save sub menu items - -private fun ComposeTestRule.editBookmarkButton() = onNodeWithContentDescription(getStringResource(R.string.browser_menu_edit_bookmark)) - -private fun ComposeTestRule.addToShortcutsButton() = onNodeWithContentDescription(getStringResource(R.string.browser_menu_add_to_shortcuts)) - -private fun ComposeTestRule.removeFromShortcutsButton() = onNodeWithContentDescription(getStringResource(R.string.browser_menu_remove_from_shortcuts)) - -private fun ComposeTestRule.addToHomeScreenButton() = onNodeWithContentDescription(getStringResource(R.string.browser_menu_add_to_homescreen)) - -private fun ComposeTestRule.saveToCollectionButton() = onNodeWithContentDescription(getStringResource(R.string.browser_menu_save_to_collection_2)) - -private fun ComposeTestRule.saveAsPDFButton() = onNodeWithContentDescription(getStringResource(R.string.browser_menu_save_as_pdf_2)) - -private fun ComposeTestRule.translatePageButton() = onNodeWithContentDescription(getStringResource(R.string.browser_menu_translations)) - -private fun ComposeTestRule.translatedButton() = onNodeWithContentDescription(getStringResource(R.string.browser_menu_translated)) - -private fun ComposeTestRule.reportBrokenSiteButton() = onNodeWithContentDescription(getStringResource(R.string.browser_menu_webcompat_reporter_2)) - -private fun ComposeTestRule.printContentButton() = onNodeWithContentDescription(getStringResource(R.string.browser_menu_print_2)) - -private fun ComposeTestRule.defaultOpenInAppButton() = onNodeWithContentDescription(getStringResource(R.string.browser_menu_open_app_link)) - -private fun ComposeTestRule.openInAppNameButton(appName: String) = onNodeWithContentDescription(getStringResource(R.string.browser_menu_open_in_fenix, appName)) - -private fun ComposeTestRule.extensionsChevronButton() = onNodeWithTag(EXTENSIONS_OPTION_CHEVRON, useUnmergedTree = true) diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/TranslationsRobot.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/TranslationsRobot.kt @@ -49,13 +49,13 @@ class TranslationsRobot(private val composeTestRule: ComposeTestRule) { throw e } else { if (isRedesignedToolbarEnabled) { - browserScreen { + browserScreen(composeTestRule) { refreshPageFromRedesignedToolbar() } } else { - navigationToolbar { + browserScreen(composeTestRule) { }.openThreeDotMenu { - }.refreshPage { + }.clickRefreshButton { } } } @@ -303,8 +303,8 @@ class TranslationsRobot(private val composeTestRule: ComposeTestRule) { } } - BrowserRobot().interact() - return BrowserRobot.Transition() + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } fun clickShowOriginalButton(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { @@ -312,8 +312,8 @@ class TranslationsRobot(private val composeTestRule: ComposeTestRule) { composeTestRule.onNodeWithText("Show original").performClick() Log.i(TAG, "clickShowOriginalButton: Clicked on the Show Original button.") - BrowserRobot().interact() - return BrowserRobot.Transition() + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } fun clickNotNowButton(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { @@ -321,8 +321,8 @@ class TranslationsRobot(private val composeTestRule: ComposeTestRule) { composeTestRule.onNodeWithText(getStringResource(R.string.translations_bottom_sheet_negative_button)).performClick() Log.i(TAG, "clickShowOriginalButton: Clicked on the \"Not now\" button.") - BrowserRobot().interact() - return BrowserRobot.Transition() + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } fun swipeCloseTranslationsSheet(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { @@ -344,8 +344,8 @@ class TranslationsRobot(private val composeTestRule: ComposeTestRule) { } } - BrowserRobot().interact() - return BrowserRobot.Transition() + BrowserRobot(composeTestRule).interact() + return BrowserRobot.Transition(composeTestRule) } fun clickTranslationSettingsButton(interact: SettingsTranslationsRobot.() -> Unit): SettingsTranslationsRobot.Transition { diff --git a/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/UnifiedTrustPanelRobot.kt b/mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/UnifiedTrustPanelRobot.kt @@ -1,9 +1,12 @@ package org.mozilla.fenix.ui.robots import android.util.Log +import androidx.compose.ui.test.assert import androidx.compose.ui.test.assertIsDisplayed +import androidx.compose.ui.test.hasText import androidx.compose.ui.test.junit4.ComposeTestRule import androidx.compose.ui.test.onNodeWithContentDescription +import androidx.compose.ui.test.onNodeWithTag import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.performClick import androidx.core.text.HtmlCompat @@ -18,6 +21,7 @@ class UnifiedTrustPanelRobot { fun verifyUnifiedTrustPanelItems( composeTestRule: ComposeTestRule, webSite: String, + shouldWebSiteURLBeDisplayed: Boolean = true, webSiteURL: String, isTheWebSiteSecure: Boolean, isEnhancedTrackingProtectionEnabled: Boolean, @@ -26,11 +30,13 @@ class UnifiedTrustPanelRobot { ) { waitForAppWindowToBeUpdated() Log.i(TAG, "verifyUnifiedTrustPanelItems: Trying to verify that the web site title: $webSite is displayed") - composeTestRule.onNodeWithText(webSite, useUnmergedTree = true).assertIsDisplayed() + composeTestRule.onNodeWithTag("unified.trust.panel.website").assert(hasText(webSite)) Log.i(TAG, "verifyUnifiedTrustPanelItems: Verified that the web site title: $webSite is displayed") - Log.i(TAG, "verifyUnifiedTrustPanelItems: Trying to verify that the web site url: $webSiteURL is displayed") - composeTestRule.onNodeWithText(webSiteURL, useUnmergedTree = true, substring = true).assertIsDisplayed() - Log.i(TAG, "verifyUnifiedTrustPanelItems: Verified that the web site url: $webSiteURL is displayed") + if (shouldWebSiteURLBeDisplayed) { + Log.i(TAG, "verifyUnifiedTrustPanelItems: Trying to verify that the web site url: $webSiteURL is displayed") + composeTestRule.onNodeWithTag("unified.trust.panel.website.url").assert(hasText(webSiteURL)) + Log.i(TAG, "verifyUnifiedTrustPanelItems: Verified that the web site url: $webSiteURL is displayed") + } verifyTheEnhancedTrackingProtectionState(composeTestRule, isEnhancedTrackingProtectionEnabled, isTheWebSiteSecure) verifyTheTrackersBlockedOptionState(composeTestRule, isTrackerBlockingEnabled, areTrackersBlocked) verifyTheSiteSecurityOption(composeTestRule, isTheWebSiteSecure) diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/trustpanel/ui/ProtectionPanelHeader.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/trustpanel/ui/ProtectionPanelHeader.kt @@ -21,6 +21,9 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.asImageBitmap +import androidx.compose.ui.semantics.semantics +import androidx.compose.ui.semantics.testTag +import androidx.compose.ui.semantics.testTagsAsResourceId import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.PreviewLightDark @@ -63,6 +66,10 @@ internal fun ProtectionPanelHeader( maxLines = 1, style = FirefoxTheme.typography.headline7, overflow = TextOverflow.Ellipsis, + modifier = Modifier.semantics { + testTagsAsResourceId = true + testTag = "unified.trust.panel.website" + }, ) if (websiteInfoState.websiteTitle.isNotEmpty()) { @@ -70,6 +77,10 @@ internal fun ProtectionPanelHeader( text = websiteInfoState.websiteUrl.tryGetHostFromUrl(), color = MaterialTheme.colorScheme.onSurfaceVariant, style = FirefoxTheme.typography.body2, + modifier = Modifier.semantics { + testTagsAsResourceId = true + testTag = "unified.trust.panel.website.url" + }, ) } }