You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
iceraven-browser/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsSearchTest.kt

615 lines
22 KiB
Kotlin

/* 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.compose.ui.test.junit4.AndroidComposeTestRule
import androidx.test.espresso.Espresso.pressBack
import okhttp3.mockwebserver.MockWebServer
import org.junit.After
import org.junit.Before
import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.mozilla.fenix.customannotations.SmokeTest
import org.mozilla.fenix.helpers.AndroidAssetDispatcher
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
import org.mozilla.fenix.helpers.MockBrowserDataHelper.addCustomSearchEngine
import org.mozilla.fenix.helpers.MockBrowserDataHelper.createBookmarkItem
import org.mozilla.fenix.helpers.MockBrowserDataHelper.createHistoryItem
import org.mozilla.fenix.helpers.SearchDispatcher
import org.mozilla.fenix.helpers.TestAssetHelper.getGenericAsset
import org.mozilla.fenix.helpers.TestHelper.appContext
import org.mozilla.fenix.helpers.TestHelper.exitMenu
import org.mozilla.fenix.helpers.TestHelper.restartApp
import org.mozilla.fenix.helpers.TestHelper.runWithSystemLocaleChanged
import org.mozilla.fenix.helpers.TestHelper.setSystemLocale
import org.mozilla.fenix.helpers.TestHelper.setTextToClipBoard
import org.mozilla.fenix.helpers.TestHelper.verifySnackBarText
import org.mozilla.fenix.ui.robots.EngineShortcut
import org.mozilla.fenix.ui.robots.homeScreen
import org.mozilla.fenix.ui.robots.searchScreen
import java.util.Locale
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(),
) { it.activity }
@Before
fun setUp() {
mockWebServer = MockWebServer().apply {
dispatcher = AndroidAssetDispatcher()
start()
}
searchMockServer = MockWebServer().apply {
dispatcher = SearchDispatcher()
start()
}
}
@After
fun tearDown() {
mockWebServer.shutdown()
}
@Test
fun searchSettingsItemsTest() {
homeScreen {
}.openThreeDotMenu {
}.openSettings {
}.openSearchSubMenu {
verifyToolbarText("Search")
verifySearchEnginesSectionHeader()
verifyDefaultSearchEngineHeader()
verifyDefaultSearchEngineSummary("Google")
verifyManageSearchShortcutsHeader()
verifyManageShortcutsSummary()
verifyAddressBarSectionHeader()
verifyAutocompleteURlsIsEnabled(true)
verifyShowClipboardSuggestionsEnabled(true)
verifySearchBrowsingHistoryEnabled(true)
verifySearchBookmarksEnabled(true)
verifySearchSyncedTabsEnabled(true)
verifyVoiceSearchEnabled(true)
verifyShowSearchSuggestionsEnabled(true)
verifyShowSearchSuggestionsInPrivateEnabled(false)
}
}
@Test
fun defaultSearchEnginesSettingsItemsTest() {
homeScreen {
}.openThreeDotMenu {
}.openSettings {
}.openSearchSubMenu {
verifyDefaultSearchEngineHeader()
openDefaultSearchEngineMenu()
verifyToolbarText("Default search engine")
verifyDefaultSearchEngineList()
verifyDefaultSearchEngineSelected("Google")
}
}
@SmokeTest
@Test
fun selectNewDefaultSearchEngine() {
// Goes through the settings and changes the default search engine, then verifies it has changed.
defaultSearchEngineList.forEach {
homeScreen {
}.openThreeDotMenu {
}.openSettings {
}.openSearchSubMenu {
openDefaultSearchEngineMenu()
changeDefaultSearchEngine(it)
exitMenu()
}
searchScreen {
verifySearchEngineIcon(it)
}
}
}
@Test
fun toggleSearchAutocomplete() {
homeScreen {
}.openSearch {
typeSearch("mo")
verifyTypedToolbarText("monster.com")
typeSearch("moz")
verifyTypedToolbarText("mozilla.org")
}.dismissSearchBar {
}.openThreeDotMenu {
}.openSettings {
}.openSearchSubMenu {
toggleAutocomplete()
}.goBack {
}.goBack {
}.openSearch {
typeSearch("moz")
verifyTypedToolbarText("moz")
}
}
@Test
fun toggleOffHistorySearchSuggestionsTest() {
val websiteURL = getGenericAsset(mockWebServer, 1).url.toString()
createHistoryItem(websiteURL)
homeScreen {
}.openThreeDotMenu {
}.openSettings {
}.openSearchSubMenu {
switchSearchHistoryToggle()
exitMenu()
}
homeScreen {
}.openSearch {
typeSearch("test")
verifySuggestionsAreNotDisplayed(
activityTestRule,
"Firefox Suggest",
websiteURL,
)
}
}
@Test
fun toggleOffBookmarksSearchSuggestionsTest() {
val website = getGenericAsset(mockWebServer, 1)
createBookmarkItem(website.url.toString(), website.title, 1u)
homeScreen {
}.openThreeDotMenu {
}.openSettings {
}.openSearchSubMenu {
switchSearchBookmarksToggle()
// We want to avoid confusion between history and bookmarks searches,
// so we'll disable this too.
switchSearchHistoryToggle()
exitMenu()
}
homeScreen {
}.openSearch {
typeSearch("test")
verifySuggestionsAreNotDisplayed(
activityTestRule,
"Firefox Suggest",
website.title,
)
}
}
// Verifies setting as default a customized search engine name and URL
@SmokeTest
@Test
fun addCustomDefaultSearchEngineTest() {
val customSearchEngine = object {
val title = "TestSearchEngine"
val url = "http://localhost:${searchMockServer.port}/searchResults.html?search=%s"
}
homeScreen {
}.openThreeDotMenu {
}.openSettings {
}.openSearchSubMenu {
openDefaultSearchEngineMenu()
openAddSearchEngineMenu()
verifySaveSearchEngineButtonEnabled(false)
typeCustomEngineDetails(customSearchEngine.title, customSearchEngine.url)
verifySaveSearchEngineButtonEnabled(true)
saveNewSearchEngine()
verifySnackBarText("Created ${customSearchEngine.title}")
verifyEngineListContains(customSearchEngine.title, shouldExist = true)
openEngineOverflowMenu(customSearchEngine.title)
pressBack()
changeDefaultSearchEngine(customSearchEngine.title)
pressBack()
openManageShortcutsMenu()
verifyEngineListContains(customSearchEngine.title, shouldExist = true)
pressBack()
}.goBack {
verifySettingsOptionSummary("Search", customSearchEngine.title)
}.goBack {
}.openSearch {
verifySearchEngineIcon(customSearchEngine.title)
clickSearchSelectorButton()
verifySearchShortcutListContains(customSearchEngine.title)
}
}
@Test
fun addSearchEngineToManageShortcutsListTest() {
val customSearchEngine = object {
val title = "TestSearchEngine"
val url = "http://localhost:${searchMockServer.port}/searchResults.html?search=%s"
}
homeScreen {
}.openThreeDotMenu {
}.openSettings {
}.openSearchSubMenu {
openManageShortcutsMenu()
openAddSearchEngineMenu()
typeCustomEngineDetails(customSearchEngine.title, customSearchEngine.url)
saveNewSearchEngine()
verifyEngineListContains(customSearchEngine.title, shouldExist = true)
pressBack()
openDefaultSearchEngineMenu()
verifyEngineListContains(customSearchEngine.title, shouldExist = true)
}
}
@Test
fun addSearchEngineLearnMoreLinksTest() {
homeScreen {
}.openThreeDotMenu {
}.openSettings {
}.openSearchSubMenu {
openDefaultSearchEngineMenu()
openAddSearchEngineMenu()
}.clickCustomSearchStringLearnMoreLink {
verifyUrl(
"support.mozilla.org/en-US/kb/manage-my-default-search-engines-firefox-android?as=u&utm_source=inproduct",
)
}.openThreeDotMenu {
}.openSettings {
}.openSearchSubMenu {
openDefaultSearchEngineMenu()
openAddSearchEngineMenu()
}.clickCustomSearchSuggestionsLearnMoreLink {
verifyUrl(
"support.mozilla.org/en-US/kb/manage-my-default-search-engines-firefox-android?as=u&utm_source=inproduct",
)
}
}
@Test
fun editCustomSearchEngineTest() {
val customSearchEngine = object {
val title = "TestSearchEngine"
val url = "http://localhost:${searchMockServer.port}/searchResults.html?search=%s"
val newTitle = "NewEngineTitle"
}
addCustomSearchEngine(searchMockServer, customSearchEngine.title)
restartApp(activityTestRule.activityRule)
homeScreen {
}.openThreeDotMenu {
}.openSettings {
}.openSearchSubMenu {
openDefaultSearchEngineMenu()
verifyEngineListContains(customSearchEngine.title, shouldExist = true)
openEngineOverflowMenu(customSearchEngine.title)
clickEdit()
typeCustomEngineDetails(customSearchEngine.newTitle, customSearchEngine.url)
saveEditSearchEngine()
verifySnackBarText("Saved ${customSearchEngine.newTitle}")
verifyEngineListContains(customSearchEngine.newTitle, shouldExist = true)
pressBack()
openManageShortcutsMenu()
verifyEngineListContains(customSearchEngine.newTitle, shouldExist = true)
}
}
@Ignore("Failing, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1848623")
@Test
fun errorForInvalidSearchEngineStringsTest() {
val customSearchEngine = object {
val title = "TestSearchEngine"
val badTemplateUrl = "http://localhost:${searchMockServer.port}/searchResults.html?search="
val typoUrl = "http://local:${searchMockServer.port}/searchResults.html?search=%s"
val goodUrl = "http://localhost:${searchMockServer.port}/searchResults.html?search=%s"
}
homeScreen {
}.openThreeDotMenu {
}.openSettings {
}.openSearchSubMenu {
openDefaultSearchEngineMenu()
openAddSearchEngineMenu()
typeCustomEngineDetails(customSearchEngine.title, customSearchEngine.badTemplateUrl)
saveNewSearchEngine()
verifyInvalidTemplateSearchStringFormatError()
typeCustomEngineDetails(customSearchEngine.title, customSearchEngine.typoUrl)
saveNewSearchEngine()
verifyErrorConnectingToSearchString(customSearchEngine.title)
typeCustomEngineDetails(customSearchEngine.title, customSearchEngine.goodUrl)
typeSearchEngineSuggestionString(customSearchEngine.badTemplateUrl)
saveNewSearchEngine()
verifyInvalidTemplateSearchStringFormatError()
typeSearchEngineSuggestionString(customSearchEngine.typoUrl)
saveNewSearchEngine()
verifyErrorConnectingToSearchString(customSearchEngine.title)
}
}
@Test
fun deleteCustomSearchEngineTest() {
val customSearchEngineTitle = "TestSearchEngine"
addCustomSearchEngine(mockWebServer, searchEngineName = customSearchEngineTitle)
restartApp(activityTestRule.activityRule)
homeScreen {
}.openThreeDotMenu {
}.openSettings {
}.openSearchSubMenu {
openDefaultSearchEngineMenu()
verifyEngineListContains(customSearchEngineTitle, shouldExist = true)
openEngineOverflowMenu(customSearchEngineTitle)
clickDeleteSearchEngine()
verifySnackBarText("Deleted $customSearchEngineTitle")
clickUndoSnackBarButton()
verifyEngineListContains(customSearchEngineTitle, shouldExist = true)
changeDefaultSearchEngine(customSearchEngineTitle)
openEngineOverflowMenu(customSearchEngineTitle)
clickDeleteSearchEngine()
verifyEngineListContains(customSearchEngineTitle, shouldExist = false)
verifyDefaultSearchEngineSelected("Google")
pressBack()
openManageShortcutsMenu()
verifyEngineListContains(customSearchEngineTitle, shouldExist = false)
exitMenu()
}
searchScreen {
clickSearchSelectorButton()
verifySearchShortcutListContains(customSearchEngineTitle, shouldExist = false)
}
}
@Test
fun deleteCustomSearchShortcutTest() {
val customSearchEngineTitle = "TestSearchEngine"
addCustomSearchEngine(mockWebServer, searchEngineName = customSearchEngineTitle)
restartApp(activityTestRule.activityRule)
homeScreen {
}.openThreeDotMenu {
}.openSettings {
}.openSearchSubMenu {
openManageShortcutsMenu()
verifyEngineListContains(customSearchEngineTitle, shouldExist = true)
openCustomShortcutOverflowMenu(activityTestRule, customSearchEngineTitle)
clickDeleteSearchEngine(activityTestRule)
verifyEngineListContains(customSearchEngineTitle, shouldExist = false)
pressBack()
openDefaultSearchEngineMenu()
verifyEngineListContains(customSearchEngineTitle, shouldExist = false)
exitMenu()
}
searchScreen {
clickSearchSelectorButton()
verifySearchShortcutListContains(customSearchEngineTitle, shouldExist = false)
}
}
// Test running on beta/release builds in CI:
// caution when making changes to it, so they don't block the builds
// Goes through the settings and changes the search suggestion toggle, then verifies it changes.
@Ignore("Failing, see: https://github.com/mozilla-mobile/fenix/issues/23817")
@SmokeTest
@Test
fun toggleSearchSuggestionsTest() {
homeScreen {
}.openSearch {
typeSearch("mozilla ")
verifySearchEngineSuggestionResults(
activityTestRule,
"mozilla firefox",
searchTerm = "mozilla ",
)
}.dismissSearchBar {
}.openThreeDotMenu {
}.openSettings {
}.openSearchSubMenu {
toggleShowSearchSuggestions()
}.goBack {
}.goBack {
}.openSearch {
typeSearch("mozilla")
verifySuggestionsAreNotDisplayed(activityTestRule, "mozilla firefox")
}
}
// Tests the "Don't allow" option from private mode search suggestions onboarding dialog
@Test
fun blockSearchSuggestionsInPrivateModeOnboardingTest() {
homeScreen {
togglePrivateBrowsingModeOnOff()
}.openSearch {
typeSearch("mozilla")
verifyAllowSuggestionsInPrivateModeDialog()
denySuggestionsInPrivateMode()
verifySuggestionsAreNotDisplayed(activityTestRule, "mozilla firefox")
}
}
// Tests the "Allow" option from private mode search suggestions onboarding dialog
@Test
fun allowSearchSuggestionsInPrivateModeOnboardingTest() {
homeScreen {
togglePrivateBrowsingModeOnOff()
}.openSearch {
typeSearch("mozilla")
verifyAllowSuggestionsInPrivateModeDialog()
allowSuggestionsInPrivateMode()
verifySearchEngineSuggestionResults(
activityTestRule,
"mozilla firefox",
searchTerm = "mozilla",
)
}.dismissSearchBar {
}.openThreeDotMenu {
}.openSettings {
}.openSearchSubMenu {
switchShowSuggestionsInPrivateSessionsToggle()
}.goBack {
}.goBack {
}.openSearch {
typeSearch("mozilla")
verifySuggestionsAreNotDisplayed(activityTestRule, "mozilla firefox")
}
}
@Test
fun toggleVoiceSearchTest() {
homeScreen {
}.openSearch {
verifyVoiceSearchButtonVisibility(true)
startVoiceSearch()
}.dismissSearchBar {
}.openThreeDotMenu {
}.openSettings {
}.openSearchSubMenu {
toggleVoiceSearch()
exitMenu()
}
homeScreen {
}.openSearch {
verifyVoiceSearchButtonVisibility(false)
}
}
@Test
fun toggleShowClipboardSuggestionsTest() {
val link = "https://www.mozilla.org/en-US/"
setTextToClipBoard(appContext, link)
homeScreen {
}.openNavigationToolbar {
verifyClipboardSuggestionsAreDisplayed(link, true)
}.visitLinkFromClipboard {
}.openThreeDotMenu {
}.openSettings {
}.openSearchSubMenu {
verifyShowClipboardSuggestionsEnabled(true)
toggleClipboardSuggestion()
verifyShowClipboardSuggestionsEnabled(false)
exitMenu()
}
homeScreen {
}.openNavigationToolbar {
verifyClipboardSuggestionsAreDisplayed(link, false)
}
}
// Expected for app language set to Arabic
@Test
fun verifySearchEnginesWithRTLLocale() {
val arabicLocale = Locale("ar", "AR")
runWithSystemLocaleChanged(arabicLocale, activityTestRule.activityRule) {
homeScreen {
}.openSearch {
verifyTranslatedFocusedNavigationToolbar("ابحث أو أدخِل عنوانا")
clickSearchSelectorButton()
verifySearchShortcutListContains(
"Google",
"Bing",
"Amazon.com",
"DuckDuckGo",
"ويكيبيديا (ar)",
)
selectTemporarySearchMethod("ويكيبيديا (ar)")
}.submitQuery("firefox") {
verifyUrl("firefox")
}
}
}
@Test
fun searchEnginesListRespectLocaleTest() {
runWithSystemLocaleChanged(Locale.CHINA, activityTestRule.activityRule) {
// Checking search engines for CH locale
homeScreen {
}.openSearch {
clickSearchSelectorButton()
verifySearchShortcutListContains(
"Google",
"百度",
"Bing",
"DuckDuckGo",
)
}.dismissSearchBar {}
// Checking search engines for FR locale
setSystemLocale(Locale.FRENCH)
homeScreen {
}.openSearch {
clickSearchSelectorButton()
verifySearchShortcutListContains(
"Google",
"Bing",
"DuckDuckGo",
"Qwant",
"Wikipédia (fr)",
)
}
}
}
@Test
fun manageSearchShortcutsSettingsItemsTest() {
homeScreen {
}.openThreeDotMenu {
}.openSettings {
}.openSearchSubMenu {
openManageShortcutsMenu()
verifyToolbarText("Manage search shortcuts")
verifyEnginesShortcutsListHeader()
verifyManageShortcutsList(activityTestRule)
verifySearchShortcutChecked(
EngineShortcut(name = "Google", checkboxIndex = 1, isChecked = true),
EngineShortcut(name = "Bing", checkboxIndex = 4, isChecked = true),
EngineShortcut(name = "Amazon.com", checkboxIndex = 7, isChecked = true),
EngineShortcut(name = "DuckDuckGo", checkboxIndex = 10, isChecked = true),
EngineShortcut(name = "eBay", checkboxIndex = 13, isChecked = true),
EngineShortcut(name = "Wikipedia", checkboxIndex = 16, isChecked = true),
EngineShortcut(name = "Reddit", checkboxIndex = 19, isChecked = false),
EngineShortcut(name = "YouTube", checkboxIndex = 22, isChecked = false),
)
}
}
@SmokeTest
@Test
fun changeSearchShortcutsListTest() {
homeScreen {
}.openThreeDotMenu {
}.openSettings {
}.openSearchSubMenu {
openManageShortcutsMenu()
selectSearchShortcut(EngineShortcut(name = "Google", checkboxIndex = 1))
selectSearchShortcut(EngineShortcut(name = "Amazon.com", checkboxIndex = 7))
selectSearchShortcut(EngineShortcut(name = "Reddit", checkboxIndex = 19))
selectSearchShortcut(EngineShortcut(name = "YouTube", checkboxIndex = 22))
exitMenu()
}
searchScreen {
clickSearchSelectorButton()
verifySearchShortcutListContains("Google", "Amazon.com", shouldExist = false)
verifySearchShortcutListContains("YouTube", shouldExist = true)
verifySearchShortcutListContains("Reddit", shouldExist = true)
}
}
}