From c5962b2502d1d8ce7474dbdda80b45d3eb7aec6e Mon Sep 17 00:00:00 2001 From: Oana Horvath Date: Fri, 11 Jun 2021 11:54:56 +0300 Subject: [PATCH] For #10587: Fix and re-enable old CollectionTest.kt --- .../org/mozilla/fenix/ui/CollectionTest.kt | 259 +++++++++++++++++ .../mozilla/fenix/ui/CollectionTest.kt.ignore | 266 ------------------ .../mozilla/fenix/ui/robots/BrowserRobot.kt | 7 +- .../fenix/ui/robots/CollectionRobot.kt | 265 +++++++++++++++++ .../fenix/ui/robots/HomeScreenRobot.kt | 154 ++-------- .../mozilla/fenix/ui/robots/TabDrawerRobot.kt | 45 ++- .../fenix/ui/robots/ThreeDotMenuMainRobot.kt | 70 +---- 7 files changed, 580 insertions(+), 486 deletions(-) create mode 100644 app/src/androidTest/java/org/mozilla/fenix/ui/CollectionTest.kt delete mode 100644 app/src/androidTest/java/org/mozilla/fenix/ui/CollectionTest.kt.ignore create mode 100644 app/src/androidTest/java/org/mozilla/fenix/ui/robots/CollectionRobot.kt diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/CollectionTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/CollectionTest.kt new file mode 100644 index 000000000..094fefeba --- /dev/null +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/CollectionTest.kt @@ -0,0 +1,259 @@ +/* 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 + +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.Rule +import org.junit.Test +import org.mozilla.fenix.helpers.AndroidAssetDispatcher +import org.mozilla.fenix.helpers.HomeActivityTestRule +import org.mozilla.fenix.helpers.TestAssetHelper.getGenericAsset +import org.mozilla.fenix.ui.robots.browserScreen +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 + * + */ + +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" + + @get:Rule + val activityTestRule = HomeActivityTestRule() + + @Before + fun setUp() { + mockWebServer = MockWebServer().apply { + dispatcher = AndroidAssetDispatcher() + start() + } + } + + @After + fun tearDown() { + mockWebServer.shutdown() + } + + @Test + // open a webpage, and add currently opened tab to existing collection + fun mainMenuSaveToExistingCollection() { + val firstWebPage = getGenericAsset(mockWebServer, 1) + val secondWebPage = getGenericAsset(mockWebServer, 2) + + navigationToolbar { + }.enterURLAndEnterToBrowser(firstWebPage.url) { + }.openTabDrawer { + createCollection(firstWebPage.title, firstCollectionName) + verifySnackBarText("Collection saved!") + }.closeTabDrawer {} + + navigationToolbar { + }.enterURLAndEnterToBrowser(secondWebPage.url) { + verifyPageContent(secondWebPage.content) + }.openThreeDotMenu { + }.openSaveToCollection { + }.selectExistingCollection(firstCollectionName) { + verifySnackBarText("Tab saved!") + }.goToHomescreen { + }.expandCollection(firstCollectionName) { + verifyTabSavedInCollection(firstWebPage.title) + verifyTabSavedInCollection(secondWebPage.title) + } + } + + @Test + fun verifyAddTabButtonOfCollectionMenu() { + val firstWebPage = getGenericAsset(mockWebServer, 1) + val secondWebPage = getGenericAsset(mockWebServer, 2) + + navigationToolbar { + }.enterURLAndEnterToBrowser(firstWebPage.url) { + }.openTabDrawer { + createCollection(firstWebPage.title, firstCollectionName) + verifySnackBarText("Collection saved!") + }.closeTabDrawer {} + + navigationToolbar { + }.enterURLAndEnterToBrowser(secondWebPage.url) { + }.goToHomescreen { + }.expandCollection(firstCollectionName) { + clickCollectionThreeDotButton() + selectAddTabToCollection() + 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, 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!") + }.closeTabDrawer { + }.goToHomescreen { + }.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) { + }.goToHomescreen {} + + homeScreen { + }.expandCollection(firstCollectionName) { + 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) +// } + } + + @Test + fun selectTabOnLongTapTest() { + val firstWebPage = getGenericAsset(mockWebServer, 1) + val secondWebPage = getGenericAsset(mockWebServer, 2) + + navigationToolbar { + }.enterURLAndEnterToBrowser(firstWebPage.url) { + }.openTabDrawer { + }.openNewTab { + }.submitQuery(secondWebPage.url.toString()) { + }.openTabDrawer { + longClickTab(firstWebPage.title) + verifyTabsMultiSelectionCounter(1) + selectTab(secondWebPage.title) + verifyTabsMultiSelectionCounter(2) + }.clickSaveCollection { + typeCollectionNameAndSave(firstCollectionName) + verifySnackBarText("Tabs saved!") + } + + tabDrawer { + }.closeTabDrawer { + }.goToHomescreen { + }.expandCollection(firstCollectionName) { + verifyTabSavedInCollection(firstWebPage.title) + verifyTabSavedInCollection(secondWebPage.title) + } + } + + @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() + } + } +} diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/CollectionTest.kt.ignore b/app/src/androidTest/java/org/mozilla/fenix/ui/CollectionTest.kt.ignore deleted file mode 100644 index 81b62c4f7..000000000 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/CollectionTest.kt.ignore +++ /dev/null @@ -1,266 +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 -// -//import androidx.test.espresso.NoMatchingViewException -//import androidx.test.platform.app.InstrumentationRegistry -//import androidx.test.uiautomator.By -//import androidx.test.uiautomator.UiDevice -//import androidx.test.uiautomator.Until -//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.helpers.AndroidAssetDispatcher -//import org.mozilla.fenix.helpers.HomeActivityTestRule -//import org.mozilla.fenix.helpers.TestAssetHelper -//import org.mozilla.fenix.ui.robots.homeScreen -//import org.mozilla.fenix.ui.robots.navigationToolbar -// -///** -// * Tests for verifying basic functionality of tab collection -// * -// */ -// -//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" -// -// @get:Rule -// val activityTestRule = HomeActivityTestRule() -// -// @Before -// fun setUp() { -// mockWebServer = MockWebServer().apply { -// setDispatcher(AndroidAssetDispatcher()) -// start() -// } -// } -// -// @After -// fun tearDown() { -// mockWebServer.shutdown() -// } -// -// @Ignore("Intermittent failures, see: https://github.com/mozilla-mobile/fenix/issues/10587") -// @Test -// // open a webpage, and add currently opened tab to existing collection -// fun addTabToExistingCollectionTest() { -// val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) -// val secondWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 2) -// -// createCollection(firstCollectionName) -// -// homeScreen { -//// verifyExistingTabList() -// closeTab() -// }.openNavigationToolbar { -// }.enterURLAndEnterToBrowser(secondWebPage.url) { -// verifyPageContent(secondWebPage.content) -// }.openThreeDotMenu { -// clickBrowserViewSaveCollectionButton() -// }.selectExistingCollection(firstCollectionName) { -// verifySnackBarText("Tab saved!") -// }.openHomeScreen { -//// verifyExistingTabList() -// expandCollection(firstCollectionName) -// verifyItemInCollectionExists(firstWebPage.title) -// verifyItemInCollectionExists(secondWebPage.title) -// } -// } -// -// @Ignore("Intermittent failures, see: https://github.com/mozilla-mobile/fenix/issues/10587") -// @Test -// fun collectionMenuAddTabButtonTest() { -// val secondWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 2) -// -// createCollection(firstCollectionName) -// -// homeScreen { -// closeTab() -// }.openNavigationToolbar { -// }.enterURLAndEnterToBrowser(secondWebPage.url) { -// }.openHomeScreen { -// expandCollection(firstCollectionName) -// clickCollectionThreeDotButton() -// selectAddTabToCollection() -// verifyTabsSelectedCounterText(1) -// saveTabsSelectedForCollection() -// verifySnackBarText("Tab saved!") -// verifyItemInCollectionExists(secondWebPage.title) -// } -// } -// -// @Ignore("Intermittent failures, see: https://github.com/mozilla-mobile/fenix/issues/10587") -// @Test -// fun renameCollectionTest() { -// createCollection(firstCollectionName) -// -// homeScreen { -// // On homeview, tap the 3-dot button to expand, select rename, rename collection -// expandCollection(firstCollectionName) -// clickCollectionThreeDotButton() -// selectRenameCollection() -// typeCollectionName("renamed_collection") -// verifyCollectionIsDisplayed("renamed_collection") -// } -// } -// -// @Ignore("Intermittent failures, see: https://github.com/mozilla-mobile/fenix/issues/10587") -// @Test -// fun createCollectionFromTabTest() { -// val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) -// -// createCollection(firstCollectionName) -// homeScreen { -// }.openTabDrawer { -// verifyExistingOpenTabs(firstWebPage.title) -// }.openHomeScreen { -// try { -// verifyCollectionIsDisplayed(firstCollectionName) -// } catch (e: NoMatchingViewException) { -// scrollToElementByText(firstCollectionName) -// } -// } -// } -// -// @Ignore("Intermittent failures, see: https://github.com/mozilla-mobile/fenix/issues/10587") -// @Test -// fun removeTabFromCollectionTest() { -// val webPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) -// -// createCollection(firstCollectionName) -// homeScreen { -// closeTab() -// expandCollection(firstCollectionName) -// removeTabFromCollection(webPage.title) -// verifyItemInCollectionExists(webPage.title, false) -// } -// -// createCollection(firstCollectionName) -// homeScreen { -// closeTab() -// expandCollection(firstCollectionName) -// swipeCollectionItemLeft(webPage.title) -// verifyItemInCollectionExists(webPage.title, false) -// } -// -// createCollection(firstCollectionName) -// homeScreen { -// closeTab() -// expandCollection(firstCollectionName) -// swipeCollectionItemRight(webPage.title) -// verifyItemInCollectionExists(webPage.title, false) -// } -// } -// -// @Ignore("Intermittent failures, see: https://github.com/mozilla-mobile/fenix/issues/10587") -// @Test -// fun selectTabOnLongTapTest() { -// val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) -// val secondWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 2) -// -// navigationToolbar { -// }.enterURLAndEnterToBrowser(firstWebPage.url) { -// }.openHomeScreen { -// }.openNavigationToolbar { -// }.enterURLAndEnterToBrowser(secondWebPage.url) { -// }.openHomeScreen { -// longTapSelectTab(firstWebPage.title) -// verifySelectTabsView() -// verifyTabsSelectedCounterText(1) -// selectTabForCollection(secondWebPage.title) -// verifyTabsSelectedCounterText(2) -// saveTabsSelectedForCollection() -// typeCollectionName(firstCollectionName) -// verifySnackBarText("Tabs saved!") -//// closeTabViaXButton(firstWebPage.title) -//// closeTabViaXButton(secondWebPage.title) -// expandCollection(firstCollectionName) -// verifyItemInCollectionExists(firstWebPage.title) -// verifyItemInCollectionExists(secondWebPage.title) -// } -// } -// -// @Ignore("Intermittent failures, see: https://github.com/mozilla-mobile/fenix/issues/10587") -// @Test -// fun tabsOverflowMenuSaveCollectionTest() { -// val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) -// val secondWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 2) -// -// navigationToolbar { -// }.enterURLAndEnterToBrowser(firstWebPage.url) { -// }.openHomeScreen { -// }.openNavigationToolbar { -// }.enterURLAndEnterToBrowser(secondWebPage.url) { -// }.openHomeScreen { -// }.openTabsListThreeDotMenu { -// verifySaveCollection() -// }.clickOpenTabsMenuSaveCollection { -// verifySelectTabsView() -// verifyTabsSelectedCounterText(0) -// selectAllTabsForCollection() -// verifyTabsSelectedCounterText(2) -// saveTabsSelectedForCollection() -// typeCollectionName(firstCollectionName) -//// closeTabViaXButton(firstWebPage.title) -//// closeTabViaXButton(secondWebPage.title) -// expandCollection(firstCollectionName) -// verifyItemInCollectionExists(firstWebPage.title) -// verifyItemInCollectionExists(secondWebPage.title) -// } -// } -// -// @Ignore("Intermittent failures, see: https://github.com/mozilla-mobile/fenix/issues/10587") -// @Test -// fun navigateBackInCollectionFlowTest() { -// val secondWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 2) -// -// createCollection(firstCollectionName) -// navigationToolbar { -// }.enterURLAndEnterToBrowser(secondWebPage.url) { -// }.openHomeScreen { -// longTapSelectTab(secondWebPage.title) -// verifySelectTabsView() -// saveTabsSelectedForCollection() -// verifySelectCollectionView() -// clickAddNewCollection() -// verifyNameCollectionView() -// goBackCollectionFlow() -// verifySelectCollectionView() -// goBackCollectionFlow() -// verifySelectTabsView() -// goBackCollectionFlow() -// verifyHomeComponent() -// } -// } -// -// private fun createCollection(collectionName: String, firstCollection: Boolean = true) { -// val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) -// -// navigationToolbar { -// }.enterURLAndEnterToBrowser(firstWebPage.url) { -// verifyPageContent(firstWebPage.content) -// }.openThreeDotMenu { -// clickBrowserViewSaveCollectionButton() -// if (!firstCollection) -// clickAddNewCollection() -// -// }.typeCollectionName(collectionName) { -// verifySnackBarText("Tab saved!") -// }.openHomeScreen { -// mDevice.wait( -// Until.findObject(By.text(collectionName)), -// TestAssetHelper.waitingTime -// ) -// } -// } -//} diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/BrowserRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/BrowserRobot.kt index 30a1691bf..a7057e084 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/BrowserRobot.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/BrowserRobot.kt @@ -23,6 +23,7 @@ import androidx.test.espresso.matcher.ViewMatchers import androidx.test.espresso.matcher.ViewMatchers.Visibility import androidx.test.espresso.matcher.ViewMatchers.isCompletelyDisplayed 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.withResourceName @@ -481,9 +482,9 @@ class BrowserRobot { } fun goToHomescreen(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition { - openTabDrawer { - }.openNewTab { - }.dismissSearchBar {} + onView(withContentDescription("Home screen")) + .check(matches(isDisplayed())) + .click() HomeScreenRobot().interact() return HomeScreenRobot.Transition() 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 new file mode 100644 index 000000000..dae19ca4f --- /dev/null +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/CollectionRobot.kt @@ -0,0 +1,265 @@ +package org.mozilla.fenix.ui.robots + +import androidx.test.espresso.Espresso.onView +import androidx.test.espresso.NoMatchingViewException +import androidx.test.espresso.action.ViewActions +import androidx.test.espresso.action.ViewActions.pressImeActionButton +import androidx.test.espresso.action.ViewActions.replaceText +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.matcher.ViewMatchers.withId +import androidx.test.espresso.matcher.ViewMatchers.withText +import androidx.test.uiautomator.By +import androidx.test.uiautomator.UiSelector +import androidx.test.uiautomator.Until +import org.hamcrest.Matchers.allOf +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())) + } + + fun clickAddNewCollection() = addNewCollectionButton().click() + + fun selectTabForCollection(title: String) { + onView(withText(title)) + .check(matches(isDisplayed())) + .click() + } + + fun verifyCollectionNameTextField() { + mainMenuEditCollectionNameField().check(matches(isDisplayed())) + } + + // names a collection saved from tab drawer + fun typeCollectionNameAndSave(collectionName: String) { + collectionNameTextField().perform(replaceText(collectionName)) + mDevice.findObject(UiSelector().textContains("OK")).click() + } + + fun verifyTabsSelectedCounterText(numOfTabs: Int) { + mDevice.findObject(UiSelector().text("Select tabs to save")) + .waitUntilGone(waitingTime) + + val tabsCounter = onView(withId(R.id.bottom_bar_text)) + when (numOfTabs) { + 1 -> tabsCounter.check(matches(withText("$numOfTabs tab selected"))) + 2 -> tabsCounter.check(matches(withText("$numOfTabs tabs selected"))) + } + } + + fun saveTabsSelectedForCollection() { + onView(withId(R.id.save_button)).click() + } + + fun verifyTabSavedInCollection(title: String, visible: Boolean = true) { + try { + collectionItem(title) + .check( + if (visible) matches(isDisplayed()) else doesNotExist() + ) + } catch (e: NoMatchingViewException) { + scrollToElementByText(title) + } + } + + fun verifyCollectionTabUrl() { + onView(withId(R.id.caption)).check(matches(isDisplayed())) + } + + fun verifyCollectionTabLogo() { + onView(withId(R.id.favicon)).check(matches(isDisplayed())) + } + + fun verifyShareCollectionButtonIsVisible(visible: Boolean) { + shareCollectionButton() + .check( + if (visible) matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)) + else matches(withEffectiveVisibility(ViewMatchers.Visibility.GONE)) + ) + } + + fun clickShareCollectionButton() = onView(withId(R.id.collection_share_button)).click() + + 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 selectRenameCollection() { + onView(withText("Rename collection")).click() + mDevice.waitNotNull(Until.findObject(By.text("Rename collection"))) + } + + fun selectAddTabToCollection() { + onView(withText("Add tab")).click() + mDevice.waitNotNull(Until.findObject(By.text("Select Tabs"))) + } + + fun selectDeleteCollection() { + onView(withText("Delete collection")).click() + mDevice.waitNotNull(Until.findObject(By.res("android:id/message")), waitingTime) + } + + fun confirmDeleteCollection() { + onView(withText("DELETE")).click() + mDevice.waitNotNull( + Until.findObject(By.res("$packageName:id/no_collections_header")), + waitingTime + ) + } + + fun verifyCollectionItemRemoveButtonIsVisible(title: String, visible: Boolean) { + removeTabFromCollectionButton(title) + .check( + if (visible) matches( + withEffectiveVisibility( + ViewMatchers.Visibility.VISIBLE + ) + ) + else doesNotExist() + ) + } + + fun removeTabFromCollection(title: String) = removeTabFromCollectionButton(title).click() + + fun swipeCollectionItemRight(title: String) { + try { + collectionItem(title).perform(ViewActions.swipeRight()) + } catch (e: NoMatchingViewException) { + scrollToElementByText(title) + } + } + + fun swipeCollectionItemLeft(title: String) { + try { + collectionItem(title).perform(ViewActions.swipeLeft()) + } catch (e: NoMatchingViewException) { + scrollToElementByText(title) + } + } + + fun verifySnackBarText(expectedText: String) { + mDevice.findObject(UiSelector().text(expectedText)).waitForExists(waitingTime) + } + + fun goBackInCollectionFlow() = backButton().click() + + 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 selectExistingCollection( + title: String, + interact: BrowserRobot.() -> Unit + ): BrowserRobot.Transition { + mDevice.waitNotNull(Until.findObject(By.text(title)), waitingTime) + onView(withText(title)).click() + + BrowserRobot().interact() + return BrowserRobot.Transition() + } + } +} + +fun collectionRobot(interact: CollectionRobot.() -> Unit): CollectionRobot.Transition { + CollectionRobot().interact() + return CollectionRobot.Transition() +} + +private fun collectionThreeDotButton() = + onView(withId(R.id.collection_overflow_button)) + +private fun collectionItem(title: String) = + onView(allOf(withId(R.id.label), withText(title))) + +private fun shareCollectionButton() = onView(withId(R.id.collection_share_button)) + +private fun removeTabFromCollectionButton(title: String) = + onView( + allOf( + withId(R.id.secondary_button), + hasSibling(withText(title)) + ) + ) + +// collection name text field, opened from tab drawer +private fun collectionNameTextField() = onView(withId(R.id.collection_name)) + +// collection name text field, opened from main menu +private fun mainMenuEditCollectionNameField() = + onView(withId(R.id.name_collection_edittext)) + +private fun addNewCollectionButton() = onView(withText("Add new collection")) + +private fun backButton() = + onView(withId(R.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 3e1ca0801..5c0681b69 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 @@ -13,15 +13,11 @@ import androidx.test.espresso.Espresso.onView import androidx.test.espresso.NoMatchingViewException import androidx.test.espresso.action.ViewActions import androidx.test.espresso.action.ViewActions.click -import androidx.test.espresso.action.ViewActions.swipeLeft -import androidx.test.espresso.action.ViewActions.swipeRight -import androidx.test.espresso.assertion.ViewAssertions.doesNotExist import androidx.test.espresso.assertion.ViewAssertions.matches import androidx.test.espresso.contrib.RecyclerViewActions.actionOnItem import androidx.test.espresso.matcher.ViewMatchers import androidx.test.espresso.matcher.ViewMatchers.Visibility import androidx.test.espresso.matcher.ViewMatchers.hasDescendant -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.matcher.ViewMatchers.withHint @@ -120,127 +116,19 @@ class HomeScreenRobot { fun verifyExistingTopSitesTabs(title: String) = assertExistingTopSitesTabs(title) fun verifyTopSiteContextMenuItems() = assertTopSiteContextMenuItems() - // Collections element - fun clickCollectionThreeDotButton() { - collectionThreeDotButton().click() - mDevice.waitNotNull(findObject(text("Delete collection")), waitingTime) - } - - fun selectOpenTabs() { - onView(allOf(withText("Open tabs"))).click() - } - - fun selectRenameCollection() { - onView(allOf(withText("Rename collection"))).click() - mDevice.waitNotNull(findObject(text("Rename collection"))) - } - - fun selectAddTabToCollection() { - onView(allOf(withText("Add tab"))).click() - mDevice.waitNotNull(findObject(text("Select Tabs"))) - } - - fun selectDeleteCollection() { - onView(allOf(withText("Delete collection"))).click() - mDevice.waitNotNull(findObject(By.res("android:id/message")), waitingTime) - } - - fun confirmDeleteCollection() { - onView(allOf(withText("DELETE"))).click() - mDevice.waitNotNull( - findObject(By.res("$packageName:id/no_collections_header")), - waitingTime - ) - } - - fun verifyCollectionIsDisplayed(title: String) { - mDevice.findObject(UiSelector().text(title)).waitForExists(waitingTime) - collectionTitle(title).check(matches(isDisplayed())) - } - - fun verifyCollectionIcon() = onView(withId(R.id.collection_icon)).check(matches(isDisplayed())) - - fun expandCollection(title: String) { - try { - mDevice.waitNotNull(findObject(text(title)), waitingTime) - collectionTitle(title).click() - } catch (e: NoMatchingViewException) { - scrollToElementByText(title) - } - } - - fun collapseCollection(title: String) { - try { - mDevice.waitNotNull(findObject(text(title)), waitingTime) - onView(allOf(withId(R.id.chevron), hasSibling(withText(title)))).click() - } catch (e: NoMatchingViewException) { - scrollToElementByText(title) - } - } - - fun verifyTabSavedInCollection(title: String, visible: Boolean = true) { - try { - collectionItem(title) - .check( - if (visible) matches(isDisplayed()) else doesNotExist() - ) - } catch (e: NoMatchingViewException) { - scrollToElementByText(title) + // Collections elements + fun verifyCollectionIsDisplayed(title: String, collectionExists: Boolean = true) { + if (collectionExists) { + assertTrue(mDevice.findObject(UiSelector().text(title)).waitForExists(waitingTime)) + } else { + assertTrue(mDevice.findObject(UiSelector().text(title)).waitUntilGone(waitingTime)) } } - fun verifyCollectionTabLogo() = - onView(withId(R.id.favicon)).check(matches(isDisplayed())) - - fun verifyCollectionTabUrl() = - onView(withId(R.id.caption)).check(matches(isDisplayed())) - - fun verifyShareCollectionButtonIsVisible(visible: Boolean) { - shareCollectionButton() - .check( - if (visible) matches(withEffectiveVisibility(Visibility.VISIBLE)) - else matches(withEffectiveVisibility(Visibility.GONE)) - ) - } - - fun verifyCollectionMenuIsVisible(visible: Boolean) { - collectionThreeDotButton() - .check( - if (visible) matches(withEffectiveVisibility(Visibility.VISIBLE)) - else matches(withEffectiveVisibility(Visibility.GONE)) - ) - } - - fun verifyCollectionItemRemoveButtonIsVisible(title: String, visible: Boolean) { - removeTabFromCollectionButton(title) - .check( - if (visible) matches(withEffectiveVisibility(Visibility.VISIBLE)) - else doesNotExist() - ) - } + fun verifyCollectionIcon() = onView(withId(R.id.collection_icon)).check(matches(isDisplayed())) fun verifyShareTabsOverlay() = assertShareTabsOverlay() - fun clickShareCollectionButton() = onView(withId(R.id.collection_share_button)).click() - - fun removeTabFromCollection(title: String) = removeTabFromCollectionButton(title).click() - - fun swipeCollectionItemRight(title: String) { - try { - collectionItem(title).perform(swipeRight()) - } catch (e: NoMatchingViewException) { - scrollToElementByText(title) - } - } - - fun swipeCollectionItemLeft(title: String) { - try { - collectionItem(title).perform(swipeLeft()) - } catch (e: NoMatchingViewException) { - scrollToElementByText(title) - } - } - fun togglePrivateBrowsingModeOnOff() { onView(ViewMatchers.withResourceName("privateBrowsingButton")) .perform(click()) @@ -416,6 +304,18 @@ class HomeScreenRobot { TabDrawerRobot().interact() return TabDrawerRobot.Transition() } + + fun expandCollection(title: String, interact: CollectionRobot.() -> Unit): CollectionRobot.Transition { + try { + mDevice.waitNotNull(findObject(text(title)), waitingTime) + collectionTitle(title).click() + } catch (e: NoMatchingViewException) { + scrollToElementByText(title) + } + + CollectionRobot().interact() + return CollectionRobot.Transition() + } } } @@ -637,9 +537,6 @@ private fun assertPrivateSessionMessage() = onView(withId(R.id.private_session_description)) .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) -private fun collectionThreeDotButton() = - onView(allOf(withId(R.id.collection_overflow_button))) - private fun collectionTitle(title: String) = onView(allOf(withId(R.id.collection_title), withText(title))) @@ -678,21 +575,8 @@ private fun assertShareTabsOverlay() { private fun privateBrowsingButton() = onView(withId(R.id.privateBrowsingButton)) -private fun collectionItem(title: String) = - onView(allOf(withId(R.id.label), withText(title))) - private fun saveTabsToCollectionButton() = onView(withId(R.id.add_tabs_to_collections_button)) -private fun shareCollectionButton() = onView(withId(R.id.collection_share_button)) - -private fun removeTabFromCollectionButton(title: String) = - onView( - allOf( - withId(R.id.secondary_button), - hasSibling(withText(title)) - ) - ) - private fun tabsCounter() = onView(withId(R.id.tab_button)) private fun startBrowsingButton(): UiObject { 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 18327df43..e780d6250 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 @@ -18,7 +18,7 @@ import androidx.test.espresso.ViewAction import androidx.test.espresso.action.GeneralLocation import androidx.test.espresso.action.ViewActions import androidx.test.espresso.action.ViewActions.click -import androidx.test.espresso.action.ViewActions.replaceText +import androidx.test.espresso.action.ViewActions.longClick import androidx.test.espresso.assertion.ViewAssertions.doesNotExist import androidx.test.espresso.assertion.ViewAssertions.matches import androidx.test.espresso.contrib.RecyclerViewActions @@ -36,6 +36,7 @@ import androidx.test.uiautomator.UiSelector import androidx.test.uiautomator.Until import androidx.test.uiautomator.Until.findObject import com.google.android.material.bottomsheet.BottomSheetBehavior +import junit.framework.TestCase.assertTrue import org.hamcrest.CoreMatchers.allOf import org.hamcrest.CoreMatchers.anyOf import org.hamcrest.CoreMatchers.containsString @@ -173,8 +174,6 @@ class TabDrawerRobot { selectTabsButton.click() } - fun clickAddNewCollection() = addNewCollectionButton().click() - fun selectTab(title: String) { mDevice.waitNotNull( findObject(text(title)), @@ -185,11 +184,14 @@ class TabDrawerRobot { tab.click() } - fun clickSaveCollection() = saveTabsToCollectionButton().click() + fun longClickTab(title: String) { + mDevice.waitNotNull( + findObject(text(title)), + waitingTime + ) - fun typeCollectionName(collectionName: String) { - collectionNameTextField().perform(replaceText(collectionName)) - mDevice.findObject(UiSelector().textContains("OK")).click() + val tab = onView(withText(title)) + tab.perform(longClick()) } fun createCollection( @@ -199,10 +201,19 @@ class TabDrawerRobot { ) { clickSelectTabs() selectTab(tabTitle) - clickSaveCollection() - if (!firstCollection) - clickAddNewCollection() - typeCollectionName(collectionName) + tabDrawer { + }.clickSaveCollection { + if (!firstCollection) + clickAddNewCollection() + typeCollectionNameAndSave(collectionName) + } + } + + fun verifyTabsMultiSelectionCounter(numOfTabs: Int) { + assertTrue( + mDevice.findObject(UiSelector().text("$numOfTabs selected")) + .waitForExists(waitingTime) + ) } class Transition { @@ -343,6 +354,14 @@ class TabDrawerRobot { RecentlyClosedTabsRobot().interact() return RecentlyClosedTabsRobot.Transition() } + + fun clickSaveCollection(interact: CollectionRobot.() -> Unit): + CollectionRobot.Transition { + saveTabsToCollectionButton().click() + + CollectionRobot().interact() + return CollectionRobot.Transition() + } } } @@ -464,8 +483,4 @@ private fun tabsCounter() = onView(withId(R.id.tab_button)) private fun visibleOrGone(visibility: Boolean) = if (visibility) ViewMatchers.Visibility.VISIBLE else ViewMatchers.Visibility.GONE -private fun addNewCollectionButton() = onView(withId(R.id.add_new_collection)) - private fun saveTabsToCollectionButton() = onView(withId(R.id.collect_multi_select)) - -private fun collectionNameTextField() = onView(withId(R.id.collection_name)) diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ThreeDotMenuMainRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ThreeDotMenuMainRobot.kt index 11313c44c..d42318879 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ThreeDotMenuMainRobot.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ThreeDotMenuMainRobot.kt @@ -8,7 +8,6 @@ package org.mozilla.fenix.ui.robots import androidx.recyclerview.widget.RecyclerView import androidx.test.espresso.Espresso.onView -import androidx.test.espresso.action.ViewActions import androidx.test.espresso.action.ViewActions.swipeDown import androidx.test.espresso.action.ViewActions.swipeUp import androidx.test.espresso.assertion.ViewAssertions.matches @@ -80,15 +79,6 @@ class ThreeDotMenuMainRobot { fun verifySaveCollection() = assertSaveCollectionButton() fun verifySelectTabs() = assertSelectTabsButton() - fun clickSaveCollectionButton() { - browserViewSaveCollectionButton().click() - } - - fun clickAddNewCollection() { - addNewCollectionButton().click() - } - - fun verifyCollectionNameTextField() = assertCollectionNameTextField() fun verifyFindInPageButton() = assertFindInPageButton() fun verifyShareScrim() = assertShareScrim() fun verifySendToDeviceTitle() = assertSendToDeviceTitle() @@ -287,26 +277,6 @@ class ThreeDotMenuMainRobot { return BrowserRobot.Transition() } - fun typeCollectionName( - name: String, - interact: BrowserRobot.() -> Unit - ): BrowserRobot.Transition { - mDevice.wait( - Until.findObject(By.res("$packageName:id/name_collection_edittext")), - waitingTime - ) - - collectionNameTextField().perform( - ViewActions.replaceText(name), - ViewActions.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 openReaderViewAppearance(interact: ReaderViewRobot.() -> Unit): ReaderViewRobot.Transition { var maxSwipes = 3 while (!readerViewAppearanceToggle().exists() && maxSwipes != 0) { @@ -346,15 +316,7 @@ class ThreeDotMenuMainRobot { return AddToHomeScreenRobot.Transition() } - fun selectExistingCollection(title: String, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { - mDevice.waitNotNull(Until.findObject(By.text(title)), waitingTime) - onView(withText(title)).click() - - BrowserRobot().interact() - return BrowserRobot.Transition() - } - - fun openSaveToCollection(interact: ThreeDotMenuMainRobot.() -> Unit): ThreeDotMenuMainRobot.Transition { + fun openSaveToCollection(interact: CollectionRobot.() -> Unit): CollectionRobot.Transition { // Ensure the menu is expanded and fully scrolled to the bottom. for (i in 0..3) { threeDotMenuRecyclerView().perform(swipeUp()) @@ -362,8 +324,8 @@ class ThreeDotMenuMainRobot { mDevice.waitNotNull(Until.findObject(By.text("Save to collection")), waitingTime) saveCollectionButton().click() - ThreeDotMenuMainRobot().interact() - return ThreeDotMenuMainRobot.Transition() + CollectionRobot().interact() + return CollectionRobot.Transition() } fun openAddonsManagerMenu(interact: SettingsSubMenuAddonsManagerRobot.() -> Unit): SettingsSubMenuAddonsManagerRobot.Transition { @@ -375,13 +337,6 @@ class ThreeDotMenuMainRobot { SettingsSubMenuAddonsManagerRobot().interact() return SettingsSubMenuAddonsManagerRobot.Transition() } - - fun exitSaveCollection(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { - exitSaveCollectionButton().click() - - BrowserRobot().interact() - return BrowserRobot.Transition() - } } } private fun threeDotMenuRecyclerView() = @@ -444,13 +399,6 @@ private fun assertShareTabButton() = shareTabButton() private fun shareButton() = mDevice.findObject(UiSelector().description("Share")) private fun assertShareButton() = assertTrue(shareButton().waitForExists(waitingTime)) -private fun browserViewSaveCollectionButton() = onView( - allOf( - withText("Save to collection"), - withEffectiveVisibility(Visibility.VISIBLE) - ) -) - private fun saveCollectionButton() = onView(allOf(withText("Save to collection"))).inRoot(RootMatchers.isPlatformPopup()) private fun assertSaveCollectionButton() = saveCollectionButton() .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) @@ -459,16 +407,6 @@ private fun selectTabsButton() = onView(allOf(withText("Select tabs"))).inRoot(R private fun assertSelectTabsButton() = selectTabsButton() .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) -private fun addNewCollectionButton() = onView(allOf(withText("Add new collection"))) -private fun assertaddNewCollectionButton() = addNewCollectionButton() - .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) - -private fun collectionNameTextField() = - onView(allOf(withResourceName("name_collection_edittext"))) - -private fun assertCollectionNameTextField() = collectionNameTextField() - .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) - private fun reportSiteIssueButton() = onView(withText("Report Site Issue…")) private fun assertReportSiteIssueButton() = reportSiteIssueButton().check(matches(isDisplayed())) @@ -568,8 +506,6 @@ private fun clickAddonsManagerButton() { addOnsButton().check(matches(isCompletelyDisplayed())).click() } -private fun exitSaveCollectionButton() = onView(withId(R.id.back_button)).check(matches(isDisplayed())) - private fun tabSettingsButton() = onView(allOf(withText("Tab settings"))).inRoot(RootMatchers.isPlatformPopup())