Bug 1841493 - Update search settings tests with new unified search UI

fenix/117.0
oana.horvath 11 months ago committed by mergify[bot]
parent e058ba73c6
commit 5fd4307d32

@ -87,6 +87,11 @@ interface FeatureSettingsHelper {
*/
var isUnifiedSearchEnabled: Boolean
/**
* Enable or disable the Unified search settings feature.
*/
var newSearchSettingsEnabled: Boolean
fun applyFlagUpdates()
fun resetAllFeatureFlags()

@ -58,6 +58,7 @@ class FeatureSettingsHelperDelegate() : FeatureSettingsHelper {
}
override var isUnifiedSearchEnabled: Boolean by updatedFeatureFlags::isUnifiedSearchEnabled
override var newSearchSettingsEnabled: Boolean by updatedFeatureFlags::newSearchSettingsEnabled
override var isPocketEnabled: Boolean by updatedFeatureFlags::isPocketEnabled
override var isJumpBackInCFREnabled: Boolean by updatedFeatureFlags::isJumpBackInCFREnabled
override var isWallpaperOnboardingEnabled: Boolean by updatedFeatureFlags::isWallpaperOnboardingEnabled

@ -57,6 +57,7 @@ class HomeActivityTestRule(
etpPolicy: ETPPolicy = getETPPolicy(settings),
tabsTrayRewriteEnabled: Boolean = false,
isUnifiedSearchEnabled: Boolean = false,
newSearchSettingsEnabled: Boolean = false,
) : this(initialTouchMode, launchActivity, skipOnboarding) {
this.isHomeOnboardingDialogEnabled = isHomeOnboardingDialogEnabled
this.isPocketEnabled = isPocketEnabled
@ -72,6 +73,7 @@ class HomeActivityTestRule(
this.etpPolicy = etpPolicy
this.tabsTrayRewriteEnabled = tabsTrayRewriteEnabled
this.isUnifiedSearchEnabled = isUnifiedSearchEnabled
this.newSearchSettingsEnabled = newSearchSettingsEnabled
}
/**
@ -128,6 +130,7 @@ class HomeActivityTestRule(
isCookieBannerReductionDialogEnabled = false,
isOpenInAppBannerEnabled = false,
isUnifiedSearchEnabled = false,
newSearchSettingsEnabled = false,
)
}
}
@ -162,6 +165,7 @@ class HomeActivityIntentTestRule internal constructor(
isPWAsPromptEnabled: Boolean = !settings.userKnowsAboutPwas,
isTCPCFREnabled: Boolean = settings.shouldShowTotalCookieProtectionCFR,
isUnifiedSearchEnabled: Boolean = false,
newSearchSettingsEnabled: Boolean = false,
isWallpaperOnboardingEnabled: Boolean = settings.showWallpaperOnboarding,
isDeleteSitePermissionsEnabled: Boolean = settings.deleteSitePermissions,
isCookieBannerReductionDialogEnabled: Boolean = !settings.userOptOutOfReEngageCookieBannerDialog,
@ -177,6 +181,7 @@ class HomeActivityIntentTestRule internal constructor(
this.isPWAsPromptEnabled = isPWAsPromptEnabled
this.isTCPCFREnabled = isTCPCFREnabled
this.isUnifiedSearchEnabled = isUnifiedSearchEnabled
this.newSearchSettingsEnabled = newSearchSettingsEnabled
this.isWallpaperOnboardingEnabled = isWallpaperOnboardingEnabled
this.isDeleteSitePermissionsEnabled = isDeleteSitePermissionsEnabled
this.isCookieBannerReductionDialogEnabled = isCookieBannerReductionDialogEnabled
@ -265,6 +270,7 @@ class HomeActivityIntentTestRule internal constructor(
skipOnboarding: Boolean = false,
tabsTrayRewriteEnabled: Boolean = false,
isUnifiedSearchEnabled: Boolean = false,
newSearchSettingsEnabled: Boolean = false,
) = HomeActivityIntentTestRule(
initialTouchMode = initialTouchMode,
launchActivity = launchActivity,
@ -274,6 +280,7 @@ class HomeActivityIntentTestRule internal constructor(
isPWAsPromptEnabled = false,
isTCPCFREnabled = false,
isUnifiedSearchEnabled = isUnifiedSearchEnabled,
newSearchSettingsEnabled = newSearchSettingsEnabled,
isWallpaperOnboardingEnabled = false,
isCookieBannerReductionDialogEnabled = false,
isOpenInAppBannerEnabled = false,

@ -569,4 +569,17 @@ class SearchTest {
verifyUrl(searchEngineCodes["DuckDuckGo"]!!)
}
}
// Expected for en-us defaults
@Test
fun changeSearchEnginesBasedOnTextTest() {
homeScreen {
}.openSearch {
typeSearch("D")
verifySearchEnginePrompt(activityTestRule, "DuckDuckGo")
clickSearchEnginePrompt(activityTestRule, "DuckDuckGo")
}.submitQuery("firefox") {
verifyUrl("duckduckgo.com/?q=firefox")
}
}
}

@ -1,6 +1,7 @@
package org.mozilla.fenix.ui
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
import androidx.test.espresso.Espresso.pressBack
import okhttp3.mockwebserver.MockWebServer
import org.junit.After
import org.junit.Before
@ -9,7 +10,6 @@ import org.junit.Rule
import org.junit.Test
import org.mozilla.fenix.R
import org.mozilla.fenix.customannotations.SmokeTest
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.helpers.AndroidAssetDispatcher
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
import org.mozilla.fenix.helpers.RecyclerViewIdlingResource
@ -18,19 +18,26 @@ import org.mozilla.fenix.helpers.TestAssetHelper.getGenericAsset
import org.mozilla.fenix.helpers.TestHelper
import org.mozilla.fenix.helpers.TestHelper.appContext
import org.mozilla.fenix.helpers.TestHelper.exitMenu
import org.mozilla.fenix.helpers.TestHelper.runWithCondition
import org.mozilla.fenix.helpers.TestHelper.setTextToClipBoard
import org.mozilla.fenix.helpers.TestHelper.verifySnackBarText
import org.mozilla.fenix.ui.robots.homeScreen
import org.mozilla.fenix.ui.robots.navigationToolbar
import org.mozilla.fenix.ui.robots.searchScreen
import org.mozilla.fenix.ui.util.ARABIC_LANGUAGE_HEADER
class SettingsSearchTest {
private lateinit var mockWebServer: MockWebServer
private lateinit var searchMockServer: MockWebServer
private val defaultSearchEngineList =
listOf(
"Bing",
"DuckDuckGo",
"Google",
)
@get:Rule
val activityTestRule = AndroidComposeTestRule(
HomeActivityIntentTestRule.withDefaultSettingsOverrides(),
HomeActivityIntentTestRule.withDefaultSettingsOverrides(isUnifiedSearchEnabled = true, newSearchSettingsEnabled = true),
) { it.activity }
@Before
@ -52,28 +59,40 @@ class SettingsSearchTest {
}.openThreeDotMenu {
}.openSettings {
}.openSearchSubMenu {
verifySearchToolbar()
verifySearchSettingsToolbar()
verifySearchEnginesSectionHeader()
verifyDefaultSearchEngineHeader()
verifySearchEngineList()
verifyShowSearchSuggestions()
verifyShowSearchShortcuts()
verifySearchBrowsingHistory()
verifySearchBookmarks()
verifyShowClipboardSuggestionsDefault()
verifyDefaultSearchEngineSummary("Google")
verifyManageSearchShortcutsHeader()
verifyManageShortcutsSummary()
verifyAddressBarSectionHeader()
verifyAutocompleteURlsIsEnabled(true)
verifyShowClipboardSuggestionsEnabled(true)
verifySearchBrowsingHistoryEnabled(true)
verifySearchBookmarksEnabled(true)
verifySearchSyncedTabsEnabled(true)
verifyVoiceSearchEnabled(true)
verifyShowSearchSuggestionsEnabled(true)
verifyShowSearchSuggestionsInPrivateEnabled(false)
}
}
@SmokeTest
@Test
fun selectNewDefaultSearchEngine() {
// Goes through the settings and changes the default search engine, then verifies it has changed.
homeScreen {
}.openThreeDotMenu {
}.openSettings {
}.openSearchSubMenu {
changeDefaultSearchEngine("DuckDuckGo")
}.goBack {
}.goBack {
verifyDefaultSearchEngine("DuckDuckGo")
defaultSearchEngineList.forEach {
homeScreen {
}.openThreeDotMenu {
}.openSettings {
}.openSearchSubMenu {
openDefaultSearchEngineMenu()
changeDefaultSearchEngine(it)
exitMenu()
}
searchScreen {
verifySearchEngineIcon(it)
}
}
}
@ -98,11 +117,9 @@ class SettingsSearchTest {
}
}
@Ignore("Failing, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1807268")
@Test
fun toggleSearchBookmarksAndHistoryTest() {
fun toggleSearchHistoryTest() {
val page1 = getGenericAsset(mockWebServer, 1)
val page2 = getGenericAsset(mockWebServer, 2)
navigationToolbar {
}.enterURLAndEnterToBrowser(page1.url) {
@ -125,8 +142,32 @@ class SettingsSearchTest {
closeTab()
}
homeScreen {
}.openThreeDotMenu {
}.openSettings {
}.openSearchSubMenu {
switchSearchHistoryToggle()
exitMenu()
}
homeScreen {
}.openSearch {
typeSearch("test")
verifyNoSuggestionsAreDisplayed(
activityTestRule,
"Firefox Suggest",
"Test_Page_1",
)
}
}
@Ignore("Failing, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1807268")
@Test
fun toggleSearchBookmarksTest() {
val website = getGenericAsset(mockWebServer, 1)
navigationToolbar {
}.enterURLAndEnterToBrowser(page2.url) {
}.enterURLAndEnterToBrowser(website.url) {
}.openThreeDotMenu {
}.bookmarkPage {
}.openTabDrawer {
@ -137,11 +178,10 @@ class SettingsSearchTest {
}.openThreeDotMenu {
}.openHistory {
verifyHistoryListExists()
clickDeleteHistoryButton("Test_Page_2")
clickDeleteHistoryButton("Test_Page_1")
exitMenu()
}
exitMenu()
homeScreen {
}.openSearch {
typeSearch("test")
@ -149,10 +189,10 @@ class SettingsSearchTest {
activityTestRule,
"test",
"Firefox Suggest",
"Test_Page_2",
"Test_Page_1",
)
}.clickSearchSuggestion("Test_Page_2") {
verifyUrl(page2.url.toString())
}.clickSearchSuggestion("Test_Page_1") {
verifyUrl(website.url.toString())
}.openTabDrawer {
closeTab()
}
@ -161,12 +201,13 @@ class SettingsSearchTest {
}.openThreeDotMenu {
}.openSettings {
}.openSearchSubMenu {
switchSearchHistoryToggle()
switchSearchBookmarksToggle()
// We want to avoid confusion between history and bookmarks searches,
// so we'll disable this too.
switchSearchHistoryToggle()
exitMenu()
}
exitMenu()
homeScreen {
}.openSearch {
typeSearch("test")
@ -174,48 +215,14 @@ class SettingsSearchTest {
activityTestRule,
"Firefox Suggest",
"Test_Page_1",
"Test_Page_2",
)
}
}
// Ads a new search engine from the list of custom engines
@SmokeTest
@Test
fun addPredefinedSearchEngineTest() {
val searchEngine = "Reddit"
homeScreen {
}.openThreeDotMenu {
}.openSettings {
}.openSearchSubMenu {
openAddSearchEngineMenu()
verifyAddSearchEngineList()
addNewSearchEngine(searchEngine)
verifyEngineListContains(searchEngine)
}.goBack {
}.goBack {
}.openSearch {
verifyKeyboardVisibility()
clickSearchEngineShortcutButton()
verifyEnginesListShortcutContains(activityTestRule, searchEngine)
changeDefaultSearchEngine(activityTestRule, searchEngine)
}.submitQuery("mozilla ") {
verifyUrl(searchEngine)
}.openThreeDotMenu {
}.openSettings {
verifySettingsOptionSummary("Search", "Google")
}.openSearchSubMenu {
changeDefaultSearchEngine(searchEngine)
}.goBack {
verifySettingsOptionSummary("Search", searchEngine)
}
}
// Verifies setting as default a customized search engine name and URL
@SmokeTest
@Test
fun editCustomSearchEngineTest() {
fun addCustomDefaultSearchEngineTest() {
searchMockServer = MockWebServer().apply {
dispatcher = SearchDispatcher()
start()
@ -223,29 +230,33 @@ class SettingsSearchTest {
val searchEngine = object {
val title = "TestSearchEngine"
val url = "http://localhost:${searchMockServer.port}/searchResults.html?search=%s"
val newTitle = "Test"
}
homeScreen {
}.openThreeDotMenu {
}.openSettings {
}.openSearchSubMenu {
openDefaultSearchEngineMenu()
openAddSearchEngineMenu()
selectAddCustomSearchEngine()
verifySaveSearchEngineButtonEnabled(false)
typeCustomEngineDetails(searchEngine.title, searchEngine.url)
verifySaveSearchEngineButtonEnabled(true)
saveNewSearchEngine()
verifyEngineListContains(searchEngine.title)
openEngineOverflowMenu(searchEngine.title)
clickEdit()
typeCustomEngineDetails(searchEngine.newTitle, searchEngine.url)
saveEditSearchEngine()
changeDefaultSearchEngine(searchEngine.newTitle)
pressBack()
changeDefaultSearchEngine(searchEngine.title)
pressBack()
openManageShortcutsMenu()
verifyEngineListContains(searchEngine.title)
pressBack()
}.goBack {
verifySettingsOptionSummary("Search", searchEngine.newTitle)
verifySettingsOptionSummary("Search", searchEngine.title)
}.goBack {
}.openSearch {
verifyDefaultSearchEngine(searchEngine.newTitle)
clickSearchEngineShortcutButton()
verifyEnginesListShortcutContains(activityTestRule, searchEngine.newTitle)
verifySearchEngineIcon(searchEngine.title)
clickSearchSelectorButton()
verifySearchShortcutListContains(searchEngine.title)
}
}
@ -300,7 +311,7 @@ class SettingsSearchTest {
}.openThreeDotMenu {
}.openSettings {
}.openSearchSubMenu {
toggleShowSuggestionsInPrivateSessions()
switchShowSuggestionsInPrivateSessionsToggle()
}.goBack {
}.goBack {
}.openSearch {
@ -309,7 +320,6 @@ class SettingsSearchTest {
}
}
@SmokeTest
@Test
fun toggleVoiceSearchTest() {
homeScreen {
@ -341,8 +351,9 @@ class SettingsSearchTest {
}.openThreeDotMenu {
}.openSettings {
}.openSearchSubMenu {
verifyShowClipboardSuggestionsDefault()
verifyShowClipboardSuggestionsEnabled(true)
toggleClipboardSuggestion()
verifyShowClipboardSuggestionsEnabled(false)
exitMenu()
}
homeScreen {
@ -351,97 +362,37 @@ class SettingsSearchTest {
}
}
// Expected for en-us defaults
@Test
fun undoDeleteSearchEngineTest() {
homeScreen {
}.openThreeDotMenu {
}.openSettings {
}.openSearchSubMenu {
verifyEngineListContains("Bing")
openEngineOverflowMenu("Bing")
clickDeleteSearchEngine()
clickUndoSnackBarButton()
verifyEngineListContains("Bing")
fun deleteCustomSearchEngineTest() {
searchMockServer = MockWebServer().apply {
dispatcher = SearchDispatcher()
start()
}
}
// Expected for en-us defaults
@Test
fun deleteDefaultSearchEngineTest() {
homeScreen {
}.openThreeDotMenu {
}.openSettings {
}.openSearchSubMenu {
verifyEngineListContains("Google")
verifyDefaultSearchEngine("Google")
openEngineOverflowMenu("Google")
clickDeleteSearchEngine()
verifyEngineListDoesNotContain("Google")
verifyDefaultSearchEngine("Bing")
val searchEngine = object {
val title = "TestSearchEngine"
val url = "http://localhost:${searchMockServer.port}/searchResults.html?search=%s"
}
}
// Expected for en-us defaults
@Test
fun deleteAllSearchEnginesTest() {
homeScreen {
}.openThreeDotMenu {
}.openSettings {
}.openSearchSubMenu {
runWithCondition(!appContext.settings().showUnifiedSearchFeature) {
// If the feature is disabled run old steps.
deleteMultipleSearchEngines(
"Google",
"Bing",
"Amazon.com",
"DuckDuckGo",
"eBay",
)
verifyDefaultSearchEngine("Wikipedia")
verifyThreeDotButtonIsNotDisplayed("Wikipedia")
openAddSearchEngineMenu()
verifyAddSearchEngineListContains(
"Google",
"Bing",
"Amazon.com",
"DuckDuckGo",
"eBay",
)
}
runWithCondition(appContext.settings().showUnifiedSearchFeature) {
// Run steps suitable for the enabled unified search feature.
deleteMultipleSearchEngines(
"Google",
"Bing",
"Amazon.com",
"eBay",
"Wikipedia",
)
verifyDefaultSearchEngine("DuckDuckGo")
verifyThreeDotButtonIsNotDisplayed("DuckDuckGo")
openAddSearchEngineMenu()
verifyAddSearchEngineListContains(
"Google",
"Bing",
"Amazon.com",
"eBay",
"Wikipedia",
)
}
}
}
// Expected for en-us defaults
@Test
fun changeSearchEnginesBasedOnTextTest() {
homeScreen {
}.openSearch {
typeSearch("D")
verifySearchEnginePrompt(activityTestRule, "DuckDuckGo")
clickSearchEnginePrompt(activityTestRule, "DuckDuckGo")
}.submitQuery("firefox") {
verifyUrl("duckduckgo.com/?q=firefox")
openDefaultSearchEngineMenu()
openAddSearchEngineMenu()
verifySaveSearchEngineButtonEnabled(false)
typeCustomEngineDetails(searchEngine.title, searchEngine.url)
verifySaveSearchEngineButtonEnabled(true)
saveNewSearchEngine()
verifyEngineListContains(searchEngine.title)
openEngineOverflowMenu(searchEngine.title)
clickDeleteSearchEngine()
clickUndoSnackBarButton()
verifyEngineListContains(searchEngine.title)
changeDefaultSearchEngine(searchEngine.title)
openEngineOverflowMenu(searchEngine.title)
clickDeleteSearchEngine()
verifySnackBarText("Deleted ${searchEngine.title}")
verifyEngineListDoesNotContain(searchEngine.title)
}
}
@ -451,9 +402,6 @@ class SettingsSearchTest {
homeScreen {
}.openThreeDotMenu {
}.openSettings {
}.openSearchSubMenu {
toggleShowSearchShortcuts()
}.goBack {
}.openLanguageSubMenu {
TestHelper.registerAndCleanupIdlingResources(
RecyclerViewIdlingResource(
@ -471,74 +419,17 @@ class SettingsSearchTest {
homeScreen {
}.openSearch {
verifyTranslatedFocusedNavigationToolbar("ابحث أو أدخِل عنوانا")
verifySearchEngineShortcuts(
activityTestRule,
clickSearchSelectorButton()
verifySearchShortcutListContains(
"Google",
"Bing",
"Amazon.com",
"DuckDuckGo",
"ويكيبيديا (ar)",
)
changeDefaultSearchEngine(activityTestRule, "ويكيبيديا (ar)")
selectTemporarySearchMethod("ويكيبيديا (ar)")
}.submitQuery("firefox") {
verifyUrl("ar.m.wikipedia.org")
}
}
// Expected for en-us defaults
@Test
fun toggleSearchEnginesShortcutListTest() {
homeScreen {
}.openThreeDotMenu {
}.openSettings {
}.openSearchSubMenu {
verifyShowSearchEnginesToggleState(false)
toggleShowSearchShortcuts()
verifyShowSearchEnginesToggleState(true)
}
exitMenu()
homeScreen {
}.openSearch {
verifySearchEngineShortcuts(
activityTestRule,
"Google",
"Bing",
"Amazon.com",
"DuckDuckGo",
"eBay",
"Wikipedia",
)
scrollToSearchEngineSettings(activityTestRule)
}.clickSearchEngineSettings(activityTestRule) {
toggleShowSearchShortcuts()
verifyShowSearchEnginesToggleState(false)
}
exitMenu()
homeScreen {
}.openSearch {
verifySearchEngineShortcutsAreNotDisplayed(
activityTestRule,
"Google",
"Bing",
"Amazon.com",
"DuckDuckGo",
"eBay",
"Wikipedia",
)
clickSearchEngineShortcutButton()
verifySearchEngineShortcuts(
activityTestRule,
"Google",
"Bing",
"Amazon.com",
"DuckDuckGo",
"eBay",
"Wikipedia",
)
verifyUrl("firefox")
}
}
}

@ -7,11 +7,9 @@
package org.mozilla.fenix.ui.robots
import androidx.compose.ui.test.ExperimentalTestApi
import androidx.compose.ui.test.assertHasClickAction
import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.hasText
import androidx.compose.ui.test.junit4.ComposeTestRule
import androidx.compose.ui.test.junit4.android.ComposeNotIdleException
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick
@ -24,7 +22,6 @@ import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.intent.Intents
import androidx.test.espresso.intent.matcher.IntentMatchers
import androidx.test.espresso.matcher.ViewMatchers
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.withText
@ -188,15 +185,26 @@ class SearchRobot {
).click()
}
fun verifySearchEnginePrompt(rule: ComposeTestRule, searchEngineName: String) =
assertSearchEnginePrompt(rule, searchEngineName)
fun verifySearchEnginePrompt(rule: ComposeTestRule, searchEngineName: String) {
rule.waitForIdle()
rule.onNodeWithText("Search $searchEngineName").assertIsDisplayed()
rule.onNodeWithText(
getStringResource(R.string.search_engine_suggestions_description),
).assertIsDisplayed()
}
fun verifySearchBarEmpty() = assertSearchBarEmpty()
fun verifyKeyboardVisibility() = assertKeyboardVisibility(isExpectedToBeVisible = true)
fun verifySearchEngineList(rule: ComposeTestRule) = rule.assertSearchEngineList()
fun verifySearchSelectorButton() {
assertTrue(itemWithResId("$packageName:id/search_selector").waitForExists(waitingTime))
assertTrue(searchSelectorButton.waitForExists(waitingTime))
}
fun clickSearchSelectorButton() {
searchSelectorButton.waitForExists(waitingTime)
searchSelectorButton.click()
}
fun verifySearchEngineIcon(name: String) =
@ -209,13 +217,25 @@ class SearchRobot {
)
}
fun verifyDefaultSearchEngine(expectedText: String) = assertDefaultSearchEngine(expectedText)
fun verifyEnginesListShortcutContains(rule: ComposeTestRule, searchEngineName: String) = assertEngineListShortcutContains(rule, searchEngineName)
fun verifySearchShortcutListContains(vararg searchEngineName: String) {
searchEngineName.forEach {
assertTrue(
searchShortcutList.getChild(UiSelector().text(it))
.waitForExists(waitingTimeShort),
)
}
}
// Old search UI shortcut selector - to be removed.
fun changeDefaultSearchEngine(rule: ComposeTestRule, searchEngineName: String) =
rule.selectDefaultSearchEngine(searchEngineName)
// New unified search UI search selector.
fun selectTemporarySearchMethod(searchEngineName: String) {
searchShortcutList.getChild(UiSelector().text(searchEngineName)).click()
}
// Old search UI shortcut selector - to be removed.
fun clickSearchEngineShortcutButton() {
itemWithResId("$packageName:id/search_engines_shortcut_button").also {
it.waitForExists(waitingTime)
@ -317,17 +337,6 @@ class SearchRobot {
}
}
fun verifySearchEngineShortcutsAreNotDisplayed(rule: ComposeTestRule, vararg searchEngines: String) {
mDevice.findObject(
UiSelector().resourceId("$packageName:id/pill_wrapper_divider"),
).waitForExists(waitingTime)
for (searchEngine in searchEngines) {
rule.waitForIdle()
rule.onNodeWithText(searchEngine).assertDoesNotExist()
}
}
fun verifyTypedToolbarText(expectedText: String) {
mDevice.findObject(UiSelector().resourceId("$packageName:id/toolbar"))
.waitForExists(waitingTime)
@ -439,14 +448,6 @@ private fun clearButton() =
private fun searchWrapper() = mDevice.findObject(UiSelector().resourceId("$packageName:id/search_wrapper"))
private fun assertSearchEnginePrompt(rule: ComposeTestRule, searchEngineName: String) {
rule.waitForIdle()
rule.onNodeWithText("Search $searchEngineName").assertIsDisplayed()
rule.onNodeWithText(
getStringResource(R.string.search_engine_suggestions_description),
).assertIsDisplayed()
}
private fun assertScanButton() =
assertTrue(
scanButton.waitForExists(waitingTime),
@ -459,6 +460,8 @@ private fun assertSearchButton() =
).waitForExists(waitingTime),
)
private val searchSelectorButton = itemWithResId("$packageName:id/search_selector")
private fun assertSearchBarEmpty() =
assertTrue(
mDevice.findObject(
@ -513,29 +516,8 @@ private fun ComposeTestRule.assertSearchEngineList() {
.assertIsDisplayed()
}
@OptIn(ExperimentalTestApi::class)
private fun assertEngineListShortcutContains(rule: ComposeTestRule, searchEngineName: String) {
try {
rule.waitForIdle()
} catch (e: ComposeNotIdleException) {
mDevice.pressBack()
navigationToolbar {
}.clickUrlbar {
clickSearchEngineShortcutButton()
}
} finally {
mDevice.findObject(
UiSelector().textContains("Google"),
).waitForExists(waitingTime)
rule.onNodeWithTag("mozac.awesomebar.suggestions")
.performScrollToNode(hasText(searchEngineName))
rule.onNodeWithText(searchEngineName)
.assertIsDisplayed()
.assertHasClickAction()
}
}
private val searchShortcutList =
mDevice.findObject(UiSelector().resourceId("$packageName:id/mozac_browser_menu_recyclerView"))
private fun ComposeTestRule.selectDefaultSearchEngine(searchEngine: String) {
onNodeWithText(searchEngine)
@ -544,15 +526,6 @@ private fun ComposeTestRule.selectDefaultSearchEngine(searchEngine: String) {
.performClick()
}
private fun assertDefaultSearchEngine(expectedText: String) =
assertTrue(
mDevice.findObject(
UiSelector()
.resourceId("$packageName:id/mozac_browser_toolbar_edit_icon")
.descriptionContains(expectedText),
).waitForExists(waitingTime),
)
private fun assertTranslatedFocusedNavigationToolbar(toolbarHintString: String) =
assertTrue(
mDevice.findObject(
@ -566,5 +539,3 @@ private val awesomeBar =
mDevice.findObject(UiSelector().resourceId("$packageName:id/mozac_browser_toolbar_edit_url_view"))
private val voiceSearchButton = mDevice.findObject(UiSelector().description("Voice search"))
private fun goBackButton() = onView(allOf(withContentDescription("Navigate up")))

@ -8,11 +8,13 @@ package org.mozilla.fenix.ui.robots
import androidx.recyclerview.widget.RecyclerView
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.ViewInteraction
import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.contrib.RecyclerViewActions
import androidx.test.espresso.matcher.ViewMatchers
import androidx.test.espresso.matcher.ViewMatchers.hasDescendant
import androidx.test.espresso.matcher.ViewMatchers.hasSibling
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
import androidx.test.espresso.matcher.ViewMatchers.withChild
import androidx.test.espresso.matcher.ViewMatchers.withClassName
@ -30,6 +32,7 @@ import org.hamcrest.Matchers.endsWith
import org.junit.Assert.assertTrue
import org.mozilla.fenix.R
import org.mozilla.fenix.helpers.MatcherHelper.itemContainingText
import org.mozilla.fenix.helpers.MatcherHelper.itemWithText
import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime
import org.mozilla.fenix.helpers.TestAssetHelper.waitingTimeShort
import org.mozilla.fenix.helpers.TestHelper.getStringResource
@ -38,88 +41,134 @@ import org.mozilla.fenix.helpers.TestHelper.mDevice
import org.mozilla.fenix.helpers.TestHelper.packageName
import org.mozilla.fenix.helpers.click
import org.mozilla.fenix.helpers.isChecked
import org.mozilla.fenix.helpers.isEnabled
/**
* Implementation of Robot Pattern for the settings search sub menu.
*/
class SettingsSubMenuSearchRobot {
fun verifySearchToolbar() = assertSearchToolbar()
fun verifyDefaultSearchEngineHeader() = assertDefaultSearchEngineHeader()
fun verifySearchEngineList() = assertSearchEngineList()
fun verifyShowSearchSuggestions() {
onView(withId(androidx.preference.R.id.recycler_view)).perform(
RecyclerViewActions.scrollTo<RecyclerView.ViewHolder>(
hasDescendant(withText("Show search suggestions")),
fun verifySearchSettingsToolbar() {
onView(
allOf(
withId(R.id.navigationToolbar),
hasDescendant(withContentDescription(R.string.action_bar_up_description)),
hasDescendant(withText(R.string.preferences_search)),
),
)
onView(withText("Show search suggestions"))
).check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
}
fun verifySearchEnginesSectionHeader() {
onView(withText("Search Engines")).check(matches(isDisplayed()))
}
fun verifyDefaultSearchEngineHeader() {
defaultSearchEngineHeader
.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
}
fun verifyShowSearchShortcuts() = assertShowSearchShortcuts()
fun verifyDefaultSearchEngineSummary(engineName: String) {
defaultSearchEngineHeader.check(matches(hasSibling(withText(engineName))))
}
fun verifyShowClipboardSuggestionsDefault() {
onView(withId(androidx.preference.R.id.recycler_view)).perform(
RecyclerViewActions.scrollTo<RecyclerView.ViewHolder>(
hasDescendant(withText(getStringResource(R.string.preferences_show_clipboard_suggestions))),
),
)
onView(withText(getStringResource(R.string.preferences_show_clipboard_suggestions)))
fun verifyManageSearchShortcutsHeader() {
manageSearchShortcutsHeader.check(matches(isDisplayed()))
}
fun verifyManageShortcutsSummary() {
manageSearchShortcutsHeader
.check(matches(hasSibling(withText("Edit engines visible in the search menu"))))
}
fun verifyAddressBarSectionHeader() {
onView(withText("Address bar")).check(matches(isDisplayed()))
}
fun verifySearchEngineList() {
onView(withText("Google"))
.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
onView(withText("Amazon.com"))
.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
onView(withText("Bing"))
.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
onView(withText("DuckDuckGo"))
.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
onView(withText("Wikipedia"))
.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
onView(withText("Add search engine"))
.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
.check(matches(hasCousin(allOf(withClassName(endsWith("Switch")), isChecked(true)))))
}
fun toggleClipboardSuggestion() {
onView(withText(getStringResource(R.string.preferences_show_clipboard_suggestions)))
.click()
fun verifyAutocompleteURlsIsEnabled(enabled: Boolean) {
autocompleteSwitchButton()
.check(matches(hasCousin(allOf(withClassName(endsWith("Switch")), isChecked(enabled)))))
}
fun verifySearchBrowsingHistory() {
onView(withId(androidx.preference.R.id.recycler_view)).perform(
RecyclerViewActions.scrollTo<RecyclerView.ViewHolder>(
hasDescendant(withText("Search browsing history")),
),
)
searchHistoryToggle
fun verifyShowSearchSuggestionsEnabled(enabled: Boolean) {
showSearchSuggestionSwitchButton()
.check(matches(hasCousin(allOf(withClassName(endsWith("Switch")), isChecked(enabled)))))
}
fun verifyShowSearchSuggestionsInPrivateEnabled(enabled: Boolean) {
showSuggestionsInPrivateModeSwitch()
.check(
matches(
hasSibling(
withChild(
allOf(
withClassName(endsWith("CheckBox")),
isChecked(enabled),
),
),
),
),
)
}
fun verifyShowClipboardSuggestionsEnabled(enabled: Boolean) {
showClipboardSuggestionSwitch()
.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
.check(matches(hasCousin(allOf(withClassName(endsWith("Switch")), isChecked(enabled)))))
}
fun verifySearchBookmarks() {
onView(withId(androidx.preference.R.id.recycler_view)).perform(
RecyclerViewActions.scrollTo<RecyclerView.ViewHolder>(
hasDescendant(withText("Search bookmarks")),
),
)
searchBookmarksToggle
fun verifySearchBrowsingHistoryEnabled(enabled: Boolean) {
searchHistorySwitchButton()
.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
.check(matches(hasCousin(allOf(withClassName(endsWith("Switch")), isChecked(enabled)))))
}
fun changeDefaultSearchEngine(searchEngineName: String) =
selectSearchEngine(searchEngineName)
fun verifySearchBookmarksEnabled(enabled: Boolean) {
searchBookmarksSwitchButton()
.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
.check(matches(hasCousin(allOf(withClassName(endsWith("Switch")), isChecked(enabled)))))
}
fun toggleAutocomplete() {
onView(withId(androidx.preference.R.id.recycler_view)).perform(
RecyclerViewActions.scrollTo<RecyclerView.ViewHolder>(
hasDescendant(withText(getStringResource(R.string.preferences_enable_autocomplete_urls))),
),
)
fun verifySearchSyncedTabsEnabled(enabled: Boolean) {
searchSyncedTabsSwitchButton()
.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
.check(matches(hasCousin(allOf(withClassName(endsWith("Switch")), isChecked(enabled)))))
}
onView(withText(getStringResource(R.string.preferences_enable_autocomplete_urls)))
.click()
fun verifyVoiceSearchEnabled(enabled: Boolean) {
voiceSearchSwitchButton()
.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
.check(matches(hasCousin(allOf(withClassName(endsWith("Switch")), isChecked(enabled)))))
}
fun toggleShowSearchSuggestions() {
onView(withId(androidx.preference.R.id.recycler_view)).perform(
RecyclerViewActions.scrollTo<RecyclerView.ViewHolder>(
hasDescendant(withText("Show search suggestions")),
),
)
fun openDefaultSearchEngineMenu() {
defaultSearchEngineHeader.click()
}
onView(withText("Show search suggestions"))
.perform(click())
fun openManageShortcutsMenu() {
manageSearchShortcutsHeader.click()
}
fun changeDefaultSearchEngine(searchEngineName: String) =
selectSearchEngine(searchEngineName)
fun toggleAutocomplete() = autocompleteSwitchButton().click()
fun toggleShowSearchSuggestions() = showSearchSuggestionSwitchButton().click()
fun toggleShowSearchShortcuts() =
itemContainingText(getStringResource(R.string.preferences_show_search_engines))
.also {
@ -128,60 +177,48 @@ class SettingsSubMenuSearchRobot {
}
fun toggleVoiceSearch() {
onView(withId(androidx.preference.R.id.recycler_view)).perform(
RecyclerViewActions.scrollTo<RecyclerView.ViewHolder>(
hasDescendant(withText("Show voice search")),
),
)
onView(withText("Show voice search")).perform(click())
voiceSearchSwitchButton().perform(click())
}
fun switchSearchHistoryToggle() {
onView(withId(androidx.preference.R.id.recycler_view)).perform(
RecyclerViewActions.scrollTo<RecyclerView.ViewHolder>(
hasDescendant(withText("Search browsing history")),
),
)
searchHistoryToggle.click()
fun toggleClipboardSuggestion() {
showClipboardSuggestionSwitch().click()
}
fun switchSearchBookmarksToggle() {
onView(withId(androidx.preference.R.id.recycler_view)).perform(
RecyclerViewActions.scrollTo<RecyclerView.ViewHolder>(
hasDescendant(withText("Search bookmarks")),
),
)
searchBookmarksToggle.click()
}
fun switchSearchHistoryToggle() = searchHistorySwitchButton().click()
fun toggleShowSuggestionsInPrivateSessions() {
onView(withId(androidx.preference.R.id.recycler_view)).perform(
RecyclerViewActions.scrollTo<RecyclerView.ViewHolder>(
hasDescendant(withText(getStringResource(R.string.preferences_show_search_suggestions_in_private))),
),
)
onView(withText(getStringResource(R.string.preferences_show_search_suggestions_in_private)))
.click()
}
fun switchSearchBookmarksToggle() = searchBookmarksSwitchButton().click()
fun openAddSearchEngineMenu() = addSearchEngineButton().click()
fun switchShowSuggestionsInPrivateSessionsToggle() = showSuggestionsInPrivateModeSwitch().click()
fun verifyAddSearchEngineList() = assertAddSearchEngineList()
fun openAddSearchEngineMenu() = addSearchEngineButton().click()
fun verifyEngineListContains(searchEngineName: String) = assertEngineListContains(searchEngineName)
fun verifyEngineListContains(searchEngineName: String) {
assertTrue(itemWithText(searchEngineName).waitForExists(waitingTimeShort))
}
fun verifyEngineListDoesNotContain(searchEngineName: String) = assertEngineListDoesNotContain(searchEngineName)
fun verifyDefaultSearchEngine(searchEngineName: String) = assertDefaultSearchEngine(searchEngineName)
fun verifyDefaultSearchEngine(searchEngineName: String) {
onView(
allOf(
withId(R.id.radio_button),
withParent(withChild(withText(searchEngineName))),
),
).check(matches(isChecked(true)))
}
fun verifyThreeDotButtonIsNotDisplayed(searchEngineName: String) = assertThreeDotButtonIsNotDisplayed(searchEngineName)
fun verifyAddSearchEngineListContains(vararg searchEngines: String) {
for (searchEngine in searchEngines) {
assertEngineListContains(searchEngine)
onView(withId(R.id.search_engine_group)).check(matches(hasDescendant(withText(searchEngine))))
}
}
fun verifySaveSearchEngineButtonEnabled(enabled: Boolean) {
addSearchEngineSaveButton().check(matches(isEnabled(enabled)))
}
fun saveNewSearchEngine() {
addSearchEngineSaveButton().click()
assertTrue(
@ -191,20 +228,10 @@ class SettingsSubMenuSearchRobot {
)
}
fun addNewSearchEngine(searchEngineName: String) {
selectSearchEngine(searchEngineName)
saveNewSearchEngine()
}
fun selectAddCustomSearchEngine() = onView(withText("Other")).click()
fun typeCustomEngineDetails(engineName: String, engineURL: String) {
mDevice.findObject(By.res("$packageName:id/edit_engine_name")).clear()
mDevice.findObject(By.res("$packageName:id/edit_engine_name")).setText(engineName)
mDevice.findObject(By.res("$packageName:id/edit_search_string")).clear()
mDevice.findObject(By.res("$packageName:id/edit_search_string")).setText(engineURL)
try {
mDevice.findObject(By.res("$packageName:id/edit_engine_name")).clear()
mDevice.findObject(By.res("$packageName:id/edit_engine_name")).text = engineName
assertTrue(
mDevice.findObject(
UiSelector()
@ -213,6 +240,8 @@ class SettingsSubMenuSearchRobot {
).waitForExists(waitingTime),
)
mDevice.findObject(By.res("$packageName:id/edit_search_string")).clear()
mDevice.findObject(By.res("$packageName:id/edit_search_string")).text = engineURL
assertTrue(
mDevice.findObject(
UiSelector()
@ -222,17 +251,13 @@ class SettingsSubMenuSearchRobot {
)
} catch (e: AssertionError) {
println("The name or the search string were not set properly")
// Lets again set both name and search string
goBackButton().click()
openAddSearchEngineMenu()
selectAddCustomSearchEngine()
//
// // Lets again set both name and search string
// goBackButton().click()
// openAddSearchEngineMenu()
mDevice.findObject(By.res("$packageName:id/edit_engine_name")).clear()
mDevice.findObject(By.res("$packageName:id/edit_engine_name")).setText(engineName)
mDevice.findObject(By.res("$packageName:id/edit_search_string")).clear()
mDevice.findObject(By.res("$packageName:id/edit_search_string")).setText(engineURL)
assertTrue(
mDevice.findObject(
UiSelector()
@ -241,6 +266,8 @@ class SettingsSubMenuSearchRobot {
).waitForExists(waitingTime),
)
mDevice.findObject(By.res("$packageName:id/edit_search_string")).clear()
mDevice.findObject(By.res("$packageName:id/edit_search_string")).setText(engineURL)
assertTrue(
mDevice.findObject(
UiSelector()
@ -305,47 +332,84 @@ fun searchSettingsScreen(interact: SettingsSubMenuSearchRobot.() -> Unit): Setti
return SettingsSubMenuSearchRobot.Transition()
}
private fun assertSearchToolbar() =
onView(
allOf(
withId(R.id.navigationToolbar),
hasDescendant(withContentDescription(R.string.action_bar_up_description)),
hasDescendant(withText(R.string.preferences_search)),
private val defaultSearchEngineHeader =
onView(withText("Default search engine"))
private val manageSearchShortcutsHeader = onView(withText("Manage search shortcuts"))
private fun searchHistorySwitchButton(): ViewInteraction {
onView(withId(androidx.preference.R.id.recycler_view)).perform(
RecyclerViewActions.scrollTo<RecyclerView.ViewHolder>(
hasDescendant(withText("Search browsing history")),
),
).check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
)
return onView(withText("Search browsing history"))
}
private fun assertDefaultSearchEngineHeader() =
onView(withText("Default search engine"))
.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
private fun searchBookmarksSwitchButton(): ViewInteraction {
onView(withId(androidx.preference.R.id.recycler_view)).perform(
RecyclerViewActions.scrollTo<RecyclerView.ViewHolder>(
hasDescendant(withText("Search bookmarks")),
),
)
return onView(withText("Search bookmarks"))
}
private fun assertSearchEngineList() {
onView(withText("Google"))
.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
onView(withText("Amazon.com"))
.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
onView(withText("Bing"))
.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
onView(withText("DuckDuckGo"))
.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
onView(withText("Wikipedia"))
.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
onView(withText("Add search engine"))
.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
private fun searchSyncedTabsSwitchButton(): ViewInteraction {
onView(withId(androidx.preference.R.id.recycler_view)).perform(
RecyclerViewActions.scrollTo<RecyclerView.ViewHolder>(
hasDescendant(withText("Search synced tabs")),
),
)
return onView(withText("Search synced tabs"))
}
private fun assertShowSearchShortcuts() {
private fun voiceSearchSwitchButton(): ViewInteraction {
onView(withId(androidx.preference.R.id.recycler_view)).perform(
RecyclerViewActions.scrollTo<RecyclerView.ViewHolder>(
hasDescendant(withText("Show search engines")),
hasDescendant(withText("Show voice search")),
),
)
onView(withText("Show search engines"))
.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
return onView(withText("Show voice search"))
}
private fun autocompleteSwitchButton(): ViewInteraction {
onView(withId(androidx.preference.R.id.recycler_view)).perform(
RecyclerViewActions.scrollTo<RecyclerView.ViewHolder>(
hasDescendant(withText(getStringResource(R.string.preferences_enable_autocomplete_urls))),
),
)
return onView(withText(getStringResource(R.string.preferences_enable_autocomplete_urls)))
}
private val searchHistoryToggle = onView(withText("Search browsing history"))
private fun showSearchSuggestionSwitchButton(): ViewInteraction {
onView(withId(androidx.preference.R.id.recycler_view)).perform(
RecyclerViewActions.scrollTo<RecyclerView.ViewHolder>(
hasDescendant(withText("Show search suggestions")),
),
)
private val searchBookmarksToggle = onView(withText("Search bookmarks"))
return onView(withText("Show search suggestions"))
}
private fun showClipboardSuggestionSwitch(): ViewInteraction {
onView(withId(androidx.preference.R.id.recycler_view)).perform(
RecyclerViewActions.scrollTo<RecyclerView.ViewHolder>(
hasDescendant(withText(getStringResource(R.string.preferences_show_clipboard_suggestions))),
),
)
return onView(withText(getStringResource(R.string.preferences_show_clipboard_suggestions)))
}
private fun showSuggestionsInPrivateModeSwitch(): ViewInteraction {
onView(withId(androidx.preference.R.id.recycler_view)).perform(
RecyclerViewActions.scrollTo<RecyclerView.ViewHolder>(
hasDescendant(withText(getStringResource(R.string.preferences_show_search_suggestions_in_private))),
),
)
return onView(withText(getStringResource(R.string.preferences_show_search_suggestions_in_private)))
}
private fun selectSearchEngine(searchEngine: String) {
onView(withText(searchEngine))
@ -358,25 +422,7 @@ private fun goBackButton() =
private fun addSearchEngineButton() = onView(withText("Add search engine"))
private fun assertAddSearchEngineList() {
onView(withText("Reddit")).check(matches(isDisplayed()))
onView(withText("YouTube")).check(matches(isDisplayed()))
onView(withText("Other")).check(matches(isDisplayed()))
}
private fun addSearchEngineSaveButton() = onView(withId(R.id.add_search_engine))
private fun assertEngineListContains(searchEngineName: String) {
onView(withId(R.id.search_engine_group)).check(matches(hasDescendant(withText(searchEngineName))))
}
private fun assertDefaultSearchEngine(searchEngineName: String) =
onView(
allOf(
withId(R.id.radio_button),
withParent(withChild(withText(searchEngineName))),
),
).check(matches(isChecked(true)))
private fun addSearchEngineSaveButton() = onView(withId(R.id.save_button))
private fun assertEngineListDoesNotContain(searchEngineName: String) {
onView(withId(R.id.search_engine_group)).check(matches(not(hasDescendant(withText(searchEngineName)))))

Loading…
Cancel
Save