1
0
Fork 0

UI tests for Private browsing settings sub-menu (#8395)

master
Oana Horvath 2020-03-05 12:25:48 +02:00 committed by GitHub
parent ec98fd948b
commit 0cdb0680e7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 448 additions and 71 deletions

View File

@ -4,7 +4,9 @@
package org.mozilla.fenix.helpers package org.mozilla.fenix.helpers
import android.content.ActivityNotFoundException
import android.content.Context import android.content.Context
import android.content.Intent
import android.net.Uri import android.net.Uri
import android.os.Build import android.os.Build
import android.preference.PreferenceManager import android.preference.PreferenceManager
@ -12,6 +14,7 @@ import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions.longClick import androidx.test.espresso.action.ViewActions.longClick
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.uiautomator.By import androidx.test.uiautomator.By
import androidx.test.uiautomator.UiScrollable import androidx.test.uiautomator.UiScrollable
import androidx.test.uiautomator.UiSelector import androidx.test.uiautomator.UiSelector
@ -48,6 +51,14 @@ object TestHelper {
editor.apply() editor.apply()
} }
fun restartApp(activity: HomeActivityTestRule) {
with(activity) {
finishActivity()
mDevice.waitForIdle()
launchActivity(null)
}
}
fun getPermissionAllowID(): String { fun getPermissionAllowID(): String {
return when return when
(Build.VERSION.SDK_INT > Build.VERSION_CODES.P) { (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) {
@ -62,4 +73,20 @@ object TestHelper {
TestAssetHelper.waitingTime TestAssetHelper.waitingTime
) )
} }
fun openAppFromExternalLink(url: String) {
val context = InstrumentationRegistry.getInstrumentation().getTargetContext()
val intent = Intent().apply {
action = Intent.ACTION_VIEW
data = Uri.parse(url)
`package` = "org.mozilla.fenix.debug"
flags = Intent.FLAG_ACTIVITY_NEW_TASK
}
try {
context.startActivity(intent)
} catch (ex: ActivityNotFoundException) {
intent.setPackage(null)
context.startActivity(intent)
}
}
} }

View File

@ -7,15 +7,19 @@ package org.mozilla.fenix.ui
import androidx.test.platform.app.InstrumentationRegistry import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.uiautomator.UiDevice import androidx.test.uiautomator.UiDevice
import okhttp3.mockwebserver.MockWebServer import okhttp3.mockwebserver.MockWebServer
import org.junit.Rule
import org.junit.Before
import org.junit.After import org.junit.After
import org.junit.Before
import org.junit.Ignore import org.junit.Ignore
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 import org.mozilla.fenix.helpers.TestHelper
import org.mozilla.fenix.helpers.TestHelper.openAppFromExternalLink
import org.mozilla.fenix.helpers.TestHelper.restartApp
import org.mozilla.fenix.ui.robots.addToHomeScreen
import org.mozilla.fenix.ui.robots.browserScreen
import org.mozilla.fenix.ui.robots.homeScreen import org.mozilla.fenix.ui.robots.homeScreen
import org.mozilla.fenix.ui.robots.navigationToolbar import org.mozilla.fenix.ui.robots.navigationToolbar
@ -29,6 +33,7 @@ class SettingsPrivacyTest {
private val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) private val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
private lateinit var mockWebServer: MockWebServer private lateinit var mockWebServer: MockWebServer
private val pageShortcutName = "TestShortcut"
@get:Rule @get:Rule
val activityTestRule = HomeActivityTestRule() val activityTestRule = HomeActivityTestRule()
@ -100,7 +105,7 @@ class SettingsPrivacyTest {
// Logins // Logins
verifyLoginsButton() verifyLoginsButton()
// drill down to submenu // drill down to submenu
verifyAddPrivateBrowsingShortcutButton() verifyPrivateBrowsingButton()
verifySitePermissionsButton() verifySitePermissionsButton()
// drill down on search // drill down on search
verifyDeleteBrowsingDataButton() verifyDeleteBrowsingDataButton()
@ -138,21 +143,21 @@ class SettingsPrivacyTest {
@Test @Test
fun saveLoginFromPromptTest() { fun saveLoginFromPromptTest() {
val saveLoginTest = val saveLoginTest =
TestAssetHelper.getSaveLoginAsset(mockWebServer) TestAssetHelper.getSaveLoginAsset(mockWebServer)
navigationToolbar { navigationToolbar {
}.enterURLAndEnterToBrowser(saveLoginTest.url) { }.enterURLAndEnterToBrowser(saveLoginTest.url) {
verifySaveLoginPromptIsShown() verifySaveLoginPromptIsShown()
// Click save to save the login // Click save to save the login
saveLoginFromPrompt("Save") saveLoginFromPrompt("Save")
}.openHomeScreen { }.openHomeScreen {
}.openThreeDotMenu { }.openThreeDotMenu {
}.openSettings { }.openSettings {
TestHelper.scrollToElementByText("Logins and passwords") TestHelper.scrollToElementByText("Logins and passwords")
}.openLoginsAndPasswordSubMenu { }.openLoginsAndPasswordSubMenu {
verifyDefaultView() verifyDefaultView()
verifyDefaultValueSyncLogins() verifyDefaultValueSyncLogins()
}.openSavedLogins { }.openSavedLogins {
verifySavedLoginsView() verifySavedLoginsView()
tapSetupLater() tapSetupLater()
// Verify that the login appears correctly // Verify that the login appears correctly
@ -194,6 +199,110 @@ class SettingsPrivacyTest {
} }
} }
@Test
fun verifyPrivateBrowsingMenuItemsTest() {
homeScreen {
}.openThreeDotMenu {
}.openSettings {
}.openPrivateBrowsingSubMenu {
verifyAddPrivateBrowsingShortcutButton()
verifyOpenLinksInPrivateTab()
verifyOpenLinksInPrivateTabOff()
}.goBack {
verifySettingsView()
}
}
@Test
fun openExternalLinksInPrivateTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
setOpenLinksInPrivateOn()
openAppFromExternalLink(defaultWebPage.url.toString())
browserScreen {
}.openHomeScreen {
verifyPrivateSessionHeader()
}
setOpenLinksInPrivateOff()
openAppFromExternalLink(defaultWebPage.url.toString())
browserScreen {
}.openHomeScreen {
verifyOpenTabsHeader()
}
}
@Test
fun launchPageShortcutInPrivateModeTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
setOpenLinksInPrivateOn()
navigationToolbar {
}.enterURLAndEnterToBrowser(defaultWebPage.url) {
}.openThreeDotMenu {
}.openAddToHomeScreen {
addShortcutName(pageShortcutName)
clickAddShortcutButton()
clickAddAutomaticallyButton()
}.openHomeScreenShortcut(pageShortcutName) {
}.openHomeScreen {
verifyPrivateSessionHeader()
}
}
@Test
fun launchLinksInPrivateToggleOffStateDoesntChangeTest() {
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
setOpenLinksInPrivateOn()
navigationToolbar {
}.enterURLAndEnterToBrowser(defaultWebPage.url) {
}.openThreeDotMenu {
}.openAddToHomeScreen {
addShortcutName(pageShortcutName)
clickAddShortcutButton()
clickAddAutomaticallyButton()
}.openHomeScreenShortcut(pageShortcutName) {
}.openHomeScreen {}
setOpenLinksInPrivateOff()
restartApp(activityTestRule)
mDevice.waitForIdle()
addToHomeScreen {
}.searchAndOpenHomeScreenShortcut(pageShortcutName) {
}.openHomeScreen {
verifyOpenTabsHeader()
}.openThreeDotMenu {
}.openSettings {
}.openPrivateBrowsingSubMenu {
verifyOpenLinksInPrivateTabOff()
}
}
@Test
fun addPrivateBrowsingShortcut() {
homeScreen {
}.openThreeDotMenu {
}.openSettings {
}.openPrivateBrowsingSubMenu {
addPrivateShortcutToHomescreen()
verifyPrivateBrowsingShortcutIcon()
}.openPrivateBrowsingShortcut {
verifySearchView()
}.openBrowser {
}.openHomeScreen {
verifyPrivateSessionHeader()
}
}
@Ignore("This is a stub test, ignore for now") @Ignore("This is a stub test, ignore for now")
@Test @Test
fun toggleTrackingProtection() { fun toggleTrackingProtection() {
@ -365,3 +474,29 @@ class SettingsPrivacyTest {
// Verify 'dump' message // Verify 'dump' message
} }
} }
private fun setOpenLinksInPrivateOn() {
homeScreen {
}.openThreeDotMenu {
}.openSettings {
}.openPrivateBrowsingSubMenu {
verifyOpenLinksInPrivateTabEnabled()
clickOpenLinksInPrivateTabSwitch()
}.goBack {
}.goBack {
verifyHomeComponent()
}
}
private fun setOpenLinksInPrivateOff() {
homeScreen {
}.openThreeDotMenu {
}.openSettings {
}.openPrivateBrowsingSubMenu {
clickOpenLinksInPrivateTabSwitch()
verifyOpenLinksInPrivateTabOff()
}.goBack {
}.goBack {
verifyHomeComponent()
}
}

View File

@ -0,0 +1,83 @@
/* 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 android.os.Build
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions.clearText
import androidx.test.espresso.action.ViewActions.typeText
import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.espresso.matcher.ViewMatchers.withText
import androidx.test.uiautomator.By
import androidx.test.uiautomator.By.textContains
import androidx.test.uiautomator.UiScrollable
import androidx.test.uiautomator.UiSelector
import androidx.test.uiautomator.Until
import org.hamcrest.CoreMatchers.anyOf
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 Add to homescreen feature.
*/
class AddToHomeScreenRobot {
fun addShortcutName(title: String) {
mDevice.waitNotNull(Until.findObject(By.text("Add to Home screen")), waitingTime)
shortcutNameField()
.perform(clearText())
.perform(typeText(title))
}
fun clickAddShortcutButton() = addButton().click()
fun clickAddAutomaticallyButton() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
mDevice.wait(Until.findObject(textContains("add automatically")), waitingTime)
addAutomaticallyButton().click()
}
}
class Transition {
fun openHomeScreenShortcut(title: String, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition {
mDevice.wait(
Until.findObject(By.text(title)),
waitingTime
)
mDevice.findObject((UiSelector().text(title))).clickAndWaitForNewWindow(waitingTime)
BrowserRobot().interact()
return BrowserRobot.Transition()
}
fun searchAndOpenHomeScreenShortcut(title: String, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition {
mDevice.pressHome()
fun homeScreenView() = UiScrollable(UiSelector().scrollable(true))
homeScreenView().setAsHorizontalList()
fun shortcut() =
homeScreenView().getChildByText(UiSelector().textContains(title), title)
shortcut().clickAndWaitForNewWindow()
BrowserRobot().interact()
return BrowserRobot.Transition()
}
}
}
fun addToHomeScreen(interact: AddToHomeScreenRobot.() -> Unit): AddToHomeScreenRobot.Transition {
AddToHomeScreenRobot().interact()
return AddToHomeScreenRobot.Transition()
}
private fun shortcutNameField() = onView(withId(R.id.shortcut_text))
private fun addButton() = onView(anyOf(withText("ADD")))
private fun addAutomaticallyButton() =
mDevice.findObject(UiSelector().textContains("add automatically"))

View File

@ -73,6 +73,10 @@ class BookmarksRobot {
} }
fun clickAddFolderButton() { fun clickAddFolderButton() {
mDevice.waitNotNull(
Until.findObject(By.res("org.mozilla.fenix.debug:id/add_bookmark_folder")),
TestAssetHelper.waitingTime
)
addFolderButton().click() addFolderButton().click()
} }

View File

@ -17,17 +17,21 @@ import androidx.test.espresso.intent.Intents.intended
import androidx.test.espresso.intent.matcher.IntentMatchers.toPackage import androidx.test.espresso.intent.matcher.IntentMatchers.toPackage
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.hasDescendant
import androidx.test.espresso.matcher.ViewMatchers.isCompletelyDisplayed import androidx.test.espresso.matcher.ViewMatchers.isCompletelyDisplayed
import androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility import androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility
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.By import androidx.test.uiautomator.By
import androidx.test.uiautomator.By.textContains
import androidx.test.uiautomator.UiDevice import androidx.test.uiautomator.UiDevice
import androidx.test.uiautomator.Until import androidx.test.uiautomator.Until
import org.hamcrest.CoreMatchers import org.hamcrest.CoreMatchers
import org.mozilla.fenix.R import org.mozilla.fenix.R
import org.mozilla.fenix.helpers.Constants.PackageName.GOOGLE_PLAY_SERVICES import org.mozilla.fenix.helpers.Constants.PackageName.GOOGLE_PLAY_SERVICES
import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime
import org.mozilla.fenix.helpers.TestHelper import org.mozilla.fenix.helpers.TestHelper.scrollToElementByText
import org.mozilla.fenix.helpers.click import org.mozilla.fenix.helpers.click
/** /**
@ -52,7 +56,7 @@ class SettingsRobot {
fun verifyEnhancedTrackingProtectionValue(state: String) = fun verifyEnhancedTrackingProtectionValue(state: String) =
assertEnhancedTrackingProtectionValue(state) assertEnhancedTrackingProtectionValue(state)
fun verifyAddPrivateBrowsingShortcutButton() = assertPrivateBrowsingButton() fun verifyPrivateBrowsingButton() = assertPrivateBrowsingButton()
fun verifySitePermissionsButton() = assertSitePermissionsButton() fun verifySitePermissionsButton() = assertSitePermissionsButton()
fun verifyDeleteBrowsingDataButton() = assertDeleteBrowsingDataButton() fun verifyDeleteBrowsingDataButton() = assertDeleteBrowsingDataButton()
fun verifyDeleteBrowsingDataOnQuitButton() = assertDeleteBrowsingDataOnQuitButton() fun verifyDeleteBrowsingDataOnQuitButton() = assertDeleteBrowsingDataOnQuitButton()
@ -95,7 +99,7 @@ class SettingsRobot {
fun openSearchSubMenu(interact: SettingsSubMenuSearchRobot.() -> Unit): fun openSearchSubMenu(interact: SettingsSubMenuSearchRobot.() -> Unit):
SettingsSubMenuSearchRobot.Transition { SettingsSubMenuSearchRobot.Transition {
fun searchEngineButton() = onView(ViewMatchers.withText("Search")) fun searchEngineButton() = onView(withText("Search"))
searchEngineButton().click() searchEngineButton().click()
SettingsSubMenuSearchRobot().interact() SettingsSubMenuSearchRobot().interact()
@ -104,7 +108,7 @@ class SettingsRobot {
fun openCustomizeSubMenu(interact: SettingsSubMenuThemeRobot.() -> Unit): SettingsSubMenuThemeRobot.Transition { fun openCustomizeSubMenu(interact: SettingsSubMenuThemeRobot.() -> Unit): SettingsSubMenuThemeRobot.Transition {
fun customizeButton() = onView(ViewMatchers.withText("Customize")) fun customizeButton() = onView(withText("Customize"))
customizeButton().click() customizeButton().click()
SettingsSubMenuThemeRobot().interact() SettingsSubMenuThemeRobot().interact()
@ -113,7 +117,7 @@ class SettingsRobot {
fun openAccessibilitySubMenu(interact: SettingsSubMenuAccessibilityRobot.() -> Unit): SettingsSubMenuAccessibilityRobot.Transition { fun openAccessibilitySubMenu(interact: SettingsSubMenuAccessibilityRobot.() -> Unit): SettingsSubMenuAccessibilityRobot.Transition {
fun accessibilityButton() = onView(ViewMatchers.withText("Accessibility")) fun accessibilityButton() = onView(withText("Accessibility"))
accessibilityButton().click() accessibilityButton().click()
SettingsSubMenuAccessibilityRobot().interact() SettingsSubMenuAccessibilityRobot().interact()
@ -122,7 +126,7 @@ class SettingsRobot {
fun openDefaultBrowserSubMenu(interact: SettingsSubMenuDefaultBrowserRobot.() -> Unit): SettingsSubMenuDefaultBrowserRobot.Transition { fun openDefaultBrowserSubMenu(interact: SettingsSubMenuDefaultBrowserRobot.() -> Unit): SettingsSubMenuDefaultBrowserRobot.Transition {
fun defaultBrowserButton() = onView(ViewMatchers.withText("Set as default browser")) fun defaultBrowserButton() = onView(withText("Set as default browser"))
defaultBrowserButton().click() defaultBrowserButton().click()
SettingsSubMenuDefaultBrowserRobot().interact() SettingsSubMenuDefaultBrowserRobot().interact()
@ -131,7 +135,7 @@ class SettingsRobot {
fun openEnhancedTrackingProtectionSubMenu(interact: SettingsSubMenuEnhancedTrackingProtectionRobot.() -> Unit): SettingsSubMenuEnhancedTrackingProtectionRobot.Transition { fun openEnhancedTrackingProtectionSubMenu(interact: SettingsSubMenuEnhancedTrackingProtectionRobot.() -> Unit): SettingsSubMenuEnhancedTrackingProtectionRobot.Transition {
fun enhancedTrackingProtectionButton() = fun enhancedTrackingProtectionButton() =
onView(ViewMatchers.withText("Enhanced Tracking Protection")) onView(withText("Enhanced Tracking Protection"))
enhancedTrackingProtectionButton().click() enhancedTrackingProtectionButton().click()
SettingsSubMenuEnhancedTrackingProtectionRobot().interact() SettingsSubMenuEnhancedTrackingProtectionRobot().interact()
@ -139,8 +143,8 @@ class SettingsRobot {
} }
fun openLoginsAndPasswordSubMenu(interact: SettingsSubMenuLoginsAndPasswordRobot.() -> Unit): SettingsSubMenuLoginsAndPasswordRobot.Transition { fun openLoginsAndPasswordSubMenu(interact: SettingsSubMenuLoginsAndPasswordRobot.() -> Unit): SettingsSubMenuLoginsAndPasswordRobot.Transition {
TestHelper.scrollToElementByText("Logins and passwords") scrollToElementByText("Logins and passwords")
fun loginsAndPasswordsButton() = onView(ViewMatchers.withText("Logins and passwords")) fun loginsAndPasswordsButton() = onView(withText("Logins and passwords"))
loginsAndPasswordsButton().click() loginsAndPasswordsButton().click()
SettingsSubMenuLoginsAndPasswordRobot().interact() SettingsSubMenuLoginsAndPasswordRobot().interact()
@ -148,12 +152,21 @@ class SettingsRobot {
} }
fun openTurnOnSyncMenu(interact: SettingsTurnOnSyncRobot.() -> Unit): SettingsTurnOnSyncRobot.Transition { fun openTurnOnSyncMenu(interact: SettingsTurnOnSyncRobot.() -> Unit): SettingsTurnOnSyncRobot.Transition {
fun turnOnSyncButton() = onView(ViewMatchers.withText("Turn on Sync")) fun turnOnSyncButton() = onView(withText("Turn on Sync"))
turnOnSyncButton().click() turnOnSyncButton().click()
SettingsTurnOnSyncRobot().interact() SettingsTurnOnSyncRobot().interact()
return SettingsTurnOnSyncRobot.Transition() return SettingsTurnOnSyncRobot.Transition()
} }
fun openPrivateBrowsingSubMenu(interact: SettingsSubMenuPrivateBrowsingRobot.() -> Unit): SettingsSubMenuPrivateBrowsingRobot.Transition {
scrollToElementByText("Private browsing")
fun privateBrowsingButton() = mDevice.findObject(textContains("Private browsing"))
privateBrowsingButton().click()
SettingsSubMenuPrivateBrowsingRobot().interact()
return SettingsSubMenuPrivateBrowsingRobot.Transition()
}
} }
} }
@ -166,114 +179,114 @@ private fun assertSettingsView() {
} }
// GENERAL SECTION // GENERAL SECTION
private fun assertGeneralHeading() = onView(ViewMatchers.withText("General")) private fun assertGeneralHeading() = onView(withText("General"))
.check(matches(withEffectiveVisibility(Visibility.VISIBLE))) .check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
private fun assertSearchEngineButton() { private fun assertSearchEngineButton() {
mDevice.wait(Until.findObject(By.text("Search")), waitingTime) mDevice.wait(Until.findObject(By.text("Search")), waitingTime)
onView(ViewMatchers.withText("Search")) onView(withText("Search"))
.check(matches(withEffectiveVisibility(Visibility.VISIBLE))) .check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
} }
private fun assertCustomizeButton() = onView(ViewMatchers.withText("Customize")) private fun assertCustomizeButton() = onView(withText("Customize"))
.check(matches(withEffectiveVisibility(Visibility.VISIBLE))) .check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
private fun assertThemeSelected() = onView(ViewMatchers.withText("Light")) private fun assertThemeSelected() = onView(withText("Light"))
.check(matches(withEffectiveVisibility(Visibility.VISIBLE))) .check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
private fun assertAccessibilityButton() = onView(ViewMatchers.withText("Accessibility")) private fun assertAccessibilityButton() = onView(withText("Accessibility"))
.check(matches(withEffectiveVisibility(Visibility.VISIBLE))) .check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
private fun assertSetAsDefaultBrowserButton() = private fun assertSetAsDefaultBrowserButton() =
onView(ViewMatchers.withText("Set as default browser")) onView(withText("Set as default browser"))
.check(matches(withEffectiveVisibility(Visibility.VISIBLE))) .check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
// PRIVACY SECTION // PRIVACY SECTION
private fun assertPrivacyHeading() { private fun assertPrivacyHeading() {
onView(ViewMatchers.withText("Privacy and security")) onView(withText("Privacy and security"))
.check(matches(withEffectiveVisibility(Visibility.VISIBLE))) .check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
} }
private fun assertEnhancedTrackingProtectionButton() { private fun assertEnhancedTrackingProtectionButton() {
mDevice.wait(Until.findObject(By.text("Privacy and Security")), waitingTime) mDevice.wait(Until.findObject(By.text("Privacy and Security")), waitingTime)
onView(ViewMatchers.withId(R.id.recycler_view)).perform( onView(withId(R.id.recycler_view)).perform(
RecyclerViewActions.scrollTo<RecyclerView.ViewHolder>( RecyclerViewActions.scrollTo<RecyclerView.ViewHolder>(
ViewMatchers.hasDescendant(ViewMatchers.withText("Enhanced Tracking Protection")) hasDescendant(withText("Enhanced Tracking Protection"))
) )
).check(matches(withEffectiveVisibility(Visibility.VISIBLE))) ).check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
} }
private fun assertEnhancedTrackingProtectionValue(state: String) { private fun assertEnhancedTrackingProtectionValue(state: String) {
mDevice.wait(Until.findObject(By.text("Enhanced Tracking Protection")), waitingTime) mDevice.wait(Until.findObject(By.text("Enhanced Tracking Protection")), waitingTime)
onView(ViewMatchers.withText(state)).check(matches(withEffectiveVisibility(Visibility.VISIBLE))) onView(withText(state)).check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
} }
private fun assertLoginsButton() { private fun assertLoginsButton() {
TestHelper.scrollToElementByText("Logins and passwords") scrollToElementByText("Logins and passwords")
onView(ViewMatchers.withText("Logins and passwords")) onView(withText("Logins and passwords"))
.check(matches(withEffectiveVisibility(Visibility.VISIBLE))) .check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
} }
private fun assertPrivateBrowsingButton() { private fun assertPrivateBrowsingButton() {
TestHelper.scrollToElementByText("Private browsing") scrollToElementByText("Private browsing")
mDevice.wait(Until.findObject(By.text("Private browsing")), waitingTime) mDevice.wait(Until.findObject(By.text("Private browsing")), waitingTime)
onView(ViewMatchers.withText("Private browsing")) onView(withText("Private browsing"))
.check(matches(withEffectiveVisibility(Visibility.VISIBLE))) .check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
} }
private fun assertSitePermissionsButton() { private fun assertSitePermissionsButton() {
TestHelper.scrollToElementByText("Site permissions") scrollToElementByText("Site permissions")
onView(ViewMatchers.withText("Site permissions")) onView(withText("Site permissions"))
.check(matches(withEffectiveVisibility(Visibility.VISIBLE))) .check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
} }
private fun assertDeleteBrowsingDataButton() { private fun assertDeleteBrowsingDataButton() {
TestHelper.scrollToElementByText("Delete browsing data") scrollToElementByText("Delete browsing data")
onView(ViewMatchers.withText("Delete browsing data")) onView(withText("Delete browsing data"))
.check(matches(withEffectiveVisibility(Visibility.VISIBLE))) .check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
} }
private fun assertDeleteBrowsingDataOnQuitButton() { private fun assertDeleteBrowsingDataOnQuitButton() {
TestHelper.scrollToElementByText("Delete browsing data on quit") scrollToElementByText("Delete browsing data on quit")
onView(ViewMatchers.withText("Delete browsing data on quit")) onView(withText("Delete browsing data on quit"))
.check(matches(withEffectiveVisibility(Visibility.VISIBLE))) .check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
} }
private fun assertDataCollectionButton() = onView(ViewMatchers.withText("Data collection")) private fun assertDataCollectionButton() = onView(withText("Data collection"))
.check(matches(withEffectiveVisibility(Visibility.VISIBLE))) .check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
private fun assertLeakCanaryButton() = onView(ViewMatchers.withText("LeakCanary")) private fun assertLeakCanaryButton() = onView(withText("LeakCanary"))
.check(matches(withEffectiveVisibility(Visibility.VISIBLE))) .check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
// DEVELOPER TOOLS SECTION // DEVELOPER TOOLS SECTION
private fun assertDeveloperToolsHeading() { private fun assertDeveloperToolsHeading() {
TestHelper.scrollToElementByText("Developer tools") scrollToElementByText("Developer tools")
onView(ViewMatchers.withText("Developer tools")) onView(withText("Developer tools"))
.check(matches(withEffectiveVisibility(Visibility.VISIBLE))) .check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
} }
private fun assertRemoteDebug() { private fun assertRemoteDebug() {
TestHelper.scrollToElementByText("Remote debugging via USB") scrollToElementByText("Remote debugging via USB")
onView(ViewMatchers.withText("Remote debugging via USB")) onView(withText("Remote debugging via USB"))
.check(matches(withEffectiveVisibility(Visibility.VISIBLE))) .check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
} }
// ABOUT SECTION // ABOUT SECTION
private fun assertAboutHeading(): ViewInteraction { private fun assertAboutHeading(): ViewInteraction {
TestHelper.scrollToElementByText("About") scrollToElementByText("About")
return onView(ViewMatchers.withText("About")) return onView(withText("About"))
.check(matches(isCompletelyDisplayed())) .check(matches(isCompletelyDisplayed()))
} }
private fun assertRateOnGooglePlay(): ViewInteraction { private fun assertRateOnGooglePlay(): ViewInteraction {
TestHelper.scrollToElementByText("About Firefox Preview") scrollToElementByText("About Firefox Preview")
return onView(ViewMatchers.withText("Rate on Google Play")) return onView(withText("Rate on Google Play"))
.check(matches(isCompletelyDisplayed())) .check(matches(isCompletelyDisplayed()))
} }
private fun assertAboutFirefoxPreview(): ViewInteraction { private fun assertAboutFirefoxPreview(): ViewInteraction {
TestHelper.scrollToElementByText("About Firefox Preview") scrollToElementByText("About Firefox Preview")
return onView(ViewMatchers.withText("About Firefox Preview")) return onView(withText("About Firefox Preview"))
.check(matches(isCompletelyDisplayed())) .check(matches(isCompletelyDisplayed()))
} }

View File

@ -7,18 +7,15 @@
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.action.ViewActions
import androidx.test.espresso.action.ViewActions.click import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.assertion.ViewAssertions.matches import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.intent.Intents.intended import androidx.test.espresso.intent.Intents.intended
import androidx.test.espresso.intent.matcher.IntentMatchers.hasAction import androidx.test.espresso.intent.matcher.IntentMatchers.hasAction
import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.espresso.matcher.ViewMatchers.isNotChecked import androidx.test.espresso.matcher.ViewMatchers.isNotChecked
import androidx.test.espresso.matcher.ViewMatchers.withContentDescription
import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.espresso.matcher.ViewMatchers.withParent import androidx.test.espresso.matcher.ViewMatchers.withParent
import androidx.test.espresso.matcher.ViewMatchers.withText import androidx.test.espresso.matcher.ViewMatchers.withText
import androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility
import androidx.test.espresso.matcher.ViewMatchers.Visibility
import androidx.test.espresso.matcher.ViewMatchers.withContentDescription
import androidx.test.platform.app.InstrumentationRegistry import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.uiautomator.UiDevice import androidx.test.uiautomator.UiDevice
import org.hamcrest.CoreMatchers.allOf import org.hamcrest.CoreMatchers.allOf
@ -35,7 +32,6 @@ class SettingsSubMenuDefaultBrowserRobot {
const val DEFAULT_APPS_SETTINGS_ACTION = "android.settings.MANAGE_DEFAULT_APPS_SETTINGS" const val DEFAULT_APPS_SETTINGS_ACTION = "android.settings.MANAGE_DEFAULT_APPS_SETTINGS"
} }
fun verifyOpenLinksInPrivateTab() = assertOpenLinksInPrivateTab()
fun verifyDefaultBrowserIsDisabled() = assertDefaultBrowserIsDisabled() fun verifyDefaultBrowserIsDisabled() = assertDefaultBrowserIsDisabled()
fun clickDefaultBrowserSwitch() = toggleDefaultBrowserSwitch() fun clickDefaultBrowserSwitch() = toggleDefaultBrowserSwitch()
fun verifyAndroidDefaultAppsMenuAppears() = assertAndroidDefaultAppsMenuAppears() fun verifyAndroidDefaultAppsMenuAppears() = assertAndroidDefaultAppsMenuAppears()
@ -45,7 +41,7 @@ class SettingsSubMenuDefaultBrowserRobot {
fun goBack(interact: SettingsRobot.() -> Unit): SettingsRobot.Transition { fun goBack(interact: SettingsRobot.() -> Unit): SettingsRobot.Transition {
mDevice.waitForIdle() mDevice.waitForIdle()
goBackButton().perform(ViewActions.click()) goBackButton().perform(click())
SettingsRobot().interact() SettingsRobot().interact()
return SettingsRobot.Transition() return SettingsRobot.Transition()
@ -72,10 +68,5 @@ private fun assertAndroidDefaultAppsMenuAppears() {
intended(hasAction(DEFAULT_APPS_SETTINGS_ACTION)) intended(hasAction(DEFAULT_APPS_SETTINGS_ACTION))
} }
private fun assertOpenLinksInPrivateTab() {
onView(withText("Open links in private tab"))
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
}
private fun goBackButton() = private fun goBackButton() =
onView(allOf(withContentDescription("Navigate up"))) onView(allOf(withContentDescription("Navigate up")))

View File

@ -0,0 +1,114 @@
package org.mozilla.fenix.ui.robots
import android.os.Build
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.isEnabled
import androidx.test.espresso.matcher.ViewMatchers.withContentDescription
import androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility
import androidx.test.espresso.matcher.ViewMatchers.withText
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.uiautomator.By
import androidx.test.uiautomator.By.text
import androidx.test.uiautomator.UiDevice
import androidx.test.uiautomator.UiSelector
import androidx.test.uiautomator.Until
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime
import org.mozilla.fenix.helpers.click
/**
* Implementation of Robot Pattern for the settings PrivateBrowsing sub menu.
*/
class SettingsSubMenuPrivateBrowsingRobot {
fun verifyOpenLinksInPrivateTab() = assertOpenLinksInPrivateTab()
fun verifyAddPrivateBrowsingShortcutButton() = assertAddPrivateBrowsingShortcutButton()
fun verifyOpenLinksInPrivateTabEnabled() = assertOpenLinksInPrivateTabEnabled()
fun verifyOpenLinksInPrivateTabOff() = assertOpenLinksInPrivateTabOff()
fun verifyPrivateBrowsingShortcutIcon() = assertPrivateBrowsingShortcutIcon()
fun clickOpenLinksInPrivateTabSwitch() = openLinksInPrivateTabSwitch().click()
fun addPrivateShortcutToHomescreen() {
mDevice.wait(
Until.findObject(text("Add private browsing shortcut")),
waitingTime
)
addPrivateBrowsingShortcutButton().click()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
mDevice.wait(Until.findObject(By.textContains("add automatically")), waitingTime)
addAutomaticallyButton().click()
}
}
class Transition {
val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
fun goBack(interact: SettingsRobot.() -> Unit): SettingsRobot.Transition {
mDevice.waitForIdle()
goBackButton().perform(ViewActions.click())
SettingsRobot().interact()
return SettingsRobot.Transition()
}
fun openPrivateBrowsingShortcut(interact: SearchRobot.() -> Unit): SearchRobot.Transition {
privateBrowsingShortcutIcon().click()
SearchRobot().interact()
return SearchRobot.Transition()
}
}
}
private fun openLinksInPrivateTabSwitch() =
onView(withText("Open links in a private tab"))
private fun addPrivateBrowsingShortcutButton() = onView(withText("Add private browsing shortcut"))
private fun goBackButton() = onView(withContentDescription("Navigate up"))
private fun addAutomaticallyButton() =
mDevice.findObject(UiSelector().textStartsWith("add automatically"))
private fun privateBrowsingShortcutIcon() = mDevice.findObject(text("Private Firefox Preview"))
private fun assertAddPrivateBrowsingShortcutButton() {
mDevice.wait(
Until.findObject(text("Add private browsing shortcut")),
waitingTime
)
addPrivateBrowsingShortcutButton()
.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
}
private fun assertOpenLinksInPrivateTab() {
openLinksInPrivateTabSwitch()
.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
}
private fun assertOpenLinksInPrivateTabEnabled() =
openLinksInPrivateTabSwitch().check(matches(isEnabled()))
private fun assertOpenLinksInPrivateTabOff() {
assertFalse(mDevice.findObject(UiSelector().resourceId("android:id/switch_widget")).isChecked())
openLinksInPrivateTabSwitch()
.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
}
private fun assertPrivateBrowsingShortcutIcon() {
mDevice.wait(
Until.findObject(text("Private Firefox Preview")),
waitingTime
)
assertTrue(mDevice.hasObject(text("Private Firefox Preview")))
}

View File

@ -233,6 +233,14 @@ class ThreeDotMenuMainRobot {
BrowserRobot().interact() BrowserRobot().interact()
return BrowserRobot.Transition() return BrowserRobot.Transition()
} }
fun openAddToHomeScreen(interact: AddToHomeScreenRobot.() -> Unit): AddToHomeScreenRobot.Transition {
mDevice.waitNotNull(Until.findObject(By.text("Add to Home screen")), waitingTime)
addToHomeScreenButton().click()
AddToHomeScreenRobot().interact()
return AddToHomeScreenRobot.Transition()
}
} }
} }
@ -336,6 +344,8 @@ private fun whatsNewButton() = onView(
private fun assertWhatsNewButton() = whatsNewButton() private fun assertWhatsNewButton() = whatsNewButton()
.check(matches(withEffectiveVisibility(Visibility.VISIBLE))) .check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
private fun addToHomeScreenButton() = onView(withText("Add to Home screen"))
private fun readerViewToggle() = onView(allOf(withText(R.string.browser_menu_read))) private fun readerViewToggle() = onView(allOf(withText(R.string.browser_menu_read)))
private fun assertReaderViewToggle(visible: Boolean) = readerViewToggle() private fun assertReaderViewToggle(visible: Boolean) = readerViewToggle()
.check( .check(