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

272 lines
12 KiB
Kotlin

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.fenix.ui.robots
import android.app.NotificationManager
import android.content.Context
import android.util.Log
import androidx.test.uiautomator.UiScrollable
import androidx.test.uiautomator.UiSelector
import org.mozilla.fenix.helpers.Constants.RETRY_COUNT
import org.mozilla.fenix.helpers.Constants.TAG
import org.mozilla.fenix.helpers.MatcherHelper.assertUIObjectExists
import org.mozilla.fenix.helpers.MatcherHelper.itemContainingText
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
import org.mozilla.fenix.helpers.TestHelper.appName
import org.mozilla.fenix.helpers.TestHelper.mDevice
import org.mozilla.fenix.helpers.TestHelper.packageName
import kotlin.AssertionError
class NotificationRobot {
fun verifySystemNotificationExists(notificationMessage: String) {
val notification = UiSelector().text(notificationMessage)
var notificationFound = mDevice.findObject(notification).waitForExists(waitingTime)
while (!notificationFound) {
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)
}
assertUIObjectExists(itemWithText(notificationMessage))
}
fun clearNotifications() {
if (clearButton.exists()) {
Log.i(TAG, "clearNotifications: Verified that clear notifications button exists")
clearButton.click()
Log.i(TAG, "clearNotifications: Clicked clear notifications button")
} else {
scrollToEnd()
Log.i(TAG, "clearNotifications: Scrolled to end of notifications tray")
if (clearButton.exists()) {
Log.i(TAG, "clearNotifications: Verified that clear notifications button exists")
clearButton.click()
Log.i(TAG, "clearNotifications: Clicked clear notifications button")
} else if (notificationTray().exists()) {
mDevice.pressBack()
Log.i(TAG, "clearNotifications: Dismiss notifications tray by clicking device back button")
}
}
}
fun cancelAllShownNotifications() {
cancelAll()
Log.i(TAG, "cancelAllShownNotifications: Canceled all system notifications")
}
fun verifySystemNotificationDoesNotExist(notificationMessage: String) {
Log.i(TAG, "verifySystemNotificationDoesNotExist: Waiting for $notificationMessage notification to be gone")
mDevice.findObject(UiSelector().textContains(notificationMessage)).waitUntilGone(waitingTime)
assertUIObjectExists(itemContainingText(notificationMessage), exists = false)
Log.i(TAG, "verifySystemNotificationDoesNotExist: Verified that $notificationMessage notification does not exist")
}
fun verifyPrivateTabsNotification() {
verifySystemNotificationExists("$appName (Private)")
verifySystemNotificationExists("Close private tabs")
}
fun clickMediaNotificationControlButton(action: String) {
mediaSystemNotificationButton(action).waitForExists(waitingTime)
mediaSystemNotificationButton(action).click()
}
fun clickDownloadNotificationControlButton(action: String) {
for (i in 1..RETRY_COUNT) {
Log.i(TAG, "clickPageObject: For loop i = $i")
try {
assertUIObjectExists(downloadSystemNotificationButton(action))
downloadSystemNotificationButton(action).clickAndWaitForNewWindow(waitingTimeShort)
Log.i(TAG, "clickDownloadNotificationControlButton: Clicked app notification $action button and waits for a new window for $waitingTimeShort ms")
assertUIObjectExists(
downloadSystemNotificationButton(action),
exists = false,
)
break
} catch (e: AssertionError) {
Log.i(TAG, "clickDownloadNotificationControlButton: Catch block")
if (i == RETRY_COUNT) {
throw e
}
mDevice.waitForWindowUpdate(packageName, waitingTimeShort)
Log.i(TAG, "clickDownloadNotificationControlButton: Waited $waitingTimeShort ms for window update")
}
}
}
fun verifyMediaSystemNotificationButtonState(action: String) =
assertUIObjectExists(mediaSystemNotificationButton(action))
fun expandNotificationMessage() {
while (!notificationHeader.exists()) {
scrollToEnd()
Log.i(TAG, "expandNotificationMessage: Scrolled to end of notification tray")
}
if (notificationHeader.exists()) {
// expand the notification
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
while (!mDevice.findObject(UiSelector().resourceId("android:id/action0")).exists() &&
!mDevice.findObject(UiSelector().resourceId("android:id/actions_container")).exists()
) {
Log.i(TAG, "expandNotificationMessage: App notification action buttons do not exist")
scrollToEnd()
Log.i(TAG, "expandNotificationMessage: Scrolled to end of notification tray")
}
}
}
// Performs swipe action on download system notifications
fun swipeDownloadNotification(
direction: String,
shouldDismissNotification: Boolean,
canExpandNotification: Boolean = true,
) {
// In case it fails, retry max 3x the swipe action on download system notifications
for (i in 1..RETRY_COUNT) {
Log.i(TAG, "swipeDownloadNotification: For loop i = $i")
try {
Log.i(TAG, "swipeDownloadNotification: Try block")
var retries = 0
while (itemContainingText(appName).exists() && retries++ < 3) {
Log.i(TAG, "swipeDownloadNotification: While loop retries = $retries")
// Swipe left the download system notification
if (direction == "Left") {
itemContainingText(appName)
.also {
it.waitForExists(waitingTime)
it.swipeLeft(3)
}
Log.i(TAG, "swipeDownloadNotification: Swiped left download notification")
} else {
// Swipe right the download system notification
itemContainingText(appName)
.also {
it.waitForExists(waitingTime)
it.swipeRight(3)
}
Log.i(TAG, "swipeDownloadNotification: Swiped right download notification")
}
}
// Not all download related system notifications can be dismissed
if (shouldDismissNotification) {
assertUIObjectExists(itemContainingText(appName), exists = false)
} else {
assertUIObjectExists(itemContainingText(appName))
Log.i(TAG, "swipeDownloadNotification: Verified that $appName notification exist")
}
break
} catch (e: AssertionError) {
Log.i(TAG, "swipeDownloadNotification: Catch block")
if (i == RETRY_COUNT) {
throw e
} else {
notificationShade {
}.closeNotificationTray {
}.openNotificationShade {
// The download complete system notification can't be expanded
if (canExpandNotification) {
// In all cases the download system notification title will be the app name
verifySystemNotificationExists(appName)
Log.i(TAG, "swipeDownloadNotification: Verified that $appName notification exist")
expandNotificationMessage()
} else {
// Using the download completed system notification summary to bring in to view an properly verify it
verifySystemNotificationExists("Download completed")
}
}
}
}
}
}
fun clickNotification(notificationMessage: String) {
Log.i(TAG, "clickNotification: Looking for $notificationMessage notification")
mDevice.findObject(UiSelector().text(notificationMessage)).waitForExists(waitingTime)
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 {
fun clickClosePrivateTabsNotification(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition {
try {
assertUIObjectExists(closePrivateTabsNotification())
} catch (e: AssertionError) {
notificationTray().flingToEnd(1)
}
closePrivateTabsNotification().click()
HomeScreenRobot().interact()
return HomeScreenRobot.Transition()
}
fun closeNotificationTray(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition {
mDevice.pressBack()
Log.i(TAG, "closeNotificationTray: Closed notification tray using device back button")
BrowserRobot().interact()
return BrowserRobot.Transition()
}
}
}
fun notificationShade(interact: NotificationRobot.() -> Unit): NotificationRobot.Transition {
NotificationRobot().interact()
return NotificationRobot.Transition()
}
private fun closePrivateTabsNotification() =
mDevice.findObject(UiSelector().text("Close private tabs"))
private fun downloadSystemNotificationButton(action: String) =
mDevice.findObject(
UiSelector()
.resourceId("android:id/action0")
.textContains(action),
)
private fun mediaSystemNotificationButton(action: String) =
mDevice.findObject(
UiSelector()
.resourceId("com.android.systemui:id/action0")
.descriptionContains(action),
)
private fun notificationTray() = UiScrollable(
UiSelector().resourceId("com.android.systemui:id/notification_stack_scroller"),
).setAsVerticalList()
private val notificationHeader =
mDevice.findObject(
UiSelector()
.resourceId("android:id/app_name_text")
.text(appName),
)
private fun scrollToEnd() {
notificationTray().scrollToEnd(1)
}
private val clearButton = mDevice.findObject(UiSelector().resourceId("com.android.systemui:id/dismiss_text"))
private fun cancelAll() {
val notificationManager: NotificationManager =
TestHelper.appContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
notificationManager.cancelAll()
}