From 24fd376707a15e77ddacca7c3507a907e7437d8a Mon Sep 17 00:00:00 2001 From: sv-ohorvath Date: Mon, 30 May 2022 16:52:24 +0300 Subject: [PATCH] Refactor collections UI tests for Compose --- .../fenix/helpers/FeatureSettingsHelper.kt | 6 + .../mozilla/fenix/helpers/TestAssetHelper.kt | 1 + .../org/mozilla/fenix/ui/CollectionTest.kt | 566 ++++++++++++------ .../fenix/ui/robots/CollectionRobot.kt | 359 ++++++----- .../fenix/ui/robots/HomeScreenRobot.kt | 34 +- .../fenix/ui/robots/ShareOverlayRobot.kt | 9 +- .../mozilla/fenix/ui/robots/TabDrawerRobot.kt | 90 ++- 7 files changed, 630 insertions(+), 435 deletions(-) diff --git a/app/src/androidTest/java/org/mozilla/fenix/helpers/FeatureSettingsHelper.kt b/app/src/androidTest/java/org/mozilla/fenix/helpers/FeatureSettingsHelper.kt index 2246a469fd..2ed17ff692 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/helpers/FeatureSettingsHelper.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/helpers/FeatureSettingsHelper.kt @@ -16,6 +16,7 @@ class FeatureSettingsHelper { private var isPocketEnabled: Boolean = settings.showPocketRecommendationsFeature private var isJumpBackInCFREnabled: Boolean = settings.shouldShowJumpBackInCFR private var isRecentTabsFeatureEnabled: Boolean = settings.showRecentTabsFeature + private var isRecentlyVisitedFeatureEnabled: Boolean = settings.historyMetadataUIFeature private var isUserKnowsAboutPwasTrue: Boolean = settings.userKnowsAboutPwas fun setPocketEnabled(enabled: Boolean) { @@ -30,6 +31,10 @@ class FeatureSettingsHelper { settings.showRecentTabsFeature = enabled } + fun setRecentlyVisitedFeatureEnabled(enabled: Boolean) { + settings.historyMetadataUIFeature = enabled + } + fun setStrictETPEnabled() { settings.setStrictETP() } @@ -49,6 +54,7 @@ class FeatureSettingsHelper { settings.showPocketRecommendationsFeature = isPocketEnabled settings.shouldShowJumpBackInCFR = isJumpBackInCFREnabled settings.showRecentTabsFeature = isRecentTabsFeatureEnabled + settings.historyMetadataUIFeature = isRecentlyVisitedFeatureEnabled settings.userKnowsAboutPwas = isUserKnowsAboutPwasTrue } } diff --git a/app/src/androidTest/java/org/mozilla/fenix/helpers/TestAssetHelper.kt b/app/src/androidTest/java/org/mozilla/fenix/helpers/TestAssetHelper.kt index bef92460e8..1b60d89b82 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/helpers/TestAssetHelper.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/helpers/TestAssetHelper.kt @@ -15,6 +15,7 @@ import org.mozilla.fenix.helpers.ext.toUri object TestAssetHelper { @Suppress("MagicNumber") val waitingTime: Long = TimeUnit.SECONDS.toMillis(15) + val waitingTimeLong = TimeUnit.SECONDS.toMillis(25) val waitingTimeShort: Long = TimeUnit.SECONDS.toMillis(3) data class TestAsset(val url: Uri, val content: String, val title: String) diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/CollectionTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/CollectionTest.kt index 1bc08847db..b8553dcb40 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/CollectionTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/CollectionTest.kt @@ -4,19 +4,24 @@ package org.mozilla.fenix.ui +import androidx.compose.ui.test.junit4.AndroidComposeTestRule import androidx.test.platform.app.InstrumentationRegistry import androidx.test.uiautomator.UiDevice 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.SmokeTest import org.mozilla.fenix.helpers.AndroidAssetDispatcher import org.mozilla.fenix.helpers.FeatureSettingsHelper -import org.mozilla.fenix.helpers.HomeActivityTestRule +import org.mozilla.fenix.helpers.HomeActivityIntentTestRule import org.mozilla.fenix.helpers.TestAssetHelper.getGenericAsset +import org.mozilla.fenix.ui.robots.browserScreen +import org.mozilla.fenix.ui.robots.collectionRobot +import org.mozilla.fenix.ui.robots.homeScreen import org.mozilla.fenix.ui.robots.navigationToolbar +import org.mozilla.fenix.ui.robots.tabDrawer /** * Tests for verifying basic functionality of tab collections @@ -24,24 +29,27 @@ import org.mozilla.fenix.ui.robots.navigationToolbar */ class CollectionTest { - /* ktlint-disable no-blank-line-before-rbrace */ - // This imposes unreadable grouping. - private val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) private lateinit var mockWebServer: MockWebServer private val firstCollectionName = "testcollection_1" private val secondCollectionName = "testcollection_2" + private val collectionName = "First Collection" private val featureSettingsHelper = FeatureSettingsHelper() @get:Rule - val activityTestRule = HomeActivityTestRule() + val composeTestRule = AndroidComposeTestRule( + HomeActivityIntentTestRule(), + { it.activity } + ) @Before fun setUp() { - // disabling these features to have better visibility of Collections + // disabling these features to have better visibility of Collections, + // and to avoid multiple matches on tab items featureSettingsHelper.setRecentTabsFeatureEnabled(false) featureSettingsHelper.setPocketEnabled(false) featureSettingsHelper.setJumpBackCFREnabled(false) + featureSettingsHelper.setRecentlyVisitedFeatureEnabled(false) mockWebServer = MockWebServer().apply { dispatcher = AndroidAssetDispatcher() @@ -57,6 +65,171 @@ class CollectionTest { featureSettingsHelper.resetAllFeatureFlags() } + @SmokeTest + @Test + fun createFirstCollectionTest() { + val firstWebPage = getGenericAsset(mockWebServer, 1) + val secondWebPage = getGenericAsset(mockWebServer, 2) + + navigationToolbar { + }.enterURLAndEnterToBrowser(firstWebPage.url) { + mDevice.waitForIdle() + }.openTabDrawer { + }.openNewTab { + }.submitQuery(secondWebPage.url.toString()) { + mDevice.waitForIdle() + }.goToHomescreen { + swipeToBottom() + }.clickSaveTabsToCollectionButton { + longClickTab(firstWebPage.title) + selectTab(secondWebPage.title, numOfTabs = 2) + }.clickSaveCollection { + typeCollectionNameAndSave(collectionName) + } + + tabDrawer { + verifySnackBarText("Collection saved!") + snackBarButtonClick("VIEW") + } + + homeScreen { + verifyCollectionIsDisplayed(collectionName) + } + } + + @SmokeTest + @Test + fun verifyExpandedCollectionItemsTest() { + val webPage = getGenericAsset(mockWebServer, 1) + val webPageUrl = webPage.url.host.toString() + + navigationToolbar { + }.enterURLAndEnterToBrowser(webPage.url) { + }.openTabDrawer { + createCollection(webPage.title, collectionName = collectionName) + snackBarButtonClick("VIEW") + } + + homeScreen { + verifyCollectionIsDisplayed(collectionName) + }.expandCollection(collectionName, composeTestRule) { + verifyTabSavedInCollection(webPage.title) + verifyCollectionTabUrl(true, webPageUrl) + verifyShareCollectionButtonIsVisible(true) + verifyCollectionMenuIsVisible(true, composeTestRule) + verifyCollectionItemRemoveButtonIsVisible(webPage.title, true) + }.collapseCollection(collectionName) {} + + collectionRobot { + verifyTabSavedInCollection(webPage.title, false) + verifyShareCollectionButtonIsVisible(false) + verifyCollectionMenuIsVisible(false, composeTestRule) + verifyCollectionTabUrl(false, webPageUrl) + verifyCollectionItemRemoveButtonIsVisible(webPage.title, false) + } + + homeScreen { + }.expandCollection(collectionName, composeTestRule) { + verifyTabSavedInCollection(webPage.title) + verifyCollectionTabUrl(true, webPageUrl) + verifyShareCollectionButtonIsVisible(true) + verifyCollectionMenuIsVisible(true, composeTestRule) + verifyCollectionItemRemoveButtonIsVisible(webPage.title, true) + }.collapseCollection(collectionName) {} + + collectionRobot { + verifyTabSavedInCollection(webPage.title, false) + verifyShareCollectionButtonIsVisible(false) + verifyCollectionMenuIsVisible(false, composeTestRule) + verifyCollectionTabUrl(false, webPageUrl) + verifyCollectionItemRemoveButtonIsVisible(webPage.title, false) + } + } + + @SmokeTest + @Test + fun openAllTabsInCollectionTest() { + val firstTestPage = getGenericAsset(mockWebServer, 1) + val secondTestPage = getGenericAsset(mockWebServer, 2) + + navigationToolbar { + }.enterURLAndEnterToBrowser(firstTestPage.url) { + waitForPageToLoad() + }.openTabDrawer { + }.openNewTab { + }.submitQuery(secondTestPage.url.toString()) { + waitForPageToLoad() + }.openTabDrawer { + createCollection( + firstTestPage.title, + secondTestPage.title, + collectionName = collectionName + ) + closeTab() + } + + homeScreen { + }.expandCollection(collectionName, composeTestRule) { + clickCollectionThreeDotButton(composeTestRule) + selectOpenTabs(composeTestRule) + } + tabDrawer { + verifyExistingOpenTabs(firstTestPage.title, secondTestPage.title) + } + } + + @SmokeTest + @Test + fun shareCollectionTest() { + val firstWebsite = getGenericAsset(mockWebServer, 1) + val secondWebsite = getGenericAsset(mockWebServer, 2) + val sharingApp = "Gmail" + val urlString = "${secondWebsite.url}\n\n${firstWebsite.url}" + + navigationToolbar { + }.enterURLAndEnterToBrowser(firstWebsite.url) { + }.openTabDrawer { + }.openNewTab { + }.submitQuery(secondWebsite.url.toString()) { + waitForPageToLoad() + }.openTabDrawer { + createCollection(firstWebsite.title, secondWebsite.title, collectionName = collectionName) + verifySnackBarText("Collection saved!") + }.openTabsListThreeDotMenu { + }.closeAllTabs { + }.expandCollection(collectionName, composeTestRule) { + }.clickShareCollectionButton { + verifyShareTabsOverlay(firstWebsite.title, secondWebsite.title) + verifySharingWithSelectedApp(sharingApp, urlString, collectionName) + } + } + + @SmokeTest + @Test + // Test running on beta/release builds in CI: + // caution when making changes to it, so they don't block the builds + fun deleteCollectionTest() { + val webPage = getGenericAsset(mockWebServer, 1) + + navigationToolbar { + }.enterURLAndEnterToBrowser(webPage.url) { + }.openTabDrawer { + createCollection(webPage.title, collectionName = collectionName) + snackBarButtonClick("VIEW") + } + + homeScreen { + }.expandCollection(collectionName, composeTestRule) { + clickCollectionThreeDotButton(composeTestRule) + selectDeleteCollection(composeTestRule) + } + + homeScreen { + verifySnackBarText("Collection deleted") + verifyNoCollectionsText() + } + } + @Test // open a webpage, and add currently opened tab to existing collection fun mainMenuSaveToExistingCollection() { @@ -66,7 +239,7 @@ class CollectionTest { navigationToolbar { }.enterURLAndEnterToBrowser(firstWebPage.url) { }.openTabDrawer { - createCollection(firstWebPage.title, firstCollectionName) + createCollection(firstWebPage.title, collectionName = collectionName) verifySnackBarText("Collection saved!") }.closeTabDrawer {} @@ -75,12 +248,12 @@ class CollectionTest { verifyPageContent(secondWebPage.content) }.openThreeDotMenu { }.openSaveToCollection { - }.selectExistingCollection(firstCollectionName) { + }.selectExistingCollection(collectionName) { verifySnackBarText("Tab saved!") - // }.goToHomescreen { - // }.expandCollection(firstCollectionName) { - // verifyTabSavedInCollection(firstWebPage.title) - // verifyTabSavedInCollection(secondWebPage.title) + }.goToHomescreen { + }.expandCollection(collectionName, composeTestRule) { + verifyTabSavedInCollection(firstWebPage.title) + verifyTabSavedInCollection(secondWebPage.title) } } @@ -92,7 +265,7 @@ class CollectionTest { navigationToolbar { }.enterURLAndEnterToBrowser(firstWebPage.url) { }.openTabDrawer { - createCollection(firstWebPage.title, firstCollectionName) + createCollection(firstWebPage.title, collectionName = collectionName) verifySnackBarText("Collection saved!") closeTab() } @@ -100,117 +273,131 @@ class CollectionTest { navigationToolbar { }.enterURLAndEnterToBrowser(secondWebPage.url) { }.goToHomescreen { - // }.expandCollection(firstCollectionName) { - // clickCollectionThreeDotButton() - // selectAddTabToCollection() - // verifyTabsSelectedCounterText(1) - // saveTabsSelectedForCollection() - // verifySnackBarText("Tab saved!") - // verifyTabSavedInCollection(secondWebPage.title) + }.expandCollection(collectionName, composeTestRule) { + clickCollectionThreeDotButton(composeTestRule) + selectAddTabToCollection(composeTestRule) + verifyTabsSelectedCounterText(1) + saveTabsSelectedForCollection() + verifySnackBarText("Tab saved!") + verifyTabSavedInCollection(secondWebPage.title) + } + } + + @Test + fun renameCollectionTest() { + val webPage = getGenericAsset(mockWebServer, 1) + + navigationToolbar { + }.enterURLAndEnterToBrowser(webPage.url) { + }.openTabDrawer { + createCollection(webPage.title, collectionName = firstCollectionName) + verifySnackBarText("Collection saved!") + }.closeTabDrawer { + }.goToHomescreen { + }.expandCollection(firstCollectionName, composeTestRule) { + clickCollectionThreeDotButton(composeTestRule) + selectRenameCollection(composeTestRule) + }.typeCollectionNameAndSave(secondCollectionName) {} + homeScreen { + verifyCollectionIsDisplayed(secondCollectionName) + } + } + + @Test + fun createSecondCollectionTest() { + val webPage = getGenericAsset(mockWebServer, 1) + + navigationToolbar { + }.enterURLAndEnterToBrowser(webPage.url) { + }.openTabDrawer { + createCollection(webPage.title, collectionName = firstCollectionName) + verifySnackBarText("Collection saved!") + createCollection( + webPage.title, collectionName = secondCollectionName, + firstCollection = false + ) + verifySnackBarText("Collection saved!") + }.closeTabDrawer { + }.goToHomescreen { + verifyCollectionIsDisplayed(firstCollectionName) + verifyCollectionIsDisplayed(secondCollectionName) + } + } + + @Test + fun removeTabFromCollectionTest() { + val webPage = getGenericAsset(mockWebServer, 1) + + navigationToolbar { + }.enterURLAndEnterToBrowser(webPage.url) { + }.openTabDrawer { + createCollection(webPage.title, collectionName = collectionName) + closeTab() + } + + homeScreen { + }.expandCollection(collectionName, composeTestRule) { + verifyTabSavedInCollection(webPage.title, true) + removeTabFromCollection(webPage.title) + verifyTabSavedInCollection(webPage.title, false) + } + homeScreen { + verifyCollectionIsDisplayed(collectionName, false) + } + } + + @Test + fun swipeLeftToRemoveTabFromCollectionTest() { + val testPage = getGenericAsset(mockWebServer, 1) + + navigationToolbar { + }.enterURLAndEnterToBrowser(testPage.url) { + waitForPageToLoad() + }.openTabDrawer { + createCollection( + testPage.title, + collectionName = collectionName + ) + closeTab() + } + + homeScreen { + }.expandCollection(collectionName, composeTestRule) { + swipeToBottom() + swipeTabLeft(testPage.title, composeTestRule) + verifyTabSavedInCollection(testPage.title, false) + } + homeScreen { + verifyCollectionIsDisplayed(collectionName, false) + } + } + + @Test + fun swipeRightToRemoveTabFromCollectionTest() { + val testPage = getGenericAsset(mockWebServer, 1) + + navigationToolbar { + }.enterURLAndEnterToBrowser(testPage.url) { + waitForPageToLoad() + }.openTabDrawer { + createCollection( + testPage.title, + collectionName = collectionName + ) + closeTab() + } + + homeScreen { + }.expandCollection(collectionName, composeTestRule) { + swipeToBottom() + swipeTabRight(testPage.title, composeTestRule) + verifyTabSavedInCollection(testPage.title, false) + } + homeScreen { + verifyCollectionIsDisplayed(collectionName, false) } } - // @Test - // fun renameCollectionTest() { - // val webPage = getGenericAsset(mockWebServer, 1) - // - // navigationToolbar { - // }.enterURLAndEnterToBrowser(webPage.url) { - // }.openTabDrawer { - // createCollection(webPage.title, firstCollectionName) - // verifySnackBarText("Collection saved!") - // }.closeTabDrawer { - // }.goToHomescreen { - // }.expandCollection(firstCollectionName) { - // clickCollectionThreeDotButton() - // selectRenameCollection() - // }.typeCollectionNameAndSave("renamed_collection") {} - // - // homeScreen { - // verifyCollectionIsDisplayed("renamed_collection") - // } - // } - - // @Test - // fun createSecondCollectionTest() { - // val webPage = getGenericAsset(mockWebServer, 1) - // - // navigationToolbar { - // }.enterURLAndEnterToBrowser(webPage.url) { - // }.openTabDrawer { - // createCollection(webPage.title, firstCollectionName) - // verifySnackBarText("Collection saved!") - // createCollection(webPage.title, secondCollectionName, false) - // verifySnackBarText("Collection saved!") - // }.closeTabDrawer { - // }.goToHomescreen {} - // - // homeScreen { - // verifyCollectionIsDisplayed(firstCollectionName) - // verifyCollectionIsDisplayed(secondCollectionName) - // } - // } - -// @Test -// fun removeTabFromCollectionTest() { -// val webPage = getGenericAsset(mockWebServer, 1) -// -// navigationToolbar { -// }.enterURLAndEnterToBrowser(webPage.url) { -// }.openTabDrawer { -// createCollection(webPage.title, firstCollectionName) -// verifySnackBarText("Collection saved!") -// closeTab() -// } -// -// homeScreen { -// }.expandCollection(firstCollectionName) { -// removeTabFromCollection(webPage.title) -// verifyTabSavedInCollection(webPage.title, false) -// } -// // To add this step when https://github.com/mozilla-mobile/fenix/issues/13177 is fixed -// // homeScreen { -// // verifyCollectionIsDisplayed(firstCollectionName, false) -// // } -// } - - // @Test - // fun swipeToRemoveTabFromCollectionTest() { - // val firstWebPage = getGenericAsset(mockWebServer, 1) - // val secondWebPage = getGenericAsset(mockWebServer, 2) - // - // navigationToolbar { - // }.enterURLAndEnterToBrowser(firstWebPage.url) { - // }.openTabDrawer { - // createCollection(firstWebPage.title, firstCollectionName) - // verifySnackBarText("Collection saved!") - // closeTab() - // } - // - // navigationToolbar { - // }.enterURLAndEnterToBrowser(secondWebPage.url) { - // }.openThreeDotMenu { - // }.openSaveToCollection { - // }.selectExistingCollection(firstCollectionName) { - // }.openTabDrawer { - // closeTab() - // } - // - // homeScreen { - // }.expandCollection(firstCollectionName) { - // swipeToBottom() - // swipeCollectionItemLeft(firstWebPage.title) - // verifyTabSavedInCollection(firstWebPage.title, false) - // swipeCollectionItemRight(secondWebPage.title) - // verifyTabSavedInCollection(secondWebPage.title, false) - // } - // To add this step when https://github.com/mozilla-mobile/fenix/issues/13177 is fixed -// homeScreen { -// verifyCollectionIsDisplayed(firstCollectionName, false) -// } -// } - - @Ignore("Failing, see: https://github.com/mozilla-mobile/fenix/issues/24997") @Test fun selectTabOnLongTapTest() { val firstWebPage = getGenericAsset(mockWebServer, 1) @@ -218,83 +405,84 @@ class CollectionTest { navigationToolbar { }.enterURLAndEnterToBrowser(firstWebPage.url) { + waitForPageToLoad() }.openTabDrawer { }.openNewTab { }.submitQuery(secondWebPage.url.toString()) { - mDevice.waitForIdle() + waitForPageToLoad() }.openTabDrawer { + verifyExistingOpenTabs(firstWebPage.title, secondWebPage.title) longClickTab(firstWebPage.title) verifyTabsMultiSelectionCounter(1) - selectTab(secondWebPage.title) - verifyTabsMultiSelectionCounter(2) + selectTab(secondWebPage.title, numOfTabs = 2) }.clickSaveCollection { - typeCollectionNameAndSave(firstCollectionName) + typeCollectionNameAndSave(collectionName) verifySnackBarText("Tabs saved!") } - // tabDrawer { - // }.closeTabDrawer { - // }.goToHomescreen { - // }.expandCollection(firstCollectionName) { - // verifyTabSavedInCollection(firstWebPage.title) - // verifyTabSavedInCollection(secondWebPage.title) - // } + tabDrawer { + }.closeTabDrawer { + }.goToHomescreen { + }.expandCollection(collectionName, composeTestRule) { + verifyTabSavedInCollection(firstWebPage.title) + verifyTabSavedInCollection(secondWebPage.title) + } + } + + @Test + fun navigateBackInCollectionFlowTest() { + val webPage = getGenericAsset(mockWebServer, 1) + + navigationToolbar { + }.enterURLAndEnterToBrowser(webPage.url) { + }.openTabDrawer { + createCollection(webPage.title, collectionName = collectionName) + verifySnackBarText("Collection saved!") + }.closeTabDrawer { + }.openThreeDotMenu { + }.openSaveToCollection { + verifySelectCollectionScreen() + goBackInCollectionFlow() + } + + browserScreen { + }.openThreeDotMenu { + }.openSaveToCollection { + verifySelectCollectionScreen() + clickAddNewCollection() + verifyCollectionNameTextField() + goBackInCollectionFlow() + verifySelectCollectionScreen() + goBackInCollectionFlow() + } + // verify the browser layout is visible + browserScreen { + verifyMenuButton() + } } - // @Test - // fun navigateBackInCollectionFlowTest() { - // val webPage = getGenericAsset(mockWebServer, 1) - // - // navigationToolbar { - // }.enterURLAndEnterToBrowser(webPage.url) { - // }.openTabDrawer { - // createCollection(webPage.title, firstCollectionName) - // verifySnackBarText("Collection saved!") - // }.closeTabDrawer { - // }.openThreeDotMenu { - // }.openSaveToCollection { - // verifySelectCollectionScreen() - // goBackInCollectionFlow() - // } - // - // browserScreen { - // }.openThreeDotMenu { - // }.openSaveToCollection { - // verifySelectCollectionScreen() - // clickAddNewCollection() - // verifyCollectionNameTextField() - // goBackInCollectionFlow() - // verifySelectCollectionScreen() - // goBackInCollectionFlow() - // } - // // verify the browser layout is visible - // browserScreen { - // verifyMenuButton() - // } - // } - - // @SmokeTest - // @Test - // fun undoDeleteCollectionTest() { - // val webPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) - // - // navigationToolbar { - // }.enterURLAndEnterToBrowser(webPage.url) { - // }.openTabDrawer { - // createCollection(webPage.title, firstCollectionName) - // snackBarButtonClick("VIEW") - // } - // - // homeScreen { - // }.expandCollection(firstCollectionName) { - // clickCollectionThreeDotButton() - // selectDeleteCollection() - // } - // - // homeScreen { - // verifySnackBarText("Collection deleted") - // clickUndoCollectionDeletion("UNDO") - // verifyCollectionIsDisplayed(firstCollectionName, true) - // } - // } + @SmokeTest + @Test + fun undoDeleteCollectionTest() { + val webPage = getGenericAsset(mockWebServer, 1) + + navigationToolbar { + }.enterURLAndEnterToBrowser(webPage.url) { + }.openTabDrawer { + createCollection(webPage.title, collectionName = collectionName) + snackBarButtonClick("VIEW") + } + + homeScreen { + }.expandCollection(collectionName, composeTestRule) { + clickCollectionThreeDotButton(composeTestRule) + selectDeleteCollection(composeTestRule) + } + + homeScreen { + verifySnackBarText("Collection deleted") + clickUndoCollectionDeletion("UNDO") + verifyCollectionIsDisplayed(collectionName, true) + } + } } diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/CollectionRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/CollectionRobot.kt index 179e14ddd9..84192a8d73 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/CollectionRobot.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/CollectionRobot.kt @@ -4,52 +4,58 @@ package org.mozilla.fenix.ui.robots +import androidx.compose.ui.test.assertIsDisplayed +import androidx.compose.ui.test.hasContentDescription +import androidx.compose.ui.test.hasText +import androidx.compose.ui.test.junit4.ComposeTestRule +import androidx.compose.ui.test.performClick +import androidx.compose.ui.test.performTouchInput +import androidx.compose.ui.test.swipeLeft +import androidx.compose.ui.test.swipeRight import androidx.test.espresso.Espresso.onView -import androidx.test.espresso.action.ViewActions.replaceText -import androidx.test.espresso.action.ViewActions.swipeLeft -import androidx.test.espresso.action.ViewActions.swipeRight -import androidx.test.espresso.action.ViewActions.swipeUp -import androidx.test.espresso.assertion.ViewAssertions.doesNotExist -import androidx.test.espresso.assertion.ViewAssertions.matches -import androidx.test.espresso.matcher.ViewMatchers -import androidx.test.espresso.matcher.ViewMatchers.hasSibling -import androidx.test.espresso.matcher.ViewMatchers.isDisplayed -import androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility +import androidx.test.espresso.NoMatchingViewException +import androidx.test.espresso.action.ViewActions.pressImeActionButton 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 org.hamcrest.Matchers.allOf +import org.junit.Assert.assertFalse +import org.junit.Assert.assertTrue import org.mozilla.fenix.R import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime import org.mozilla.fenix.helpers.TestHelper.packageName import org.mozilla.fenix.helpers.TestHelper.scrollToElementByText -import org.mozilla.fenix.helpers.click import org.mozilla.fenix.helpers.ext.waitNotNull class CollectionRobot { fun verifySelectCollectionScreen() { - onView(withText("Select collection")) - .check(matches(isDisplayed())) - - onView(withId(R.id.collections_list)) - .check(matches(isDisplayed())) - - onView(withText("Add new collection")) - .check(matches(isDisplayed())) + assertTrue( + mDevice.findObject(UiSelector().text("Select collection")) + .exists() + ) + assertTrue( + mDevice.findObject(UiSelector().resourceId("$packageName:id/collections_list")) + .exists() + ) + assertTrue( + mDevice.findObject(UiSelector().text("Add new collection")) + .exists() + ) } fun clickAddNewCollection() = addNewCollectionButton().click() fun verifyCollectionNameTextField() { - mainMenuEditCollectionNameField().check(matches(isDisplayed())) + assertTrue( + mainMenuEditCollectionNameField().waitForExists(waitingTime) + ) } // names a collection saved from tab drawer fun typeCollectionNameAndSave(collectionName: String) { - collectionNameTextField().perform(replaceText(collectionName)) + collectionNameTextField().text = collectionName mDevice.findObject(UiSelector().textContains("OK")).click() } @@ -57,141 +63,115 @@ class CollectionRobot { mDevice.findObject(UiSelector().text("Select tabs to save")) .waitUntilGone(waitingTime) - val tabsCounter = onView(withId(R.id.bottom_bar_text)) + val tabsCounter = mDevice.findObject(UiSelector().resourceId("$packageName:id/bottom_bar_text")) when (numOfTabs) { - 1 -> tabsCounter.check(matches(withText("$numOfTabs tab selected"))) - 2 -> tabsCounter.check(matches(withText("$numOfTabs tabs selected"))) + 1 -> assertTrue(tabsCounter.text.equals("$numOfTabs tab selected")) + 2 -> assertTrue(tabsCounter.text.equals("$numOfTabs tabs selected")) } } fun saveTabsSelectedForCollection() { - onView(withId(R.id.save_button)).click() + mDevice.findObject(UiSelector().resourceId("$packageName:id/save_button")).click() } fun verifyTabSavedInCollection(title: String, visible: Boolean = true) { if (visible) { scrollToElementByText(title) - collectionItem(title) - .check( - matches(isDisplayed()) - ) + assertTrue( + collectionListItem(title).waitForExists(waitingTime) + ) } else - collectionItem(title) - .check(doesNotExist()) + assertTrue( + collectionListItem(title).waitUntilGone(waitingTime) + ) } - fun verifyCollectionTabUrl(visible: Boolean) { - onView(withId(R.id.caption)) - .check( - if (visible) matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)) - else doesNotExist() - ) + fun verifyCollectionTabUrl(visible: Boolean, url: String) { + val tabUrl = mDevice.findObject(UiSelector().text(url)) + + if (visible) { + assertTrue(tabUrl.exists()) + } else { + assertFalse(tabUrl.exists()) + } } - fun verifyCollectionTabLogo(visible: Boolean) { - onView(withId(R.id.favicon)) - .check( - if (visible) matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)) - else doesNotExist() - ) + fun verifyShareCollectionButtonIsVisible(visible: Boolean) { + if (visible) { + assertTrue(shareCollectionButton().exists()) + } else { + assertFalse(shareCollectionButton().exists()) + } } - // fun verifyShareCollectionButtonIsVisible(visible: Boolean) { - // shareCollectionButton() - // .check( - // if (visible) matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)) - // else matches(withEffectiveVisibility(ViewMatchers.Visibility.GONE)) - // ) - // } - - // fun verifyCollectionMenuIsVisible(visible: Boolean) { - // collectionThreeDotButton() - // .check( - // if (visible) matches( - // withEffectiveVisibility( - // ViewMatchers.Visibility.VISIBLE - // ) - // ) - // else matches(withEffectiveVisibility(ViewMatchers.Visibility.GONE)) - // ) - // } - - // fun clickCollectionThreeDotButton() { - // collectionThreeDotButton().click() - // mDevice.waitNotNull( - // Until.findObject(By.text("Delete collection")), - // waitingTime - // ) - // } - - fun selectOpenTabs() { - onView(withText("Open tabs")).click() + fun verifyCollectionMenuIsVisible(visible: Boolean, rule: ComposeTestRule) { + if (visible) { + collectionThreeDotButton(rule) + .assertExists() + .assertIsDisplayed() + } else { + collectionThreeDotButton(rule) + .assertDoesNotExist() + } } - fun selectRenameCollection() { - onView(withText("Rename collection")).click() - mDevice.waitNotNull(Until.findObject(By.text("Rename collection"))) + fun clickCollectionThreeDotButton(rule: ComposeTestRule) { + collectionThreeDotButton(rule) + .assertIsDisplayed() + .performClick() } - fun selectAddTabToCollection() { - onView(withText("Add tab")).click() - mDevice.waitNotNull(Until.findObject(By.text("Select Tabs"))) + fun selectOpenTabs(rule: ComposeTestRule) { + rule.onNode(hasText("Open tabs")) + .assertIsDisplayed() + .performClick() } - fun selectDeleteCollection() { - onView(withText("Delete collection")).click() + fun selectRenameCollection(rule: ComposeTestRule) { + rule.onNode(hasText("Rename collection")) + .assertIsDisplayed() + .performClick() + mainMenuEditCollectionNameField().waitForExists(waitingTime) } - fun confirmDeleteCollection() { - onView(withText("DELETE")).click() - mDevice.waitNotNull( - Until.findObject(By.res("$packageName:id/no_collections_header")), - waitingTime - ) + fun selectAddTabToCollection(rule: ComposeTestRule) { + rule.onNode(hasText("Add tab")) + .assertIsDisplayed() + .performClick() + + mDevice.waitNotNull(Until.findObject(By.text("Select Tabs"))) + } + + fun selectDeleteCollection(rule: ComposeTestRule) { + rule.onNode(hasText("Delete collection")) + .assertIsDisplayed() + .performClick() } fun verifyCollectionItemRemoveButtonIsVisible(title: String, visible: Boolean) { - removeTabFromCollectionButton(title) - .check( - if (visible) matches( - withEffectiveVisibility( - ViewMatchers.Visibility.VISIBLE - ) - ) - else doesNotExist() + if (visible) { + assertTrue( + removeTabFromCollectionButton(title).exists() ) + } else { + assertFalse( + removeTabFromCollectionButton(title).exists() + ) + } } fun removeTabFromCollection(title: String) = removeTabFromCollectionButton(title).click() - fun swipeCollectionItemRight(title: String) { - scrollToElementByText(title) - // Swipping can sometimes fail to remove the tab, so if the tab still exists, we need to repeat it - var retries = 0 // number of retries before failing, will stop at 2 - while (mDevice.findObject( - UiSelector() - .resourceId("$packageName:id/label") - .text(title) - ).exists() && retries < 2 - ) { - collectionItem(title).perform(swipeRight()) - retries++ - } + fun swipeTabLeft(title: String, rule: ComposeTestRule) { + rule.onNode(hasText(title), useUnmergedTree = true) + .performTouchInput { swipeLeft() } + rule.waitForIdle() } - fun swipeCollectionItemLeft(title: String) { - scrollToElementByText(title) - // Swipping can sometimes fail to remove the tab, so if the tab still exists, we need to repeat it - var retries = 0 // number of retries before failing, will stop at 2 - while (mDevice.findObject( - UiSelector() - .resourceId("$packageName:id/label") - .text(title) - ).exists() && retries < 2 - ) { - collectionItem(title).perform(swipeLeft()) - retries++ - } + fun swipeTabRight(title: String, rule: ComposeTestRule) { + rule.onNode(hasText(title), useUnmergedTree = true) + .performTouchInput { swipeRight() } + rule.waitForIdle() } fun verifySnackBarText(expectedText: String) { @@ -200,61 +180,62 @@ class CollectionRobot { fun goBackInCollectionFlow() = backButton().click() - fun swipeToBottom() = onView(withId(R.id.sessionControlRecyclerView)).perform(swipeUp()) + fun swipeToBottom() = + UiScrollable( + UiSelector().resourceId("$packageName:id/sessionControlRecyclerView") + ).scrollToEnd(3) class Transition { -// fun collapseCollection( -// title: String, -// interact: HomeScreenRobot.() -> Unit -// ): HomeScreenRobot.Transition { -// try { -// mDevice.waitNotNull(Until.findObject(By.text(title)), waitingTime) -// onView(allOf(withId(R.id.chevron), hasSibling(withText(title)))).click() -// } catch (e: NoMatchingViewException) { -// scrollToElementByText(title) -// } -// -// HomeScreenRobot().interact() -// return HomeScreenRobot.Transition() -// } -// -// // names a collection saved from the 3dot menu -// fun typeCollectionNameAndSave( -// name: String, -// interact: BrowserRobot.() -> Unit -// ): BrowserRobot.Transition { -// mDevice.findObject(UiSelector().resourceId("$packageName:id/name_collection_edittext")) -// .waitForExists(waitingTime) -// -// mainMenuEditCollectionNameField().perform( -// replaceText(name), -// pressImeActionButton() -// ) -// -// // wait for the collection creation wrapper to be dismissed -// mDevice.waitNotNull(Until.gone(By.res("$packageName:id/createCollectionWrapper"))) -// -// BrowserRobot().interact() -// return BrowserRobot.Transition() -// } + fun collapseCollection( + title: String, + interact: HomeScreenRobot.() -> Unit + ): HomeScreenRobot.Transition { + try { + collectionTitle(title).waitForExists(waitingTime) + collectionTitle(title).click() + } catch (e: NoMatchingViewException) { + scrollToElementByText(title) + collectionTitle(title).click() + } + + HomeScreenRobot().interact() + return HomeScreenRobot.Transition() + } + + // names a collection saved from the 3dot menu + fun typeCollectionNameAndSave( + name: String, + interact: BrowserRobot.() -> Unit + ): BrowserRobot.Transition { + mainMenuEditCollectionNameField().waitForExists(waitingTime) + mainMenuEditCollectionNameField().text = name + onView(withId(R.id.name_collection_edittext)).perform(pressImeActionButton()) + + // wait for the collection creation wrapper to be dismissed + mDevice.waitNotNull(Until.gone(By.res("$packageName:id/createCollectionWrapper"))) + + BrowserRobot().interact() + return BrowserRobot.Transition() + } fun selectExistingCollection( title: String, interact: BrowserRobot.() -> Unit ): BrowserRobot.Transition { - mDevice.waitNotNull(Until.findObject(By.text(title)), waitingTime) - onView(withText(title)).click() + collectionTitle(title).waitForExists(waitingTime) + collectionTitle(title).click() BrowserRobot().interact() return BrowserRobot.Transition() } - // fun clickShareCollectionButton(interact: ShareOverlayRobot.() -> Unit): ShareOverlayRobot.Transition { - // shareCollectionButton().click() - // - // ShareOverlayRobot().interact() - // return ShareOverlayRobot.Transition() - // } + fun clickShareCollectionButton(interact: ShareOverlayRobot.() -> Unit): ShareOverlayRobot.Transition { + shareCollectionButton().waitForExists(waitingTime) + shareCollectionButton().click() + + ShareOverlayRobot().interact() + return ShareOverlayRobot.Transition() + } } } @@ -263,30 +244,46 @@ fun collectionRobot(interact: CollectionRobot.() -> Unit): CollectionRobot.Trans return CollectionRobot.Transition() } -// private fun collectionThreeDotButton() = -// onView(withId(R.id.collection_overflow_button)) +private fun collectionTitle(title: String) = + mDevice.findObject( + UiSelector() + .text(title) + ) -private fun collectionItem(title: String) = - onView(allOf(withId(R.id.label), withText(title))) +private fun collectionThreeDotButton(rule: ComposeTestRule) = + rule.onNode(hasContentDescription("Collection menu")) -// private fun shareCollectionButton() = onView(withId(R.id.collection_share_button)) +private fun collectionListItem(title: String) = mDevice.findObject(UiSelector().text(title)) + +private fun shareCollectionButton() = + mDevice.findObject( + UiSelector().description("Share") + ) private fun removeTabFromCollectionButton(title: String) = - onView( - allOf( - withId(R.id.secondary_button), - hasSibling(withText(title)) - ) + mDevice.findObject( + UiSelector().text(title) + ).getFromParent( + UiSelector() + .description("Remove tab from collection") ) // collection name text field, opened from tab drawer -private fun collectionNameTextField() = onView(withId(R.id.collection_name)) +private fun collectionNameTextField() = + mDevice.findObject( + UiSelector().resourceId("$packageName:id/collection_name") + ) -// collection name text field, opened from main menu +// collection name text field, when saving from the main menu option private fun mainMenuEditCollectionNameField() = - onView(withId(R.id.name_collection_edittext)) + mDevice.findObject( + UiSelector().resourceId("$packageName:id/name_collection_edittext") + ) -private fun addNewCollectionButton() = onView(withText("Add new collection")) +private fun addNewCollectionButton() = + mDevice.findObject(UiSelector().text("Add new collection")) private fun backButton() = - onView(withId(R.id.back_button)) + mDevice.findObject( + UiSelector().resourceId("$packageName:id/back_button") + ) diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/HomeScreenRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/HomeScreenRobot.kt index d6ef1deff9..6f3ee609f5 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/HomeScreenRobot.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/HomeScreenRobot.kt @@ -8,6 +8,10 @@ package org.mozilla.fenix.ui.robots import android.graphics.Bitmap import android.widget.EditText +import androidx.compose.ui.test.assertIsDisplayed +import androidx.compose.ui.test.hasText +import androidx.compose.ui.test.junit4.ComposeTestRule +import androidx.compose.ui.test.performClick import androidx.recyclerview.widget.RecyclerView import androidx.test.espresso.Espresso.onView import androidx.test.espresso.action.ViewActions @@ -42,6 +46,7 @@ import org.junit.Assert.assertFalse import org.junit.Assert.assertTrue import org.mozilla.fenix.R import org.mozilla.fenix.ext.components +import org.mozilla.fenix.helpers.Constants.LISTS_MAXSWIPES import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime import org.mozilla.fenix.helpers.TestAssetHelper.waitingTimeShort import org.mozilla.fenix.helpers.TestHelper.appContext @@ -189,8 +194,6 @@ class HomeScreenRobot { } } - fun verifyCollectionIcon() = onView(withId(R.id.collection_icon)).check(matches(isDisplayed())) - fun togglePrivateBrowsingModeOnOff() { onView(ViewMatchers.withResourceName("privateBrowsingButton")) .perform(click()) @@ -392,21 +395,15 @@ class HomeScreenRobot { return TabDrawerRobot.Transition() } - // fun expandCollection( - // title: String, - // interact: CollectionRobot.() -> Unit - // ): CollectionRobot.Transition { - // // Depending on the screen dimensions collections might report as visible on screen - // // but actually have the bottom toolbar above so interactions with collections might fail. - // // As a quick solution we'll try scrolling to the element below collection on the homescreen - // // so that they are displayed above in their entirety. - // scrollToElementByText(appContext.getString(R.string.pocket_stories_header_1)) - // - // collectionTitle(title).click() - // - // CollectionRobot().interact() - // return CollectionRobot.Transition() - // } + fun expandCollection(title: String, rule: ComposeTestRule, interact: CollectionRobot.() -> Unit): CollectionRobot.Transition { + homeScreenList().scrollToEnd(LISTS_MAXSWIPES) + collectionTitle(title, rule) + .assertIsDisplayed() + .performClick() + + CollectionRobot().interact() + return CollectionRobot.Transition() + } fun openRecentlyVisitedSearchGroupHistoryList(title: String, interact: HistoryRobot.() -> Unit): HistoryRobot.Transition { val searchGroup = recentlyVisitedList.getChildByText(UiSelector().text(title), title, true) @@ -649,6 +646,9 @@ private fun assertPrivateSessionMessage() = ).waitForExists(waitingTime) ) +private fun collectionTitle(title: String, rule: ComposeTestRule) = + rule.onNode(hasText(title)) + private fun assertExistingTopSitesList() = onView(allOf(withId(R.id.top_sites_list))) .check((matches(withEffectiveVisibility(Visibility.VISIBLE)))) diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ShareOverlayRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ShareOverlayRobot.kt index c31b6f4b9c..e401763f8b 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ShareOverlayRobot.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ShareOverlayRobot.kt @@ -49,8 +49,13 @@ class ShareOverlayRobot { mDevice.waitNotNull(Until.findObject(By.res("android:id/resolver_list"))) } - fun selectAppToShareWith(appName: String) = - mDevice.findObject(UiSelector().text(appName)).clickAndWaitForNewWindow() + fun verifySharingWithSelectedApp(appName: String, content: String, subject: String) { + val sharingApp = mDevice.findObject(UiSelector().text(appName)) + if (sharingApp.exists()) { + sharingApp.clickAndWaitForNewWindow() + verifySharedTabsIntent(content, subject) + } + } fun verifySendToDeviceTitle() = assertSendToDeviceTitle() diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/TabDrawerRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/TabDrawerRobot.kt index 9fe33ad8fc..33f255e680 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/TabDrawerRobot.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/TabDrawerRobot.kt @@ -7,6 +7,7 @@ package org.mozilla.fenix.ui.robots import android.content.Context +import android.text.TextUtils.indexOf import android.view.View import androidx.test.core.app.ApplicationProvider import androidx.test.espresso.Espresso @@ -41,9 +42,9 @@ import org.hamcrest.CoreMatchers.anyOf import org.hamcrest.CoreMatchers.containsString import org.hamcrest.Matcher import org.mozilla.fenix.R +import org.mozilla.fenix.helpers.TestAssetHelper.waitingTimeLong import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime import org.mozilla.fenix.helpers.TestAssetHelper.waitingTimeShort -import org.mozilla.fenix.helpers.TestHelper.getStringResource import org.mozilla.fenix.helpers.TestHelper.packageName import org.mozilla.fenix.helpers.TestHelper.scrollToElementByText import org.mozilla.fenix.helpers.click @@ -77,7 +78,7 @@ class TabDrawerRobot { assertPrivateBrowsingButtonIsSelected(isSelected) fun verifySyncedTabsButtonIsSelected(isSelected: Boolean) = assertSyncedTabsButtonIsSelected(isSelected) - fun verifyExistingOpenTabs(title: String) = assertExistingOpenTabs(title) + fun verifyExistingOpenTabs(vararg titles: String) = assertExistingOpenTabs(*titles) fun verifyCloseTabsButton(title: String) = assertCloseTabsButton(title) fun verifyExistingTabList() = assertExistingTabList() @@ -229,28 +230,28 @@ class TabDrawerRobot { tabMediaControlButton().click() } - private fun clickSelectTabs() { + fun clickSelectTabsOption() { threeDotMenu().click() - mDevice.waitNotNull( - findObject( - text(getStringResource(R.string.tabs_tray_select_tabs)) - ), - waitingTime - ) - - val selectTabsButton = mDevice.findObject(text(getStringResource(R.string.tabs_tray_select_tabs))) + val selectTabsButton = mDevice.findObject(UiSelector().text("Select tabs")) + selectTabsButton.waitForExists(waitingTime) selectTabsButton.click() } - fun selectTab(title: String) { - mDevice.waitNotNull( - findObject(text(title)), - waitingTime + fun selectTab(title: String, tabsSelected: Int) { + val tab = mDevice.findObject( + UiSelector() + .resourceId("$packageName:id/tab_item") + .childSelector(UiSelector().text(title)) ) - - val tab = mDevice.findObject(text(title)) + tab.waitForExists(waitingTime) tab.click() + try { + verifyTabsMultiSelectionCounter(tabsSelected) + } catch (e: AssertionError) { + tab.click() + verifyTabsMultiSelectionCounter(tabsSelected) + } } fun longClickTab(title: String) { @@ -264,13 +265,15 @@ class TabDrawerRobot { } fun createCollection( - tabTitle: String, + vararg tabTitle: String, collectionName: String, firstCollection: Boolean = true ) { - clickSelectTabs() - selectTab(tabTitle) tabDrawer { + clickSelectTabsOption() + for (tab in tabTitle) { + selectTab(tab, tabTitle.indexOf(tab) + 1) + } }.clickSaveCollection { if (!firstCollection) clickAddNewCollection() @@ -489,32 +492,27 @@ private fun syncedTabsButton() = onView(withContentDescription("Synced tabs")) private fun newTabButton() = mDevice.findObject(UiSelector().resourceId("$packageName:id/new_tab_button")) private fun threeDotMenu() = onView(withId(R.id.tab_tray_overflow)) -private fun assertExistingOpenTabs(title: String) { - try { - mDevice.findObject( - UiSelector() - .resourceId("$packageName:id/mozac_browser_tabstray_title") - .textContains(title) - ) - .waitForExists(waitingTime) - - assertTrue( - mDevice.findObject( - UiSelector() - .resourceId("$packageName:id/mozac_browser_tabstray_title") - .textContains(title) - ).waitForExists(waitingTime) - ) - } catch (e: AssertionError) { - println("The tab wasn't found") - mDevice.findObject(UiSelector().resourceId("$packageName:id/tabsTray")).swipeUp(2) - assertTrue( - mDevice.findObject( - UiSelector() - .resourceId("$packageName:id/mozac_browser_tabstray_title") - .textContains(title) - ).waitForExists(waitingTime) - ) +private fun assertExistingOpenTabs(vararg tabTitles: String) { + for (title in tabTitles) { + try { + assertTrue( + mDevice.findObject( + UiSelector() + .resourceId("$packageName:id/mozac_browser_tabstray_title") + .textContains(title) + ).waitForExists(waitingTimeLong) + ) + } catch (e: AssertionError) { + println("The tab wasn't found") + mDevice.findObject(UiSelector().resourceId("$packageName:id/tabsTray")).swipeUp(2) + assertTrue( + mDevice.findObject( + UiSelector() + .resourceId("$packageName:id/mozac_browser_tabstray_title") + .textContains(title) + ).waitForExists(waitingTime) + ) + } } }