You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
iceraven-browser/app/src/androidTest/java/org/mozilla/fenix/ui/robots/CollectionRobot.kt

316 lines
16 KiB
Kotlin

/* 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.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.pressImeActionButton
import androidx.test.espresso.matcher.RootMatchers
import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.uiautomator.By
import androidx.test.uiautomator.UiSelector
import androidx.test.uiautomator.Until
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
import org.mozilla.fenix.helpers.MatcherHelper.assertUIObjectExists
import org.mozilla.fenix.helpers.MatcherHelper.assertUIObjectIsGone
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.itemWithText
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.scrollToElementByText
import org.mozilla.fenix.helpers.click
import org.mozilla.fenix.helpers.ext.waitNotNull
class CollectionRobot {
fun verifySelectCollectionScreen() =
assertUIObjectExists(
itemContainingText("Select collection"),
itemContainingText("Add new collection"),
itemWithResId("$packageName:id/collections_list"),
)
fun clickAddNewCollection() {
Log.i(TAG, "clickAddNewCollection: Trying to click the add new collection button")
addNewCollectionButton().click()
Log.i(TAG, "clickAddNewCollection: Clicked the add new collection button")
}
fun verifyCollectionNameTextField() = assertUIObjectExists(mainMenuEditCollectionNameField())
// names a collection saved from tab drawer
fun typeCollectionNameAndSave(collectionName: String) {
Log.i(TAG, "typeCollectionNameAndSave: Trying to set collection name text field to: $collectionName")
collectionNameTextField().setText(collectionName)
Log.i(TAG, "typeCollectionNameAndSave: Collection name text field set to: $collectionName")
Log.i(TAG, "typeCollectionNameAndSave: Waiting for $waitingTime ms for add collection button panel to exist")
addCollectionButtonPanel().waitForExists(waitingTime)
Log.i(TAG, "typeCollectionNameAndSave: Waited for $waitingTime ms for add collection button panel to exist")
Log.i(TAG, "typeCollectionNameAndSave: Trying to click \"OK\" panel button")
addCollectionOkButton().click()
Log.i(TAG, "typeCollectionNameAndSave: Clicked \"OK\" panel button")
}
fun verifyTabsSelectedCounterText(numOfTabs: Int) {
Log.i(TAG, "verifyTabsSelectedCounterText: Waiting for $waitingTime ms for \"Select tabs to save\" prompt to be gone")
itemWithText("Select tabs to save").waitUntilGone(waitingTime)
Log.i(TAG, "verifyTabsSelectedCounterText: Waited for $waitingTime ms for \"Select tabs to save\" prompt to be gone")
val tabsCounter = mDevice.findObject(UiSelector().resourceId("$packageName:id/bottom_bar_text"))
Log.i(TAG, "verifyTabsSelectedCounterText: Trying to assert that number of tabs selected is: $numOfTabs")
when (numOfTabs) {
1 -> assertItemTextEquals(tabsCounter, expectedText = "$numOfTabs tab selected")
2 -> assertItemTextEquals(tabsCounter, expectedText = "$numOfTabs tabs selected")
}
Log.i(TAG, "verifyTabsSelectedCounterText: Asserted number of tabs selected is: $numOfTabs")
}
fun saveTabsSelectedForCollection() {
Log.i(TAG, "saveTabsSelectedForCollection: Trying to click \"Save\" button")
itemWithResId("$packageName:id/save_button").click()
Log.i(TAG, "saveTabsSelectedForCollection: Clicked \"Save\" button")
}
fun verifyTabSavedInCollection(title: String, visible: Boolean = true) {
if (visible) {
scrollToElementByText(title)
assertUIObjectExists(collectionListItem(title))
} else {
assertUIObjectIsGone(collectionListItem(title))
}
}
fun verifyCollectionTabUrl(visible: Boolean, url: String) =
assertUIObjectExists(itemContainingText(url), exists = visible)
fun verifyShareCollectionButtonIsVisible(visible: Boolean) =
assertUIObjectExists(shareCollectionButton(), exists = visible)
fun verifyCollectionMenuIsVisible(visible: Boolean, rule: ComposeTestRule) {
if (visible) {
Log.i(TAG, "verifyCollectionMenuIsVisible: Trying to verify collection three dot button exists")
collectionThreeDotButton(rule).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()
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)
.assertDoesNotExist()
Log.i(TAG, "verifyCollectionMenuIsVisible: Verified collection three dot button does not exist")
}
}
fun clickCollectionThreeDotButton(rule: ComposeTestRule) {
Log.i(TAG, "clickCollectionThreeDotButton: Trying to verify three dot button is displayed")
collectionThreeDotButton(rule).assertIsDisplayed()
Log.i(TAG, "clickCollectionThreeDotButton: Verified three dot button is displayed")
Log.i(TAG, "clickCollectionThreeDotButton: Trying to click three dot button")
collectionThreeDotButton(rule).performClick()
Log.i(TAG, "clickCollectionThreeDotButton: Clicked three dot button")
}
fun selectOpenTabs(rule: ComposeTestRule) {
Log.i(TAG, "selectOpenTabs: Trying to verify \"Open tabs\" menu option is displayed")
rule.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()
Log.i(TAG, "selectOpenTabs: Clicked \"Open tabs\" menu option")
}
fun selectRenameCollection(rule: ComposeTestRule) {
Log.i(TAG, "selectRenameCollection: Trying to verify \"Rename collection\" menu option is displayed")
rule.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()
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)
Log.i(TAG, "selectRenameCollection: Waited for $waitingTime ms for collection name text field to exist")
}
fun selectAddTabToCollection(rule: ComposeTestRule) {
Log.i(TAG, "selectAddTabToCollection: Trying to verify \"Add tab\" menu option is displayed")
rule.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()
Log.i(TAG, "selectAddTabToCollection: Clicked \"Add tab\" menu option")
mDevice.waitNotNull(Until.findObject(By.text("Select Tabs")))
}
fun selectDeleteCollection(rule: ComposeTestRule) {
Log.i(TAG, "selectDeleteCollection: Trying to verify \"Delete collection\" menu option is displayed")
rule.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()
Log.i(TAG, "selectDeleteCollection: Clicked \"Delete collection\" menu option")
}
fun verifyCollectionItemRemoveButtonIsVisible(title: String, visible: Boolean) =
assertUIObjectExists(removeTabFromCollectionButton(title), exists = visible)
fun removeTabFromCollection(title: String) {
Log.i(TAG, "removeTabFromCollection: Trying to click remove button for tab: $title")
removeTabFromCollectionButton(title).click()
Log.i(TAG, "removeTabFromCollection: Clicked remove button for tab: $title")
}
fun swipeTabLeft(title: String, rule: ComposeTestRule) {
Log.i(TAG, "swipeTabLeft: Trying to remove tab: $title using swipe left action")
rule.onNode(hasText(title), useUnmergedTree = true)
.performTouchInput { swipeLeft() }
Log.i(TAG, "swipeTabLeft: Removed tab: $title using swipe left action")
Log.i(TAG, "swipeTabLeft: Waiting for rule to be idle")
rule.waitForIdle()
Log.i(TAG, "swipeTabLeft: Waited for rule to be idle")
}
fun swipeTabRight(title: String, rule: ComposeTestRule) {
Log.i(TAG, "swipeTabRight: Trying to remove tab: $title using swipe right action")
rule.onNode(hasText(title), useUnmergedTree = true)
.performTouchInput { swipeRight() }
Log.i(TAG, "swipeTabRight: Removed tab: $title using swipe right action")
Log.i(TAG, "swipeTabRight: Waiting for rule to be idle")
rule.waitForIdle()
Log.i(TAG, "swipeTabRight: Waited for rule to be idle")
}
fun goBackInCollectionFlow() {
Log.i(TAG, "goBackInCollectionFlow: Trying to click collection creation flow back button")
backButton().click()
Log.i(TAG, "goBackInCollectionFlow: Clicked collection creation flow back button")
}
class Transition {
fun collapseCollection(
title: String,
interact: HomeScreenRobot.() -> Unit,
): HomeScreenRobot.Transition {
assertUIObjectExists(itemContainingText(title))
Log.i(TAG, "collapseCollection: Trying to click collection $title and wait for $waitingTimeShort ms for a new window")
itemContainingText(title).clickAndWaitForNewWindow(waitingTimeShort)
Log.i(TAG, "collapseCollection: Clicked collection $title and waited for $waitingTimeShort ms for a new window")
assertUIObjectExists(itemWithDescription(getStringResource(R.string.remove_tab_from_collection)), exists = false)
HomeScreenRobot().interact()
return HomeScreenRobot.Transition()
}
// names a collection saved from the 3dot menu
fun typeCollectionNameAndSave(
name: String,
interact: BrowserRobot.() -> Unit,
): BrowserRobot.Transition {
Log.i(TAG, "typeCollectionNameAndSave: Waiting for $waitingTime ms for collection name text field to exist")
mainMenuEditCollectionNameField().waitForExists(waitingTime)
Log.i(TAG, "typeCollectionNameAndSave: Waited for $waitingTime ms for collection name text field to exist")
Log.i(TAG, "typeCollectionNameAndSave: Trying to set collection name text field to: $name")
mainMenuEditCollectionNameField().setText(name)
Log.i(TAG, "typeCollectionNameAndSave: Collection name text field set to: $name")
Log.i(TAG, "typeCollectionNameAndSave: Trying to press done action button")
onView(withId(R.id.name_collection_edittext)).perform(pressImeActionButton())
Log.i(TAG, "typeCollectionNameAndSave: Pressed done action button")
// 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 {
Log.i(TAG, "selectExistingCollection: Waiting for $waitingTime ms for collection with title: $title to exist")
collectionTitle(title).waitForExists(waitingTime)
Log.i(TAG, "selectExistingCollection: Waited for $waitingTime ms for collection with title: $title to exist")
Log.i(TAG, "selectExistingCollection: Trying to click collection with title: $title")
collectionTitle(title).click()
Log.i(TAG, "selectExistingCollection: Clicked collection with title: $title")
BrowserRobot().interact()
return BrowserRobot.Transition()
}
fun clickShareCollectionButton(interact: ShareOverlayRobot.() -> Unit): ShareOverlayRobot.Transition {
Log.i(TAG, "clickShareCollectionButton: Waiting for $waitingTime ms for share collection button to exist")
shareCollectionButton().waitForExists(waitingTime)
Log.i(TAG, "clickShareCollectionButton: Waited for $waitingTime ms for share collection button to exist")
Log.i(TAG, "clickShareCollectionButton: Trying to click share collection button")
shareCollectionButton().click()
Log.i(TAG, "clickShareCollectionButton: Clicked share collection button")
ShareOverlayRobot().interact()
return ShareOverlayRobot.Transition()
}
}
}
fun collectionRobot(interact: CollectionRobot.() -> Unit): CollectionRobot.Transition {
CollectionRobot().interact()
return CollectionRobot.Transition()
}
private fun collectionTitle(title: String) = itemWithText(title)
private fun collectionThreeDotButton(rule: ComposeTestRule) =
rule.onNode(hasContentDescription("Collection menu"))
private fun collectionListItem(title: String) = mDevice.findObject(UiSelector().text(title))
private fun shareCollectionButton() = itemWithDescription("Share")
private fun removeTabFromCollectionButton(title: String) =
mDevice.findObject(
UiSelector().text(title),
).getFromParent(
UiSelector()
.description("Remove tab from collection"),
)
// collection name text field, opened from tab drawer
private fun collectionNameTextField() =
mDevice.findObject(
UiSelector().resourceId("$packageName:id/collection_name"),
)
// collection name text field, when saving from the main menu option
private fun mainMenuEditCollectionNameField() =
itemWithResId("$packageName:id/name_collection_edittext")
private fun addNewCollectionButton() =
mDevice.findObject(UiSelector().text("Add new collection"))
private fun backButton() =
mDevice.findObject(
UiSelector().resourceId("$packageName:id/back_button"),
)
private fun addCollectionButtonPanel() =
itemWithResId("$packageName:id/buttonPanel")
private fun addCollectionOkButton() = onView(withId(android.R.id.button1)).inRoot(RootMatchers.isDialog())