- Adds UI tests (and assets) for basic navigation fix: review changes fix: linter cleanup fix: detekt cleanup fix: adjust wait approaches
This commit is contained in:
parent
3143227692
commit
6aa6cf8a99
|
@ -0,0 +1,7 @@
|
|||
<html>
|
||||
<body>
|
||||
<h1>
|
||||
<p id="testContent">Page content: 1</p>
|
||||
</h1>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,7 @@
|
|||
<html>
|
||||
<body>
|
||||
<h1>
|
||||
<p id="testContent">Page content: 2</p>
|
||||
</h1>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,7 @@
|
|||
<html>
|
||||
<body>
|
||||
<h1>
|
||||
<p id="testContent">Page content: 3</p>
|
||||
</h1>
|
||||
</body>
|
||||
</html>
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,45 @@
|
|||
|
||||
<html>
|
||||
<script src="jquery-3.4.1.slim.min.js"></script>
|
||||
<script>
|
||||
|
||||
function setCookie(newVal){
|
||||
window.document.cookie = "pageStatus = " + newVal + ";";
|
||||
}
|
||||
|
||||
|
||||
function readCookie(name) {
|
||||
var nameEQ = name + "=";
|
||||
var ca = document.cookie.split(';');
|
||||
for(var i=0;i < ca.length;i++) {
|
||||
var c = ca[i];
|
||||
while (c.charAt(0)==' ') c = c.substring(1,c.length);
|
||||
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function valSwap(){
|
||||
currentCookie = readCookie("pageStatus");
|
||||
if(currentCookie == null) {
|
||||
setCookie("DEFAULT");
|
||||
}
|
||||
|
||||
if (currentCookie.localeCompare("REFRESHED") == 0) {
|
||||
setCookie("DEFAULT");
|
||||
return "My little test page - DEFAULT";
|
||||
} else {
|
||||
setCookie("REFRESHED");
|
||||
return "My little test page - REFRESHED!";
|
||||
}
|
||||
}
|
||||
|
||||
var textToShow = valSwap();
|
||||
window.addEventListener('DOMContentLoaded', (event) => {
|
||||
document.querySelector('h1').innerHTML = textToShow;
|
||||
});
|
||||
</script>
|
||||
<body>
|
||||
<h1>My little test page - DEFAULT</h1>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,121 @@
|
|||
/* 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.navigationToolbar
|
||||
|
||||
/**
|
||||
* Tests for verifying basic functionality of browser navigation
|
||||
*
|
||||
* Including:
|
||||
* - Visiting a URL
|
||||
* - Back and Forward navigation
|
||||
* - Refresh
|
||||
*/
|
||||
|
||||
class NavigationToolbarTest {
|
||||
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 goBackTest() {
|
||||
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
|
||||
val nextWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 2)
|
||||
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(defaultWebPage.url) {
|
||||
verifyPageContent(defaultWebPage.content)
|
||||
}.openNavigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(nextWebPage.url) {
|
||||
verifyPageContent(nextWebPage.content)
|
||||
}
|
||||
|
||||
// Re-open the three-dot menu for verification
|
||||
navigationToolbar {
|
||||
}.openThreeDotMenu {
|
||||
verifyThreeDotMenuExists()
|
||||
}.goBack {
|
||||
verifyPageContent(defaultWebPage.content)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun goForwardTest() {
|
||||
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
|
||||
val nextWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 2)
|
||||
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(defaultWebPage.url) {
|
||||
verifyPageContent(defaultWebPage.content)
|
||||
}.openNavigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(nextWebPage.url) {
|
||||
verifyPageContent(nextWebPage.content)
|
||||
mDevice.pressBack()
|
||||
verifyPageContent(defaultWebPage.content)
|
||||
}
|
||||
|
||||
// Re-open the three-dot menu for verification
|
||||
navigationToolbar {
|
||||
}.openThreeDotMenu {
|
||||
verifyThreeDotMenuExists()
|
||||
}.goForward {
|
||||
verifyPageContent(nextWebPage.content)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun refreshPageTest() {
|
||||
val refreshWebPage = TestAssetHelper.getRefreshAsset(mockWebServer)
|
||||
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(refreshWebPage.url) {
|
||||
verifyPageContent("DEFAULT")
|
||||
}
|
||||
|
||||
// Use refresh from the three-dot menu
|
||||
navigationToolbar {
|
||||
}.openThreeDotMenu {
|
||||
}.refreshPage {
|
||||
verifyPageContent("REFRESHED")
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun visitURLTest() {
|
||||
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
|
||||
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(defaultWebPage.url) {
|
||||
verifyPageContent(defaultWebPage.content)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -11,9 +11,13 @@ 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.By
|
||||
import androidx.test.uiautomator.UiDevice
|
||||
import androidx.test.uiautomator.Until
|
||||
import org.hamcrest.CoreMatchers.containsString
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.helpers.TestAssetHelper
|
||||
import org.mozilla.fenix.helpers.click
|
||||
|
||||
class BrowserRobot {
|
||||
|
||||
|
@ -26,8 +30,24 @@ class BrowserRobot {
|
|||
.check(matches(withText(containsString(redirectUrl))))
|
||||
}
|
||||
|
||||
class Transition {
|
||||
/* Asserts that the text within DOM element with ID="testContent" has the given text, i.e.
|
||||
* document.querySelector('#testContent').innerText == expectedText
|
||||
*/
|
||||
fun verifyPageContent(expectedText: String) {
|
||||
val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
|
||||
mDevice.wait(Until.findObject(By.res(expectedText)), TestAssetHelper.waitingTime)
|
||||
}
|
||||
|
||||
class Transition {
|
||||
private val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
|
||||
|
||||
fun openNavigationToolbar(interact: NavigationToolbarRobot.() -> Unit): NavigationToolbarRobot.Transition {
|
||||
|
||||
navURLBar().click()
|
||||
|
||||
NavigationToolbarRobot().interact()
|
||||
return NavigationToolbarRobot.Transition()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -35,3 +55,5 @@ fun browserScreen(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition {
|
|||
BrowserRobot().interact()
|
||||
return BrowserRobot.Transition()
|
||||
}
|
||||
|
||||
fun navURLBar() = onView(withId(R.id.mozac_browser_toolbar_url_view))
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
/* 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 android.net.Uri
|
||||
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.replaceText
|
||||
import androidx.test.espresso.matcher.ViewMatchers
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.test.uiautomator.By
|
||||
import androidx.test.uiautomator.UiDevice
|
||||
import androidx.test.uiautomator.Until
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime
|
||||
import org.mozilla.fenix.helpers.click
|
||||
|
||||
/**
|
||||
* Implementation of Robot Pattern for the URL toolbar.
|
||||
*/
|
||||
class NavigationToolbarRobot {
|
||||
class Transition {
|
||||
|
||||
val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
|
||||
|
||||
fun enterURLAndEnterToBrowser(url: Uri, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition {
|
||||
mDevice.wait(Until.findObject(By.text("Search or enter address")), waitingTime)
|
||||
urlBar().click()
|
||||
awesomeBar().perform(replaceText(url.toString()), pressImeActionButton())
|
||||
|
||||
BrowserRobot().interact()
|
||||
return BrowserRobot.Transition()
|
||||
}
|
||||
|
||||
fun openThreeDotMenu(interact: ThreeDotMenuRobot.() -> Unit): ThreeDotMenuRobot.Transition {
|
||||
mDevice.wait(Until.findObject(By.text("Menu")), waitingTime)
|
||||
threeDotButton().click()
|
||||
|
||||
ThreeDotMenuRobot().interact()
|
||||
return ThreeDotMenuRobot.Transition()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun navigationToolbar(interact: NavigationToolbarRobot.() -> Unit): NavigationToolbarRobot.Transition {
|
||||
NavigationToolbarRobot().interact()
|
||||
return NavigationToolbarRobot.Transition()
|
||||
}
|
||||
|
||||
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 threeDotButton() = onView(ViewMatchers.withContentDescription("Menu"))
|
|
@ -8,12 +8,18 @@ package org.mozilla.fenix.ui.robots
|
|||
|
||||
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
|
||||
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
|
||||
import androidx.test.espresso.matcher.ViewMatchers.withId
|
||||
import androidx.test.espresso.matcher.ViewMatchers.withText
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.test.uiautomator.By
|
||||
import androidx.test.uiautomator.UiDevice
|
||||
import androidx.test.uiautomator.Until
|
||||
import org.hamcrest.Matchers.allOf
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime
|
||||
import org.mozilla.fenix.helpers.click
|
||||
|
||||
/**
|
||||
|
@ -23,13 +29,17 @@ class ThreeDotMenuRobot {
|
|||
fun verifySettingsButton() = assertSettingsButton()
|
||||
fun verifyLibraryButton() = assertLibraryButton()
|
||||
fun verifyHelpButton() = assertHelpButton()
|
||||
fun verifyThreeDotMenuExists() = threeDotMenuRecyclerViewExists()
|
||||
fun verifyForwardButton() = assertForwardButton()
|
||||
fun verifyBackButton() = assertBackButton()
|
||||
fun verifyRefreshButton() = assertRefreshButton()
|
||||
|
||||
class Transition {
|
||||
|
||||
val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
|
||||
private val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
|
||||
|
||||
fun openSettings(interact: SettingsRobot.() -> Unit): SettingsRobot.Transition {
|
||||
mDevice.waitForIdle()
|
||||
mDevice.wait(Until.findObject(By.text("Settings")), waitingTime)
|
||||
settingsButton().click()
|
||||
|
||||
SettingsRobot().interact()
|
||||
|
@ -37,7 +47,7 @@ class ThreeDotMenuRobot {
|
|||
}
|
||||
|
||||
fun openLibrary(interact: LibraryRobot.() -> Unit): LibraryRobot.Transition {
|
||||
mDevice.waitForIdle()
|
||||
mDevice.wait(Until.findObject(By.text("Library")), waitingTime)
|
||||
libraryButton().click()
|
||||
|
||||
LibraryRobot().interact()
|
||||
|
@ -45,15 +55,41 @@ class ThreeDotMenuRobot {
|
|||
}
|
||||
|
||||
fun openHelp(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition {
|
||||
mDevice.waitForIdle()
|
||||
mDevice.wait(Until.findObject(By.text("Help")), waitingTime)
|
||||
helpButton().click()
|
||||
|
||||
BrowserRobot().interact()
|
||||
return BrowserRobot.Transition()
|
||||
}
|
||||
|
||||
fun goForward(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition {
|
||||
mDevice.wait(Until.findObject(By.desc("Forward")), waitingTime)
|
||||
forwardButton().click()
|
||||
|
||||
BrowserRobot().interact()
|
||||
return BrowserRobot.Transition()
|
||||
}
|
||||
|
||||
fun goBack(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition {
|
||||
mDevice.wait(Until.findObject(By.desc("Back")), waitingTime)
|
||||
backButton().click()
|
||||
|
||||
BrowserRobot().interact()
|
||||
return BrowserRobot.Transition()
|
||||
}
|
||||
|
||||
fun refreshPage(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition {
|
||||
mDevice.wait(Until.findObject(By.desc("Refresh")), waitingTime)
|
||||
refreshButton().click()
|
||||
|
||||
BrowserRobot().interact()
|
||||
return BrowserRobot.Transition()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun threeDotMenuRecyclerViewExists() {
|
||||
onView(withId(R.id.mozac_browser_menu_recyclerView)).check(matches(isDisplayed()))
|
||||
}
|
||||
private fun settingsButton() = onView(allOf(withText("Settings")))
|
||||
private fun assertSettingsButton() = settingsButton()
|
||||
.check(ViewAssertions.matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
|
||||
|
@ -65,3 +101,15 @@ private fun assertLibraryButton() = libraryButton()
|
|||
private fun helpButton() = onView(allOf(withText(R.string.browser_menu_help)))
|
||||
private fun assertHelpButton() = helpButton()
|
||||
.check(ViewAssertions.matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
|
||||
|
||||
private fun forwardButton() = onView(ViewMatchers.withContentDescription("Forward"))
|
||||
private fun assertForwardButton() = forwardButton()
|
||||
.check(ViewAssertions.matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
|
||||
|
||||
private fun backButton() = onView(ViewMatchers.withContentDescription("Back"))
|
||||
private fun assertBackButton() = backButton()
|
||||
.check(ViewAssertions.matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
|
||||
|
||||
private fun refreshButton() = onView(ViewMatchers.withContentDescription("Refresh"))
|
||||
private fun assertRefreshButton() = refreshButton()
|
||||
.check(ViewAssertions.matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
|
||||
|
|
Loading…
Reference in New Issue