History menu UI tests (#6272)

Removed failing verifyOverflowMenuButton method

Added new Robot for MultipleSelectionTooolbar

Renamed MultipleSelectionToolbarRobot to LibrarySubMenusMultipleSelectionToolbarRobot
nightly-build-test
Oana Horvath 5 years ago committed by GitHub
parent 905c7856fb
commit 7813fb22d4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -4,6 +4,10 @@
package org.mozilla.fenix.helpers package org.mozilla.fenix.helpers
import android.net.Uri
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions.longClick
import androidx.test.espresso.matcher.ViewMatchers.withText
import androidx.test.uiautomator.UiScrollable import androidx.test.uiautomator.UiScrollable
import androidx.test.uiautomator.UiSelector import androidx.test.uiautomator.UiSelector
@ -13,4 +17,8 @@ object TestHelper {
appView.scrollTextIntoView(text) appView.scrollTextIntoView(text)
return appView return appView
} }
fun longTapSelectItem(url: Uri) {
onView(withText(url.toString())).perform(longClick())
}
} }

@ -4,29 +4,29 @@
package org.mozilla.fenix.ui package org.mozilla.fenix.ui
import androidx.test.platform.app.InstrumentationRegistry import android.content.Context
import androidx.test.uiautomator.UiDevice import androidx.test.espresso.Espresso.openActionBarOverflowOrOptionsMenu
import kotlinx.coroutines.runBlocking
import mozilla.components.browser.storage.sync.PlacesHistoryStorage
import okhttp3.mockwebserver.MockWebServer import okhttp3.mockwebserver.MockWebServer
import org.junit.After import org.junit.After
import org.junit.Before import org.junit.Before
import org.junit.Ignore
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test
import org.mozilla.fenix.helpers.AndroidAssetDispatcher import org.mozilla.fenix.helpers.AndroidAssetDispatcher
import org.mozilla.fenix.helpers.HomeActivityTestRule import org.mozilla.fenix.helpers.HomeActivityTestRule
import org.mozilla.fenix.helpers.TestAssetHelper import org.mozilla.fenix.helpers.TestAssetHelper
import org.mozilla.fenix.helpers.TestHelper.longTapSelectItem
import org.mozilla.fenix.ui.robots.homeScreen import org.mozilla.fenix.ui.robots.homeScreen
import org.mozilla.fenix.ui.robots.multipleSelectionToolbar
import org.mozilla.fenix.ui.robots.navigationToolbar import org.mozilla.fenix.ui.robots.navigationToolbar
/** /**
* Tests for verifying basic functionality of history * Tests for verifying basic functionality of history
* *
*/ */
class HistoryTest { class HistoryTest {
/* ktlint-disable no-blank-line-before-rbrace */ // This imposes unreadable grouping. /* ktlint-disable no-blank-line-before-rbrace */ // This imposes unreadable grouping.
private val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
private lateinit var mockWebServer: MockWebServer private lateinit var mockWebServer: MockWebServer
@get:Rule @get:Rule
@ -43,52 +43,208 @@ class HistoryTest {
@After @After
fun tearDown() { fun tearDown() {
mockWebServer.shutdown() mockWebServer.shutdown()
// Clearing all history data after each test to avoid overlapping data
val applicationContext: Context = activityTestRule.activity.applicationContext
val historyStorage = PlacesHistoryStorage(applicationContext)
runBlocking {
historyStorage.deleteEverything()
}
} }
@Ignore("This is a stub test, ignore for now")
@Test @Test
fun noHistoryItemsInCacheTest() { fun noHistoryItemsInCacheTest() {
homeScreen { }.dismissOnboarding() homeScreen {
}.openThreeDotMenu {
verifyLibraryButton()
}.openLibrary {
verifyHistoryButton()
}.openHistory {
verifyHistoryMenuView()
verifyEmptyHistoryView()
}
}
@Test
fun visitedUrlHistoryTest() {
val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
navigationToolbar {
}.enterURLAndEnterToBrowser(firstWebPage.url) {
}.openHomeScreen {
}.openThreeDotMenu {
}.openLibrary {
}.openHistory {
verifyHistoryMenuView()
verifyVisitedTimeTitle()
verifyFirstTestPageTitle("Test_Page_1")
verifyTestPageUrl(firstWebPage.url)
}
}
@Test
fun deleteHistoryItemTest() {
val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
navigationToolbar {
}.enterURLAndEnterToBrowser(firstWebPage.url) {
}.openHomeScreen {
}.openThreeDotMenu {
}.openLibrary {
}.openHistory {
openOverflowMenu()
clickThreeDotMenuDelete()
verifyEmptyHistoryView()
}
}
@Test
fun deleteAllHistoryTest() {
val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
navigationToolbar {
}.enterURLAndEnterToBrowser(firstWebPage.url) {
}.openHomeScreen {
}.openThreeDotMenu {
}.openLibrary {
}.openHistory {
clickDeleteHistoryButton()
verifyDeleteConfirmationMessage()
confirmDeleteAllHistory()
verifyEmptyHistoryView()
}
}
@Test
fun multiSelectionToolbarItemsTest() {
val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
navigationToolbar {
}.enterURLAndEnterToBrowser(firstWebPage.url) {
}.openHomeScreen {
}.openThreeDotMenu {
}.openLibrary {
}.openHistory {
longTapSelectItem(firstWebPage.url)
}
// Verify "Your Library" in 3-dot menu is visible multipleSelectionToolbar {
// Verify "History" line-item in library is visible verifyMultiSelectionCheckmark()
// Verify "No history here" is visible verifyMultiSelectionCounter()
// Verify "History" UI elements verifyShareButton()
verifyCloseToolbarButton()
}.closeToolbarReturnToHistory {
verifyHistoryMenuView()
}
}
@Test
fun openHistoryInNewTabTest() {
val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
navigationToolbar {
}.enterURLAndEnterToBrowser(firstWebPage.url) {
}.openHomeScreen {
closeTab()
}.openThreeDotMenu {
}.openLibrary {
}.openHistory {
longTapSelectItem(firstWebPage.url)
openActionBarOverflowOrOptionsMenu(activityTestRule.getActivity())
}
multipleSelectionToolbar {
}.clickOpenNewTab {
verifyExistingTabList()
verifyOpenTabsHeader()
}
} }
@Ignore("This is a stub test, ignore for now")
@Test @Test
fun historyTest() { fun openHistoryInPrivateTabTest() {
// Setup: val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
// - Visit a URL
// - Visit a second URL
// Verify browser view exists for each visit
// Verify "Your Library" in 3-dot menu is visible
// Click "Your Library"
// Verify "History" line-item in Library is visible
// Click "History"
// Verify "History" UI elements (view is visible)
// Verify history is added, URLs match history added in Library
// Verify history 3-dot menu functions: navigationToolbar {
// 1. Delete }.enterURLAndEnterToBrowser(firstWebPage.url) {
}.openHomeScreen {
}.openThreeDotMenu {
}.openLibrary {
}.openHistory {
longTapSelectItem(firstWebPage.url)
openActionBarOverflowOrOptionsMenu(activityTestRule.getActivity())
}
multipleSelectionToolbar {
}.clickOpenPrivateTab {
verifyExistingTabList()
verifyPrivateSessionHeader()
}
}
// Verify history visibility in new URL search @Test
fun deleteMultipleSelectionTest() {
val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
val secondWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 2)
// Verify "Delete history" navigationToolbar {
// Verify "This will delete all your browsing data." }.enterURLAndEnterToBrowser(firstWebPage.url) {
// Verify "No history here" UI element }.openNavigationToolbar {
}.enterURLAndEnterToBrowser(secondWebPage.url) {
}.openHomeScreen {
}.openThreeDotMenu {
}.openLibrary {
}.openHistory {
longTapSelectItem(firstWebPage.url)
longTapSelectItem(secondWebPage.url)
openActionBarOverflowOrOptionsMenu(activityTestRule.getActivity())
}
// Verify return to "Your Library" multipleSelectionToolbar {
}.clickMultiSelectionDelete {
verifyEmptyHistoryView()
}
} }
@Ignore("This is a sample test, ignore")
@Test @Test
fun sampleTest() { fun shareButtonTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
navigationToolbar { navigationToolbar {
}.enterURLAndEnterToBrowser(defaultWebPage.url) { }.enterURLAndEnterToBrowser(firstWebPage.url) {
}.openHomeScreen {
}.openThreeDotMenu {
}.openLibrary {
}.openHistory {
longTapSelectItem(firstWebPage.url)
}
multipleSelectionToolbar {
clickShareButton()
verifyShareOverlay()
verifyShareTabFavicon()
verifyShareTabTitle()
verifyShareTabUrl()
}
}
@Test
fun verifyBackNavigation() {
homeScreen {
}.openThreeDotMenu {
}.openLibrary {
}.openHistory {
}.goBack {
verifyLibraryView()
}
}
@Test
fun verifyCloseMenu() {
homeScreen {
}.openThreeDotMenu {
}.openLibrary {
}.openHistory {
}.closeMenu {
verifyHomeScreen()
} }
} }
} }

@ -1,20 +1,60 @@
/* 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 package org.mozilla.fenix.ui.robots
import android.net.Uri
import androidx.test.espresso.Espresso.onView import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.assertion.ViewAssertions import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.matcher.ViewMatchers.withText import androidx.test.espresso.matcher.RootMatchers.isDialog
import androidx.test.espresso.matcher.ViewMatchers.withParent import androidx.test.espresso.matcher.ViewMatchers
import androidx.test.espresso.matcher.ViewMatchers.withId import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
import androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility
import androidx.test.espresso.matcher.ViewMatchers.Visibility
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.withId
import androidx.test.espresso.matcher.ViewMatchers.withParent
import androidx.test.espresso.matcher.ViewMatchers.withText
import org.hamcrest.Matchers
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.click import org.mozilla.fenix.helpers.click
/**
* Implementation of Robot Pattern for the history menu.
*/
class HistoryRobot { class HistoryRobot {
fun verifyHistoryMenuView() = assertHistoryView() fun verifyHistoryMenuView() = assertHistoryMenuView()
fun verifyEmptyHistoryView() = assertEmptyHistoryView()
fun verifyVisitedTimeTitle() = assertVisitedTimeTitle()
fun verifyFirstTestPageTitle(title: String) = assertTestPageTitle(title)
fun verifyTestPageUrl(expectedUrl: Uri) = assertPageUrl(expectedUrl)
fun verifyDeleteConfirmationMessage() = assertDeleteConfirmationMessage()
fun openOverflowMenu() {
overflowMenu().click()
}
fun clickThreeDotMenuDelete() {
threeDotMenuDeleteButton().click()
}
fun clickDeleteHistoryButton() {
deleteAllHistoryButton().click()
}
fun confirmDeleteAllHistory() {
onView(withText("Delete"))
.inRoot(isDialog())
.check(matches(isDisplayed()))
.click()
}
class Transition { class Transition {
fun goBack(interact: LibraryRobot.() -> Unit): LibraryRobot.Transition { fun goBack(interact: LibraryRobot.() -> Unit): LibraryRobot.Transition {
@ -23,17 +63,58 @@ class HistoryRobot {
LibraryRobot().interact() LibraryRobot().interact()
return LibraryRobot.Transition() return LibraryRobot.Transition()
} }
fun closeMenu(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition {
closeButton().click()
HomeScreenRobot().interact()
return HomeScreenRobot.Transition()
}
} }
} }
fun historyMenu(interact: HistoryRobot.() -> Unit): HistoryRobot.Transition { private fun goBackButton() = onView(withContentDescription("Navigate up"))
HistoryRobot().interact()
return HistoryRobot.Transition() private fun testPageTitle() = onView(allOf(withId(R.id.title), withText("Test_Page_1")))
}
private fun pageUrl() = onView(withId(R.id.url))
private fun assertHistoryView() { private fun overflowMenu() = onView(withId(R.id.overflow_menu))
onView(allOf(withText("History"), withParent(withId(R.id.navigationToolbar))))
.check(ViewAssertions.matches(withEffectiveVisibility(Visibility.VISIBLE))) private fun threeDotMenuDeleteButton() = onView(withId(R.id.simple_text))
private fun deleteAllHistoryButton() = onView(withId(R.id.delete_button))
private fun assertHistoryMenuView() {
onView(
allOf(withText("History"), withParent(withId(R.id.navigationToolbar)))
)
.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
} }
private fun goBackButton() = onView(withContentDescription("Navigate up")) private fun assertEmptyHistoryView() =
onView(
allOf(
withId(R.id.history_empty_view),
withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)
)
)
.check(matches(withText("No history here")))
private fun assertVisitedTimeTitle() =
onView(withId(R.id.header_title)).check(matches(withText("Last 24 hours")))
private fun assertTestPageTitle(title: String) = testPageTitle()
.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
.check(matches(withText(title)))
private fun assertPageUrl(expectedUrl: Uri) = pageUrl()
.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
.check(matches(withText(Matchers.containsString(expectedUrl.toString()))))
private fun assertDeleteConfirmationMessage() =
onView(withText("This will delete all of your browsing data."))
.inRoot(isDialog())
.check(matches(isDisplayed()))
private fun closeButton() = onView(withId(R.id.libraryClose))

@ -16,6 +16,8 @@ import androidx.test.espresso.matcher.ViewMatchers.Visibility
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
import androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility import androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility
import androidx.test.espresso.matcher.ViewMatchers.hasFocus import androidx.test.espresso.matcher.ViewMatchers.hasFocus
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.Until import androidx.test.uiautomator.Until
import androidx.test.uiautomator.By import androidx.test.uiautomator.By
@ -26,6 +28,7 @@ import org.hamcrest.CoreMatchers
import org.hamcrest.Matchers.allOf import org.hamcrest.Matchers.allOf
import org.hamcrest.Matchers.containsString import org.hamcrest.Matchers.containsString
import org.mozilla.fenix.R import org.mozilla.fenix.R
import org.mozilla.fenix.helpers.click
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
@ -113,6 +116,10 @@ class HomeScreenRobot {
scrollToElementByText("Start browsing") scrollToElementByText("Start browsing")
} }
fun closeTab() {
closeTabButton().click()
}
class Transition { class Transition {
val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
@ -165,6 +172,8 @@ val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
private fun navigationToolbar() = private fun navigationToolbar() =
onView(CoreMatchers.allOf(ViewMatchers.withText("Search or enter address"))) onView(CoreMatchers.allOf(ViewMatchers.withText("Search or enter address")))
private fun closeTabButton() = onView(withId(R.id.close_tab_button))
private fun assertNavigationToolbar() = private fun assertNavigationToolbar() =
onView(CoreMatchers.allOf(ViewMatchers.withText("Search or enter address"))) onView(CoreMatchers.allOf(ViewMatchers.withText("Search or enter address")))
.check(matches(withEffectiveVisibility(Visibility.VISIBLE))) .check(matches(withEffectiveVisibility(Visibility.VISIBLE)))

@ -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.robots
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
import androidx.test.espresso.matcher.ViewMatchers.withContentDescription
import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.espresso.matcher.ViewMatchers.withText
import androidx.test.uiautomator.By
import androidx.test.uiautomator.Until
import org.mozilla.fenix.R
import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime
import org.mozilla.fenix.helpers.click
import org.mozilla.fenix.helpers.ext.waitNotNull
/*
* Implementation of Robot Pattern for the multiple selection toolbar of History and Bookmarks menus.
*/
class LibrarySubMenusMultipleSelectionToolbarRobot {
fun verifyMultiSelectionCheckmark() = assertMultiSelectionCheckmark()
fun verifyMultiSelectionCounter() = assertMultiSelectionCounter()
fun verifyShareButton() = assertShareButton()
fun verifyShareOverlay() = assertShareOverlay()
fun verifyShareTabFavicon() = assertShareTabFavicon()
fun verifyShareTabTitle() = assertShareTabTitle()
fun verifyShareTabUrl() = assertShareTabUrl()
fun verifyCloseToolbarButton() = assertCloseToolbarButton()
fun clickShareButton() {
shareButton().click()
mDevice.waitNotNull(
Until.findObject(
By.text("SHARE A LINK")
), waitingTime
)
}
class Transition {
fun closeToolbarReturnToHistory(interact: HistoryRobot.() -> Unit): HistoryRobot.Transition {
closeToolbarButton().click()
HistoryRobot().interact()
return HistoryRobot.Transition()
}
fun closeToolbarReturnToBookmarks(interact: BookmarksRobot.() -> Unit): BookmarksRobot.Transition {
closeToolbarButton().click()
BookmarksRobot().interact()
return BookmarksRobot.Transition()
}
fun clickOpenNewTab(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition {
openInNewTabButton().click()
mDevice.waitNotNull(Until.findObject(By.text("Open tabs")), waitingTime)
HomeScreenRobot().interact()
return HomeScreenRobot.Transition()
}
fun clickOpenPrivateTab(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition {
openInPrivateTabButton().click()
mDevice.waitNotNull(
Until.findObject(By.text("Private session")),
waitingTime
)
HomeScreenRobot().interact()
return HomeScreenRobot.Transition()
}
fun clickMultiSelectionDelete(interact: HistoryRobot.() -> Unit): HistoryRobot.Transition {
multiSelectionDeleteButton().click()
HistoryRobot().interact()
return HistoryRobot.Transition()
}
}
}
fun multipleSelectionToolbar(interact: LibrarySubMenusMultipleSelectionToolbarRobot.() -> Unit): LibrarySubMenusMultipleSelectionToolbarRobot.Transition {
LibrarySubMenusMultipleSelectionToolbarRobot().interact()
return LibrarySubMenusMultipleSelectionToolbarRobot.Transition()
}
private fun closeToolbarButton() = onView(withContentDescription("Navigate up"))
private fun shareButton() = onView(withId(R.id.share_history_multi_select))
private fun openInNewTabButton() = onView(withText("Open in new tab"))
private fun openInPrivateTabButton() = onView(withText("Open in private tab"))
private fun multiSelectionDeleteButton() = onView(withText("Delete"))
private fun assertMultiSelectionCheckmark() =
onView(withId(R.id.checkmark))
.check(matches(isDisplayed()))
private fun assertMultiSelectionCounter() =
onView(withText("1 selected")).check(matches(isDisplayed()))
private fun assertShareButton() =
shareButton().check(matches(isDisplayed()))
private fun assertShareOverlay() =
onView(withId(R.id.shareWrapper)).check(matches(isDisplayed()))
private fun assertShareTabTitle() =
onView(withId(R.id.share_tab_title)).check(matches(isDisplayed()))
private fun assertShareTabFavicon() =
onView(withId(R.id.share_tab_favicon)).check(matches(isDisplayed()))
private fun assertShareTabUrl() = onView(withId(R.id.share_tab_url))
private fun assertCloseToolbarButton() = closeToolbarButton().check(matches(isDisplayed()))
Loading…
Cancel
Save