Updated the method to verify system notifications and added new tests for media notifications (#9330)

fennec/production
Oana Horvath 4 years ago committed by GitHub
parent cee34893ed
commit 5f68d6cb29
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,26 @@
<html>
<head>
<title>Audio_Test_Page</title>
</head>
<body>
<p id="testContent">Page content: audio player</p>
<div class="audioPlayer">
<audio id="audioSample" controls loop>
<source src="../resources/audioSample.mp3">
</audio>
</div>
<div class="playbackState">
</div>
<script>
const audio = document.querySelector('audio');
audio.addEventListener('playing', (event) => {
document.querySelector('.playbackState').innerText="Media file is playing"
});
audio.addEventListener('pause', (event) => {
document.querySelector('.playbackState').innerText="Media file is paused"
});
</script>
</body>
</html>

@ -0,0 +1,26 @@
<html>
<head>
<title>Video_Test_Page</title>
</head>
<body>
<p id="testContent">Page content: video player</p>
<div id="video-container">
<video id="videoSample" width="320" height="240" controls loop>
<source src="../resources/videoSample.webm">
</video>
</div>
<div class="playbackState">
</div>
<script>
const video = document.querySelector('video');
video.addEventListener('playing', (event) => {
document.querySelector('.playbackState').innerText="Media file is playing";
});
video.addEventListener('pause', (event) => {
document.querySelector('.playbackState').innerHTML="Media file is paused";
});
</script>
</body>
</html>

@ -18,7 +18,7 @@ object TestAssetHelper {
val waitingTime: Long = TimeUnit.SECONDS.toMillis(15) val waitingTime: Long = TimeUnit.SECONDS.toMillis(15)
val waitingTimeShort: Long = TimeUnit.SECONDS.toMillis(1) val waitingTimeShort: Long = TimeUnit.SECONDS.toMillis(1)
data class TestAsset(val url: Uri, val content: String) data class TestAsset(val url: Uri, val content: String, val title: String)
/** /**
* Hosts 3 simple websites, found at androidTest/assets/pages/generic[1|2|3].html * Hosts 3 simple websites, found at androidTest/assets/pages/generic[1|2|3].html
@ -33,7 +33,8 @@ object TestAssetHelper {
return (1..4).map { return (1..4).map {
TestAsset( TestAsset(
server.url("pages/generic$it.html").toString().toUri()!!, server.url("pages/generic$it.html").toString().toUri()!!,
"Page content: $it" "Page content: $it",
""
) )
} }
} }
@ -41,52 +42,70 @@ object TestAssetHelper {
fun getGenericAsset(server: MockWebServer, pageNum: Int): TestAsset { fun getGenericAsset(server: MockWebServer, pageNum: Int): TestAsset {
val url = server.url("pages/generic$pageNum.html").toString().toUri()!! val url = server.url("pages/generic$pageNum.html").toString().toUri()!!
val content = "Page content: $pageNum" val content = "Page content: $pageNum"
val title = "Test_Page_$pageNum"
return TestAsset(url, content) return TestAsset(url, content, title)
} }
fun getLoremIpsumAsset(server: MockWebServer): TestAsset { fun getLoremIpsumAsset(server: MockWebServer): TestAsset {
val url = server.url("pages/lorem-ipsum.html").toString().toUri()!! val url = server.url("pages/lorem-ipsum.html").toString().toUri()!!
val content = "Page content: lorem ipsum" val content = "Page content: lorem ipsum"
return TestAsset(url, content)
return TestAsset(url, content, "")
} }
fun getRefreshAsset(server: MockWebServer): TestAsset { fun getRefreshAsset(server: MockWebServer): TestAsset {
val url = server.url("pages/refresh.html").toString().toUri()!! val url = server.url("pages/refresh.html").toString().toUri()!!
val content = "Page content: refresh" val content = "Page content: refresh"
return TestAsset(url, content) return TestAsset(url, content, "")
} }
fun getUUIDPage(server: MockWebServer): TestAsset { fun getUUIDPage(server: MockWebServer): TestAsset {
val url = server.url("pages/basic_nav_uuid.html").toString().toUri()!! val url = server.url("pages/basic_nav_uuid.html").toString().toUri()!!
val content = "Page content: basic_nav_uuid" val content = "Page content: basic_nav_uuid"
return TestAsset(url, content) return TestAsset(url, content, "")
} }
fun getDownloadAsset(server: MockWebServer): TestAsset { fun getDownloadAsset(server: MockWebServer): TestAsset {
val url = server.url("pages/download.html").toString().toUri()!! val url = server.url("pages/download.html").toString().toUri()!!
val content = "Page content: Globe.svg" val content = "Page content: Globe.svg"
return TestAsset(url, content) return TestAsset(url, content, "")
} }
fun getEnhancedTrackingProtectionAsset(server: MockWebServer): TestAsset { fun getEnhancedTrackingProtectionAsset(server: MockWebServer): TestAsset {
val url = server.url("pages/etp.html").toString().toUri()!! val url = server.url("pages/etp.html").toString().toUri()!!
return TestAsset(url, "") return TestAsset(url, "", "")
} }
fun getImageAsset(server: MockWebServer): TestAsset { fun getImageAsset(server: MockWebServer): TestAsset {
val url = server.url("resources/rabbit.jpg").toString().toUri()!! val url = server.url("resources/rabbit.jpg").toString().toUri()!!
return TestAsset(url, "") return TestAsset(url, "", "")
} }
fun getSaveLoginAsset(server: MockWebServer): TestAsset { fun getSaveLoginAsset(server: MockWebServer): TestAsset {
val url = server.url("pages/password.html").toString().toUri()!! val url = server.url("pages/password.html").toString().toUri()!!
return TestAsset(url, "") return TestAsset(url, "", "")
}
fun getAudioPageAsset(server: MockWebServer): TestAsset {
val url = server.url("pages/audioMediaPage.html").toString().toUri()!!
val title = "Audio_Test_Page"
val content = "Page content: audio player"
return TestAsset(url, content, title)
}
fun getVideoPageAsset(server: MockWebServer): TestAsset {
val url = server.url("pages/videoMediaPage.html").toString().toUri()!!
val title = "Video_Test_Page"
val content = "Page content: video player"
return TestAsset(url, content, title)
} }
} }

@ -0,0 +1,131 @@
/* 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
import okhttp3.mockwebserver.MockWebServer
import org.junit.After
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.mozilla.fenix.helpers.AndroidAssetDispatcher
import org.mozilla.fenix.helpers.HomeActivityTestRule
import org.mozilla.fenix.helpers.TestAssetHelper
import org.mozilla.fenix.ui.robots.browserScreen
import org.mozilla.fenix.ui.robots.homeScreen
import org.mozilla.fenix.ui.robots.mDevice
import org.mozilla.fenix.ui.robots.navigationToolbar
/**
* Tests for verifying basic functionality of media notifications:
* - video and audio playback system notifications appear and can pause/play the media content
* - a media notification icon is displayed on the homescreen for the tab playing media content
* Note: this test only verifies media notifications, not media itself
*/
class MediaNotificationTest {
/* ktlint-disable no-blank-line-before-rbrace */ // This imposes unreadable grouping.
private lateinit var mockWebServer: MockWebServer
@get:Rule
val activityTestRule = HomeActivityTestRule()
@Before
fun setUp() {
mockWebServer = MockWebServer().apply {
setDispatcher(AndroidAssetDispatcher())
start()
}
}
@After
fun tearDown() {
mockWebServer.shutdown()
}
@Test
fun videoPlaybackSystemNotificationTest() {
val videoTestPage = TestAssetHelper.getVideoPageAsset(mockWebServer)
navigationToolbar {
}.enterURLAndEnterToBrowser(videoTestPage.url) {
clickMediaPlayerPlayButton()
waitForPlaybackToStart()
}.openNotificationShade {
verifySystemNotificationExists(videoTestPage.title)
clickMediaSystemNotificationControlButton("Pause")
verifyMediaSystemNotificationButtonState("Play")
}
mDevice.pressBack()
browserScreen {
verifyMediaIsPaused()
}
}
@Test
fun audioPlaybackSystemNotificationTest() {
val audioTestPage = TestAssetHelper.getAudioPageAsset(mockWebServer)
navigationToolbar {
}.enterURLAndEnterToBrowser(audioTestPage.url) {
verifyPageContent(audioTestPage.content)
clickMediaPlayerPlayButton()
waitForPlaybackToStart()
}.openNotificationShade {
verifySystemNotificationExists(audioTestPage.title)
clickMediaSystemNotificationControlButton("Pause")
verifyMediaSystemNotificationButtonState("Play")
}
mDevice.pressBack()
browserScreen {
verifyMediaIsPaused()
}
}
@Test
fun tabMediaControlButtonTest() {
val audioTestPage = TestAssetHelper.getAudioPageAsset(mockWebServer)
navigationToolbar {
}.enterURLAndEnterToBrowser(audioTestPage.url) {
verifyPageContent(audioTestPage.content)
clickMediaPlayerPlayButton()
waitForPlaybackToStart()
}.openHomeScreen {
verifyTabMediaControlButtonState("Pause")
clickTabMediaControlButton()
verifyTabMediaControlButtonState("Play")
}.openTab(audioTestPage.title) {
verifyMediaIsPaused()
}
}
@Test
fun mediaSystemNotificationInPrivateModeTest() {
val audioTestPage = TestAssetHelper.getAudioPageAsset(mockWebServer)
homeScreen { }.togglePrivateBrowsingMode()
navigationToolbar {
}.enterURLAndEnterToBrowser(audioTestPage.url) {
verifyPageContent(audioTestPage.content)
clickMediaPlayerPlayButton()
waitForPlaybackToStart()
}.openNotificationShade {
verifySystemNotificationExists("A site is playing media")
clickMediaSystemNotificationControlButton("Pause")
verifyMediaSystemNotificationButtonState("Play")
}
mDevice.pressBack()
browserScreen {
verifyMediaIsPaused()
}
}
}

@ -19,6 +19,7 @@ import org.mozilla.fenix.helpers.TestAssetHelper
import org.mozilla.fenix.helpers.ext.waitNotNull import org.mozilla.fenix.helpers.ext.waitNotNull
import org.mozilla.fenix.ui.robots.homeScreen import org.mozilla.fenix.ui.robots.homeScreen
import org.mozilla.fenix.ui.robots.navigationToolbar import org.mozilla.fenix.ui.robots.navigationToolbar
import org.mozilla.fenix.ui.robots.notificationShade
/** /**
* Tests for verifying basic functionality of tabbed browsing * Tests for verifying basic functionality of tabbed browsing
@ -259,6 +260,9 @@ class TabbedBrowsingTest {
navigationToolbar { navigationToolbar {
}.enterURLAndEnterToBrowser(defaultWebPage.url) { }.enterURLAndEnterToBrowser(defaultWebPage.url) {
mDevice.openNotification() mDevice.openNotification()
}
notificationShade {
verifyPrivateTabsNotification() verifyPrivateTabsNotification()
}.clickClosePrivateTabsNotification { }.clickClosePrivateTabsNotification {
verifyPrivateSessionMessage() verifyPrivateSessionMessage()

@ -26,6 +26,7 @@ import androidx.test.uiautomator.By.text
import androidx.test.uiautomator.UiDevice import androidx.test.uiautomator.UiDevice
import androidx.test.uiautomator.UiSelector import androidx.test.uiautomator.UiSelector
import androidx.test.uiautomator.Until import androidx.test.uiautomator.Until
import androidx.test.uiautomator.Until.hasObject
import org.hamcrest.CoreMatchers.allOf import org.hamcrest.CoreMatchers.allOf
import org.hamcrest.CoreMatchers.containsString import org.hamcrest.CoreMatchers.containsString
import org.junit.Assert.assertTrue import org.junit.Assert.assertTrue
@ -34,6 +35,7 @@ import org.mozilla.fenix.ext.components
import org.mozilla.fenix.helpers.Constants.LongClickDuration import org.mozilla.fenix.helpers.Constants.LongClickDuration
import org.mozilla.fenix.helpers.TestAssetHelper import org.mozilla.fenix.helpers.TestAssetHelper
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.click import org.mozilla.fenix.helpers.click
import org.mozilla.fenix.helpers.ext.waitNotNull import org.mozilla.fenix.helpers.ext.waitNotNull
@ -57,7 +59,7 @@ class BrowserRobot {
) )
TestAssetHelper.waitingTime TestAssetHelper.waitingTime
onView(withId(R.id.mozac_browser_toolbar_url_view)) onView(withId(R.id.mozac_browser_toolbar_url_view))
.check(matches(withText(containsString(url.replace("http://", ""))))) .check(matches(withText(containsString(url.replace("http://", "")))))
} }
fun verifyHelpUrl() { fun verifyHelpUrl() {
@ -145,11 +147,6 @@ class BrowserRobot {
) )
} }
fun verifyPrivateTabsNotification() {
mDevice.wait(Until.hasObject(text("Close private tabs")), waitingTime)
assertPrivateTabsNotification()
}
fun clickContextOpenLinkInNewTab() { fun clickContextOpenLinkInNewTab() {
val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
mDevice.waitNotNull( mDevice.waitNotNull(
@ -289,6 +286,36 @@ class BrowserRobot {
mDevice.findObject(text(optionToSaveLogin)).click() mDevice.findObject(text(optionToSaveLogin)).click()
} }
fun clickMediaPlayerPlayButton() {
mDevice.waitNotNull(
hasObject(
By
.clazz("android.widget.Button")
.textContains("Play")
),
waitingTime
)
mediaPlayerPlayButton().click()
}
fun waitForPlaybackToStart() {
mDevice.waitNotNull(
hasObject(
text("Media file is playing")
), waitingTimeShort
)
}
fun verifyMediaIsPaused() {
mDevice.waitNotNull(
hasObject(
text("Media file is paused")
), waitingTimeShort
)
mDevice.findObject(UiSelector().text("Media file is paused")).exists()
}
class Transition { class Transition {
private val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) private val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
private fun threeDotButton() = onView( private fun threeDotButton() = onView(
@ -329,12 +356,11 @@ class BrowserRobot {
return HomeScreenRobot.Transition() return HomeScreenRobot.Transition()
} }
fun clickClosePrivateTabsNotification(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition { fun openNotificationShade(interact: NotificationRobot.() -> Unit): NotificationRobot.Transition {
mDevice.wait(Until.hasObject(text("Close private tabs")), waitingTime) mDevice.openNotification()
closePrivateTabsNotification().clickAndWaitForNewWindow(waitingTime)
HomeScreenRobot().interact() NotificationRobot().interact()
return HomeScreenRobot.Transition() return NotificationRobot.Transition()
} }
} }
} }
@ -355,10 +381,9 @@ fun navURLBar() = onView(withId(R.id.mozac_browser_toolbar_url_view))
private fun tabsCounter() = onView(withId(R.id.mozac_browser_toolbar_browser_actions)) private fun tabsCounter() = onView(withId(R.id.mozac_browser_toolbar_browser_actions))
private fun closePrivateTabsNotification() = private fun mediaPlayerPlayButton() =
mDevice.findObject(UiSelector().text("Close private tabs")) mDevice.findObject(
By
private fun assertPrivateTabsNotification() { .clazz("android.widget.Button")
mDevice.findObject(UiSelector().text("Firefox Preview (Private)")).exists() .textContains("Play")
mDevice.findObject(UiSelector().text("Close private tabs")).exists() )
}

@ -6,8 +6,8 @@
package org.mozilla.fenix.ui.robots package org.mozilla.fenix.ui.robots
import androidx.recyclerview.widget.RecyclerView
import android.graphics.Bitmap import android.graphics.Bitmap
import androidx.recyclerview.widget.RecyclerView
import androidx.test.espresso.Espresso.onView import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions import androidx.test.espresso.action.ViewActions
import androidx.test.espresso.action.ViewActions.click import androidx.test.espresso.action.ViewActions.click
@ -16,30 +16,32 @@ import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.contrib.RecyclerViewActions import androidx.test.espresso.contrib.RecyclerViewActions
import androidx.test.espresso.contrib.RecyclerViewActions.actionOnItem import androidx.test.espresso.contrib.RecyclerViewActions.actionOnItem
import androidx.test.espresso.matcher.ViewMatchers import androidx.test.espresso.matcher.ViewMatchers
import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.espresso.matcher.ViewMatchers.withText
import androidx.test.espresso.matcher.ViewMatchers.Visibility import androidx.test.espresso.matcher.ViewMatchers.Visibility
import androidx.test.espresso.matcher.ViewMatchers.hasDescendant import androidx.test.espresso.matcher.ViewMatchers.hasDescendant
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
import androidx.test.espresso.matcher.ViewMatchers.withContentDescription import androidx.test.espresso.matcher.ViewMatchers.withContentDescription
import androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility import androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility
import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.espresso.matcher.ViewMatchers.withText
import androidx.test.platform.app.InstrumentationRegistry import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.uiautomator.By import androidx.test.uiautomator.By
import androidx.test.uiautomator.By.text
import androidx.test.uiautomator.UiDevice import androidx.test.uiautomator.UiDevice
import androidx.test.uiautomator.UiScrollable import androidx.test.uiautomator.UiScrollable
import androidx.test.uiautomator.UiSelector import androidx.test.uiautomator.UiSelector
import androidx.test.uiautomator.Until import androidx.test.uiautomator.Until
import org.hamcrest.CoreMatchers.containsString import androidx.test.uiautomator.Until.findObject
import org.hamcrest.CoreMatchers.allOf import org.hamcrest.CoreMatchers.allOf
import org.hamcrest.CoreMatchers.containsString
import org.hamcrest.CoreMatchers.not import org.hamcrest.CoreMatchers.not
import org.mozilla.fenix.R import org.mozilla.fenix.R
import org.mozilla.fenix.components.Search
import org.mozilla.fenix.helpers.TestAssetHelper import org.mozilla.fenix.helpers.TestAssetHelper
import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime
import org.mozilla.fenix.helpers.click import org.mozilla.fenix.helpers.click
import org.mozilla.fenix.helpers.ext.waitNotNull import org.mozilla.fenix.helpers.ext.waitNotNull
import org.mozilla.fenix.components.Search
import org.mozilla.fenix.helpers.withBitmapDrawable
import org.mozilla.fenix.helpers.matchers.hasItem import org.mozilla.fenix.helpers.matchers.hasItem
import org.mozilla.fenix.helpers.withBitmapDrawable
/** /**
* Implementation of Robot Pattern for the home screen menu. * Implementation of Robot Pattern for the home screen menu.
@ -168,7 +170,8 @@ class HomeScreenRobot {
fun swipeToBottom() = onView(withId(R.id.homeLayout)).perform(ViewActions.swipeUp()) fun swipeToBottom() = onView(withId(R.id.homeLayout)).perform(ViewActions.swipeUp())
fun swipeToTop() = onView(withId(R.id.sessionControlRecyclerView)).perform(ViewActions.swipeDown()) fun swipeToTop() =
onView(withId(R.id.sessionControlRecyclerView)).perform(ViewActions.swipeDown())
fun swipeTabRight(title: String) = fun swipeTabRight(title: String) =
onView(allOf(withId(R.id.tab_title), withText(title))).perform(ViewActions.swipeRight()) onView(allOf(withId(R.id.tab_title), withText(title))).perform(ViewActions.swipeRight())
@ -185,10 +188,21 @@ class HomeScreenRobot {
fun snackBarButtonClick(expectedText: String) { fun snackBarButtonClick(expectedText: String) {
onView(allOf(withId(R.id.snackbar_btn), withText(expectedText))).check( onView(allOf(withId(R.id.snackbar_btn), withText(expectedText))).check(
matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)) matches(withEffectiveVisibility(Visibility.VISIBLE))
).perform(ViewActions.click()) ).perform(click())
} }
fun verifyTabMediaControlButtonState(action: String) {
mDevice.waitNotNull(
Until.findObject(By.res("org.mozilla.fenix.debug:id/play_pause_button")),
waitingTime
)
tabMediaControlButton().check(matches(withContentDescription(action)))
}
fun clickTabMediaControlButton() = tabMediaControlButton().click()
class Transition { class Transition {
val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
@ -242,16 +256,25 @@ class HomeScreenRobot {
return NavigationToolbarRobot.Transition() return NavigationToolbarRobot.Transition()
} }
fun openContextMenuOnTopSitesWithTitle(title: String, interact: HomeScreenRobot.() -> Unit): Transition { fun openContextMenuOnTopSitesWithTitle(
title: String,
interact: HomeScreenRobot.() -> Unit
): Transition {
onView(withId(R.id.top_sites_list)).perform( onView(withId(R.id.top_sites_list)).perform(
actionOnItem<RecyclerView.ViewHolder>(hasDescendant(withText(title)), ViewActions.longClick()) actionOnItem<RecyclerView.ViewHolder>(
hasDescendant(withText(title)),
ViewActions.longClick()
)
) )
HomeScreenRobot().interact() HomeScreenRobot().interact()
return Transition() return Transition()
} }
fun openTopSiteTabWithTitle(title: String, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { fun openTopSiteTabWithTitle(
title: String,
interact: BrowserRobot.() -> Unit
): BrowserRobot.Transition {
onView(withId(R.id.top_sites_list)).perform( onView(withId(R.id.top_sites_list)).perform(
actionOnItem<RecyclerView.ViewHolder>(hasDescendant(withText(title)), click()) actionOnItem<RecyclerView.ViewHolder>(hasDescendant(withText(title)), click())
) )
@ -280,7 +303,20 @@ class HomeScreenRobot {
fun openCommonMythsLink(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { fun openCommonMythsLink(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition {
onView(withId(R.id.private_session_common_myths)) onView(withId(R.id.private_session_common_myths))
.perform(click()) .perform(click())
BrowserRobot().interact()
return BrowserRobot.Transition()
}
fun openTab(title: String, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition {
mDevice.waitNotNull(findObject(text(title)))
onView(
allOf(
withId(R.id.tab_title),
withText(title)
)
).click()
BrowserRobot().interact() BrowserRobot().interact()
return BrowserRobot.Transition() return BrowserRobot.Transition()
@ -355,12 +391,12 @@ private fun assertCollectionsHeaderIsNotVisible() =
.check(doesNotExist()) .check(doesNotExist())
private fun assertNoCollectionsText() = private fun assertNoCollectionsText() =
onView( onView(
allOf( allOf(
withText("Collect the things that matter to you. To start, save open tabs to a new collection.") withText("Collect the things that matter to you. To start, save open tabs to a new collection.")
)
) )
.check(matches(withEffectiveVisibility(Visibility.VISIBLE))) )
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
private fun assertNoCollectionsTextIsNotVisible() = private fun assertNoCollectionsTextIsNotVisible() =
onView( onView(
@ -370,8 +406,9 @@ private fun assertNoCollectionsTextIsNotVisible() =
) )
.check(doesNotExist()) .check(doesNotExist())
private fun assertHomeComponent() = onView(ViewMatchers.withResourceName("sessionControlRecyclerView")) private fun assertHomeComponent() =
.check(matches(withEffectiveVisibility(Visibility.VISIBLE))) onView(ViewMatchers.withResourceName("sessionControlRecyclerView"))
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
private fun threeDotButton() = onView(allOf(withId(R.id.menuButton))) private fun threeDotButton() = onView(allOf(withId(R.id.menuButton)))
@ -485,10 +522,10 @@ private fun assertPrivacyNoticeButton() =
// What's new elements // What's new elements
private fun assertWhatsNewHeather() = onView(allOf(withText("See whats new"))) private fun assertWhatsNewHeather() = onView(allOf(withText("See whats new")))
.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) .check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
private fun assertWhatsNewLink() = onView(allOf(withText("Get answers here"))) private fun assertWhatsNewLink() = onView(allOf(withText("Get answers here")))
.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) .check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
private fun assertStartBrowsingButton() = private fun assertStartBrowsingButton() =
onView(allOf(withText("Start browsing"))) onView(allOf(withText("Start browsing")))
@ -496,18 +533,20 @@ private fun assertStartBrowsingButton() =
// Take a position // Take a position
private fun assertTakePositionheader() = onView(allOf(withText("Take a position"))) private fun assertTakePositionheader() = onView(allOf(withText("Take a position")))
.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) .check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
private fun assertTakePositionTopRadioButton() = onView(ViewMatchers.withResourceName("toolbar_top_radio_button")) private fun assertTakePositionTopRadioButton() =
onView(ViewMatchers.withResourceName("toolbar_top_radio_button"))
.check(matches(withEffectiveVisibility(Visibility.VISIBLE))) .check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
private fun assertTakePositionBottomRadioButton() = onView(ViewMatchers.withResourceName("toolbar_bottom_radio_button")) private fun assertTakePositionBottomRadioButton() =
onView(ViewMatchers.withResourceName("toolbar_bottom_radio_button"))
.check(matches(withEffectiveVisibility(Visibility.VISIBLE))) .check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
// Private mode elements // Private mode elements
private fun assertPrivateSessionHeader() = private fun assertPrivateSessionHeader() =
onView(allOf(withText("Private tabs"))) onView(allOf(withText("Private tabs")))
.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) .check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
const val PRIVATE_SESSION_MESSAGE = "Firefox Preview clears your search and browsing history " + const val PRIVATE_SESSION_MESSAGE = "Firefox Preview clears your search and browsing history " +
"when you quit the app or close all private tabs. While this doesnt make you anonymous to websites or " + "when you quit the app or close all private tabs. While this doesnt make you anonymous to websites or " +
@ -521,9 +560,11 @@ private fun assertPrivateSessionMessage(visible: Boolean) =
) )
private fun assertShareTabsButton(visible: Boolean) = onView(allOf(withId(R.id.share_tabs_button))) private fun assertShareTabsButton(visible: Boolean) = onView(allOf(withId(R.id.share_tabs_button)))
.check( .check(
if (visible) matches(withEffectiveVisibility(Visibility.VISIBLE)) else matches(withEffectiveVisibility(Visibility.INVISIBLE)) if (visible) matches(withEffectiveVisibility(Visibility.VISIBLE)) else matches(
withEffectiveVisibility(Visibility.INVISIBLE)
) )
)
private fun assertCloseTabsButton(title: String) = private fun assertCloseTabsButton(title: String) =
onView(allOf(withId(R.id.close_tab_button), withContentDescription("Close tab $title"))) onView(allOf(withId(R.id.close_tab_button), withContentDescription("Close tab $title")))
@ -588,3 +629,5 @@ private fun assertTopSiteContextMenuItems() {
waitingTime waitingTime
) )
} }
private fun tabMediaControlButton() = onView(withId(R.id.play_pause_button))

@ -0,0 +1,83 @@
package org.mozilla.fenix.ui.robots
import android.content.res.Resources
import androidx.test.uiautomator.By.text
import androidx.test.uiautomator.UiScrollable
import androidx.test.uiautomator.UiSelector
import androidx.test.uiautomator.Until
import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime
import org.mozilla.fenix.helpers.ext.waitNotNull
class NotificationRobot {
fun verifySystemNotificationExists(notificationMessage: String) {
fun notificationTray() = UiScrollable(
UiSelector().resourceId("com.android.systemui:id/notification_stack_scroller")
)
mDevice.waitNotNull(
Until.hasObject(text(notificationMessage)),
waitingTime
)
var notificationFound = false
while (!notificationFound) {
try {
val notification = notificationTray().getChildByText(
UiSelector().text(notificationMessage), notificationMessage,
true
)
notification.exists()
notificationFound = true
} catch (e: Resources.NotFoundException) {
e.printStackTrace()
}
}
}
fun verifyPrivateTabsNotification() {
mDevice.waitNotNull(Until.hasObject(text("Close private tabs")), waitingTime)
assertPrivateTabsNotification()
}
fun clickMediaSystemNotificationControlButton(action: String) {
mediaSystemNotificationButton(action).waitForExists(waitingTime)
mediaSystemNotificationButton(action).click()
}
fun verifyMediaSystemNotificationButtonState(action: String) {
mediaSystemNotificationButton(action).waitForExists(waitingTime)
}
class Transition {
fun clickClosePrivateTabsNotification(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition {
NotificationRobot().verifySystemNotificationExists("Close private tabs")
closePrivateTabsNotification().clickAndWaitForNewWindow()
HomeScreenRobot().interact()
return HomeScreenRobot.Transition()
}
}
}
fun notificationShade(interact: NotificationRobot.() -> Unit): NotificationRobot.Transition {
NotificationRobot().interact()
return NotificationRobot.Transition()
}
private fun assertPrivateTabsNotification() {
mDevice.findObject(UiSelector().text("Firefox Preview (Private)")).exists()
mDevice.findObject(UiSelector().text("Close private tabs")).exists()
}
private fun closePrivateTabsNotification() =
mDevice.findObject(UiSelector().text("Close private tabs"))
private fun mediaSystemNotificationButton(action: String) =
mDevice.findObject(
UiSelector()
.resourceId("android:id/action0")
.descriptionContains(action)
)
Loading…
Cancel
Save