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.
301 lines
10 KiB
Kotlin
301 lines
10 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 androidx.compose.ui.test.assertIsDisplayed
|
|
import androidx.compose.ui.test.hasContentDescription
|
|
import androidx.compose.ui.test.hasText
|
|
import androidx.compose.ui.test.isDialog
|
|
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.NoMatchingViewException
|
|
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.UiScrollable
|
|
import androidx.test.uiautomator.UiSelector
|
|
import androidx.test.uiautomator.Until
|
|
import org.junit.Assert.assertFalse
|
|
import org.junit.Assert.assertTrue
|
|
import org.mozilla.fenix.R
|
|
import org.mozilla.fenix.helpers.MatcherHelper.itemWithResId
|
|
import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime
|
|
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() {
|
|
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() {
|
|
assertTrue(
|
|
mainMenuEditCollectionNameField().waitForExists(waitingTime),
|
|
)
|
|
}
|
|
|
|
// names a collection saved from tab drawer
|
|
fun typeCollectionNameAndSave(collectionName: String) {
|
|
collectionNameTextField().text = collectionName
|
|
addCollectionButtonPanel.waitForExists(waitingTime)
|
|
addCollectionOkButton.click()
|
|
}
|
|
|
|
fun verifyTabsSelectedCounterText(numOfTabs: Int) {
|
|
mDevice.findObject(UiSelector().text("Select tabs to save"))
|
|
.waitUntilGone(waitingTime)
|
|
|
|
val tabsCounter = mDevice.findObject(UiSelector().resourceId("$packageName:id/bottom_bar_text"))
|
|
when (numOfTabs) {
|
|
1 -> assertTrue(tabsCounter.text.equals("$numOfTabs tab selected"))
|
|
2 -> assertTrue(tabsCounter.text.equals("$numOfTabs tabs selected"))
|
|
}
|
|
}
|
|
|
|
fun saveTabsSelectedForCollection() {
|
|
mDevice.findObject(UiSelector().resourceId("$packageName:id/save_button")).click()
|
|
}
|
|
|
|
fun verifyTabSavedInCollection(title: String, visible: Boolean = true) {
|
|
if (visible) {
|
|
scrollToElementByText(title)
|
|
assertTrue(
|
|
collectionListItem(title).waitForExists(waitingTime),
|
|
)
|
|
} else {
|
|
assertTrue(
|
|
collectionListItem(title).waitUntilGone(waitingTime),
|
|
)
|
|
}
|
|
}
|
|
|
|
fun verifyCollectionTabUrl(visible: Boolean, url: String) {
|
|
val tabUrl = mDevice.findObject(UiSelector().text(url))
|
|
|
|
if (visible) {
|
|
assertTrue(tabUrl.exists())
|
|
} else {
|
|
assertFalse(tabUrl.exists())
|
|
}
|
|
}
|
|
|
|
fun verifyShareCollectionButtonIsVisible(visible: Boolean) {
|
|
if (visible) {
|
|
assertTrue(shareCollectionButton().exists())
|
|
} else {
|
|
assertFalse(shareCollectionButton().exists())
|
|
}
|
|
}
|
|
|
|
fun verifyCollectionMenuIsVisible(visible: Boolean, rule: ComposeTestRule) {
|
|
if (visible) {
|
|
collectionThreeDotButton(rule)
|
|
.assertExists()
|
|
.assertIsDisplayed()
|
|
} else {
|
|
collectionThreeDotButton(rule)
|
|
.assertDoesNotExist()
|
|
}
|
|
}
|
|
|
|
fun clickCollectionThreeDotButton(rule: ComposeTestRule) {
|
|
collectionThreeDotButton(rule)
|
|
.assertIsDisplayed()
|
|
.performClick()
|
|
}
|
|
|
|
fun selectOpenTabs(rule: ComposeTestRule) {
|
|
rule.onNode(hasText("Open tabs"))
|
|
.assertIsDisplayed()
|
|
.performClick()
|
|
}
|
|
|
|
fun selectRenameCollection(rule: ComposeTestRule) {
|
|
rule.onNode(hasText("Rename collection"))
|
|
.assertIsDisplayed()
|
|
.performClick()
|
|
mainMenuEditCollectionNameField().waitForExists(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) {
|
|
if (visible) {
|
|
assertTrue(
|
|
removeTabFromCollectionButton(title).exists(),
|
|
)
|
|
} else {
|
|
assertFalse(
|
|
removeTabFromCollectionButton(title).exists(),
|
|
)
|
|
}
|
|
}
|
|
|
|
fun removeTabFromCollection(title: String) = removeTabFromCollectionButton(title).click()
|
|
|
|
fun swipeTabLeft(title: String, rule: ComposeTestRule) {
|
|
rule.onNode(hasText(title), useUnmergedTree = true)
|
|
.performTouchInput { swipeLeft() }
|
|
rule.waitForIdle()
|
|
}
|
|
|
|
fun swipeTabRight(title: String, rule: ComposeTestRule) {
|
|
rule.onNode(hasText(title), useUnmergedTree = true)
|
|
.performTouchInput { swipeRight() }
|
|
rule.waitForIdle()
|
|
}
|
|
|
|
fun verifySnackBarText(expectedText: String) {
|
|
mDevice.findObject(UiSelector().text(expectedText)).waitForExists(waitingTime)
|
|
}
|
|
|
|
fun goBackInCollectionFlow() = backButton().click()
|
|
|
|
fun swipeToBottom() =
|
|
UiScrollable(
|
|
UiSelector().resourceId("$packageName:id/sessionControlRecyclerView"),
|
|
).scrollToEnd(3)
|
|
|
|
class 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 {
|
|
collectionTitle(title).waitForExists(waitingTime)
|
|
collectionTitle(title).click()
|
|
|
|
BrowserRobot().interact()
|
|
return BrowserRobot.Transition()
|
|
}
|
|
|
|
fun clickShareCollectionButton(interact: ShareOverlayRobot.() -> Unit): ShareOverlayRobot.Transition {
|
|
shareCollectionButton().waitForExists(waitingTime)
|
|
shareCollectionButton().click()
|
|
|
|
ShareOverlayRobot().interact()
|
|
return ShareOverlayRobot.Transition()
|
|
}
|
|
}
|
|
}
|
|
|
|
fun collectionRobot(interact: CollectionRobot.() -> Unit): CollectionRobot.Transition {
|
|
CollectionRobot().interact()
|
|
return CollectionRobot.Transition()
|
|
}
|
|
|
|
private fun collectionTitle(title: String) =
|
|
mDevice.findObject(
|
|
UiSelector()
|
|
.text(title),
|
|
)
|
|
|
|
private fun collectionThreeDotButton(rule: ComposeTestRule) =
|
|
rule.onNode(hasContentDescription("Collection menu"))
|
|
|
|
private fun collectionListItem(title: String) = mDevice.findObject(UiSelector().text(title))
|
|
|
|
private fun shareCollectionButton() =
|
|
mDevice.findObject(
|
|
UiSelector().description("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() =
|
|
mDevice.findObject(
|
|
UiSelector().resourceId("$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 val addCollectionButtonPanel =
|
|
itemWithResId("$packageName:id/buttonPanel")
|
|
|
|
private val addCollectionOkButton = onView(withId(android.R.id.button1)).inRoot(RootMatchers.isDialog())
|