Add automated UI test for main three dot menu (#2540)
parent
b3a3c94169
commit
ba3edbcf92
@ -0,0 +1,32 @@
|
||||
/* 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.helpers
|
||||
|
||||
import android.view.View
|
||||
import org.hamcrest.CoreMatchers.not
|
||||
import org.hamcrest.Matcher
|
||||
import androidx.test.espresso.matcher.ViewMatchers.isChecked as espressoIsChecked
|
||||
import androidx.test.espresso.matcher.ViewMatchers.isEnabled as espressoIsEnabled
|
||||
import androidx.test.espresso.matcher.ViewMatchers.isSelected as espressoIsSelected
|
||||
|
||||
/**
|
||||
* The [espressoIsEnabled] function that can also handle disabled state through the boolean argument.
|
||||
*/
|
||||
fun isEnabled(isEnabled: Boolean): Matcher<View> = maybeInvertMatcher(espressoIsEnabled(), isEnabled)
|
||||
|
||||
/**
|
||||
* The [espressoIsChecked] function that can also handle unchecked state through the boolean argument.
|
||||
*/
|
||||
fun isChecked(isChecked: Boolean): Matcher<View> = maybeInvertMatcher(espressoIsChecked(), isChecked)
|
||||
|
||||
/**
|
||||
* The [espressoIsSelected] function that can also handle not selected state through the boolean argument.
|
||||
*/
|
||||
fun isSelected(isSelected: Boolean): Matcher<View> = maybeInvertMatcher(espressoIsSelected(), isSelected)
|
||||
|
||||
private fun maybeInvertMatcher(matcher: Matcher<View>, useUnmodifiedMatcher: Boolean): Matcher<View> = when {
|
||||
useUnmodifiedMatcher -> matcher
|
||||
else -> not(matcher)
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
/* 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.helpers
|
||||
|
||||
import androidx.test.espresso.ViewInteraction
|
||||
import androidx.test.espresso.action.ViewActions
|
||||
import androidx.test.espresso.assertion.ViewAssertions.matches
|
||||
|
||||
fun ViewInteraction.click(): ViewInteraction = this.perform(ViewActions.click())!!
|
||||
|
||||
fun ViewInteraction.assertIsEnabled(isEnabled: Boolean): ViewInteraction {
|
||||
return this.check(matches(isEnabled(isEnabled)))!!
|
||||
}
|
||||
|
||||
fun ViewInteraction.assertIsChecked(isChecked: Boolean): ViewInteraction {
|
||||
return this.check(matches(isChecked(isChecked)))!!
|
||||
}
|
||||
|
||||
fun ViewInteraction.assertIsSelected(isSelected: Boolean): ViewInteraction {
|
||||
return this.check(matches(isSelected(isSelected)))!!
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
/* 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 org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.mozilla.fenix.helpers.HomeActivityTestRule
|
||||
import org.mozilla.fenix.ui.robots.homeScreen
|
||||
|
||||
/**
|
||||
* Tests for verifying the main three dot menu options
|
||||
*
|
||||
* Including:
|
||||
* - Verify all menu items present
|
||||
* - Open library button opens library menu
|
||||
* - Open settings button opens settings menu
|
||||
* - Open Help button opens support page in browser
|
||||
*
|
||||
*/
|
||||
|
||||
class ThreeDotMenuTest {
|
||||
/* ktlint-disable no-blank-line-before-rbrace */ // This imposes unreadable grouping.
|
||||
@get:Rule
|
||||
val activityTestRule = HomeActivityTestRule()
|
||||
@Test
|
||||
fun threeDotMenuItemsTest() {
|
||||
homeScreen {
|
||||
}.openThreeDotMenu {
|
||||
verifySettingsButton()
|
||||
verifyLibraryButton()
|
||||
verifyHelpButton()
|
||||
}.openSettings {
|
||||
verifySettingsView()
|
||||
}.goBack {
|
||||
}.openThreeDotMenu {
|
||||
}.openLibrary {
|
||||
verifyLibraryView()
|
||||
}.goBack {
|
||||
}.openThreeDotMenu {
|
||||
}.openHelp {
|
||||
verifyHelpUrl()
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
/* 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.espresso.Espresso.onView
|
||||
import androidx.test.espresso.assertion.ViewAssertions.matches
|
||||
import androidx.test.espresso.matcher.ViewMatchers.withId
|
||||
import androidx.test.espresso.matcher.ViewMatchers.withText
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.test.uiautomator.UiDevice
|
||||
import org.hamcrest.CoreMatchers.containsString
|
||||
import org.mozilla.fenix.R
|
||||
|
||||
class BrowserRobot {
|
||||
|
||||
fun verifyHelpUrl() {
|
||||
val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
|
||||
val redirectUrl = "https://support.mozilla.org/"
|
||||
|
||||
mDevice.waitForIdle()
|
||||
onView(withId(R.id.mozac_browser_toolbar_url_view))
|
||||
.check(matches(withText(containsString(redirectUrl))))
|
||||
}
|
||||
|
||||
class Transition {
|
||||
val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
|
||||
}
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
/* 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.espresso.Espresso.onView
|
||||
import androidx.test.espresso.action.ViewActions.click
|
||||
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.UiDevice
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import org.hamcrest.CoreMatchers.allOf
|
||||
import org.mozilla.fenix.R
|
||||
|
||||
/**
|
||||
* Implementation of Robot Pattern for the your library menu.
|
||||
*/
|
||||
class LibraryRobot {
|
||||
fun verifyLibraryView() = assertLibraryView()
|
||||
|
||||
class Transition {
|
||||
|
||||
val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
|
||||
|
||||
fun goBack(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition {
|
||||
|
||||
mDevice.waitForIdle()
|
||||
goBackButton().perform(click())
|
||||
|
||||
HomeScreenRobot().interact()
|
||||
return HomeScreenRobot.Transition()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun assertLibraryView() {
|
||||
// verify that we are in the correct library view
|
||||
onView(allOf(withId(R.id.libraryItemTitle)))
|
||||
onView(allOf(withText("Bookmarks")))
|
||||
}
|
||||
|
||||
private fun goBackButton() = onView(allOf(withContentDescription("Navigate up")))
|
@ -0,0 +1,52 @@
|
||||
/* 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.espresso.Espresso.onView
|
||||
import androidx.test.espresso.action.ViewActions
|
||||
import androidx.test.espresso.assertion.ViewAssertions.matches
|
||||
import androidx.test.espresso.matcher.ViewMatchers
|
||||
import androidx.test.espresso.matcher.ViewMatchers.withContentDescription
|
||||
import androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.test.uiautomator.UiDevice
|
||||
import androidx.test.espresso.matcher.ViewMatchers.Visibility
|
||||
import org.hamcrest.CoreMatchers
|
||||
|
||||
/**
|
||||
* Implementation of Robot Pattern for the settings menu.
|
||||
*/
|
||||
class SettingsRobot {
|
||||
|
||||
fun verifySettingsView() = assertSettingsView()
|
||||
class Transition {
|
||||
|
||||
val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
|
||||
|
||||
fun goBack(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition {
|
||||
|
||||
mDevice.waitForIdle()
|
||||
goBackButton().perform(ViewActions.click())
|
||||
|
||||
HomeScreenRobot().interact()
|
||||
return HomeScreenRobot.Transition()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun assertSettingsView() {
|
||||
// verify that we are in the correct library view
|
||||
assertBasicsHeading()
|
||||
assertAdvancedHeading()
|
||||
}
|
||||
|
||||
private fun assertBasicsHeading() = onView(ViewMatchers.withText("Basics"))
|
||||
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
private fun assertAdvancedHeading() = onView(ViewMatchers.withText("Advanced"))
|
||||
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
|
||||
private fun goBackButton() = onView(CoreMatchers.allOf(withContentDescription("Navigate up")))
|
@ -0,0 +1,67 @@
|
||||
/* 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.espresso.Espresso.onView
|
||||
import androidx.test.espresso.assertion.ViewAssertions
|
||||
import androidx.test.espresso.matcher.ViewMatchers
|
||||
import androidx.test.espresso.matcher.ViewMatchers.withText
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.test.uiautomator.UiDevice
|
||||
import org.hamcrest.Matchers.allOf
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.helpers.click
|
||||
|
||||
/**
|
||||
* Implementation of Robot Pattern for the three dot (main) menu.
|
||||
*/
|
||||
class ThreeDotMenuRobot {
|
||||
fun verifySettingsButton() = assertSettingsButton()
|
||||
fun verifyLibraryButton() = assertLibraryButton()
|
||||
fun verifyHelpButton() = assertHelpButton()
|
||||
|
||||
class Transition {
|
||||
|
||||
val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
|
||||
|
||||
fun openSettings(interact: SettingsRobot.() -> Unit): SettingsRobot.Transition {
|
||||
mDevice.waitForIdle()
|
||||
settingsButton().click()
|
||||
|
||||
SettingsRobot().interact()
|
||||
return SettingsRobot.Transition()
|
||||
}
|
||||
|
||||
fun openLibrary(interact: LibraryRobot.() -> Unit): LibraryRobot.Transition {
|
||||
mDevice.waitForIdle()
|
||||
libraryButton().click()
|
||||
|
||||
LibraryRobot().interact()
|
||||
return LibraryRobot.Transition()
|
||||
}
|
||||
|
||||
fun openHelp(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition {
|
||||
mDevice.waitForIdle()
|
||||
helpButton().click()
|
||||
|
||||
BrowserRobot().interact()
|
||||
return BrowserRobot.Transition()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun settingsButton() = onView(allOf(withText("Settings")))
|
||||
private fun assertSettingsButton() = settingsButton()
|
||||
.check(ViewAssertions.matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
|
||||
|
||||
private fun libraryButton() = onView(allOf(withText(R.string.browser_menu_your_library)))
|
||||
private fun assertLibraryButton() = libraryButton()
|
||||
.check(ViewAssertions.matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
|
||||
|
||||
private fun helpButton() = onView(allOf(withText(R.string.browser_menu_help)))
|
||||
private fun assertHelpButton() = helpButton()
|
||||
.check(ViewAssertions.matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
|
Loading…
Reference in New Issue