Closes #4926: Add basic UI test for regular/private tabs (#4928)

nightly-build-test
Aaron Train 5 years ago committed by GitHub
parent 091778a4b9
commit 2bbb4c29ff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -95,7 +95,7 @@ class HomeScreenTest {
@Test @Test
fun privateModeScreenItemsTest() { fun privateModeScreenItemsTest() {
homeScreen { }.dismissOnboarding() homeScreen { }.dismissOnboarding()
homeScreen { }.turnOnPrivateMode() homeScreen { }.togglePrivateBrowsingMode()
homeScreen { homeScreen {
verifyHomeScreen() verifyHomeScreen()

@ -0,0 +1,142 @@
/* 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.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.homeScreen
import org.mozilla.fenix.ui.robots.navigationToolbar
/**
* Tests for verifying basic functionality of tabbed browsing
*
* Including:
* - Opening a tab
* - Opening a private tab
* - Verifying tab list
* - Closing all tabs
*
* TODO: Tab Collections
*/
class TabbedBrowsingTest {
private val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
private lateinit var mockWebServer: MockWebServer
/* ktlint-disable no-blank-line-before-rbrace */ // This imposes unreadable grouping.
@get:Rule
val activityTestRule = HomeActivityTestRule()
@Before
fun setUp() {
mockWebServer = MockWebServer().apply {
setDispatcher(AndroidAssetDispatcher())
start()
}
}
@After
fun tearDown() {
mockWebServer.shutdown()
}
@Test
fun openNewTabTest() {
homeScreen { }.dismissOnboarding()
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
homeScreen {
verifyOpenTabsHeader()
verifyNoTabsOpenedText()
verifyNoTabsOpenedHeader()
verifyNoCollectionsText()
verifyNoCollectionsHeader()
verifyAddTabButton()
}
navigationToolbar {
}.openNewTabAndEnterToBrowser(defaultWebPage.url) {
verifyPageContent(defaultWebPage.content)
verifyTabCounter("1")
}.openHomeScreen { }
homeScreen {
verifyExistingTabList()
}.openTabsListThreeDotMenu {
verifyCloseAllTabsButton()
verifyShareButton()
verifySaveCollection()
}
}
@Test
fun openNewPrivateTabTest() {
homeScreen { }.dismissOnboarding()
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
homeScreen { }.togglePrivateBrowsingMode()
homeScreen {
verifyPrivateSessionHeader()
verifyPrivateSessionMessage(true)
verifyAddTabButton()
}
navigationToolbar {
}.openNewTabAndEnterToBrowser(defaultWebPage.url) {
verifyPageContent(defaultWebPage.content)
verifyTabCounter("1")
}.openHomeScreen {
verifyExistingTabList()
verifyShareTabsButton(true)
verifyCloseTabsButton(true)
}.togglePrivateBrowsingMode()
// Verify private tabs remain in private browsing mode
homeScreen {
verifyNoTabsOpenedHeader()
verifyNoTabsOpenedText()
}.togglePrivateBrowsingMode()
homeScreen {
verifyExistingTabList()
}
}
@Test
fun closeAllTabsTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
navigationToolbar {
}.enterURLAndEnterToBrowser(defaultWebPage.url) {
verifyPageContent(defaultWebPage.content)
}.openHomeScreen { }
homeScreen {
verifyExistingTabList()
}.openTabsListThreeDotMenu {
verifyCloseAllTabsButton()
verifyShareButton()
verifySaveCollection()
}.closeAllTabs {
verifyNoCollectionsHeader()
verifyNoCollectionsText()
verifyNoTabsOpenedHeader()
verifyNoTabsOpenedText()
}
}
}

@ -8,7 +8,6 @@ package org.mozilla.fenix.ui.robots
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.matcher.ViewMatchers.withContentDescription
import androidx.test.espresso.matcher.ViewMatchers.withId import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.espresso.matcher.ViewMatchers.withText import androidx.test.espresso.matcher.ViewMatchers.withText
import androidx.test.platform.app.InstrumentationRegistry import androidx.test.platform.app.InstrumentationRegistry
@ -39,6 +38,11 @@ class BrowserRobot {
mDevice.wait(Until.findObject(By.res(expectedText)), TestAssetHelper.waitingTime) mDevice.wait(Until.findObject(By.res(expectedText)), TestAssetHelper.waitingTime)
} }
fun verifyTabCounter(expectedText: String) {
onView(withId(R.id.counter_text))
.check((matches(withText(containsString(expectedText)))))
}
class Transition { class Transition {
private val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) private val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
@ -68,4 +72,4 @@ fun browserScreen(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition {
fun navURLBar() = onView(withId(R.id.mozac_browser_toolbar_url_view)) fun navURLBar() = onView(withId(R.id.mozac_browser_toolbar_url_view))
private fun tabsCounter() = onView(withContentDescription("Tabs")) private fun tabsCounter() = onView(withId(R.id.counter_box))

@ -12,6 +12,7 @@ import androidx.test.espresso.assertion.ViewAssertions.doesNotExist
import androidx.test.espresso.assertion.ViewAssertions.matches import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.matcher.ViewMatchers import androidx.test.espresso.matcher.ViewMatchers
import androidx.test.espresso.matcher.ViewMatchers.Visibility import androidx.test.espresso.matcher.ViewMatchers.Visibility
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
import androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility import androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility
import androidx.test.platform.app.InstrumentationRegistry import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.uiautomator.UiDevice import androidx.test.uiautomator.UiDevice
@ -72,6 +73,8 @@ class HomeScreenRobot {
fun verifyShareTabsButton(visible: Boolean = true) = assertShareTabsButton(visible) fun verifyShareTabsButton(visible: Boolean = true) = assertShareTabsButton(visible)
fun verifyCloseTabsButton(visible: Boolean = true) = assertCloseTabsButton(visible) fun verifyCloseTabsButton(visible: Boolean = true) = assertCloseTabsButton(visible)
fun verifyExistingTabList() = assertExistingTabList()
private fun scrollToElementByText(text: String): UiScrollable { private fun scrollToElementByText(text: String): UiScrollable {
val appView = UiScrollable(UiSelector().scrollable(true)) val appView = UiScrollable(UiSelector().scrollable(true))
appView.scrollTextIntoView(text) appView.scrollTextIntoView(text)
@ -109,10 +112,18 @@ class HomeScreenRobot {
openSearch { }.openBrowser { }.openHomeScreen { } openSearch { }.openBrowser { }.openHomeScreen { }
} }
fun turnOnPrivateMode() { fun togglePrivateBrowsingMode() {
onView(ViewMatchers.withResourceName("privateBrowsingButton")) onView(ViewMatchers.withResourceName("privateBrowsingButton"))
.perform(click()) .perform(click())
} }
fun openTabsListThreeDotMenu(interact: ThreeDotMenuRobot.() -> Unit): ThreeDotMenuRobot.Transition {
mDevice.waitForIdle()
tabsListThreeDotButton().perform(click())
ThreeDotMenuRobot().interact()
return ThreeDotMenuRobot.Transition()
}
} }
} }
@ -151,7 +162,7 @@ private fun assertOpenTabsHeader() =
.check(matches(withEffectiveVisibility(Visibility.VISIBLE))) .check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
private fun assertAddTabButton() = private fun assertAddTabButton() =
onView(CoreMatchers.allOf(ViewMatchers.withResourceName("add_tab_button"))) onView(CoreMatchers.allOf(ViewMatchers.withId(R.id.add_tab_button), isDisplayed()))
.check(matches(withEffectiveVisibility(Visibility.VISIBLE))) .check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
private fun assertNoTabsOpenedHeader() = private fun assertNoTabsOpenedHeader() =
@ -296,11 +307,17 @@ private fun assertPrivateSessionMessage(visible: Boolean) =
) )
private fun assertShareTabsButton(visible: Boolean) = private fun assertShareTabsButton(visible: Boolean) =
onView(CoreMatchers.allOf(ViewMatchers.withResourceName("share_tabs_button"))) onView(CoreMatchers.allOf(ViewMatchers.withId(R.id.share_tabs_button), isDisplayed()))
.check(matches(withEffectiveVisibility(visibleOrGone(visible)))) .check(matches(withEffectiveVisibility(visibleOrGone(visible))))
private fun assertCloseTabsButton(visible: Boolean) = private fun assertCloseTabsButton(visible: Boolean) =
onView(CoreMatchers.allOf(ViewMatchers.withResourceName("close_tabs_button"))) onView(CoreMatchers.allOf(ViewMatchers.withId(R.id.close_tab_button), isDisplayed()))
.check(matches(withEffectiveVisibility(visibleOrGone(visible)))) .check(matches(withEffectiveVisibility(visibleOrGone(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(ViewMatchers.withId(R.id.item_tab)))
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
private fun tabsListThreeDotButton() = onView(allOf(ViewMatchers.withId(R.id.tabs_overflow_button)))

@ -8,7 +8,6 @@ package org.mozilla.fenix.ui.robots
import android.net.Uri import android.net.Uri
import androidx.test.espresso.Espresso.onView import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.action.ViewActions.pressImeActionButton import androidx.test.espresso.action.ViewActions.pressImeActionButton
import androidx.test.espresso.action.ViewActions.replaceText import androidx.test.espresso.action.ViewActions.replaceText
import androidx.test.espresso.matcher.ViewMatchers import androidx.test.espresso.matcher.ViewMatchers
@ -44,6 +43,15 @@ class NavigationToolbarRobot {
ThreeDotMenuRobot().interact() ThreeDotMenuRobot().interact()
return ThreeDotMenuRobot.Transition() return ThreeDotMenuRobot.Transition()
} }
fun openNewTabAndEnterToBrowser(url: Uri, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition {
mDevice.wait(Until.findObject(By.descContains("Add tab")), waitingTime)
newTab().click()
awesomeBar().perform(replaceText(url.toString()), pressImeActionButton())
BrowserRobot().interact()
return BrowserRobot.Transition()
}
} }
} }
@ -55,3 +63,4 @@ fun navigationToolbar(interact: NavigationToolbarRobot.() -> Unit): NavigationTo
private fun urlBar() = onView(ViewMatchers.withId(R.id.toolbar)) private fun urlBar() = onView(ViewMatchers.withId(R.id.toolbar))
private fun awesomeBar() = onView(ViewMatchers.withId(R.id.mozac_browser_toolbar_edit_url_view)) private fun awesomeBar() = onView(ViewMatchers.withId(R.id.mozac_browser_toolbar_edit_url_view))
private fun threeDotButton() = onView(ViewMatchers.withContentDescription("Menu")) private fun threeDotButton() = onView(ViewMatchers.withContentDescription("Menu"))
private fun newTab() = onView(ViewMatchers.withContentDescription("Add tab"))

@ -1,23 +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/. */
@file:Suppress("TooManyFunctions")
package org.mozilla.fenix.ui.robots
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.uiautomator.UiDevice
class TabsRobot {
// Tabs functions here
class Transition {
private val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
// Transition functions here
}
}
// Locaters here

@ -7,7 +7,6 @@
package org.mozilla.fenix.ui.robots package org.mozilla.fenix.ui.robots
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.assertion.ViewAssertions.matches
import androidx.test.espresso.matcher.ViewMatchers import androidx.test.espresso.matcher.ViewMatchers
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
@ -33,6 +32,9 @@ class ThreeDotMenuRobot {
fun verifyForwardButton() = assertForwardButton() fun verifyForwardButton() = assertForwardButton()
fun verifyBackButton() = assertBackButton() fun verifyBackButton() = assertBackButton()
fun verifyRefreshButton() = assertRefreshButton() fun verifyRefreshButton() = assertRefreshButton()
fun verifyCloseAllTabsButton() = assertCloseAllTabsButton()
fun verifyShareButton() = assertShareButton()
fun verifySaveCollection() = assertSaveCollectionButton()
class Transition { class Transition {
@ -85,6 +87,14 @@ class ThreeDotMenuRobot {
BrowserRobot().interact() BrowserRobot().interact()
return BrowserRobot.Transition() return BrowserRobot.Transition()
} }
fun closeAllTabs(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition {
mDevice.wait(Until.findObject(By.text("Close all tabs")), waitingTime)
closeAllTabsButton().click()
HomeScreenRobot().interact()
return HomeScreenRobot.Transition()
}
} }
} }
private fun threeDotMenuRecyclerViewExists() { private fun threeDotMenuRecyclerViewExists() {
@ -92,24 +102,36 @@ private fun threeDotMenuRecyclerViewExists() {
} }
private fun settingsButton() = onView(allOf(withText(R.string.settings))) private fun settingsButton() = onView(allOf(withText(R.string.settings)))
private fun assertSettingsButton() = settingsButton() private fun assertSettingsButton() = settingsButton()
.check(ViewAssertions.matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) .check(matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
private fun libraryButton() = onView(allOf(withText(R.string.browser_menu_your_library))) private fun libraryButton() = onView(allOf(withText(R.string.browser_menu_your_library)))
private fun assertLibraryButton() = libraryButton() private fun assertLibraryButton() = libraryButton()
.check(ViewAssertions.matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) .check(matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
private fun helpButton() = onView(allOf(withText(R.string.browser_menu_help))) private fun helpButton() = onView(allOf(withText(R.string.browser_menu_help)))
private fun assertHelpButton() = helpButton() private fun assertHelpButton() = helpButton()
.check(ViewAssertions.matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) .check(matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
private fun forwardButton() = onView(ViewMatchers.withContentDescription("Forward")) private fun forwardButton() = onView(ViewMatchers.withContentDescription("Forward"))
private fun assertForwardButton() = forwardButton() private fun assertForwardButton() = forwardButton()
.check(ViewAssertions.matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) .check(matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
private fun backButton() = onView(ViewMatchers.withContentDescription("Back")) private fun backButton() = onView(ViewMatchers.withContentDescription("Back"))
private fun assertBackButton() = backButton() private fun assertBackButton() = backButton()
.check(ViewAssertions.matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) .check(matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
private fun refreshButton() = onView(ViewMatchers.withContentDescription("Refresh")) private fun refreshButton() = onView(ViewMatchers.withContentDescription("Refresh"))
private fun assertRefreshButton() = refreshButton() private fun assertRefreshButton() = refreshButton()
.check(ViewAssertions.matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) .check(matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
private fun closeAllTabsButton() = onView(allOf(withText("Close all tabs")))
private fun assertCloseAllTabsButton() = closeAllTabsButton()
.check(matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
private fun shareButton() = onView(allOf(withText("Share tabs")))
private fun assertShareButton() = shareButton()
.check(matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
private fun saveCollectionButton() = onView(allOf(withText("Save to collection")))
private fun assertSaveCollectionButton() = saveCollectionButton()
.check(matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))

Loading…
Cancel
Save