Bug 1863700 - Add more logs to functions related to download tests and other refactoring work

fenix/121.0
AndiAJ 8 months ago committed by mergify[bot]
parent 4f2e56cb4d
commit 1a48fa3771

@ -23,9 +23,7 @@ import androidx.compose.ui.test.junit4.AndroidComposeTestRule
import androidx.test.espresso.Espresso import androidx.test.espresso.Espresso
import androidx.test.espresso.IdlingRegistry import androidx.test.espresso.IdlingRegistry
import androidx.test.espresso.IdlingResource import androidx.test.espresso.IdlingResource
import androidx.test.espresso.intent.Intents
import androidx.test.espresso.intent.Intents.intended import androidx.test.espresso.intent.Intents.intended
import androidx.test.espresso.intent.matcher.IntentMatchers
import androidx.test.espresso.intent.matcher.IntentMatchers.toPackage import androidx.test.espresso.intent.matcher.IntentMatchers.toPackage
import androidx.test.platform.app.InstrumentationRegistry import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.rule.ActivityTestRule import androidx.test.rule.ActivityTestRule
@ -41,6 +39,7 @@ import org.mozilla.fenix.Config
import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.customtabs.ExternalAppBrowserActivity import org.mozilla.fenix.customtabs.ExternalAppBrowserActivity
import org.mozilla.fenix.helpers.Constants.PackageName.YOUTUBE_APP import org.mozilla.fenix.helpers.Constants.PackageName.YOUTUBE_APP
import org.mozilla.fenix.helpers.Constants.TAG
import org.mozilla.fenix.helpers.TestHelper.mDevice import org.mozilla.fenix.helpers.TestHelper.mDevice
import org.mozilla.fenix.helpers.ext.waitNotNull import org.mozilla.fenix.helpers.ext.waitNotNull
import org.mozilla.fenix.helpers.idlingresource.NetworkConnectionIdlingResource import org.mozilla.fenix.helpers.idlingresource.NetworkConnectionIdlingResource
@ -87,13 +86,16 @@ object AppAndSystemHelper {
// Check if the downloads folder exists // Check if the downloads folder exists
if (downloadsFolder.exists() && downloadsFolder.isDirectory) { if (downloadsFolder.exists() && downloadsFolder.isDirectory) {
Log.i(TAG, "clearDownloadsFolder: Verified that \"DOWNLOADS\" folder exists")
val files = downloadsFolder.listFiles() val files = downloadsFolder.listFiles()
// Check if the folder is not empty // Check if the folder is not empty
if (files != null && files.isNotEmpty()) { if (files != null && files.isNotEmpty()) {
Log.i(TAG, "clearDownloadsFolder: Verified that \"DOWNLOADS\" folder is not empty")
// Delete all files in the folder // Delete all files in the folder
for (file in files) { for (file in files) {
file.delete() file.delete()
Log.i(TAG, "clearDownloadsFolder: Deleted $file from \"DOWNLOADS\" folder")
} }
} }
} }
@ -105,25 +107,27 @@ object AppAndSystemHelper {
when (enabled) { when (enabled) {
true -> { true -> {
TestHelper.mDevice.executeShellCommand("svc data enable") mDevice.executeShellCommand("svc data enable")
TestHelper.mDevice.executeShellCommand("svc wifi enable") mDevice.executeShellCommand("svc wifi enable")
// Wait for network connection to be completely enabled // Wait for network connection to be completely enabled
IdlingRegistry.getInstance().register(networkConnectedIdlingResource) IdlingRegistry.getInstance().register(networkConnectedIdlingResource)
Espresso.onIdle { Espresso.onIdle {
IdlingRegistry.getInstance().unregister(networkConnectedIdlingResource) IdlingRegistry.getInstance().unregister(networkConnectedIdlingResource)
} }
Log.i(TAG, "setNetworkEnabled: Network connection was enabled")
} }
false -> { false -> {
TestHelper.mDevice.executeShellCommand("svc data disable") mDevice.executeShellCommand("svc data disable")
TestHelper.mDevice.executeShellCommand("svc wifi disable") mDevice.executeShellCommand("svc wifi disable")
// Wait for network connection to be completely disabled // Wait for network connection to be completely disabled
IdlingRegistry.getInstance().register(networkDisconnectedIdlingResource) IdlingRegistry.getInstance().register(networkDisconnectedIdlingResource)
Espresso.onIdle { Espresso.onIdle {
IdlingRegistry.getInstance().unregister(networkDisconnectedIdlingResource) IdlingRegistry.getInstance().unregister(networkDisconnectedIdlingResource)
} }
Log.i(TAG, "setNetworkEnabled: Network connection was disabled")
} }
} }
} }
@ -132,23 +136,28 @@ object AppAndSystemHelper {
return try { return try {
val packageManager = InstrumentationRegistry.getInstrumentation().context.packageManager val packageManager = InstrumentationRegistry.getInstrumentation().context.packageManager
packageManager.getApplicationInfo(packageName, 0).enabled packageManager.getApplicationInfo(packageName, 0).enabled
} catch (exception: PackageManager.NameNotFoundException) { } catch (e: PackageManager.NameNotFoundException) {
Log.i(TAG, "isPackageInstalled: Catch block - ${e.message}")
false false
} }
} }
fun assertExternalAppOpens(appPackageName: String) { fun assertExternalAppOpens(appPackageName: String) {
if (isPackageInstalled(appPackageName)) { if (isPackageInstalled(appPackageName)) {
Log.i(TAG, "assertExternalAppOpens: $appPackageName is installed on device")
try { try {
Intents.intended(IntentMatchers.toPackage(appPackageName)) Log.i(TAG, "assertExternalAppOpens: Try block")
intended(toPackage(appPackageName))
Log.i(TAG, "assertExternalAppOpens: Matched intent to $appPackageName")
} catch (e: AssertionFailedError) { } catch (e: AssertionFailedError) {
e.printStackTrace() Log.i(TAG, "assertExternalAppOpens: Catch block - ${e.message}")
} }
} else { } else {
TestHelper.mDevice.waitNotNull( mDevice.waitNotNull(
Until.findObject(By.text("Could not open file")), Until.findObject(By.text("Could not open file")),
TestAssetHelper.waitingTime, TestAssetHelper.waitingTime,
) )
Log.i(TAG, "assertExternalAppOpens: Verified \"Could not open file\" message")
} }
} }

@ -62,12 +62,12 @@ object MatcherHelper {
fun assertItemWithResIdExists(vararg appItems: UiObject, exists: Boolean = true) { fun assertItemWithResIdExists(vararg appItems: UiObject, exists: Boolean = true) {
if (exists) { if (exists) {
for (appItem in appItems) { for (appItem in appItems) {
assertTrue(appItem.waitForExists(waitingTime)) assertTrue("${appItem.selector} does not exist", appItem.waitForExists(waitingTime))
Log.i(TAG, "assertItemWithResIdExists: Verified ${appItem.selector} exists") Log.i(TAG, "assertItemWithResIdExists: Verified ${appItem.selector} exists")
} }
} else { } else {
for (appItem in appItems) { for (appItem in appItems) {
assertFalse(appItem.waitForExists(waitingTimeShort)) assertFalse("${appItem.selector} exists", appItem.waitForExists(waitingTimeShort))
Log.i(TAG, "assertItemWithResIdExists: Verified ${appItem.selector} does not exist") Log.i(TAG, "assertItemWithResIdExists: Verified ${appItem.selector} does not exist")
} }
} }
@ -76,10 +76,10 @@ object MatcherHelper {
fun assertItemContainingTextExists(vararg appItems: UiObject, exists: Boolean = true) { fun assertItemContainingTextExists(vararg appItems: UiObject, exists: Boolean = true) {
for (appItem in appItems) { for (appItem in appItems) {
if (exists) { if (exists) {
assertTrue(appItem.waitForExists(waitingTime)) assertTrue("${appItem.selector} does not exist", appItem.waitForExists(waitingTime))
Log.i(TAG, "assertItemContainingTextExists: Verified ${appItem.selector} exists") Log.i(TAG, "assertItemContainingTextExists: Verified ${appItem.selector} exists")
} else { } else {
assertFalse(appItem.waitForExists(waitingTimeShort)) assertFalse("${appItem.selector} exists", appItem.waitForExists(waitingTimeShort))
Log.i(TAG, "assertItemContainingTextExists: Verified ${appItem.selector} does not exist") Log.i(TAG, "assertItemContainingTextExists: Verified ${appItem.selector} does not exist")
} }
} }
@ -88,10 +88,10 @@ object MatcherHelper {
fun assertItemWithDescriptionExists(vararg appItems: UiObject, exists: Boolean = true) { fun assertItemWithDescriptionExists(vararg appItems: UiObject, exists: Boolean = true) {
for (appItem in appItems) { for (appItem in appItems) {
if (exists) { if (exists) {
assertTrue(appItem.waitForExists(waitingTime)) assertTrue("${appItem.selector} does not exist", appItem.waitForExists(waitingTime))
Log.i(TAG, "assertItemContainingTextExists: Verified ${appItem.selector} exists") Log.i(TAG, "assertItemContainingTextExists: Verified ${appItem.selector} exists")
} else { } else {
assertFalse(appItem.waitForExists(waitingTimeShort)) assertFalse("${appItem.selector} exists", appItem.waitForExists(waitingTimeShort))
Log.i(TAG, "assertItemContainingTextExists: Verified ${appItem.selector} does not exist") Log.i(TAG, "assertItemContainingTextExists: Verified ${appItem.selector} does not exist")
} }
} }
@ -118,9 +118,11 @@ object MatcherHelper {
fun assertItemWithResIdAndTextExists(vararg appItems: UiObject, exists: Boolean = true) { fun assertItemWithResIdAndTextExists(vararg appItems: UiObject, exists: Boolean = true) {
for (appItem in appItems) { for (appItem in appItems) {
if (exists) { if (exists) {
assertTrue(appItem.waitForExists(waitingTime)) assertTrue("${appItem.selector} does not exist", appItem.waitForExists(waitingTime))
Log.i(TAG, "assertItemWithResIdExists: Verified ${appItem.selector} exists")
} else { } else {
assertFalse(appItem.waitForExists(waitingTimeShort)) assertFalse("${appItem.selector} exists", appItem.waitForExists(waitingTimeShort))
Log.i(TAG, "assertItemWithResIdExists: Verified ${appItem.selector} does not exist")
} }
} }
} }

@ -6,6 +6,7 @@ package org.mozilla.fenix.helpers
import android.content.Context import android.content.Context
import android.net.Uri import android.net.Uri
import android.util.Log
import android.view.View import android.view.View
import androidx.test.core.app.launchActivity import androidx.test.core.app.launchActivity
import androidx.test.espresso.Espresso.onView import androidx.test.espresso.Espresso.onView
@ -32,6 +33,7 @@ import org.junit.Assert
import org.junit.Assert.assertFalse import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue import org.junit.Assert.assertTrue
import org.mozilla.fenix.R import org.mozilla.fenix.R
import org.mozilla.fenix.helpers.Constants.TAG
import org.mozilla.fenix.helpers.MatcherHelper.itemWithResIdAndText import org.mozilla.fenix.helpers.MatcherHelper.itemWithResIdAndText
import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime
import org.mozilla.fenix.helpers.TestAssetHelper.waitingTimeShort import org.mozilla.fenix.helpers.TestAssetHelper.waitingTimeShort
@ -120,6 +122,7 @@ object TestHelper {
mDevice.findObject(UiSelector().resourceId("$packageName:id/toolbar")) mDevice.findObject(UiSelector().resourceId("$packageName:id/toolbar"))
while (!toolbar.waitForExists(waitingTimeShort)) { while (!toolbar.waitForExists(waitingTimeShort)) {
mDevice.pressBack() mDevice.pressBack()
Log.i(TAG, "exitMenu: Exiting app settings menus using device back button")
} }
} }

@ -205,7 +205,7 @@ class ComposeSettingsDeleteBrowsingDataOnQuitTest {
downloadRobot { downloadRobot {
openPageAndDownloadFile(url = downloadTestPage.toUri(), downloadFile = "smallZip.zip") openPageAndDownloadFile(url = downloadTestPage.toUri(), downloadFile = "smallZip.zip")
verifyDownloadCompleteNotificationPopup() verifyDownloadCompleteNotificationPopup()
}.closeCompletedDownloadPrompt { }.closeDownloadPrompt {
}.goToHomescreen { }.goToHomescreen {
}.openThreeDotMenu { }.openThreeDotMenu {
clickQuit() clickQuit()

@ -60,7 +60,7 @@ class DownloadFileTypesTest(fileName: String) {
downloadRobot { downloadRobot {
openPageAndDownloadFile(url = downloadTestPage.toUri(), downloadFile = downloadFile) openPageAndDownloadFile(url = downloadTestPage.toUri(), downloadFile = downloadFile)
verifyDownloadCompleteNotificationPopup() verifyDownloadCompleteNotificationPopup()
}.closeCompletedDownloadPrompt { }.closeDownloadPrompt {
}.openThreeDotMenu { }.openThreeDotMenu {
}.openDownloadsManager { }.openDownloadsManager {
waitForDownloadsListToExist() waitForDownloadsListToExist()

@ -201,7 +201,7 @@ class DownloadTest {
downloadRobot { downloadRobot {
openPageAndDownloadFile(url = downloadTestPage.toUri(), downloadFile = firstDownloadedFile) openPageAndDownloadFile(url = downloadTestPage.toUri(), downloadFile = firstDownloadedFile)
verifyDownloadedFileName(firstDownloadedFile) verifyDownloadedFileName(firstDownloadedFile)
}.closeCompletedDownloadPrompt { }.closeDownloadPrompt {
}.clickDownloadLink(secondDownloadedFile) { }.clickDownloadLink(secondDownloadedFile) {
verifyDownloadPrompt(secondDownloadedFile) verifyDownloadPrompt(secondDownloadedFile)
}.clickDownload { }.clickDownload {

@ -198,7 +198,7 @@ class SettingsDeleteBrowsingDataOnQuitTest {
downloadRobot { downloadRobot {
openPageAndDownloadFile(url = downloadTestPage.toUri(), downloadFile = "smallZip.zip") openPageAndDownloadFile(url = downloadTestPage.toUri(), downloadFile = "smallZip.zip")
verifyDownloadCompleteNotificationPopup() verifyDownloadCompleteNotificationPopup()
}.closeCompletedDownloadPrompt { }.closeDownloadPrompt {
}.goToHomescreen { }.goToHomescreen {
}.openThreeDotMenu { }.openThreeDotMenu {
clickQuit() clickQuit()

@ -1007,17 +1007,20 @@ class BrowserRobot {
) )
} }
fun clickStayInPrivateBrowsingPromptButton() = fun clickStayInPrivateBrowsingPromptButton() {
itemWithResIdContainingText( itemWithResIdContainingText(
"$packageName:id/deny_button", "$packageName:id/deny_button",
getStringResource(R.string.mozac_feature_downloads_cancel_active_private_downloads_deny), getStringResource(R.string.mozac_feature_downloads_cancel_active_private_downloads_deny),
).click() ).click()
Log.i(TAG, "clickStayInPrivateBrowsingPromptButton: Clicked \"STAY IN PRIVATE BROWSING\" prompt button")
}
fun clickCancelPrivateDownloadsPromptButton() { fun clickCancelPrivateDownloadsPromptButton() {
itemWithResIdContainingText( itemWithResIdContainingText(
"$packageName:id/accept_button", "$packageName:id/accept_button",
getStringResource(R.string.mozac_feature_downloads_cancel_active_downloads_accept), getStringResource(R.string.mozac_feature_downloads_cancel_active_downloads_accept),
).click() ).click()
Log.i(TAG, "clickCancelPrivateDownloadsPromptButton: Clicked \"CANCEL DOWNLOADS\" prompt button")
mDevice.waitForWindowUpdate(packageName, waitingTime) mDevice.waitForWindowUpdate(packageName, waitingTime)
} }
@ -1025,6 +1028,7 @@ class BrowserRobot {
fun fillPdfForm(name: String) { fun fillPdfForm(name: String) {
// Set PDF form text for the text box // Set PDF form text for the text box
itemWithResId("pdfjs_internal_id_10R").setText(name) itemWithResId("pdfjs_internal_id_10R").setText(name)
Log.i(TAG, "fillPdfForm: Set PDF form text box text to: $name")
mDevice.waitForWindowUpdate(packageName, waitingTime) mDevice.waitForWindowUpdate(packageName, waitingTime)
if ( if (
!itemWithResId("pdfjs_internal_id_11R").exists() && !itemWithResId("pdfjs_internal_id_11R").exists() &&
@ -1034,15 +1038,17 @@ class BrowserRobot {
) { ) {
// Close the keyboard // Close the keyboard
mDevice.pressBack() mDevice.pressBack()
Log.i(TAG, "fillPdfForm: Closing the keyboard using device back button")
} }
// Click PDF form check box // Click PDF form check box
itemWithResId("pdfjs_internal_id_11R").click() itemWithResId("pdfjs_internal_id_11R").click()
Log.i(TAG, "fillPdfForm: Clicked PDF form check box")
} }
class Transition { class Transition {
fun openThreeDotMenu(interact: ThreeDotMenuMainRobot.() -> Unit): ThreeDotMenuMainRobot.Transition { fun openThreeDotMenu(interact: ThreeDotMenuMainRobot.() -> Unit): ThreeDotMenuMainRobot.Transition {
mDevice.waitForIdle(waitingTime) mDevice.waitForIdle(waitingTime)
Log.i(TAG, "openThreeDotMenu: Device was idle for $waitingTime") Log.i(TAG, "openThreeDotMenu: Device was idle for $waitingTime ms")
threeDotButton().perform(click()) threeDotButton().perform(click())
Log.i(TAG, "openThreeDotMenu: Clicked the main menu button") Log.i(TAG, "openThreeDotMenu: Clicked the main menu button")
@ -1127,6 +1133,7 @@ class BrowserRobot {
fun openNotificationShade(interact: NotificationRobot.() -> Unit): NotificationRobot.Transition { fun openNotificationShade(interact: NotificationRobot.() -> Unit): NotificationRobot.Transition {
mDevice.openNotification() mDevice.openNotification()
Log.i(TAG, "openNotificationShade: Opened notification tray")
NotificationRobot().interact() NotificationRobot().interact()
return NotificationRobot.Transition() return NotificationRobot.Transition()

@ -23,7 +23,6 @@ import androidx.test.espresso.matcher.ViewMatchers.withText
import androidx.test.uiautomator.By import androidx.test.uiautomator.By
import androidx.test.uiautomator.UiSelector import androidx.test.uiautomator.UiSelector
import androidx.test.uiautomator.Until import androidx.test.uiautomator.Until
import org.hamcrest.CoreMatchers
import org.hamcrest.CoreMatchers.allOf import org.hamcrest.CoreMatchers.allOf
import org.junit.Assert.assertTrue import org.junit.Assert.assertTrue
import org.mozilla.fenix.R import org.mozilla.fenix.R
@ -32,12 +31,15 @@ import org.mozilla.fenix.helpers.AppAndSystemHelper.getPermissionAllowID
import org.mozilla.fenix.helpers.Constants.PackageName.GOOGLE_APPS_PHOTOS import org.mozilla.fenix.helpers.Constants.PackageName.GOOGLE_APPS_PHOTOS
import org.mozilla.fenix.helpers.Constants.TAG import org.mozilla.fenix.helpers.Constants.TAG
import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource
import org.mozilla.fenix.helpers.MatcherHelper.assertItemContainingTextExists
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.itemWithDescription
import org.mozilla.fenix.helpers.MatcherHelper.itemWithResId import org.mozilla.fenix.helpers.MatcherHelper.itemWithResId
import org.mozilla.fenix.helpers.MatcherHelper.itemWithResIdAndText import org.mozilla.fenix.helpers.MatcherHelper.itemWithResIdAndText
import org.mozilla.fenix.helpers.MatcherHelper.itemWithResIdContainingText import org.mozilla.fenix.helpers.MatcherHelper.itemWithResIdContainingText
import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime
import org.mozilla.fenix.helpers.TestAssetHelper.waitingTimeLong
import org.mozilla.fenix.helpers.TestHelper.mDevice import org.mozilla.fenix.helpers.TestHelper.mDevice
import org.mozilla.fenix.helpers.TestHelper.packageName import org.mozilla.fenix.helpers.TestHelper.packageName
import org.mozilla.fenix.helpers.click import org.mozilla.fenix.helpers.click
@ -55,18 +57,8 @@ class DownloadRobot {
Log.i(TAG, "verifyDownloadPrompt: While loop currentTries = $currentTries") Log.i(TAG, "verifyDownloadPrompt: While loop currentTries = $currentTries")
try { try {
Log.i(TAG, "verifyDownloadPrompt: Try block") Log.i(TAG, "verifyDownloadPrompt: Try block")
assertTrue( assertItemWithResIdExists(itemWithResId("$packageName:id/download_button"))
"Download prompt button not visible", assertItemContainingTextExists(itemContainingText(fileName))
mDevice.findObject(UiSelector().resourceId("$packageName:id/download_button"))
.waitForExists(waitingTimeLong),
)
Log.i(TAG, "verifyDownloadPrompt: Verified that the \"DOWNLOAD\" prompt button exists")
assertTrue(
"$fileName title doesn't match",
mDevice.findObject(UiSelector().text(fileName))
.waitForExists(waitingTimeLong),
)
Log.i(TAG, "verifyDownloadPrompt: Verified that the download prompt for $fileName exists")
break break
} catch (e: AssertionError) { } catch (e: AssertionError) {
@ -81,48 +73,28 @@ class DownloadRobot {
} }
fun verifyDownloadCompleteNotificationPopup() { fun verifyDownloadCompleteNotificationPopup() {
assertTrue( assertItemContainingTextExists(
"Download notification Open button not found", itemContainingText(getStringResource(R.string.mozac_feature_downloads_button_open)),
mDevice.findObject(UiSelector().text("Open")) itemContainingText(getStringResource(R.string.mozac_feature_downloads_completed_notification_text2)),
.waitForExists(waitingTime),
)
assertTrue(
"Download completed notification text doesn't match",
mDevice.findObject(UiSelector().textContains("Download completed"))
.waitForExists(waitingTime),
)
assertTrue(
"Downloaded file name not visible",
mDevice.findObject(UiSelector().resourceId("$packageName:id/download_dialog_filename"))
.waitForExists(waitingTime),
) )
assertItemWithResIdExists(itemWithResId("$packageName:id/download_dialog_filename"))
} }
fun verifyDownloadFailedPrompt(fileName: String) { fun verifyDownloadFailedPrompt(fileName: String) {
assertTrue( assertItemWithResIdExists(itemWithResId("$packageName:id/download_dialog_icon"))
itemWithResId("$packageName:id/download_dialog_icon") assertItemWithResIdAndTextExists(
.waitForExists(waitingTime), itemWithResIdContainingText(
)
assertTrue(
"Download dialog title not displayed",
itemWithResIdAndText(
"$packageName:id/download_dialog_title", "$packageName:id/download_dialog_title",
"Download failed", getStringResource(R.string.mozac_feature_downloads_failed_notification_text2),
).waitForExists(waitingTime), ),
)
assertTrue(
"Download file name not displayed",
itemWithResIdContainingText( itemWithResIdContainingText(
"$packageName:id/download_dialog_filename", "$packageName:id/download_dialog_filename",
fileName, fileName,
).waitForExists(waitingTime), ),
) itemWithResIdContainingText(
assertTrue(
"Try again button not displayed",
itemWithResIdAndText(
"$packageName:id/download_dialog_action_button", "$packageName:id/download_dialog_action_button",
"Try Again", getStringResource(R.string.mozac_feature_downloads_button_try_again),
).waitForExists(waitingTime), ),
) )
} }
@ -131,68 +103,78 @@ class DownloadRobot {
"$packageName:id/download_dialog_action_button", "$packageName:id/download_dialog_action_button",
"Try Again", "Try Again",
).click() ).click()
Log.i(TAG, "clickTryAgainButton: Clicked \"TRY AGAIN\" in app prompt button")
} }
fun verifyPhotosAppOpens() = assertExternalAppOpens(GOOGLE_APPS_PHOTOS) fun verifyPhotosAppOpens() = assertExternalAppOpens(GOOGLE_APPS_PHOTOS)
fun verifyDownloadedFileName(fileName: String) { fun verifyDownloadedFileName(fileName: String) = assertItemContainingTextExists(itemContainingText(fileName))
assertTrue(
"$fileName not found in Downloads list",
mDevice.findObject(UiSelector().text(fileName))
.waitForExists(waitingTime),
)
}
fun verifyDownloadedFileIcon() = assertDownloadedFileIcon() fun verifyDownloadedFileIcon() = assertItemWithResIdExists(itemWithResId("$packageName:id/favicon"))
fun verifyEmptyDownloadsList() { fun verifyEmptyDownloadsList() {
Log.i(TAG, "verifyEmptyDownloadsList: Looking for empty download list")
mDevice.findObject(UiSelector().resourceId("$packageName:id/download_empty_view")) mDevice.findObject(UiSelector().resourceId("$packageName:id/download_empty_view"))
.waitForExists(waitingTime) .waitForExists(waitingTime)
onView(withText("No downloaded files")).check(matches(isDisplayed())) onView(withText("No downloaded files")).check(matches(isDisplayed()))
Log.i(TAG, "verifyEmptyDownloadsList: Verified \"No downloaded files\" list message")
} }
fun waitForDownloadsListToExist() = fun waitForDownloadsListToExist() {
assertTrue( assertTrue(
"Downloads list either empty or not displayed", "Downloads list either empty or not displayed",
mDevice.findObject(UiSelector().resourceId("$packageName:id/download_list")) mDevice.findObject(UiSelector().resourceId("$packageName:id/download_list"))
.waitForExists(waitingTime), .waitForExists(waitingTime),
) )
Log.i(TAG, "waitForDownloadsListToExist: Verified that the download list exists")
}
fun openDownloadedFile(fileName: String) { fun openDownloadedFile(fileName: String) {
downloadedFile(fileName) downloadedFile(fileName)
.check(matches(isDisplayed())) .check(matches(isDisplayed()))
.click() .click()
Log.i(TAG, "openDownloadedFile: Clicked downloaded file: $fileName")
} }
fun deleteDownloadedItem(fileName: String) = fun deleteDownloadedItem(fileName: String) {
onView( onView(
allOf( allOf(
withId(R.id.overflow_menu), withId(R.id.overflow_menu),
hasSibling(withText(fileName)), hasSibling(withText(fileName)),
), ),
).click() ).click()
Log.i(TAG, "deleteDownloadedItem: Deleted downloaded file: $fileName using trash bin icon")
}
fun longClickDownloadedItem(title: String) = fun longClickDownloadedItem(title: String) {
onView( onView(
allOf( allOf(
withId(R.id.title), withId(R.id.title),
withText(title), withText(title),
), ),
).perform(longClick()) ).perform(longClick())
Log.i(TAG, "longClickDownloadedItem: Long clicked downloaded file: $title")
}
fun selectDownloadedItem(title: String) = fun selectDownloadedItem(title: String) {
onView( onView(
allOf( allOf(
withId(R.id.title), withId(R.id.title),
withText(title), withText(title),
), ),
).perform(click()) ).perform(click())
Log.i(TAG, "selectDownloadedItem: Selected downloaded file: $title")
}
fun openMultiSelectMoreOptionsMenu() = fun openMultiSelectMoreOptionsMenu() {
itemWithDescription(getStringResource(R.string.content_description_menu)).click() itemWithDescription(getStringResource(R.string.content_description_menu)).click()
Log.i(TAG, "openMultiSelectMoreOptionsMenu: Clicked multi-select more options button")
}
fun clickMultiSelectRemoveButton() = fun clickMultiSelectRemoveButton() {
itemWithResIdContainingText("$packageName:id/title", "Remove").click() itemWithResIdContainingText("$packageName:id/title", "Remove").click()
Log.i(TAG, "clickMultiSelectRemoveButton: Clicked multi-select remove button")
}
fun openPageAndDownloadFile(url: Uri, downloadFile: String) { fun openPageAndDownloadFile(url: Uri, downloadFile: String) {
navigationToolbar { navigationToolbar {
@ -213,44 +195,42 @@ class DownloadRobot {
return Transition() return Transition()
} }
fun closeCompletedDownloadPrompt(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition {
closeCompletedDownloadButton().click()
BrowserRobot().interact()
return BrowserRobot.Transition()
}
fun closeDownloadPrompt(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { fun closeDownloadPrompt(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition {
itemWithResId("$packageName:id/download_dialog_close_button").click() itemWithResId("$packageName:id/download_dialog_close_button").click()
Log.i(TAG, "closeDownloadPrompt: Dismissed download prompt by clicking close prompt button")
BrowserRobot().interact() BrowserRobot().interact()
return BrowserRobot.Transition() return BrowserRobot.Transition()
} }
fun clickOpen(type: String, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { fun clickOpen(type: String, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition {
Log.i(TAG, "clickOpen: Looking for \"OPEN\" download prompt button")
openDownloadButton().waitForExists(waitingTime) openDownloadButton().waitForExists(waitingTime)
openDownloadButton().click() openDownloadButton().click()
Log.i(TAG, "clickOpen: Clicked \"OPEN\" download prompt button")
// verify open intent is matched with associated data type // verify open intent is matched with associated data type
Intents.intended( Intents.intended(
CoreMatchers.allOf( allOf(
IntentMatchers.hasAction(Intent.ACTION_VIEW), IntentMatchers.hasAction(Intent.ACTION_VIEW),
IntentMatchers.hasType(type), IntentMatchers.hasType(type),
), ),
) )
Log.i(TAG, "clickOpen: Verified that open intent is matched with associated data type")
BrowserRobot().interact() BrowserRobot().interact()
return BrowserRobot.Transition() return BrowserRobot.Transition()
} }
fun clickAllowPermission(interact: DownloadRobot.() -> Unit): Transition { fun clickAllowPermission(interact: DownloadRobot.() -> Unit): Transition {
Log.i(TAG, "clickAllowPermission: Looking for \"ALLOW\" permission button")
mDevice.waitNotNull( mDevice.waitNotNull(
Until.findObject(By.res(getPermissionAllowID() + ":id/permission_allow_button")), Until.findObject(By.res(getPermissionAllowID() + ":id/permission_allow_button")),
waitingTime, waitingTime,
) )
val allowPermissionButton = mDevice.findObject(By.res(getPermissionAllowID() + ":id/permission_allow_button")) mDevice.findObject(By.res(getPermissionAllowID() + ":id/permission_allow_button")).click()
allowPermissionButton.click() Log.i(TAG, "clickAllowPermission: Clicked \"ALLOW\" permission button")
DownloadRobot().interact() DownloadRobot().interact()
return Transition() return Transition()
@ -258,6 +238,7 @@ class DownloadRobot {
fun exitDownloadsManagerToBrowser(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { fun exitDownloadsManagerToBrowser(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition {
onView(withContentDescription("Navigate up")).click() onView(withContentDescription("Navigate up")).click()
Log.i(TAG, "exitDownloadsManagerToBrowser: Exited download manager to browser by clicking the navigate up toolbar button")
BrowserRobot().interact() BrowserRobot().interact()
return BrowserRobot.Transition() return BrowserRobot.Transition()
@ -265,6 +246,7 @@ class DownloadRobot {
fun goBack(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition { fun goBack(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition {
goBackButton().click() goBackButton().click()
Log.i(TAG, "exitDownloadsManagerToBrowser: Exited download manager to home screen by clicking the navigate up toolbar button")
HomeScreenRobot().interact() HomeScreenRobot().interact()
return HomeScreenRobot.Transition() return HomeScreenRobot.Transition()
@ -277,12 +259,6 @@ fun downloadRobot(interact: DownloadRobot.() -> Unit): DownloadRobot.Transition
return DownloadRobot.Transition() return DownloadRobot.Transition()
} }
private fun closeCompletedDownloadButton() =
onView(withId(R.id.download_dialog_close_button))
private fun closePromptButton() =
onView(withId(R.id.close_button))
private fun downloadButton() = private fun downloadButton() =
onView(withId(R.id.download_button)) onView(withId(R.id.download_button))
.check(matches(isDisplayed())) .check(matches(isDisplayed()))
@ -292,11 +268,4 @@ private fun openDownloadButton() =
private fun downloadedFile(fileName: String) = onView(withText(fileName)) private fun downloadedFile(fileName: String) = onView(withText(fileName))
private fun assertDownloadedFileIcon() =
assertTrue(
"Downloaded file icon not found",
mDevice.findObject(UiSelector().resourceId("$packageName:id/favicon"))
.exists(),
)
private fun goBackButton() = onView(withContentDescription("Navigate up")) private fun goBackButton() = onView(withContentDescription("Navigate up"))

@ -6,11 +6,13 @@ package org.mozilla.fenix.ui.robots
import android.app.NotificationManager import android.app.NotificationManager
import android.content.Context import android.content.Context
import android.util.Log
import androidx.test.uiautomator.UiScrollable import androidx.test.uiautomator.UiScrollable
import androidx.test.uiautomator.UiSelector import androidx.test.uiautomator.UiSelector
import org.junit.Assert.assertFalse import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue import org.junit.Assert.assertTrue
import org.mozilla.fenix.helpers.Constants.RETRY_COUNT import org.mozilla.fenix.helpers.Constants.RETRY_COUNT
import org.mozilla.fenix.helpers.Constants.TAG
import org.mozilla.fenix.helpers.MatcherHelper.assertItemWithResIdAndTextExists import org.mozilla.fenix.helpers.MatcherHelper.assertItemWithResIdAndTextExists
import org.mozilla.fenix.helpers.MatcherHelper.itemContainingText import org.mozilla.fenix.helpers.MatcherHelper.itemContainingText
import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime
@ -29,34 +31,46 @@ class NotificationRobot {
while (!notificationFound) { while (!notificationFound) {
scrollToEnd() scrollToEnd()
Log.i(TAG, "verifySystemNotificationExists: Scrolling to the end of the notification tray")
Log.i(TAG, "verifySystemNotificationExists: Looking for $notificationMessage notification")
notificationFound = mDevice.findObject(notification).waitForExists(waitingTime) notificationFound = mDevice.findObject(notification).waitForExists(waitingTime)
} }
assertTrue(notificationFound) assertTrue(notificationFound)
Log.i(TAG, "verifySystemNotificationExists: Verified that $notificationMessage notification exists")
} }
fun clearNotifications() { fun clearNotifications() {
if (clearButton.exists()) { if (clearButton.exists()) {
Log.i(TAG, "clearNotifications: Verified that clear notifications button exists")
clearButton.click() clearButton.click()
Log.i(TAG, "clearNotifications: Clicked clear notifications button")
} else { } else {
scrollToEnd() scrollToEnd()
Log.i(TAG, "clearNotifications: Scrolled to end of notifications tray")
if (clearButton.exists()) { if (clearButton.exists()) {
Log.i(TAG, "clearNotifications: Verified that clear notifications button exists")
clearButton.click() clearButton.click()
Log.i(TAG, "clearNotifications: Clicked clear notifications button")
} else if (notificationTray().exists()) { } else if (notificationTray().exists()) {
mDevice.pressBack() mDevice.pressBack()
Log.i(TAG, "clearNotifications: Dismiss notifications tray by clicking device back button")
} }
} }
} }
fun cancelAllShownNotifications() { fun cancelAllShownNotifications() {
cancelAll() cancelAll()
Log.i(TAG, "cancelAllShownNotifications: Canceled all system notifications")
} }
fun verifySystemNotificationDoesNotExist(notificationMessage: String) { fun verifySystemNotificationDoesNotExist(notificationMessage: String) {
Log.i(TAG, "verifySystemNotificationDoesNotExist: Waiting for $notificationMessage notification to be gone")
mDevice.findObject(UiSelector().textContains(notificationMessage)).waitUntilGone(waitingTime) mDevice.findObject(UiSelector().textContains(notificationMessage)).waitUntilGone(waitingTime)
assertFalse( assertFalse(
mDevice.findObject(UiSelector().textContains(notificationMessage)).waitForExists(waitingTimeShort), mDevice.findObject(UiSelector().textContains(notificationMessage)).waitForExists(waitingTimeShort),
) )
Log.i(TAG, "verifySystemNotificationDoesNotExist: Verified that $notificationMessage notification does not exist")
} }
fun verifyPrivateTabsNotification() { fun verifyPrivateTabsNotification() {
@ -71,9 +85,11 @@ class NotificationRobot {
fun clickDownloadNotificationControlButton(action: String) { fun clickDownloadNotificationControlButton(action: String) {
for (i in 1..RETRY_COUNT) { for (i in 1..RETRY_COUNT) {
Log.i(TAG, "clickPageObject: For loop i = $i")
try { try {
assertItemWithResIdAndTextExists(downloadSystemNotificationButton(action)) assertItemWithResIdAndTextExists(downloadSystemNotificationButton(action))
downloadSystemNotificationButton(action).clickAndWaitForNewWindow(waitingTimeShort) downloadSystemNotificationButton(action).clickAndWaitForNewWindow(waitingTimeShort)
Log.i(TAG, "clickDownloadNotificationControlButton: Clicked app notification $action button and waits for a new window for $waitingTimeShort ms")
assertItemWithResIdAndTextExists( assertItemWithResIdAndTextExists(
downloadSystemNotificationButton(action), downloadSystemNotificationButton(action),
exists = false, exists = false,
@ -81,10 +97,12 @@ class NotificationRobot {
break break
} catch (e: AssertionError) { } catch (e: AssertionError) {
Log.i(TAG, "clickDownloadNotificationControlButton: Catch block")
if (i == RETRY_COUNT) { if (i == RETRY_COUNT) {
throw e throw e
} }
mDevice.waitForWindowUpdate(packageName, waitingTimeShort) mDevice.waitForWindowUpdate(packageName, waitingTimeShort)
Log.i(TAG, "clickDownloadNotificationControlButton: Waited $waitingTimeShort ms for window update")
} }
} }
} }
@ -96,17 +114,21 @@ class NotificationRobot {
fun expandNotificationMessage() { fun expandNotificationMessage() {
while (!notificationHeader.exists()) { while (!notificationHeader.exists()) {
scrollToEnd() scrollToEnd()
Log.i(TAG, "expandNotificationMessage: Scrolled to end of notification tray")
} }
if (notificationHeader.exists()) { if (notificationHeader.exists()) {
// expand the notification // expand the notification
notificationHeader.click() notificationHeader.click()
Log.i(TAG, "expandNotificationMessage: Clicked the app notification")
// double check if notification actions are viewable by checking for action existence; otherwise scroll again // double check if notification actions are viewable by checking for action existence; otherwise scroll again
while (!mDevice.findObject(UiSelector().resourceId("android:id/action0")).exists() && while (!mDevice.findObject(UiSelector().resourceId("android:id/action0")).exists() &&
!mDevice.findObject(UiSelector().resourceId("android:id/actions_container")).exists() !mDevice.findObject(UiSelector().resourceId("android:id/actions_container")).exists()
) { ) {
Log.i(TAG, "expandNotificationMessage: App notification action buttons do not exist")
scrollToEnd() scrollToEnd()
Log.i(TAG, "expandNotificationMessage: Scrolled to end of notification tray")
} }
} }
} }
@ -119,9 +141,12 @@ class NotificationRobot {
) { ) {
// In case it fails, retry max 3x the swipe action on download system notifications // In case it fails, retry max 3x the swipe action on download system notifications
for (i in 1..RETRY_COUNT) { for (i in 1..RETRY_COUNT) {
Log.i(TAG, "swipeDownloadNotification: For loop i = $i")
try { try {
Log.i(TAG, "swipeDownloadNotification: Try block")
var retries = 0 var retries = 0
while (itemContainingText(appName).exists() && retries++ < 3) { while (itemContainingText(appName).exists() && retries++ < 3) {
Log.i(TAG, "swipeDownloadNotification: While loop retries = $retries")
// Swipe left the download system notification // Swipe left the download system notification
if (direction == "Left") { if (direction == "Left") {
itemContainingText(appName) itemContainingText(appName)
@ -129,6 +154,7 @@ class NotificationRobot {
it.waitForExists(waitingTime) it.waitForExists(waitingTime)
it.swipeLeft(3) it.swipeLeft(3)
} }
Log.i(TAG, "swipeDownloadNotification: Swiped left download notification")
} else { } else {
// Swipe right the download system notification // Swipe right the download system notification
itemContainingText(appName) itemContainingText(appName)
@ -136,17 +162,21 @@ class NotificationRobot {
it.waitForExists(waitingTime) it.waitForExists(waitingTime)
it.swipeRight(3) it.swipeRight(3)
} }
Log.i(TAG, "swipeDownloadNotification: Swiped right download notification")
} }
} }
// Not all download related system notifications can be dismissed // Not all download related system notifications can be dismissed
if (shouldDismissNotification) { if (shouldDismissNotification) {
assertFalse(itemContainingText(appName).waitForExists(waitingTimeShort)) assertFalse(itemContainingText(appName).waitForExists(waitingTimeShort))
Log.i(TAG, "swipeDownloadNotification: Verified that $appName notification does not exist")
} else { } else {
assertTrue(itemContainingText(appName).waitForExists(waitingTimeShort)) assertTrue(itemContainingText(appName).waitForExists(waitingTimeShort))
Log.i(TAG, "swipeDownloadNotification: Verified that $appName notification exist")
} }
break break
} catch (e: AssertionError) { } catch (e: AssertionError) {
Log.i(TAG, "swipeDownloadNotification: Catch block")
if (i == RETRY_COUNT) { if (i == RETRY_COUNT) {
throw e throw e
} else { } else {
@ -157,6 +187,7 @@ class NotificationRobot {
if (canExpandNotification) { if (canExpandNotification) {
// In all cases the download system notification title will be the app name // In all cases the download system notification title will be the app name
verifySystemNotificationExists(appName) verifySystemNotificationExists(appName)
Log.i(TAG, "swipeDownloadNotification: Verified that $appName notification exist")
expandNotificationMessage() expandNotificationMessage()
} else { } else {
// Using the download completed system notification summary to bring in to view an properly verify it // Using the download completed system notification summary to bring in to view an properly verify it
@ -169,8 +200,10 @@ class NotificationRobot {
} }
fun clickNotification(notificationMessage: String) { fun clickNotification(notificationMessage: String) {
Log.i(TAG, "clickNotification: Looking for $notificationMessage notification")
mDevice.findObject(UiSelector().text(notificationMessage)).waitForExists(waitingTime) mDevice.findObject(UiSelector().text(notificationMessage)).waitForExists(waitingTime)
mDevice.findObject(UiSelector().text(notificationMessage)).clickAndWaitForNewWindow(waitingTimeShort) mDevice.findObject(UiSelector().text(notificationMessage)).clickAndWaitForNewWindow(waitingTimeShort)
Log.i(TAG, "clickNotification: Clicked $notificationMessage notification and waiting for $waitingTimeShort ms for a new window")
} }
class Transition { class Transition {
@ -192,6 +225,7 @@ class NotificationRobot {
fun closeNotificationTray(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { fun closeNotificationTray(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition {
mDevice.pressBack() mDevice.pressBack()
Log.i(TAG, "closeNotificationTray: Closed notification tray using device back button")
BrowserRobot().interact() BrowserRobot().interact()
return BrowserRobot.Transition() return BrowserRobot.Transition()

@ -6,6 +6,7 @@ package org.mozilla.fenix.ui.robots
import android.content.Intent import android.content.Intent
import android.net.Uri import android.net.Uri
import android.util.Log
import androidx.test.espresso.Espresso.onView import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.assertion.ViewAssertions.matches import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.intent.Intents import androidx.test.espresso.intent.Intents
@ -20,6 +21,7 @@ import androidx.test.uiautomator.UiSelector
import androidx.test.uiautomator.Until import androidx.test.uiautomator.Until
import org.hamcrest.Matchers.allOf import org.hamcrest.Matchers.allOf
import org.mozilla.fenix.R import org.mozilla.fenix.R
import org.mozilla.fenix.helpers.Constants.TAG
import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource
import org.mozilla.fenix.helpers.MatcherHelper.assertItemContainingTextExists import org.mozilla.fenix.helpers.MatcherHelper.assertItemContainingTextExists
import org.mozilla.fenix.helpers.MatcherHelper.assertItemWithResIdAndTextExists import org.mozilla.fenix.helpers.MatcherHelper.assertItemWithResIdAndTextExists
@ -137,6 +139,7 @@ class ShareOverlayRobot {
class Transition { class Transition {
fun clickSaveAsPDF(interact: DownloadRobot.() -> Unit): DownloadRobot.Transition { fun clickSaveAsPDF(interact: DownloadRobot.() -> Unit): DownloadRobot.Transition {
itemContainingText("Save as PDF").click() itemContainingText("Save as PDF").click()
Log.i(TAG, "clickSaveAsPDF: Clicked \"SAVE AS PDF\" share overlay button")
DownloadRobot().interact() DownloadRobot().interact()
return DownloadRobot.Transition() return DownloadRobot.Transition()

@ -209,7 +209,9 @@ class ThreeDotMenuMainRobot {
fun openDownloadsManager(interact: DownloadRobot.() -> Unit): DownloadRobot.Transition { fun openDownloadsManager(interact: DownloadRobot.() -> Unit): DownloadRobot.Transition {
threeDotMenuRecyclerView().perform(swipeDown()) threeDotMenuRecyclerView().perform(swipeDown())
Log.i(TAG, "openDownloadsManager: Swiped up main menu")
downloadsButton.click() downloadsButton.click()
Log.i(TAG, "openDownloadsManager: Clicked main menu \"DOWNLOADS\" button")
DownloadRobot().interact() DownloadRobot().interact()
return DownloadRobot.Transition() return DownloadRobot.Transition()
@ -310,6 +312,7 @@ class ThreeDotMenuMainRobot {
fun clickShareButton(interact: ShareOverlayRobot.() -> Unit): ShareOverlayRobot.Transition { fun clickShareButton(interact: ShareOverlayRobot.() -> Unit): ShareOverlayRobot.Transition {
shareButton.click() shareButton.click()
Log.i(TAG, "clickShareButton: Clicked main menu share button")
mDevice.waitNotNull(Until.findObject(By.text("ALL ACTIONS")), waitingTime) mDevice.waitNotNull(Until.findObject(By.text("ALL ACTIONS")), waitingTime)
ShareOverlayRobot().interact() ShareOverlayRobot().interact()

Loading…
Cancel
Save