1
0
Fork 0

Closes #8006: Add Close/Undo UI tests (#8007)

master
Aaron Train 2020-01-30 16:15:40 -05:00 committed by GitHub
parent f728cdaf05
commit 89cc5657ce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 144 additions and 145 deletions

View File

@ -110,7 +110,6 @@ class HomeScreenTest {
verifyHomeWordmark()
verifyAddTabButton()
verifyShareTabsButton(visible = false)
verifyCloseTabsButton(visible = false)
verifyPrivateSessionHeader()
verifyPrivateSessionMessage(visible = true)
verifyHomeToolbar()
@ -130,7 +129,6 @@ class HomeScreenTest {
verifyHomeWordmark()
verifyAddTabButton()
verifyShareTabsButton(visible = true)
verifyCloseTabsButton(visible = true)
verifyPrivateSessionHeader()
verifyPrivateSessionMessage(visible = false)
verifyHomeToolbar()

View File

@ -28,8 +28,10 @@ import org.mozilla.fenix.ui.robots.navigationToolbar
* - Opening a private tab
* - Verifying tab list
* - Closing all tabs
* - Close tab
* - Swipe to close tab
* - Undo close tab
*
* TODO: Tab Collections
*/
class TabbedBrowsingTest {
@ -76,7 +78,10 @@ class TabbedBrowsingTest {
homeScreen {
// Timing issue on slow devices on Firebase
mDevice.waitNotNull(Until.findObjects(By.res("org.mozilla.fenix.debug:id/item_tab")), TestAssetHelper.waitingTime)
mDevice.waitNotNull(
Until.findObjects(By.res("org.mozilla.fenix.debug:id/item_tab")),
TestAssetHelper.waitingTime
)
verifyExistingTabList()
}.openTabsListThreeDotMenu {
@ -106,10 +111,13 @@ class TabbedBrowsingTest {
verifyTabCounter("1")
}.openHomeScreen {
// Timing issue on slow devices on Firebase
mDevice.waitNotNull(Until.findObjects(By.res("org.mozilla.fenix.debug:id/item_tab")), TestAssetHelper.waitingTime)
mDevice.waitNotNull(
Until.findObjects(By.res("org.mozilla.fenix.debug:id/item_tab")),
TestAssetHelper.waitingTime
)
verifyExistingTabList()
verifyShareTabsButton(true)
verifyCloseTabsButton(true)
verifyCloseTabsButton("Test_Page_1")
}.togglePrivateBrowsingMode()
// Verify private tabs remain in private browsing mode
@ -135,7 +143,10 @@ class TabbedBrowsingTest {
homeScreen {
// Timing issue on slow devices on Firebase
mDevice.waitNotNull(Until.findObjects(By.res("org.mozilla.fenix.debug:id/item_tab")), TestAssetHelper.waitingTime)
mDevice.waitNotNull(
Until.findObjects(By.res("org.mozilla.fenix.debug:id/item_tab")),
TestAssetHelper.waitingTime
)
verifyExistingTabList()
}.openTabsListThreeDotMenu {
verifyCloseAllTabsButton()
@ -147,5 +158,59 @@ class TabbedBrowsingTest {
verifyNoTabsOpenedHeader()
verifyNoTabsOpenedText()
}
// Repeat for Private Tabs
homeScreen {
}.togglePrivateBrowsingMode()
navigationToolbar {
}.enterURLAndEnterToBrowser(defaultWebPage.url) {
verifyPageContent(defaultWebPage.content)
}.openHomeScreen { }
homeScreen {
// Timing issue on slow devices on Firebase
mDevice.waitNotNull(
Until.findObjects(By.res("org.mozilla.fenix.debug:id/item_tab")),
TestAssetHelper.waitingTime
)
verifyExistingTabList()
verifyPrivateTabsCloseTabsButton()
}.closeAllPrivateTabs {
verifyPrivateSessionHeader()
verifyPrivateSessionMessage(true)
}
}
@Test
fun closeTabTest() {
var genericURLS = TestAssetHelper.getGenericAssets(mockWebServer)
genericURLS.forEachIndexed { index, element ->
navigationToolbar {
}.openNewTabAndEnterToBrowser(element.url) {
verifyPageContent(element.content)
}.openHomeScreen { }
homeScreen {
verifyExistingOpenTabs("Test_Page_${index + 1}")
verifyCloseTabsButton("Test_Page_${index + 1}")
closeTabViaXButton("Test_Page_${index + 1}")
verifySnackBarText("Tab closed")
snackBarButtonClick("UNDO")
verifyExistingOpenTabs("Test_Page_${index + 1}")
verifyCloseTabsButton("Test_Page_${index + 1}")
swipeTabRight("Test_Page_${index + 1}")
verifySnackBarText("Tab closed")
snackBarButtonClick("UNDO")
verifyExistingOpenTabs("Test_Page_${index + 1}")
verifyCloseTabsButton("Test_Page_${index + 1}")
swipeTabLeft("Test_Page_${index + 1}")
verifySnackBarText("Tab closed")
snackBarButtonClick("UNDO")
verifyExistingOpenTabs("Test_Page_${index + 1}")
verifyCloseTabsButton("Test_Page_${index + 1}")
}
}
}
}

View File

@ -1,122 +0,0 @@
/* 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 androidx.test.platform.app.InstrumentationRegistry
import androidx.test.uiautomator.UiDevice
import okhttp3.mockwebserver.MockWebServer
import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.junit.Before
import org.junit.After
import org.mozilla.fenix.helpers.AndroidAssetDispatcher
import org.mozilla.fenix.helpers.HomeActivityTestRule
import org.mozilla.fenix.helpers.TestAssetHelper
import org.mozilla.fenix.ui.robots.homeScreen
import org.mozilla.fenix.ui.robots.navigationToolbar
/**
* Tests for verifying basic functionality of tabs
*
*/
class TabsTest {
/* ktlint-disable no-blank-line-before-rbrace */ // This imposes unreadable grouping.
private val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
private lateinit var mockWebServer: MockWebServer
@get:Rule
val activityTestRule = HomeActivityTestRule()
@Before
fun setUp() {
mockWebServer = MockWebServer().apply {
setDispatcher(AndroidAssetDispatcher())
start()
}
}
@After
fun tearDown() {
mockWebServer.shutdown()
}
@Ignore("This is a stub test, ignore for now")
@Test
fun tabsItemsTest() {
homeScreen { }.dismissOnboarding()
// Setup browser so that tabs are visible in UI
// Verify all tabs elements are visible:
// "open tabs header, + button, etc.
// Verify tabs 3-dot menu elements
}
@Ignore("This is a stub test, ignore for now")
@Test
fun noTabsInCacheTest() {
// Verify open tabs header and text exists (when no previous browsing)
// Verify + button redirects to navigation bar UI
// Verify "Collections" header exists
// Verify "No collections" text (when no previous browsing)
}
@Ignore("This is a stub test, ignore for now")
@Test
fun browsingWithTabsTest() {
// Setup:
// - Verify + button redirects to navigation bar UI
// - Enter mock website via navigation bar
// Verify "Open tabs" header exits
// Verify Collections header exits
// Verify that tabs counter is augmented by 1 count
// Click on tabs counter
// Verify that new page is listed in "Open tabs"
// Repeat for several sites
}
@Ignore("This is a stub test, ignore for now")
@Test
fun tabsThreeDotMenuTest() {
// short 3-dot menu setup:
// - create multiple tabs (using mock web server) for the following...
// Verify tabs 3-dot menu functions:
// 1. "Close all tabs"
// 2. "Share tabs" - opens share sub-menu
// 3. "Save to collection" - verify saved to collection
// NOTE: extended 3 dot menu test is verified in a separate class
}
@Ignore("This is a stub test, ignore for now")
@Test
fun collectionsTest() {
// Setup:
// - create multiple tabs (using mock web server) for the following...
// Verify collections header exits
// Verify multiple collections can be saved, named
// Verify "Select tabs to save"
// Verify collections dropdown toggle
// Verify send and share button works - opens share menu
// Verify collections 3-dot menu functions:
// 1. Delete collection
// 2. Rename collection
// 3. Open tabs
}
@Ignore("This is a sample test, ignore")
@Test
fun sampleTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
navigationToolbar {
}.enterURLAndEnterToBrowser(defaultWebPage.url) {
}
}
}

View File

@ -14,23 +14,25 @@ import androidx.test.espresso.assertion.ViewAssertions.doesNotExist
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.contrib.RecyclerViewActions
import androidx.test.espresso.matcher.ViewMatchers
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.Visibility
import androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility
import androidx.test.espresso.matcher.ViewMatchers.withText
import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.espresso.matcher.ViewMatchers.withText
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.uiautomator.Until
import androidx.test.uiautomator.By
import androidx.test.uiautomator.UiDevice
import androidx.test.uiautomator.UiScrollable
import androidx.test.uiautomator.UiSelector
import androidx.test.uiautomator.Until
import org.hamcrest.CoreMatchers
import org.hamcrest.Matchers.allOf
import org.hamcrest.Matchers.containsString
import org.mozilla.fenix.R
import org.mozilla.fenix.helpers.click
import org.mozilla.fenix.helpers.TestAssetHelper
import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime
import org.mozilla.fenix.helpers.click
import org.mozilla.fenix.helpers.ext.waitNotNull
/**
@ -80,8 +82,11 @@ class HomeScreenRobot {
// Private mode elements
fun verifyPrivateSessionHeader() = assertPrivateSessionHeader()
fun verifyPrivateSessionMessage(visible: Boolean = true) = assertPrivateSessionMessage(visible)
fun verifyPrivateTabsCloseTabsButton() = assertPrivateTabsCloseTabsButton()
fun verifyShareTabsButton(visible: Boolean = true) = assertShareTabsButton(visible)
fun verifyCloseTabsButton(visible: Boolean = true) = assertCloseTabsButton(visible)
fun verifyCloseTabsButton(title: String) =
assertCloseTabsButton(title)
fun verifyExistingTabList() = assertExistingTabList()
fun verifyExistingOpenTabs(title: String) = assertExistingOpenTabs(title)
@ -91,29 +96,35 @@ class HomeScreenRobot {
collectionThreeDotButton().click()
mDevice.waitNotNull(Until.findObject(By.text("Delete collection")), waitingTime)
}
fun selectRenameCollection() {
onView(allOf(ViewMatchers.withText("Rename collection"))).click()
mDevice.waitNotNull(Until.findObject(By.res("name_collection_edittext")))
}
fun selectDeleteCollection() {
onView(allOf(ViewMatchers.withText("Delete collection"))).click()
mDevice.waitNotNull(Until.findObject(By.res("message")), waitingTime)
}
fun confirmDeleteCollection() {
onView(allOf(ViewMatchers.withText("DELETE"))).click()
mDevice.waitNotNull(Until.findObject(By.res("collections_header")), waitingTime)
}
fun typeCollectionName(name: String) {
mDevice.wait(Until.findObject(By.res("name_collection_edittext")), waitingTime)
collectionNameTextField().perform(ViewActions.replaceText(name))
collectionNameTextField().perform(ViewActions.pressImeActionButton())
}
fun scrollToElementByText(text: String): UiScrollable {
val appView = UiScrollable(UiSelector().scrollable(true))
appView.scrollTextIntoView(text)
return appView
}
fun swipeUpToDismissFirstRun() {
scrollToElementByText("Start browsing")
}
@ -124,12 +135,31 @@ class HomeScreenRobot {
fun togglePrivateBrowsingModeOnOff() {
onView(ViewMatchers.withResourceName("privateBrowsingButton"))
.perform(click())
.perform(click())
}
fun swipeToBottom() = onView(ViewMatchers.withId(R.id.home_component)).perform(ViewActions.swipeUp())
fun swipeToBottom() = onView(withId(R.id.home_component)).perform(ViewActions.swipeUp())
fun swipeToTop() = onView(ViewMatchers.withId(R.id.home_component)).perform(ViewActions.swipeDown())
fun swipeToTop() = onView(withId(R.id.home_component)).perform(ViewActions.swipeDown())
fun swipeTabRight(title: String) =
onView(allOf(withId(R.id.tab_title), withText(title))).perform(ViewActions.swipeRight())
fun swipeTabLeft(title: String) =
onView(allOf(withId(R.id.tab_title), withText(title))).perform(ViewActions.swipeLeft())
fun closeTabViaXButton(title: String) = closeTabViaX(title)
fun verifySnackBarText(expectedText: String) {
val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
mDevice.waitNotNull(Until.findObject(By.text(expectedText)), TestAssetHelper.waitingTime)
}
fun snackBarButtonClick(expectedText: String) {
onView(CoreMatchers.allOf(withId(R.id.snackbar_btn), withText(expectedText))).check(
matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))
).perform(ViewActions.click())
}
class Transition {
val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
@ -167,6 +197,15 @@ class HomeScreenRobot {
ThreeDotMenuMainRobot().interact()
return ThreeDotMenuMainRobot.Transition()
}
fun closeAllPrivateTabs(interact: HomeScreenRobot.() -> Unit): Transition {
onView(withId(R.id.close_tabs_button))
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
.perform(click())
HomeScreenRobot().interact()
return Transition()
}
}
}
@ -322,8 +361,13 @@ private fun assertYourPrivacyHeader() =
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
private fun assertYourPrivacyText() =
onView(CoreMatchers.allOf(withText(
"Weve designed Firefox Preview to give you control over what you share online and what you share with us.")))
onView(
CoreMatchers.allOf(
withText(
"Weve designed Firefox Preview to give you control over what you share online and what you share with us."
)
)
)
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
private fun assertPrivacyNoticeButton() =
@ -337,7 +381,7 @@ private fun assertStartBrowsingButton() =
// Private mode elements
private fun assertPrivateSessionHeader() =
onView(CoreMatchers.allOf(withText("Private tabs")))
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
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 " +
@ -354,11 +398,12 @@ private fun assertShareTabsButton(visible: Boolean) =
onView(CoreMatchers.allOf(withId(R.id.share_tabs_button), isDisplayed()))
.check(matches(withEffectiveVisibility(visibleOrGone(visible))))
private fun assertCloseTabsButton(visible: Boolean) =
onView(CoreMatchers.allOf(withId(R.id.close_tab_button), isDisplayed()))
.check(matches(withEffectiveVisibility(visibleOrGone(visible))))
private fun assertCloseTabsButton(title: String) =
onView(allOf(withId(R.id.close_tab_button), withContentDescription("Close tab $title")))
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
private fun visibleOrGone(visibility: Boolean) = if (visibility) Visibility.VISIBLE else Visibility.GONE
private fun visibleOrGone(visibility: Boolean) =
if (visibility) Visibility.VISIBLE else Visibility.GONE
private fun assertExistingTabList() =
onView(CoreMatchers.allOf(withId(R.id.item_tab)))
@ -375,4 +420,17 @@ private fun tabsListThreeDotButton() = onView(allOf(withId(R.id.tabs_overflow_bu
private fun collectionThreeDotButton() = onView(allOf(withId(R.id.collection_overflow_button)))
private fun collectionNameTextField() = onView(allOf(ViewMatchers.withResourceName("name_collection_edittext")))
private fun collectionNameTextField() =
onView(allOf(ViewMatchers.withResourceName("name_collection_edittext")))
private fun closeTabViaX(title: String) {
val closeButton = onView(
allOf(
withId(R.id.close_tab_button),
withContentDescription("Close tab $title")
)
)
closeButton.perform(click())
}
private fun assertPrivateTabsCloseTabsButton() = onView(allOf(withId(R.id.close_tabs_button)))