Bug 1864642 - Create new custom assertions for UI tests

fenix/121.0
AndiAJ 7 months ago committed by mergify[bot]
parent 0ef251c789
commit ed2ca35456

@ -39,25 +39,55 @@ object MatcherHelper {
return mDevice.findObject(UiSelector().descriptionContains(description))
}
fun checkedItemWithResId(resourceId: String, isChecked: Boolean) =
mDevice.findObject(UiSelector().resourceId(resourceId).checked(isChecked))
fun itemWithIndex(index: Int): UiObject {
Log.i(TAG, "Looking for item with index: $index")
return mDevice.findObject(UiSelector().index(index))
}
fun itemWithClassName(className: String): UiObject {
Log.i(TAG, "Looking for item with class name: $className")
return mDevice.findObject(UiSelector().className(className))
}
fun checkedItemWithResIdAndText(resourceId: String, text: String, isChecked: Boolean) =
mDevice.findObject(
fun itemWithResIdAndIndex(resourceId: String, index: Int): UiObject {
Log.i(TAG, "Looking for item with resource id: $resourceId and index: $index")
return mDevice.findObject(UiSelector().resourceId(resourceId).index(index))
}
fun itemWithClassNameAndIndex(className: String, index: Int): UiObject {
Log.i(TAG, "Looking for item with class name: $className and index: $index")
return mDevice.findObject(UiSelector().className(className).index(index))
}
fun checkedItemWithResId(resourceId: String, isChecked: Boolean): UiObject {
Log.i(TAG, "Looking for checked item with resource id: $resourceId")
return mDevice.findObject(UiSelector().resourceId(resourceId).checked(isChecked))
}
fun checkedItemWithResIdAndText(resourceId: String, text: String, isChecked: Boolean): UiObject {
Log.i(TAG, "Looking for checked item with resource id: $resourceId and text: $text")
return mDevice.findObject(
UiSelector()
.resourceId(resourceId)
.textContains(text)
.checked(isChecked),
)
}
fun itemWithResIdAndDescription(resourceId: String, description: String) =
mDevice.findObject(UiSelector().resourceId(resourceId).descriptionContains(description))
fun itemWithResIdAndDescription(resourceId: String, description: String): UiObject {
Log.i(TAG, "Looking for item with resource id: $resourceId and description: $description")
return mDevice.findObject(UiSelector().resourceId(resourceId).descriptionContains(description))
}
fun itemWithResIdAndText(resourceId: String, text: String) =
mDevice.findObject(UiSelector().resourceId(resourceId).text(text))
fun itemWithResIdAndText(resourceId: String, text: String): UiObject {
Log.i(TAG, "Looking for item with resource id: $resourceId and text: $text")
return mDevice.findObject(UiSelector().resourceId(resourceId).text(text))
}
fun itemWithResIdContainingText(resourceId: String, text: String) =
mDevice.findObject(UiSelector().resourceId(resourceId).textContains(text))
fun itemWithResIdContainingText(resourceId: String, text: String): UiObject {
Log.i(TAG, "Looking for item with resource id: $resourceId and containing text: $text")
return mDevice.findObject(UiSelector().resourceId(resourceId).textContains(text))
}
fun assertItemWithResIdExists(vararg appItems: UiObject, exists: Boolean = true) {
if (exists) {
@ -73,7 +103,18 @@ object MatcherHelper {
}
}
fun assertItemContainingTextExists(vararg appItems: UiObject, exists: Boolean = true) {
fun assertItemWithResIdIsGone(vararg appItems: UiObject) {
for (appItem in appItems) {
assertTrue("${appItem.selector} is not gone", appItem.waitUntilGone(waitingTime))
Log.i(TAG, "assertItemWithResIdIsGone: Verified ${appItem.selector} is gone")
}
}
fun assertItemContainingTextExists(
vararg appItems: UiObject,
exists: Boolean = true,
waitingTime: Long = TestAssetHelper.waitingTime,
) {
for (appItem in appItems) {
if (exists) {
assertTrue("${appItem.selector} does not exist", appItem.waitForExists(waitingTime))
@ -85,14 +126,105 @@ object MatcherHelper {
}
}
fun assertItemContainingTextIsGone(vararg appItems: UiObject) {
for (appItem in appItems) {
assertTrue("${appItem.selector} is not gone", appItem.waitUntilGone(waitingTime))
Log.i(TAG, "assertItemContainingTextIsGone: Verified ${appItem.selector} is gone")
}
}
fun assertItemTextEquals(vararg appItems: UiObject, expectedText: String, isEqual: Boolean = true) {
for (appItem in appItems) {
if (isEqual) {
assertTrue(
"${appItem.selector} text does not equal to $expectedText",
appItem.text.equals(expectedText),
)
Log.i(TAG, "assertItemTextEquals: Verified ${appItem.selector} text equals to $expectedText")
} else {
assertFalse(
"${appItem.selector} text equals to $expectedText",
appItem.text.equals(expectedText),
)
Log.i(TAG, "assertItemTextEquals: Verified ${appItem.selector} text does not equal to $expectedText")
}
}
}
fun assertItemTextContains(vararg appItems: UiObject, itemText: String) {
for (appItem in appItems) {
assertTrue(
"${appItem.selector} text does not contain $itemText",
appItem.text.contains(itemText),
)
Log.i(TAG, "assertItemTextContains: Verified ${appItem.selector} text contains $itemText")
}
}
fun assertItemWithDescriptionExists(vararg appItems: UiObject, exists: Boolean = true) {
for (appItem in appItems) {
if (exists) {
assertTrue("${appItem.selector} does not exist", appItem.waitForExists(waitingTime))
Log.i(TAG, "assertItemContainingTextExists: Verified ${appItem.selector} exists")
Log.i(TAG, "assertItemWithDescriptionExists: Verified ${appItem.selector} exists")
} else {
assertFalse("${appItem.selector} exists", appItem.waitForExists(waitingTimeShort))
Log.i(TAG, "assertItemContainingTextExists: Verified ${appItem.selector} does not exist")
Log.i(TAG, "assertItemWithDescriptionExists: Verified ${appItem.selector} does not exist")
}
}
}
fun assertItemWithIndexExists(vararg appItems: UiObject, exists: Boolean = true) {
if (exists) {
for (appItem in appItems) {
assertTrue("${appItem.selector} does not exist", appItem.waitForExists(waitingTime))
Log.i(TAG, "assertItemWithIndexExists: Verified ${appItem.selector} exists")
}
} else {
for (appItem in appItems) {
assertFalse("${appItem.selector} exists", appItem.waitForExists(waitingTimeShort))
Log.i(TAG, "assertItemWithIndexExists: Verified ${appItem.selector} does not exist")
}
}
}
fun assertItemWithClassNameExists(vararg appItems: UiObject, exists: Boolean = true) {
if (exists) {
for (appItem in appItems) {
assertTrue("${appItem.selector} does not exist", appItem.waitForExists(waitingTime))
Log.i(TAG, "assertItemWithClassNameExists: Verified ${appItem.selector} exists")
}
} else {
for (appItem in appItems) {
assertFalse("${appItem.selector} exists", appItem.waitForExists(waitingTimeShort))
Log.i(TAG, "assertItemWithClassNameExists: Verified ${appItem.selector} does not exist")
}
}
}
fun assertItemWithResIdAndIndexExists(vararg appItems: UiObject, exists: Boolean = true) {
if (exists) {
for (appItem in appItems) {
assertTrue("${appItem.selector} does not exist", appItem.waitForExists(waitingTime))
Log.i(TAG, "assertItemWithResIdAndIndexExists: Verified ${appItem.selector} exists")
}
} else {
for (appItem in appItems) {
assertFalse("${appItem.selector} exists", appItem.waitForExists(waitingTimeShort))
Log.i(TAG, "assertItemWithResIdAndIndexExists: Verified ${appItem.selector} does not exist")
}
}
}
fun assertItemWithClassNameAndIndexExists(vararg appItems: UiObject, exists: Boolean = true) {
if (exists) {
for (appItem in appItems) {
assertTrue("${appItem.selector} does not exist", appItem.waitForExists(waitingTime))
Log.i(TAG, "assertItemWithClassNameAndIndexExists: Verified ${appItem.selector} exists")
}
} else {
for (appItem in appItems) {
assertFalse("${appItem.selector} exists", appItem.waitForExists(waitingTimeShort))
Log.i(TAG, "assertItemWithClassNameAndIndexExists: Verified ${appItem.selector} does not exist")
}
}
}
@ -104,7 +236,7 @@ object MatcherHelper {
Log.i(TAG, "assertCheckedItemWithResIdExists: Verified ${appItem.selector} exists")
} else {
assertFalse("${appItem.selector} exists", appItem.waitForExists(waitingTimeShort))
Log.i(TAG, "assertItemContainingTextExists: Verified ${appItem.selector} does not exist")
Log.i(TAG, "assertCheckedItemWithResIdExists: Verified ${appItem.selector} does not exist")
}
}
}
@ -112,12 +244,14 @@ object MatcherHelper {
fun assertCheckedItemWithResIdAndTextExists(vararg appItems: UiObject) {
for (appItem in appItems) {
assertTrue(appItem.waitForExists(waitingTime))
Log.i(TAG, "assertCheckedItemWithResIdAndTextExists: Verified ${appItem.selector} exists")
}
}
fun assertItemWithResIdAndDescriptionExists(vararg appItems: UiObject) {
for (appItem in appItems) {
assertTrue(appItem.waitForExists(waitingTime))
Log.i(TAG, "assertItemWithResIdAndDescriptionExists: Verified ${appItem.selector} exists")
}
}
@ -125,17 +259,25 @@ object MatcherHelper {
for (appItem in appItems) {
if (exists) {
assertTrue("${appItem.selector} does not exist", appItem.waitForExists(waitingTime))
Log.i(TAG, "assertItemWithResIdExists: Verified ${appItem.selector} exists")
Log.i(TAG, "assertItemWithResIdAndTextExists: Verified ${appItem.selector} exists")
} else {
assertFalse("${appItem.selector} exists", appItem.waitForExists(waitingTimeShort))
Log.i(TAG, "assertItemWithResIdExists: Verified ${appItem.selector} does not exist")
Log.i(TAG, "assertItemWithResIdAndTextExists: Verified ${appItem.selector} does not exist")
}
}
}
fun assertItemWithResIdAndTextIsGone(vararg appItems: UiObject) {
for (appItem in appItems) {
assertTrue("${appItem.selector} is not gone", appItem.waitUntilGone(waitingTime))
Log.i(TAG, "assertItemWithResIdAndTextIsGone: Verified ${appItem.selector} is gone")
}
}
fun assertItemIsEnabledAndVisible(vararg appItems: UiObject) {
for (appItem in appItems) {
assertTrue(appItem.waitForExists(waitingTime) && appItem.isEnabled)
Log.i(TAG, "assertItemIsEnabledAndVisible: Verified ${appItem.selector} is visible and enabled")
}
}
}

@ -46,9 +46,12 @@ import org.mozilla.fenix.helpers.Constants.TAG
import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource
import org.mozilla.fenix.helpers.HomeActivityComposeTestRule
import org.mozilla.fenix.helpers.MatcherHelper.assertItemContainingTextExists
import org.mozilla.fenix.helpers.MatcherHelper.assertItemContainingTextIsGone
import org.mozilla.fenix.helpers.MatcherHelper.assertItemTextEquals
import org.mozilla.fenix.helpers.MatcherHelper.assertItemWithDescriptionExists
import org.mozilla.fenix.helpers.MatcherHelper.assertItemWithResIdAndTextExists
import org.mozilla.fenix.helpers.MatcherHelper.assertItemWithResIdExists
import org.mozilla.fenix.helpers.MatcherHelper.assertItemWithResIdIsGone
import org.mozilla.fenix.helpers.MatcherHelper.itemContainingText
import org.mozilla.fenix.helpers.MatcherHelper.itemWithDescription
import org.mozilla.fenix.helpers.MatcherHelper.itemWithResId
@ -71,10 +74,7 @@ import java.time.LocalDate
class BrowserRobot {
private lateinit var sessionLoadedIdlingResource: SessionLoadedIdlingResource
fun waitForPageToLoad() {
progressBar().waitUntilGone(waitingTime)
Log.i(TAG, "waitForPageToLoad: The page was loaded, the progress bar is gone")
}
fun waitForPageToLoad() = assertItemWithResIdIsGone(progressBar())
fun verifyCurrentPrivateSession(context: Context) {
val selectedTab = context.components.core.store.state.selectedTab
@ -236,8 +236,7 @@ class BrowserRobot {
)
}
fun verifyNavURLBarHidden() =
assertTrue(navURLBar().waitUntilGone(waitingTime))
fun verifyNavURLBarHidden() = assertItemWithResIdIsGone(navURLBar())
fun verifySecureConnectionLockIcon() =
onView(withId(R.id.mozac_browser_toolbar_security_indicator))
@ -296,7 +295,7 @@ class BrowserRobot {
)
fun clickSubmitLoginButton() {
clickPageObject(itemWithResId("submit"))
itemWithResId("submit").waitUntilGone(waitingTime)
assertItemWithResIdIsGone(itemWithResId("submit"))
mDevice.waitForIdle(waitingTimeLong)
}
@ -304,7 +303,7 @@ class BrowserRobot {
clickPageObject(itemWithResId("password"))
setPageObjectText(itemWithResId("password"), password)
assertTrue(mDevice.findObject(UiSelector().text(password)).waitUntilGone(waitingTime))
assertItemContainingTextIsGone(itemWithText(password))
}
/**
@ -340,10 +339,10 @@ class BrowserRobot {
// failing to swipe on Firebase sometimes, so it tries again
try {
navURLBar().swipeRight(2)
assertTrue(mDevice.findObject(UiSelector().text(tabUrl)).waitUntilGone(waitingTime))
assertItemContainingTextIsGone(itemWithText(tabUrl))
} catch (e: AssertionError) {
navURLBar().swipeRight(2)
assertTrue(mDevice.findObject(UiSelector().text(tabUrl)).waitUntilGone(waitingTime))
assertItemContainingTextIsGone(itemWithText(tabUrl))
}
}
@ -351,10 +350,10 @@ class BrowserRobot {
// failing to swipe on Firebase sometimes, so it tries again
try {
navURLBar().swipeLeft(2)
assertTrue(mDevice.findObject(UiSelector().text(tabUrl)).waitUntilGone(waitingTime))
assertItemContainingTextIsGone(itemWithText(tabUrl))
} catch (e: AssertionError) {
navURLBar().swipeLeft(2)
assertTrue(mDevice.findObject(UiSelector().text(tabUrl)).waitUntilGone(waitingTime))
assertItemContainingTextIsGone(itemWithText(tabUrl))
}
}
@ -465,19 +464,10 @@ class BrowserRobot {
// Sometimes the assertion of the pre-filled logins fails so we are re-trying after refreshing the page
for (i in 1..RETRY_COUNT) {
try {
if (credentialsArePrefilled) {
mDevice.waitForObjects(itemWithResId("username"))
assertTrue(itemWithResId("username").text.equals(userName))
mDevice.waitForObjects(itemWithResId("password"))
assertTrue(itemWithResId("password").text.equals(password))
} else {
mDevice.waitForObjects(itemWithResId("username"))
assertFalse(itemWithResId("username").text.equals(userName))
mDevice.waitForObjects(itemWithResId("password"))
assertFalse(itemWithResId("password").text.equals(password))
}
mDevice.waitForObjects(itemWithResId("username"))
assertItemTextEquals(itemWithResId("username"), expectedText = userName, isEqual = credentialsArePrefilled)
mDevice.waitForObjects(itemWithResId("password"))
assertItemTextEquals(itemWithResId("password"), expectedText = password, isEqual = credentialsArePrefilled)
break
} catch (e: AssertionError) {
@ -521,7 +511,7 @@ class BrowserRobot {
try {
assertItemWithResIdExists(itemWithResId("submit"))
itemWithResId("submit").click()
assertTrue(itemWithResId("username").text.equals(userName))
assertItemTextEquals(itemWithResId("username"), expectedText = userName)
break
} catch (e: AssertionError) {
addToHomeScreen {
@ -821,16 +811,8 @@ class BrowserRobot {
fun verifySurveyButton() = assertItemContainingTextExists(itemContainingText(getStringResource(R.string.preferences_take_survey)))
fun verifySurveyButtonDoesNotExist() {
val button = mDevice.findObject(
UiSelector().text(
getStringResource(
R.string.preferences_take_survey,
),
),
)
assertTrue(button.waitUntilGone(waitingTime))
}
fun verifySurveyButtonDoesNotExist() =
assertItemContainingTextIsGone(itemWithText(getStringResource(R.string.preferences_take_survey)))
fun verifySurveyNoThanksButton() =
assertItemContainingTextExists(

@ -20,15 +20,17 @@ import androidx.test.uiautomator.By
import androidx.test.uiautomator.UiScrollable
import androidx.test.uiautomator.UiSelector
import androidx.test.uiautomator.Until
import org.junit.Assert.assertTrue
import org.mozilla.fenix.R
import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource
import org.mozilla.fenix.helpers.MatcherHelper.assertItemContainingTextExists
import org.mozilla.fenix.helpers.MatcherHelper.assertItemContainingTextIsGone
import org.mozilla.fenix.helpers.MatcherHelper.assertItemTextEquals
import org.mozilla.fenix.helpers.MatcherHelper.assertItemWithDescriptionExists
import org.mozilla.fenix.helpers.MatcherHelper.assertItemWithResIdExists
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
@ -59,13 +61,12 @@ class CollectionRobot {
}
fun verifyTabsSelectedCounterText(numOfTabs: Int) {
mDevice.findObject(UiSelector().text("Select tabs to save"))
.waitUntilGone(waitingTime)
itemWithText("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"))
1 -> assertItemTextEquals(tabsCounter, expectedText = "$numOfTabs tab selected")
2 -> assertItemTextEquals(tabsCounter, expectedText = "$numOfTabs tabs selected")
}
}
@ -78,9 +79,7 @@ class CollectionRobot {
scrollToElementByText(title)
assertItemContainingTextExists(collectionListItem(title))
} else {
assertTrue(
collectionListItem(title).waitUntilGone(waitingTime),
)
assertItemContainingTextIsGone(collectionListItem(title))
}
}

@ -48,7 +48,6 @@ import org.hamcrest.CoreMatchers.containsString
import org.hamcrest.CoreMatchers.instanceOf
import org.hamcrest.Matchers
import org.junit.Assert
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.mozilla.fenix.R
import org.mozilla.fenix.helpers.Constants.LISTS_MAXSWIPES
@ -57,13 +56,18 @@ import org.mozilla.fenix.helpers.Constants.TAG
import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource
import org.mozilla.fenix.helpers.HomeActivityComposeTestRule
import org.mozilla.fenix.helpers.MatcherHelper.assertItemContainingTextExists
import org.mozilla.fenix.helpers.MatcherHelper.assertItemContainingTextIsGone
import org.mozilla.fenix.helpers.MatcherHelper.assertItemWithDescriptionExists
import org.mozilla.fenix.helpers.MatcherHelper.assertItemWithIndexExists
import org.mozilla.fenix.helpers.MatcherHelper.assertItemWithResIdAndIndexExists
import org.mozilla.fenix.helpers.MatcherHelper.assertItemWithResIdAndTextExists
import org.mozilla.fenix.helpers.MatcherHelper.assertItemWithResIdExists
import org.mozilla.fenix.helpers.MatcherHelper.itemContainingText
import org.mozilla.fenix.helpers.MatcherHelper.itemWithDescription
import org.mozilla.fenix.helpers.MatcherHelper.itemWithIndex
import org.mozilla.fenix.helpers.MatcherHelper.itemWithResId
import org.mozilla.fenix.helpers.MatcherHelper.itemWithResIdAndDescription
import org.mozilla.fenix.helpers.MatcherHelper.itemWithResIdAndIndex
import org.mozilla.fenix.helpers.MatcherHelper.itemWithResIdAndText
import org.mozilla.fenix.helpers.MatcherHelper.itemWithResIdContainingText
import org.mozilla.fenix.helpers.MatcherHelper.itemWithText
@ -221,15 +225,13 @@ class HomeScreenRobot {
fun verifyExistingTopSitesList() = assertExistingTopSitesList()
fun verifyNotExistingTopSitesList(title: String) = assertNotExistingTopSitesList(title)
fun verifySponsoredShortcutDoesNotExist(sponsoredShortcutTitle: String, position: Int) =
assertFalse(
mDevice.findObject(
UiSelector()
.resourceId("$packageName:id/top_site_item")
.index(position - 1),
).getChild(
UiSelector()
.textContains(sponsoredShortcutTitle),
).waitForExists(waitingTimeShort),
assertItemWithResIdAndIndexExists(
itemWithResIdAndIndex("$packageName:id/top_site_item", index = position - 1)
.getChild(
UiSelector()
.textContains(sponsoredShortcutTitle),
),
exists = false,
)
fun verifyNotExistingSponsoredTopSitesList() = assertSponsoredTopSitesNotDisplayed()
fun verifyExistingTopSitesTabs(title: String) {
@ -267,10 +269,9 @@ class HomeScreenRobot {
.getFromParent(UiSelector().text("$groupSize sites")),
)
} else {
assertTrue(
mDevice.findObject(UiSelector().text(searchTerm))
.getFromParent(UiSelector().text("$groupSize sites"))
.waitUntilGone(waitingTimeShort),
assertItemContainingTextIsGone(
itemContainingText(searchTerm)
.getFromParent(UiSelector().text("$groupSize sites")),
)
}
}
@ -280,7 +281,7 @@ class HomeScreenRobot {
if (collectionExists) {
assertItemContainingTextExists(itemContainingText(title))
} else {
assertTrue(mDevice.findObject(UiSelector().text(title)).waitUntilGone(waitingTime))
assertItemContainingTextIsGone(itemWithText(title))
}
}
@ -320,12 +321,7 @@ class HomeScreenRobot {
for (position in 0..8) {
pocketStoriesList
.scrollIntoView(UiSelector().index(position))
assertTrue(
"Pocket story item at position $position not found.",
mDevice.findObject(UiSelector().index(position))
.waitForExists(waitingTimeShort),
)
assertItemWithIndexExists(itemWithIndex(position))
}
}
@ -870,39 +866,30 @@ private fun assertExistingTopSitesTabs(title: String) {
}
private fun assertSponsoredShortcutLogoIsDisplayed(position: Int) =
assertTrue(
mDevice.findObject(
UiSelector()
.resourceId("$packageName:id/top_site_item")
.index(position - 1),
).getChild(
UiSelector()
.resourceId("$packageName:id/favicon_card"),
).waitForExists(waitingTime),
assertItemWithResIdAndIndexExists(
itemWithResIdAndIndex(resourceId = "$packageName:id/top_site_item", index = position - 1)
.getChild(
UiSelector()
.resourceId("$packageName:id/favicon_card"),
),
)
private fun assertSponsoredSubtitleIsDisplayed(position: Int) =
assertTrue(
mDevice.findObject(
UiSelector()
.resourceId("$packageName:id/top_site_item")
.index(position - 1),
).getChild(
UiSelector()
.resourceId("$packageName:id/top_site_subtitle"),
).waitForExists(waitingTime),
assertItemWithResIdAndIndexExists(
itemWithResIdAndIndex(resourceId = "$packageName:id/top_site_item", index = position - 1)
.getChild(
UiSelector()
.resourceId("$packageName:id/top_site_subtitle"),
),
)
private fun assertSponsoredShortcutTitle(sponsoredShortcutTitle: String, position: Int) =
assertTrue(
mDevice.findObject(
UiSelector()
.resourceId("$packageName:id/top_site_item")
.index(position - 1),
).getChild(
UiSelector()
.textContains(sponsoredShortcutTitle),
).waitForExists(waitingTime),
assertItemWithResIdAndIndexExists(
itemWithResIdAndIndex(resourceId = "$packageName:id/top_site_item", index = position - 1)
.getChild(
UiSelector()
.textContains(sponsoredShortcutTitle),
),
)
private fun assertNotExistingTopSitesList(title: String) {

@ -38,6 +38,7 @@ import org.mozilla.fenix.helpers.Constants.LONG_CLICK_DURATION
import org.mozilla.fenix.helpers.Constants.TAG
import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource
import org.mozilla.fenix.helpers.HomeActivityComposeTestRule
import org.mozilla.fenix.helpers.MatcherHelper.assertItemTextEquals
import org.mozilla.fenix.helpers.MatcherHelper.assertItemWithResIdAndTextExists
import org.mozilla.fenix.helpers.MatcherHelper.assertItemWithResIdExists
import org.mozilla.fenix.helpers.MatcherHelper.itemWithResId
@ -117,9 +118,7 @@ class NavigationToolbarRobot {
// New unified search UI selector
fun verifySearchBarPlaceholder(text: String) {
urlBar().waitForExists(waitingTime)
assertTrue(
urlBar().text == text,
)
assertItemTextEquals(urlBar(), expectedText = text)
}
// New unified search UI selector

@ -39,8 +39,11 @@ import org.mozilla.fenix.helpers.Constants.RETRY_COUNT
import org.mozilla.fenix.helpers.Constants.SPEECH_RECOGNITION
import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource
import org.mozilla.fenix.helpers.MatcherHelper.assertItemContainingTextExists
import org.mozilla.fenix.helpers.MatcherHelper.assertItemTextContains
import org.mozilla.fenix.helpers.MatcherHelper.assertItemTextEquals
import org.mozilla.fenix.helpers.MatcherHelper.assertItemWithDescriptionExists
import org.mozilla.fenix.helpers.MatcherHelper.assertItemWithResIdExists
import org.mozilla.fenix.helpers.MatcherHelper.assertItemWithResIdIsGone
import org.mozilla.fenix.helpers.MatcherHelper.itemWithDescription
import org.mozilla.fenix.helpers.MatcherHelper.itemWithResId
import org.mozilla.fenix.helpers.MatcherHelper.itemWithText
@ -169,9 +172,7 @@ class SearchRobot {
fun verifySearchBarPlaceholder(text: String) {
browserToolbarEditView().waitForExists(waitingTime)
assertTrue(
browserToolbarEditView().text == text,
)
assertItemTextEquals(browserToolbarEditView(), expectedText = text)
}
fun verifySearchShortcutListContains(vararg searchEngineName: String, shouldExist: Boolean = true) {
@ -181,10 +182,7 @@ class SearchRobot {
searchShortcutList.getChild(UiSelector().text(it)),
)
} else {
assertTrue(
searchShortcutList.getChild(UiSelector().text(it))
.waitUntilGone(waitingTimeShort),
)
assertItemWithResIdIsGone(searchShortcutList.getChild(UiSelector().text(it)))
}
}
}
@ -264,7 +262,7 @@ class SearchRobot {
}
fun verifyTranslatedFocusedNavigationToolbar(toolbarHintString: String) =
assertTrue(browserToolbarEditView().text.contains(toolbarHintString))
assertItemTextContains(browserToolbarEditView(), itemText = toolbarHintString)
fun verifyTypedToolbarText(expectedText: String) {
mDevice.findObject(UiSelector().resourceId("$packageName:id/toolbar"))
@ -297,10 +295,10 @@ class SearchRobot {
try {
searchWrapper().waitForExists(waitingTime)
mDevice.pressBack()
assertTrue(searchWrapper().waitUntilGone(waitingTimeShort))
assertItemWithResIdIsGone(searchWrapper())
} catch (e: AssertionError) {
mDevice.pressBack()
assertTrue(searchWrapper().waitUntilGone(waitingTimeShort))
assertItemWithResIdIsGone(searchWrapper())
}
HomeScreenRobot().interact()

@ -31,12 +31,13 @@ import androidx.test.uiautomator.Until
import org.hamcrest.CoreMatchers.allOf
import org.hamcrest.CoreMatchers.containsString
import org.hamcrest.CoreMatchers.instanceOf
import org.junit.Assert.assertTrue
import org.mozilla.fenix.R
import org.mozilla.fenix.helpers.Constants.RETRY_COUNT
import org.mozilla.fenix.helpers.Constants.TAG
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
import org.mozilla.fenix.helpers.MatcherHelper.assertItemContainingTextExists
import org.mozilla.fenix.helpers.MatcherHelper.assertItemWithResIdExists
import org.mozilla.fenix.helpers.MatcherHelper.itemWithText
import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime
import org.mozilla.fenix.helpers.TestAssetHelper.waitingTimeLong
import org.mozilla.fenix.helpers.TestHelper.appName
@ -95,12 +96,8 @@ class SettingsSubMenuAddonsManagerRobot {
fun verifyAddonInstallCompleted(addonName: String, activityTestRule: HomeActivityIntentTestRule) {
for (i in 1..RETRY_COUNT) {
try {
assertTrue(
"$addonName failed to install",
mDevice.findObject(UiSelector().text("Okay, Got it"))
.waitForExists(waitingTimeLong),
)
Log.i(TAG, "verifyAddonInstallCompleted: $addonName installed successfully.")
assertItemContainingTextExists(itemWithText("Okay, Got it"), waitingTime = waitingTimeLong)
break
} catch (e: AssertionError) {
if (i == RETRY_COUNT) {
@ -154,11 +151,7 @@ class SettingsSubMenuAddonsManagerRobot {
fun verifyAddonCanBeInstalled(addonName: String) = assertAddonCanBeInstalled(addonName)
fun selectAllowInPrivateBrowsing() {
assertTrue(
"Addon install confirmation prompt not displayed",
mDevice.findObject(UiSelector().text("Allow in private browsing"))
.waitForExists(waitingTimeLong),
)
assertItemContainingTextExists(itemWithText("Allow in private browsing"), waitingTime = waitingTimeLong)
onView(withId(R.id.allow_in_private_browsing)).click()
}

@ -15,10 +15,10 @@ import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.espresso.matcher.ViewMatchers.withText
import androidx.test.uiautomator.UiSelector
import org.hamcrest.CoreMatchers.allOf
import org.junit.Assert.assertTrue
import org.mozilla.fenix.R
import org.mozilla.fenix.helpers.MatcherHelper.assertItemContainingTextExists
import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime
import org.mozilla.fenix.helpers.MatcherHelper.assertItemContainingTextIsGone
import org.mozilla.fenix.helpers.MatcherHelper.itemWithText
import org.mozilla.fenix.helpers.TestHelper.appName
import org.mozilla.fenix.helpers.TestHelper.mDevice
import org.mozilla.fenix.helpers.assertIsChecked
@ -194,13 +194,7 @@ private fun assertOpenTabsDescription(tabNumber: String) =
private fun assertBrowsingHistoryDescription(addresses: String) =
assertItemContainingTextExists(browsingHistoryDescription(addresses))
private fun assertDeleteBrowsingDataSnackbar() {
assertTrue(
mDevice.findObject(
UiSelector().text("Browsing data deleted"),
).waitUntilGone(waitingTime),
)
}
private fun assertDeleteBrowsingDataSnackbar() = assertItemContainingTextIsGone(itemWithText("Browsing data deleted"))
private fun clickOpenTabsCheckBox() = openTabsCheckBox().click()
private fun assertOpenTabsCheckBox(status: Boolean) = openTabsCheckBox().assertIsChecked(status)

@ -10,10 +10,10 @@ import androidx.test.espresso.matcher.ViewMatchers
import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.uiautomator.UiScrollable
import androidx.test.uiautomator.UiSelector
import junit.framework.TestCase.assertTrue
import org.hamcrest.CoreMatchers
import org.mozilla.fenix.R
import org.mozilla.fenix.helpers.MatcherHelper.assertItemContainingTextExists
import org.mozilla.fenix.helpers.MatcherHelper.assertItemWithResIdExists
import org.mozilla.fenix.helpers.MatcherHelper.itemWithText
import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime
import org.mozilla.fenix.helpers.TestHelper.mDevice
@ -37,11 +37,10 @@ class SettingsSubMenuLanguageRobot {
fun verifySelectedLanguage(language: String) {
languagesList.waitForExists(waitingTime)
assertTrue(
assertItemWithResIdExists(
languagesList
.getChildByText(UiSelector().text(language), language, true)
.getFromParent(UiSelector().resourceId("$packageName:id/locale_selected_icon"))
.waitForExists(waitingTime),
.getFromParent(UiSelector().resourceId("$packageName:id/locale_selected_icon")),
)
}
@ -61,9 +60,7 @@ class SettingsSubMenuLanguageRobot {
onView(withId(R.id.search_close_btn)).click()
}
fun verifyLanguageListIsDisplayed() {
assertTrue(languagesList.waitForExists(waitingTime))
}
fun verifyLanguageListIsDisplayed() = assertItemWithResIdExists(languagesList)
class Transition {

@ -21,15 +21,17 @@ import androidx.test.uiautomator.UiSelector
import androidx.test.uiautomator.Until
import org.hamcrest.CoreMatchers
import org.hamcrest.CoreMatchers.containsString
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.mozilla.fenix.R
import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
import org.mozilla.fenix.helpers.MatcherHelper.assertCheckedItemWithResIdExists
import org.mozilla.fenix.helpers.MatcherHelper.assertItemContainingTextExists
import org.mozilla.fenix.helpers.MatcherHelper.assertItemIsEnabledAndVisible
import org.mozilla.fenix.helpers.MatcherHelper.assertItemWithClassNameAndIndexExists
import org.mozilla.fenix.helpers.MatcherHelper.assertItemWithResIdExists
import org.mozilla.fenix.helpers.MatcherHelper.checkedItemWithResId
import org.mozilla.fenix.helpers.MatcherHelper.itemContainingText
import org.mozilla.fenix.helpers.MatcherHelper.itemWithClassNameAndIndex
import org.mozilla.fenix.helpers.MatcherHelper.itemWithResId
import org.mozilla.fenix.helpers.TestAssetHelper
import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime
@ -109,16 +111,13 @@ class SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot {
itemContainingText(getStringResource(R.string.saved_logins_sort_strategy_last_used)).click()
fun verifySortedLogin(position: Int, loginTitle: String) =
assertTrue(
mDevice.findObject(
UiSelector()
.className("android.view.ViewGroup")
.index(position),
).getChild(
UiSelector()
.resourceId("$packageName:id/webAddressView")
.textContains(loginTitle),
).waitForExists(waitingTime),
assertItemWithClassNameAndIndexExists(
itemWithClassNameAndIndex(className = "android.view.ViewGroup", index = position)
.getChild(
UiSelector()
.resourceId("$packageName:id/webAddressView")
.textContains(loginTitle),
),
)
fun searchLogin(searchTerm: String) =
@ -163,13 +162,11 @@ class SettingsSubMenuLoginsAndPasswordsSavedLoginsRobot {
fun saveEditedLogin() = itemWithResId("$packageName:id/save_login_button").click()
fun verifySaveLoginButtonIsEnabled(isEnabled: Boolean) {
if (isEnabled) {
assertTrue(itemWithResId("$packageName:id/save_login_button").isChecked)
} else {
assertFalse(itemWithResId("$packageName:id/save_login_button").isChecked)
}
}
fun verifySaveLoginButtonIsEnabled(isEnabled: Boolean) =
assertCheckedItemWithResIdExists(
checkedItemWithResId("$packageName:id/save_login_button", isChecked = true),
exists = isEnabled,
)
fun revealPassword() = onView(withId(R.id.revealPasswordButton)).click()

@ -1,272 +1,268 @@
/* 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.test.espresso.Espresso.onView
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.matcher.ViewMatchers.Visibility
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
import androidx.test.espresso.matcher.ViewMatchers.withContentDescription
import androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility
import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.espresso.matcher.ViewMatchers.withText
import androidx.test.uiautomator.UiSelector
import org.hamcrest.CoreMatchers.allOf
import org.junit.Assert.assertTrue
import org.mozilla.fenix.R
import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource
import org.mozilla.fenix.helpers.MatcherHelper.assertItemContainingTextExists
import org.mozilla.fenix.helpers.MatcherHelper.assertItemWithDescriptionExists
import org.mozilla.fenix.helpers.MatcherHelper.itemContainingText
import org.mozilla.fenix.helpers.MatcherHelper.itemWithDescription
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.assertIsChecked
import org.mozilla.fenix.helpers.click
import org.mozilla.fenix.helpers.isChecked
/**
* Implementation of Robot Pattern for the settings Site Permissions sub menu.
*/
class SettingsSubMenuSitePermissionsCommonRobot {
fun verifyNavigationToolBarHeader(header: String) = assertNavigationToolBarHeader(header)
fun verifyBlockAudioAndVideoOnMobileDataOnlyAudioAndVideoWillPlayOnWiFi() = assertBlockAudioAndVideoOnMobileDataOnlyAudioAndVideoWillPlayOnWiFi()
fun verifyBlockAudioOnly() = assertBlockAudioOnly()
fun verifyVideoAndAudioBlockedRecommended() = assertVideoAndAudioBlockedRecommended()
fun verifyCheckAutoPlayRadioButtonDefault() = assertCheckAutoPayRadioButtonDefault()
fun verifyAskToAllowButton(isChecked: Boolean = true) =
onView(withId(R.id.ask_to_allow_radio))
.check((matches(isDisplayed()))).assertIsChecked(isChecked)
fun verifyBlockedButton(isChecked: Boolean = false) =
onView(withId(R.id.block_radio))
.check((matches(isDisplayed()))).assertIsChecked(isChecked)
fun verifyBlockedByAndroid() = assertBlockedByAndroid()
fun verifyUnblockedByAndroid() = assertUnblockedByAndroid()
fun verifyToAllowIt() = assertToAllowIt()
fun verifyGotoAndroidSettings() = assertGotoAndroidSettings()
fun verifyTapPermissions() = assertTapPermissions()
fun verifyToggleNameToON(name: String) = assertToggleNameToON(name)
fun verifyGoToSettingsButton() = assertGoToSettingsButton()
fun verifySitePermissionsAutoPlaySubMenuItems() {
verifyBlockAudioAndVideoOnMobileDataOnlyAudioAndVideoWillPlayOnWiFi()
verifyBlockAudioOnly()
verifyVideoAndAudioBlockedRecommended()
verifyCheckAutoPlayRadioButtonDefault()
}
fun verifySitePermissionsCommonSubMenuItems() {
verifyAskToAllowButton()
verifyBlockedButton()
}
fun verifyBlockedByAndroidSection() {
verifyBlockedByAndroid()
verifyToAllowIt()
verifyGotoAndroidSettings()
verifyTapPermissions()
verifyGoToSettingsButton()
}
fun verifyNotificationSubMenuItems() {
verifyNotificationToolbar()
verifySitePermissionsCommonSubMenuItems()
}
fun verifySitePermissionsPersistentStorageSubMenuItems() {
verifyAskToAllowButton()
verifyBlockedButton()
}
fun verifyDRMControlledContentSubMenuItems() {
verifyAskToAllowButton()
verifyBlockedButton()
// Third option is "Allowed"
thirdRadioButton.check(matches(withText("Allowed")))
}
fun clickGoToSettingsButton() {
goToSettingsButton().click()
mDevice.findObject(UiSelector().resourceId("com.android.settings:id/list"))
.waitForExists(waitingTime)
}
fun openAppSystemPermissionsSettings() {
mDevice.findObject(UiSelector().textContains("Permissions")).click()
}
fun switchAppPermissionSystemSetting(permissionCategory: String, permission: String) {
mDevice.findObject(UiSelector().textContains(permissionCategory)).click()
if (permission == "Allow") {
mDevice.findObject(UiSelector().textContains("Allow")).click()
} else {
mDevice.findObject(UiSelector().textContains("Deny")).click()
}
}
fun goBackToSystemAppPermissionSettings() {
mDevice.pressBack()
mDevice.waitForIdle(waitingTime)
}
fun goBackToPermissionsSettingsSubMenu() {
while (!permissionSettingMenu().waitForExists(waitingTimeShort)) {
mDevice.pressBack()
mDevice.waitForIdle(waitingTime)
}
}
fun verifySystemGrantedPermission(permissionCategory: String) {
assertTrue(
mDevice.findObject(
UiSelector().className("android.widget.RelativeLayout"),
).getChild(
UiSelector()
.resourceId("android:id/title")
.textContains(permissionCategory),
).waitForExists(waitingTime),
)
assertTrue(
mDevice.findObject(
UiSelector().className("android.widget.RelativeLayout"),
).getChild(
UiSelector()
.resourceId("android:id/summary")
.textContains("Only while app is in use"),
).waitForExists(waitingTime),
)
}
fun verifyNotificationToolbar() {
assertItemContainingTextExists(itemContainingText(getStringResource(R.string.preference_phone_feature_notification)))
assertItemWithDescriptionExists(itemWithDescription(getStringResource(R.string.action_bar_up_description)))
}
fun selectAutoplayOption(text: String) {
when (text) {
"Allow audio and video" -> askToAllowRadioButton.click()
"Block audio and video on cellular data only" -> blockRadioButton.click()
"Block audio only" -> thirdRadioButton.click()
"Block audio and video" -> fourthRadioButton.click()
}
}
fun selectPermissionSettingOption(text: String) {
when (text) {
"Ask to allow" -> askToAllowRadioButton.click()
"Blocked" -> blockRadioButton.click()
}
}
fun selectDRMControlledContentPermissionSettingOption(text: String) {
when (text) {
"Ask to allow" -> askToAllowRadioButton.click()
"Blocked" -> blockRadioButton.click()
"Allowed" -> thirdRadioButton.click()
}
}
class Transition {
fun goBack(interact: SettingsSubMenuSitePermissionsRobot.() -> Unit): SettingsSubMenuSitePermissionsRobot.Transition {
goBackButton().click()
SettingsSubMenuSitePermissionsRobot().interact()
return SettingsSubMenuSitePermissionsRobot.Transition()
}
}
}
// common Blocked radio button for all settings
private val blockRadioButton = onView(withId(R.id.block_radio))
// common Ask to Allow radio button for all settings
private val askToAllowRadioButton = onView(withId(R.id.ask_to_allow_radio))
// common extra 3rd radio button for all settings
private val thirdRadioButton = onView(withId(R.id.third_radio))
// common extra 4th radio button for all settings
private val fourthRadioButton = onView(withId(R.id.fourth_radio))
private fun assertNavigationToolBarHeader(header: String) = onView(allOf(withContentDescription(header)))
private fun assertBlockAudioAndVideoOnMobileDataOnlyAudioAndVideoWillPlayOnWiFi() =
blockRadioButton.check((matches(withEffectiveVisibility(Visibility.VISIBLE))))
private fun assertBlockAudioOnly() =
thirdRadioButton.check((matches(withEffectiveVisibility(Visibility.VISIBLE))))
private fun assertVideoAndAudioBlockedRecommended() = onView(withId(R.id.fourth_radio))
.check((matches(withEffectiveVisibility(Visibility.VISIBLE))))
private fun assertCheckAutoPayRadioButtonDefault() {
// Allow audio and video
askToAllowRadioButton
.assertIsChecked(isChecked = false)
// Block audio and video on cellular data only
blockRadioButton
.assertIsChecked(isChecked = false)
// Block audio only (default)
thirdRadioButton
.assertIsChecked(isChecked = true)
// Block audio and video
fourthRadioButton
.assertIsChecked(isChecked = false)
}
private fun assertBlockedByAndroid() {
blockedByAndroidContainer().waitForExists(waitingTime)
assertItemContainingTextExists(itemContainingText(getStringResource(R.string.phone_feature_blocked_by_android)))
}
private fun assertUnblockedByAndroid() {
blockedByAndroidContainer().waitUntilGone(waitingTime)
assertItemContainingTextExists(itemContainingText(getStringResource(R.string.phone_feature_blocked_by_android)), exists = false)
}
private fun blockedByAndroidContainer() = mDevice.findObject(UiSelector().resourceId("$packageName:id/permissions_blocked_container"))
private fun permissionSettingMenu() = mDevice.findObject(UiSelector().resourceId("$packageName:id/container"))
private fun assertToAllowIt() = onView(withText(R.string.phone_feature_blocked_intro))
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
private fun assertGotoAndroidSettings() = onView(withText(R.string.phone_feature_blocked_step_settings))
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
private fun assertTapPermissions() = onView(withText("2. Tap Permissions"))
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
private fun assertToggleNameToON(name: String) = onView(withText(name))
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
private fun assertGoToSettingsButton() =
goToSettingsButton().check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
private fun goBackButton() =
onView(allOf(withContentDescription("Navigate up")))
private fun goToSettingsButton() = onView(withId(R.id.settings_button))
/* 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.test.espresso.Espresso.onView
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.matcher.ViewMatchers.Visibility
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
import androidx.test.espresso.matcher.ViewMatchers.withContentDescription
import androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility
import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.espresso.matcher.ViewMatchers.withText
import androidx.test.uiautomator.UiSelector
import org.hamcrest.CoreMatchers.allOf
import org.mozilla.fenix.R
import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource
import org.mozilla.fenix.helpers.MatcherHelper.assertItemContainingTextExists
import org.mozilla.fenix.helpers.MatcherHelper.assertItemWithClassNameExists
import org.mozilla.fenix.helpers.MatcherHelper.assertItemWithDescriptionExists
import org.mozilla.fenix.helpers.MatcherHelper.itemContainingText
import org.mozilla.fenix.helpers.MatcherHelper.itemWithClassName
import org.mozilla.fenix.helpers.MatcherHelper.itemWithDescription
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.assertIsChecked
import org.mozilla.fenix.helpers.click
import org.mozilla.fenix.helpers.isChecked
/**
* Implementation of Robot Pattern for the settings Site Permissions sub menu.
*/
class SettingsSubMenuSitePermissionsCommonRobot {
fun verifyNavigationToolBarHeader(header: String) = assertNavigationToolBarHeader(header)
fun verifyBlockAudioAndVideoOnMobileDataOnlyAudioAndVideoWillPlayOnWiFi() = assertBlockAudioAndVideoOnMobileDataOnlyAudioAndVideoWillPlayOnWiFi()
fun verifyBlockAudioOnly() = assertBlockAudioOnly()
fun verifyVideoAndAudioBlockedRecommended() = assertVideoAndAudioBlockedRecommended()
fun verifyCheckAutoPlayRadioButtonDefault() = assertCheckAutoPayRadioButtonDefault()
fun verifyAskToAllowButton(isChecked: Boolean = true) =
onView(withId(R.id.ask_to_allow_radio))
.check((matches(isDisplayed()))).assertIsChecked(isChecked)
fun verifyBlockedButton(isChecked: Boolean = false) =
onView(withId(R.id.block_radio))
.check((matches(isDisplayed()))).assertIsChecked(isChecked)
fun verifyBlockedByAndroid() = assertBlockedByAndroid()
fun verifyUnblockedByAndroid() = assertUnblockedByAndroid()
fun verifyToAllowIt() = assertToAllowIt()
fun verifyGotoAndroidSettings() = assertGotoAndroidSettings()
fun verifyTapPermissions() = assertTapPermissions()
fun verifyToggleNameToON(name: String) = assertToggleNameToON(name)
fun verifyGoToSettingsButton() = assertGoToSettingsButton()
fun verifySitePermissionsAutoPlaySubMenuItems() {
verifyBlockAudioAndVideoOnMobileDataOnlyAudioAndVideoWillPlayOnWiFi()
verifyBlockAudioOnly()
verifyVideoAndAudioBlockedRecommended()
verifyCheckAutoPlayRadioButtonDefault()
}
fun verifySitePermissionsCommonSubMenuItems() {
verifyAskToAllowButton()
verifyBlockedButton()
}
fun verifyBlockedByAndroidSection() {
verifyBlockedByAndroid()
verifyToAllowIt()
verifyGotoAndroidSettings()
verifyTapPermissions()
verifyGoToSettingsButton()
}
fun verifyNotificationSubMenuItems() {
verifyNotificationToolbar()
verifySitePermissionsCommonSubMenuItems()
}
fun verifySitePermissionsPersistentStorageSubMenuItems() {
verifyAskToAllowButton()
verifyBlockedButton()
}
fun verifyDRMControlledContentSubMenuItems() {
verifyAskToAllowButton()
verifyBlockedButton()
// Third option is "Allowed"
thirdRadioButton.check(matches(withText("Allowed")))
}
fun clickGoToSettingsButton() {
goToSettingsButton().click()
mDevice.findObject(UiSelector().resourceId("com.android.settings:id/list"))
.waitForExists(waitingTime)
}
fun openAppSystemPermissionsSettings() {
mDevice.findObject(UiSelector().textContains("Permissions")).click()
}
fun switchAppPermissionSystemSetting(permissionCategory: String, permission: String) {
mDevice.findObject(UiSelector().textContains(permissionCategory)).click()
if (permission == "Allow") {
mDevice.findObject(UiSelector().textContains("Allow")).click()
} else {
mDevice.findObject(UiSelector().textContains("Deny")).click()
}
}
fun goBackToSystemAppPermissionSettings() {
mDevice.pressBack()
mDevice.waitForIdle(waitingTime)
}
fun goBackToPermissionsSettingsSubMenu() {
while (!permissionSettingMenu().waitForExists(waitingTimeShort)) {
mDevice.pressBack()
mDevice.waitForIdle(waitingTime)
}
}
fun verifySystemGrantedPermission(permissionCategory: String) {
assertItemWithClassNameExists(
itemWithClassName("android.widget.RelativeLayout")
.getChild(
UiSelector()
.resourceId("android:id/title")
.textContains(permissionCategory),
),
itemWithClassName("android.widget.RelativeLayout")
.getChild(
UiSelector()
.resourceId("android:id/summary")
.textContains("Only while app is in use"),
),
)
}
fun verifyNotificationToolbar() {
assertItemContainingTextExists(itemContainingText(getStringResource(R.string.preference_phone_feature_notification)))
assertItemWithDescriptionExists(itemWithDescription(getStringResource(R.string.action_bar_up_description)))
}
fun selectAutoplayOption(text: String) {
when (text) {
"Allow audio and video" -> askToAllowRadioButton.click()
"Block audio and video on cellular data only" -> blockRadioButton.click()
"Block audio only" -> thirdRadioButton.click()
"Block audio and video" -> fourthRadioButton.click()
}
}
fun selectPermissionSettingOption(text: String) {
when (text) {
"Ask to allow" -> askToAllowRadioButton.click()
"Blocked" -> blockRadioButton.click()
}
}
fun selectDRMControlledContentPermissionSettingOption(text: String) {
when (text) {
"Ask to allow" -> askToAllowRadioButton.click()
"Blocked" -> blockRadioButton.click()
"Allowed" -> thirdRadioButton.click()
}
}
class Transition {
fun goBack(interact: SettingsSubMenuSitePermissionsRobot.() -> Unit): SettingsSubMenuSitePermissionsRobot.Transition {
goBackButton().click()
SettingsSubMenuSitePermissionsRobot().interact()
return SettingsSubMenuSitePermissionsRobot.Transition()
}
}
}
// common Blocked radio button for all settings
private val blockRadioButton = onView(withId(R.id.block_radio))
// common Ask to Allow radio button for all settings
private val askToAllowRadioButton = onView(withId(R.id.ask_to_allow_radio))
// common extra 3rd radio button for all settings
private val thirdRadioButton = onView(withId(R.id.third_radio))
// common extra 4th radio button for all settings
private val fourthRadioButton = onView(withId(R.id.fourth_radio))
private fun assertNavigationToolBarHeader(header: String) = onView(allOf(withContentDescription(header)))
private fun assertBlockAudioAndVideoOnMobileDataOnlyAudioAndVideoWillPlayOnWiFi() =
blockRadioButton.check((matches(withEffectiveVisibility(Visibility.VISIBLE))))
private fun assertBlockAudioOnly() =
thirdRadioButton.check((matches(withEffectiveVisibility(Visibility.VISIBLE))))
private fun assertVideoAndAudioBlockedRecommended() = onView(withId(R.id.fourth_radio))
.check((matches(withEffectiveVisibility(Visibility.VISIBLE))))
private fun assertCheckAutoPayRadioButtonDefault() {
// Allow audio and video
askToAllowRadioButton
.assertIsChecked(isChecked = false)
// Block audio and video on cellular data only
blockRadioButton
.assertIsChecked(isChecked = false)
// Block audio only (default)
thirdRadioButton
.assertIsChecked(isChecked = true)
// Block audio and video
fourthRadioButton
.assertIsChecked(isChecked = false)
}
private fun assertBlockedByAndroid() {
blockedByAndroidContainer().waitForExists(waitingTime)
assertItemContainingTextExists(itemContainingText(getStringResource(R.string.phone_feature_blocked_by_android)))
}
private fun assertUnblockedByAndroid() {
blockedByAndroidContainer().waitUntilGone(waitingTime)
assertItemContainingTextExists(itemContainingText(getStringResource(R.string.phone_feature_blocked_by_android)), exists = false)
}
private fun blockedByAndroidContainer() = mDevice.findObject(UiSelector().resourceId("$packageName:id/permissions_blocked_container"))
private fun permissionSettingMenu() = mDevice.findObject(UiSelector().resourceId("$packageName:id/container"))
private fun assertToAllowIt() = onView(withText(R.string.phone_feature_blocked_intro))
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
private fun assertGotoAndroidSettings() = onView(withText(R.string.phone_feature_blocked_step_settings))
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
private fun assertTapPermissions() = onView(withText("2. Tap Permissions"))
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
private fun assertToggleNameToON(name: String) = onView(withText(name))
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
private fun assertGoToSettingsButton() =
goToSettingsButton().check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
private fun goBackButton() =
onView(allOf(withContentDescription("Navigate up")))
private fun goToSettingsButton() = onView(withId(R.id.settings_button))

@ -14,9 +14,10 @@ import androidx.test.espresso.matcher.ViewMatchers.withText
import androidx.test.uiautomator.UiSelector
import org.hamcrest.CoreMatchers.allOf
import org.hamcrest.CoreMatchers.containsString
import org.junit.Assert.assertTrue
import org.mozilla.fenix.R
import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource
import org.mozilla.fenix.helpers.MatcherHelper.assertItemContainingTextIsGone
import org.mozilla.fenix.helpers.MatcherHelper.itemContainingText
import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime
import org.mozilla.fenix.helpers.TestHelper.mDevice
import org.mozilla.fenix.helpers.TestHelper.packageName
@ -37,9 +38,7 @@ class SettingsSubMenuSitePermissionsExceptionsRobot {
exceptionsList.waitForExists(waitingTime)
onView(withText(containsString(url))).check(matches(isDisplayed()))
} else {
assertTrue(
mDevice.findObject(UiSelector().textContains(url)).waitUntilGone(waitingTime),
)
assertItemContainingTextIsGone(itemContainingText(url))
}
}

@ -10,9 +10,9 @@ import androidx.test.espresso.matcher.ViewMatchers
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.uiautomator.UiSelector
import org.junit.Assert.assertTrue
import org.mozilla.fenix.R
import org.mozilla.fenix.helpers.MatcherHelper.assertItemContainingTextExists
import org.mozilla.fenix.helpers.MatcherHelper.assertItemTextEquals
import org.mozilla.fenix.helpers.MatcherHelper.itemWithText
import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime
import org.mozilla.fenix.helpers.TestHelper.mDevice
@ -23,16 +23,16 @@ class SitePermissionsRobot {
fun verifyMicrophonePermissionPrompt(url: String) {
try {
assertItemContainingTextExists(itemWithText("Allow $url to use your microphone?"))
assertTrue(denyPagePermissionButton.text.equals("Dont allow"))
assertTrue(allowPagePermissionButton.text.equals("Allow"))
assertItemTextEquals(denyPagePermissionButton, expectedText = "Dont allow")
assertItemTextEquals(allowPagePermissionButton, expectedText = "Allow")
} catch (e: AssertionError) {
browserScreen {
}.openThreeDotMenu {
}.refreshPage {
}.clickStartMicrophoneButton {
assertItemContainingTextExists(itemWithText("Allow $url to use your microphone?"))
assertTrue(denyPagePermissionButton.text.equals("Dont allow"))
assertTrue(allowPagePermissionButton.text.equals("Allow"))
assertItemTextEquals(denyPagePermissionButton, expectedText = "Dont allow")
assertItemTextEquals(allowPagePermissionButton, expectedText = "Allow")
}
}
}
@ -40,39 +40,39 @@ class SitePermissionsRobot {
fun verifyCameraPermissionPrompt(url: String) {
try {
assertItemContainingTextExists(itemWithText("Allow $url to use your camera?"))
assertTrue(denyPagePermissionButton.text.equals("Dont allow"))
assertTrue(allowPagePermissionButton.text.equals("Allow"))
assertItemTextEquals(denyPagePermissionButton, expectedText = "Dont allow")
assertItemTextEquals(allowPagePermissionButton, expectedText = "Allow")
} catch (e: AssertionError) {
browserScreen {
}.openThreeDotMenu {
}.refreshPage {
}.clickStartCameraButton {
assertItemContainingTextExists(itemWithText("Allow $url to use your camera?"))
assertTrue(denyPagePermissionButton.text.equals("Dont allow"))
assertTrue(allowPagePermissionButton.text.equals("Allow"))
assertItemTextEquals(denyPagePermissionButton, expectedText = "Dont allow")
assertItemTextEquals(allowPagePermissionButton, expectedText = "Allow")
}
}
}
fun verifyAudioVideoPermissionPrompt(url: String) {
assertItemContainingTextExists(itemWithText("Allow $url to use your camera and microphone?"))
assertTrue(denyPagePermissionButton.text.equals("Dont allow"))
assertTrue(allowPagePermissionButton.text.equals("Allow"))
assertItemTextEquals(denyPagePermissionButton, expectedText = "Dont allow")
assertItemTextEquals(allowPagePermissionButton, expectedText = "Allow")
}
fun verifyLocationPermissionPrompt(url: String) {
try {
assertItemContainingTextExists(itemWithText("Allow $url to use your location?"))
assertTrue(denyPagePermissionButton.text.equals("Dont allow"))
assertTrue(allowPagePermissionButton.text.equals("Allow"))
assertItemTextEquals(denyPagePermissionButton, expectedText = "Dont allow")
assertItemTextEquals(allowPagePermissionButton, expectedText = "Allow")
} catch (e: AssertionError) {
browserScreen {
}.openThreeDotMenu {
}.refreshPage {
}.clickGetLocationButton {
assertItemContainingTextExists(itemWithText("Allow $url to use your location?"))
assertTrue(denyPagePermissionButton.text.equals("Dont allow"))
assertTrue(allowPagePermissionButton.text.equals("Allow"))
assertItemTextEquals(denyPagePermissionButton, expectedText = "Dont allow")
assertItemTextEquals(allowPagePermissionButton, expectedText = "Allow")
}
}
}
@ -81,16 +81,16 @@ class SitePermissionsRobot {
if (!blocked) {
try {
assertItemContainingTextExists(itemWithText("Allow $url to send notifications?"))
assertTrue(denyPagePermissionButton.text.equals("Never"))
assertTrue(allowPagePermissionButton.text.equals("Always"))
assertItemTextEquals(denyPagePermissionButton, expectedText = "Never")
assertItemTextEquals(allowPagePermissionButton, expectedText = "Always")
} catch (e: AssertionError) {
browserScreen {
}.openThreeDotMenu {
}.refreshPage {
}.clickOpenNotificationButton {
assertItemContainingTextExists(itemWithText("Allow $url to send notifications?"))
assertTrue(denyPagePermissionButton.text.equals("Never"))
assertTrue(allowPagePermissionButton.text.equals("Always"))
assertItemTextEquals(denyPagePermissionButton, expectedText = "Never")
assertItemTextEquals(allowPagePermissionButton, expectedText = "Always")
}
}
} else {
@ -103,16 +103,16 @@ class SitePermissionsRobot {
fun verifyPersistentStoragePermissionPrompt(url: String) {
try {
assertItemContainingTextExists(itemWithText("Allow $url to store data in persistent storage?"))
assertTrue(denyPagePermissionButton.text.equals("Dont allow"))
assertTrue(allowPagePermissionButton.text.equals("Allow"))
assertItemTextEquals(denyPagePermissionButton, expectedText = "Dont allow")
assertItemTextEquals(allowPagePermissionButton, expectedText = "Allow")
} catch (e: AssertionError) {
browserScreen {
}.openThreeDotMenu {
}.refreshPage {
}.clickRequestPersistentStorageAccessButton {
assertItemContainingTextExists(itemWithText("Allow $url to store data in persistent storage?"))
assertTrue(denyPagePermissionButton.text.equals("Dont allow"))
assertTrue(allowPagePermissionButton.text.equals("Allow"))
assertItemTextEquals(denyPagePermissionButton, expectedText = "Dont allow")
assertItemTextEquals(allowPagePermissionButton, expectedText = "Allow")
}
}
}
@ -120,16 +120,16 @@ class SitePermissionsRobot {
fun verifyDRMContentPermissionPrompt(url: String) {
try {
assertItemContainingTextExists(itemWithText("Allow $url to store data in persistent storage?"))
assertTrue(denyPagePermissionButton.text.equals("Dont allow"))
assertTrue(allowPagePermissionButton.text.equals("Allow"))
assertItemTextEquals(denyPagePermissionButton, expectedText = "Dont allow")
assertItemTextEquals(allowPagePermissionButton, expectedText = "Allow")
} catch (e: AssertionError) {
browserScreen {
}.openThreeDotMenu {
}.refreshPage {
}.clickRequestDRMControlledContentAccessButton {
assertItemContainingTextExists(itemWithText("Allow $url to store data in persistent storage?"))
assertTrue(denyPagePermissionButton.text.equals("Dont allow"))
assertTrue(allowPagePermissionButton.text.equals("Allow"))
assertItemTextEquals(denyPagePermissionButton, expectedText = "Dont allow")
assertItemTextEquals(allowPagePermissionButton, expectedText = "Allow")
}
}
}

@ -31,7 +31,6 @@ 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
@ -43,8 +42,10 @@ import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource
import org.mozilla.fenix.helpers.MatcherHelper.assertItemContainingTextExists
import org.mozilla.fenix.helpers.MatcherHelper.assertItemWithDescriptionExists
import org.mozilla.fenix.helpers.MatcherHelper.assertItemWithResIdAndTextExists
import org.mozilla.fenix.helpers.MatcherHelper.assertItemWithResIdAndTextIsGone
import org.mozilla.fenix.helpers.MatcherHelper.assertItemWithResIdExists
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.itemWithResIdAndDescription
import org.mozilla.fenix.helpers.MatcherHelper.itemWithResIdContainingText
@ -161,12 +162,11 @@ class TabDrawerRobot {
),
).perform(swipeRight())
Log.i("MozTestLog", "Tab $title swiped right from tabs tray. Retry # $i")
assertTrue(
"Tab $title swipe right was unsuccessful.",
assertItemWithResIdAndTextIsGone(
itemWithResIdContainingText(
"$packageName:id/mozac_browser_tabstray_title",
title,
).waitUntilGone(waitingTimeShort),
),
)
break
@ -193,12 +193,11 @@ class TabDrawerRobot {
),
).perform(swipeLeft())
Log.i("MozTestLog", "Tab $title swiped left from tabs tray. Retry # $i")
assertTrue(
"Tab $title swipe left was unsuccessful.",
assertItemWithResIdAndTextIsGone(
itemWithResIdContainingText(
"$packageName:id/mozac_browser_tabstray_title",
title,
).waitUntilGone(waitingTimeShort),
),
)
break
@ -483,12 +482,8 @@ private fun closeTabButton() =
mDevice.findObject(UiSelector().descriptionContains("Close tab"))
private fun assertCloseTabsButton(title: String) =
assertTrue(
mDevice.findObject(
UiSelector()
.descriptionContains("Close tab"),
).getFromParent(UiSelector().textContains(title))
.waitForExists(waitingTime),
assertItemWithDescriptionExists(
itemWithDescription("Close tab").getFromParent(UiSelector().textContains(title)),
)
private fun normalBrowsingButton() = onView(
@ -512,11 +507,7 @@ private fun assertExistingOpenTabs(vararg tabTitles: String) {
while (!tabItem(title).waitForExists(waitingTime) && retries++ < 3) {
tabsList
.getChildByText(UiSelector().text(title), title, true)
assertTrue(
"Tab $title not found",
tabItem(title).waitForExists(waitingTimeLong),
)
Log.i("MozTestLog", "Tab $title found in tabs tray.")
assertItemContainingTextExists(tabItem(title), waitingTime = waitingTimeLong)
}
}
}

Loading…
Cancel
Save