v124
|
@ -0,0 +1,25 @@
|
|||
From 50f614cd20872910fe17df6644bc7f0d0f31c1eb Mon Sep 17 00:00:00 2001
|
||||
From: harvey186 <harvey186@hotmail.com>
|
||||
Date: Sun, 14 Apr 2024 11:34:30 +0200
|
||||
Subject: [PATCH] LeOSearch
|
||||
|
||||
---
|
||||
.../org/mozilla/fenix/ui/robots/SettingsSubMenuSearchRobot.kt | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuSearchRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuSearchRobot.kt
|
||||
index dd74241ac..a44cb97ab 100644
|
||||
--- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuSearchRobot.kt
|
||||
+++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuSearchRobot.kt
|
||||
@@ -101,7 +101,7 @@ class SettingsSubMenuSearchRobot {
|
||||
}
|
||||
|
||||
fun verifyDefaultSearchEngineList() {
|
||||
- defaultSearchEngineOption("Google")
|
||||
+ defaultSearchEngineOption("LeOSearch")
|
||||
.check(matches(hasSibling(withId(R.id.engine_icon))))
|
||||
.check(matches(isDisplayed()))
|
||||
defaultSearchEngineOption("LeOSearch")
|
||||
--
|
||||
2.34.1
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
From 1c53b4145a4b7a232b5085aa1f7bff33526393fc Mon Sep 17 00:00:00 2001
|
||||
From: harvey186 <harvey186@hotmail.com>
|
||||
Date: Sun, 14 Apr 2024 12:52:24 +0200
|
||||
Subject: [PATCH] bild_gradle
|
||||
|
||||
---
|
||||
0001-strings.patch | 20441 +++++++++++++++++++++++++++++++++++++++++++
|
||||
app/build.gradle | 8 +-
|
||||
2 files changed, 20445 insertions(+), 4 deletions(-)
|
||||
create mode 100644 0001-strings.patch
|
||||
|
||||
|
||||
diff --git a/app/build.gradle b/app/build.gradle
|
||||
index 530e1c88c..17c4822b6 100644
|
||||
--- a/app/build.gradle
|
||||
+++ b/app/build.gradle
|
||||
@@ -31,7 +31,7 @@ android {
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
- applicationId "io.github.forkmaintainers"
|
||||
+ applicationId "com.leos"
|
||||
minSdkVersion config.minSdkVersion
|
||||
compileSdk config.compileSdkVersion
|
||||
targetSdkVersion config.targetSdkVersion
|
||||
@@ -180,11 +180,11 @@ android {
|
||||
}
|
||||
forkRelease releaseTemplate >> {
|
||||
buildConfigField "boolean", "USE_RELEASE_VERSIONING", "true"
|
||||
- applicationIdSuffix ".iceraven"
|
||||
- def deepLinkSchemeValue = "iceraven"
|
||||
+ applicationIdSuffix ".leosium"
|
||||
+ def deepLinkSchemeValue = "leosium"
|
||||
buildConfigField "String", "DEEP_LINK_SCHEME", "\"$deepLinkSchemeValue\""
|
||||
manifestPlaceholders.putAll([
|
||||
- "sharedUserId": "io.github.forkmaintainers.iceraven.sharedID",
|
||||
+ "sharedUserId": "io.github.forkmaintainers.leosium.sharedID",
|
||||
"deepLinkScheme": deepLinkSchemeValue,
|
||||
])
|
||||
// Use custom default allowed addon list
|
||||
--
|
||||
2.34.1
|
||||
|
|
@ -19,7 +19,7 @@ index dd74241ac..310e0dbab 100644
|
|||
- defaultSearchEngineOption("Google")
|
||||
- .check(matches(hasSibling(withId(R.id.engine_icon))))
|
||||
- .check(matches(isDisplayed()))
|
||||
- defaultSearchEngineOption("Bing")
|
||||
- defaultSearchEngineOption("LeOSearch")
|
||||
+ defaultSearchEngineOption("LeOSearch")
|
||||
.check(matches(hasSibling(withId(R.id.engine_icon))))
|
||||
.check(matches(isDisplayed()))
|
|
@ -1,473 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
@file:Suppress("TooManyFunctions")
|
||||
|
||||
package org.mozilla.fenix.ui.robots
|
||||
|
||||
import androidx.compose.ui.test.SemanticsMatcher
|
||||
import androidx.compose.ui.test.assert
|
||||
import androidx.compose.ui.test.assertIsDisplayed
|
||||
import androidx.compose.ui.test.hasAnySibling
|
||||
import androidx.compose.ui.test.hasContentDescription
|
||||
import androidx.compose.ui.test.hasText
|
||||
import androidx.compose.ui.test.junit4.ComposeTestRule
|
||||
import androidx.compose.ui.test.onNodeWithText
|
||||
import androidx.compose.ui.test.performClick
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.test.espresso.Espresso.closeSoftKeyboard
|
||||
import androidx.test.espresso.Espresso.onView
|
||||
import androidx.test.espresso.ViewInteraction
|
||||
import androidx.test.espresso.action.ViewActions.clearText
|
||||
import androidx.test.espresso.action.ViewActions.click
|
||||
import androidx.test.espresso.action.ViewActions.typeText
|
||||
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
|
||||
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
|
||||
import androidx.test.uiautomator.By
|
||||
import androidx.test.uiautomator.UiSelector
|
||||
import org.hamcrest.CoreMatchers
|
||||
import org.hamcrest.Matchers.allOf
|
||||
import org.hamcrest.Matchers.endsWith
|
||||
import org.junit.Assert.assertFalse
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.helpers.DataGenerationHelper.getAvailableSearchEngines
|
||||
import org.mozilla.fenix.helpers.DataGenerationHelper.getRegionSearchEnginesList
|
||||
import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource
|
||||
import org.mozilla.fenix.helpers.MatcherHelper.assertUIObjectExists
|
||||
import org.mozilla.fenix.helpers.MatcherHelper.itemContainingText
|
||||
import org.mozilla.fenix.helpers.MatcherHelper.itemWithResIdAndText
|
||||
import org.mozilla.fenix.helpers.MatcherHelper.itemWithText
|
||||
import org.mozilla.fenix.helpers.TestAssetHelper.waitingTimeShort
|
||||
import org.mozilla.fenix.helpers.TestHelper.hasCousin
|
||||
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 verifyToolbarText(title: String) {
|
||||
onView(
|
||||
allOf(
|
||||
withId(R.id.navigationToolbar),
|
||||
hasDescendant(withContentDescription(R.string.action_bar_up_description)),
|
||||
hasDescendant(withText(title)),
|
||||
),
|
||||
).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 verifyDefaultSearchEngineSummary(engineName: String) {
|
||||
defaultSearchEngineHeader.check(matches(hasSibling(withText(engineName))))
|
||||
}
|
||||
|
||||
fun verifyManageSearchShortcutsHeader() {
|
||||
manageSearchShortcutsHeader.check(matches(isDisplayed()))
|
||||
}
|
||||
|
||||
fun verifyManageShortcutsSummary() {
|
||||
manageSearchShortcutsHeader
|
||||
.check(matches(hasSibling(withText("Edit engines visible in the search menu"))))
|
||||
}
|
||||
|
||||
fun verifyEnginesShortcutsListHeader() =
|
||||
assertUIObjectExists(itemWithText("Engines visible on the search menu"))
|
||||
|
||||
fun verifyAddressBarSectionHeader() {
|
||||
onView(withText("Address bar - Firefox Suggest")).check(matches(isDisplayed()))
|
||||
}
|
||||
|
||||
fun verifyDefaultSearchEngineList() {
|
||||
defaultSearchEngineOption("LeOSearch")
|
||||
.check(matches(hasSibling(withId(R.id.engine_icon))))
|
||||
.check(matches(isDisplayed()))
|
||||
defaultSearchEngineOption("DuckDuckGo")
|
||||
.check(matches(hasSibling(withId(R.id.engine_icon))))
|
||||
.check(matches(isDisplayed()))
|
||||
assertUIObjectExists(addSearchEngineButton)
|
||||
}
|
||||
|
||||
fun verifyManageShortcutsList(testRule: ComposeTestRule) {
|
||||
val availableShortcutsEngines = getRegionSearchEnginesList() + getAvailableSearchEngines()
|
||||
|
||||
availableShortcutsEngines.forEach {
|
||||
testRule.onNodeWithText(it.name)
|
||||
.assert(hasAnySibling(hasContentDescription("${it.name} search engine")))
|
||||
.assertIsDisplayed()
|
||||
}
|
||||
|
||||
assertUIObjectExists(addSearchEngineButton)
|
||||
}
|
||||
|
||||
/**
|
||||
* Method that verifies the selected engines inside the Manage search shortcuts list.
|
||||
*/
|
||||
fun verifySearchShortcutChecked(vararg engineShortcut: EngineShortcut) {
|
||||
engineShortcut.forEach {
|
||||
val shortcutIsChecked = mDevice.findObject(UiSelector().text(it.name))
|
||||
.getFromParent(
|
||||
UiSelector().index(it.checkboxIndex),
|
||||
).isChecked
|
||||
|
||||
if (it.isChecked) {
|
||||
assertTrue(shortcutIsChecked)
|
||||
} else {
|
||||
assertFalse(shortcutIsChecked)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun verifyAutocompleteURlsIsEnabled(enabled: Boolean) {
|
||||
autocompleteSwitchButton()
|
||||
.check(matches(hasCousin(allOf(withClassName(endsWith("Switch")), isChecked(enabled)))))
|
||||
}
|
||||
|
||||
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 verifySearchBrowsingHistoryEnabled(enabled: Boolean) {
|
||||
searchHistorySwitchButton()
|
||||
.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
|
||||
.check(matches(hasCousin(allOf(withClassName(endsWith("Switch")), isChecked(enabled)))))
|
||||
}
|
||||
|
||||
fun verifySearchBookmarksEnabled(enabled: Boolean) {
|
||||
searchBookmarksSwitchButton()
|
||||
.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
|
||||
.check(matches(hasCousin(allOf(withClassName(endsWith("Switch")), isChecked(enabled)))))
|
||||
}
|
||||
|
||||
fun verifySearchSyncedTabsEnabled(enabled: Boolean) {
|
||||
searchSyncedTabsSwitchButton()
|
||||
.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
|
||||
.check(matches(hasCousin(allOf(withClassName(endsWith("Switch")), isChecked(enabled)))))
|
||||
}
|
||||
|
||||
fun verifyVoiceSearchEnabled(enabled: Boolean) {
|
||||
voiceSearchSwitchButton()
|
||||
.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
|
||||
.check(matches(hasCousin(allOf(withClassName(endsWith("Switch")), isChecked(enabled)))))
|
||||
}
|
||||
|
||||
fun openDefaultSearchEngineMenu() {
|
||||
defaultSearchEngineHeader.click()
|
||||
}
|
||||
|
||||
fun openManageShortcutsMenu() {
|
||||
manageSearchShortcutsHeader.click()
|
||||
}
|
||||
|
||||
fun changeDefaultSearchEngine(searchEngineName: String) {
|
||||
onView(withText(searchEngineName))
|
||||
.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
|
||||
.perform(click())
|
||||
}
|
||||
|
||||
fun selectSearchShortcut(shortcut: EngineShortcut) {
|
||||
mDevice.findObject(UiSelector().text(shortcut.name))
|
||||
.getFromParent(UiSelector().index(shortcut.checkboxIndex))
|
||||
.click()
|
||||
}
|
||||
|
||||
fun toggleAutocomplete() = autocompleteSwitchButton().click()
|
||||
|
||||
fun toggleShowSearchSuggestions() = showSearchSuggestionSwitchButton().click()
|
||||
|
||||
fun toggleVoiceSearch() {
|
||||
voiceSearchSwitchButton().perform(click())
|
||||
}
|
||||
|
||||
fun toggleClipboardSuggestion() {
|
||||
showClipboardSuggestionSwitch().click()
|
||||
}
|
||||
|
||||
fun switchSearchHistoryToggle() = searchHistorySwitchButton().click()
|
||||
|
||||
fun switchSearchBookmarksToggle() = searchBookmarksSwitchButton().click()
|
||||
|
||||
fun switchShowSuggestionsInPrivateSessionsToggle() =
|
||||
showSuggestionsInPrivateModeSwitch().click()
|
||||
|
||||
fun openAddSearchEngineMenu() = addSearchEngineButton.click()
|
||||
|
||||
fun verifyEngineListContains(searchEngineName: String, shouldExist: Boolean) =
|
||||
assertUIObjectExists(itemWithText(searchEngineName), exists = shouldExist)
|
||||
|
||||
fun verifyDefaultSearchEngineSelected(searchEngineName: String) {
|
||||
defaultSearchEngineOption(searchEngineName).check(matches(isChecked(true)))
|
||||
}
|
||||
|
||||
fun verifySaveSearchEngineButtonEnabled(enabled: Boolean) {
|
||||
addSearchEngineSaveButton().check(matches(isEnabled(enabled)))
|
||||
}
|
||||
|
||||
fun saveNewSearchEngine() {
|
||||
closeSoftKeyboard()
|
||||
addSearchEngineSaveButton().click()
|
||||
}
|
||||
|
||||
fun typeCustomEngineDetails(engineName: String, engineURL: String) {
|
||||
try {
|
||||
mDevice.findObject(By.res("$packageName:id/edit_engine_name")).clear()
|
||||
mDevice.findObject(By.res("$packageName:id/edit_engine_name")).text = engineName
|
||||
assertUIObjectExists(
|
||||
itemWithResIdAndText("$packageName:id/edit_engine_name", engineName),
|
||||
)
|
||||
|
||||
mDevice.findObject(By.res("$packageName:id/edit_search_string")).clear()
|
||||
mDevice.findObject(By.res("$packageName:id/edit_search_string")).text = engineURL
|
||||
assertUIObjectExists(
|
||||
itemWithResIdAndText("$packageName:id/edit_search_string", engineURL),
|
||||
)
|
||||
} catch (e: AssertionError) {
|
||||
println("The name or the search string were not set properly")
|
||||
|
||||
mDevice.findObject(By.res("$packageName:id/edit_engine_name")).clear()
|
||||
mDevice.findObject(By.res("$packageName:id/edit_engine_name")).setText(engineName)
|
||||
assertUIObjectExists(
|
||||
itemWithResIdAndText("$packageName:id/edit_engine_name", engineName),
|
||||
)
|
||||
mDevice.findObject(By.res("$packageName:id/edit_search_string")).clear()
|
||||
mDevice.findObject(By.res("$packageName:id/edit_search_string")).setText(engineURL)
|
||||
assertUIObjectExists(
|
||||
itemWithResIdAndText("$packageName:id/edit_search_string", engineURL),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun typeSearchEngineSuggestionString(searchSuggestionString: String) {
|
||||
onView(withId(R.id.edit_suggest_string))
|
||||
.click()
|
||||
.perform(clearText())
|
||||
.perform(typeText(searchSuggestionString))
|
||||
}
|
||||
|
||||
// Used in the non-Compose Default search engines menu
|
||||
fun openEngineOverflowMenu(searchEngineName: String) {
|
||||
threeDotMenu(searchEngineName).waitForExists(waitingTimeShort)
|
||||
threeDotMenu(searchEngineName).click()
|
||||
}
|
||||
|
||||
// Used in the composable Manage shortcuts menu, otherwise the overflow menu is not visible
|
||||
fun openCustomShortcutOverflowMenu(testRule: ComposeTestRule, searchEngineName: String) {
|
||||
testRule.onNode(overflowMenuWithSiblingText(searchEngineName)).performClick()
|
||||
}
|
||||
|
||||
fun clickEdit() = onView(withText("Edit")).click()
|
||||
|
||||
// Used in the Default search engine menu
|
||||
fun clickDeleteSearchEngine() =
|
||||
mDevice.findObject(
|
||||
UiSelector().textContains(getStringResource(R.string.search_engine_delete)),
|
||||
).click()
|
||||
|
||||
// Used in the composable Manage search shortcuts menu, otherwise the overflow menu is not visible
|
||||
fun clickDeleteSearchEngine(testRule: ComposeTestRule) =
|
||||
testRule.onNodeWithText("Delete").performClick()
|
||||
|
||||
fun clickUndoSnackBarButton() =
|
||||
mDevice.findObject(
|
||||
UiSelector()
|
||||
.resourceId("$packageName:id/snackbar_btn"),
|
||||
).click()
|
||||
|
||||
fun saveEditSearchEngine() {
|
||||
onView(withId(R.id.save_button)).click()
|
||||
assertUIObjectExists(itemContainingText("Saved"))
|
||||
}
|
||||
|
||||
fun verifyInvalidTemplateSearchStringFormatError() {
|
||||
closeSoftKeyboard()
|
||||
onView(withText(getStringResource(R.string.search_add_custom_engine_error_missing_template)))
|
||||
.check(matches(isDisplayed()))
|
||||
}
|
||||
|
||||
fun verifyErrorConnectingToSearchString(searchEngineName: String) {
|
||||
closeSoftKeyboard()
|
||||
onView(withText(getStringResource(R.string.search_add_custom_engine_error_cannot_reach, searchEngineName)))
|
||||
.check(matches(isDisplayed()))
|
||||
}
|
||||
|
||||
class Transition {
|
||||
fun goBack(interact: SettingsRobot.() -> Unit): SettingsRobot.Transition {
|
||||
mDevice.waitForIdle()
|
||||
goBackButton().perform(click())
|
||||
|
||||
SettingsRobot().interact()
|
||||
return SettingsRobot.Transition()
|
||||
}
|
||||
|
||||
fun clickCustomSearchStringLearnMoreLink(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition {
|
||||
onView(withId(R.id.custom_search_engines_learn_more)).click()
|
||||
|
||||
BrowserRobot().interact()
|
||||
return BrowserRobot.Transition()
|
||||
}
|
||||
|
||||
fun clickCustomSearchSuggestionsLearnMoreLink(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition {
|
||||
onView(withId(R.id.custom_search_suggestions_learn_more)).click()
|
||||
|
||||
BrowserRobot().interact()
|
||||
return BrowserRobot.Transition()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Matches search shortcut items inside the 'Manage search shortcuts' menu
|
||||
* @param name, of type String, should be the name of the search engine.
|
||||
* @param checkboxIndex, of type Int, is the checkbox' index afferent to the search engine.
|
||||
* @param isChecked, of type Boolean, should show if the checkbox is expected to be checked.
|
||||
*/
|
||||
class EngineShortcut(
|
||||
val name: String,
|
||||
val checkboxIndex: Int,
|
||||
val isChecked: Boolean = true,
|
||||
)
|
||||
|
||||
private val defaultSearchEngineHeader = onView(withText("Default search engine"))
|
||||
|
||||
private val manageSearchShortcutsHeader = onView(withText("Manage alternative search engines"))
|
||||
|
||||
private fun searchHistorySwitchButton(): ViewInteraction {
|
||||
onView(withId(androidx.preference.R.id.recycler_view)).perform(
|
||||
RecyclerViewActions.scrollTo<RecyclerView.ViewHolder>(
|
||||
hasDescendant(withText("Search browsing history")),
|
||||
),
|
||||
)
|
||||
return onView(withText("Search browsing history"))
|
||||
}
|
||||
|
||||
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 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 voiceSearchSwitchButton(): ViewInteraction {
|
||||
onView(withId(androidx.preference.R.id.recycler_view)).perform(
|
||||
RecyclerViewActions.scrollTo<RecyclerView.ViewHolder>(
|
||||
hasDescendant(withText("Show voice search")),
|
||||
),
|
||||
)
|
||||
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 fun showSearchSuggestionSwitchButton(): ViewInteraction {
|
||||
onView(withId(androidx.preference.R.id.recycler_view)).perform(
|
||||
RecyclerViewActions.scrollTo<RecyclerView.ViewHolder>(
|
||||
hasDescendant(withText("Show search suggestions")),
|
||||
),
|
||||
)
|
||||
|
||||
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 goBackButton() =
|
||||
onView(CoreMatchers.allOf(withContentDescription("Navigate up")))
|
||||
|
||||
private val addSearchEngineButton = mDevice.findObject(UiSelector().text("Add search engine"))
|
||||
|
||||
private fun addSearchEngineSaveButton() = onView(withId(R.id.save_button))
|
||||
|
||||
private fun threeDotMenu(searchEngineName: String) =
|
||||
mDevice.findObject(UiSelector().text(searchEngineName))
|
||||
.getFromParent(UiSelector().description("More options"))
|
||||
|
||||
private fun defaultSearchEngineOption(searchEngineName: String) =
|
||||
onView(
|
||||
allOf(
|
||||
withId(R.id.radio_button),
|
||||
hasSibling(withText(searchEngineName)),
|
||||
),
|
||||
)
|
||||
|
||||
private fun overflowMenuWithSiblingText(text: String): SemanticsMatcher =
|
||||
hasAnySibling(hasText(text)) and hasContentDescription("More options")
|
|
@ -161,15 +161,15 @@ android {
|
|||
forkDebug {
|
||||
shrinkResources false
|
||||
minifyEnabled false
|
||||
applicationIdSuffix ".leosium.debug"
|
||||
applicationIdSuffix ".iceraven.debug"
|
||||
pseudoLocalesEnabled true
|
||||
// Need to replicate default debug config features
|
||||
signingConfig signingConfigs.debug
|
||||
debuggable true
|
||||
def deepLinkSchemeValue = "leosium-debug"
|
||||
def deepLinkSchemeValue = "iceraven-debug"
|
||||
buildConfigField "String", "DEEP_LINK_SCHEME", "\"$deepLinkSchemeValue\""
|
||||
manifestPlaceholders.putAll([
|
||||
"sharedUserId": "io.github.forkmaintainers.leosium.sharedID",
|
||||
"sharedUserId": "io.github.forkmaintainers.iceraven.sharedID",
|
||||
"deepLinkScheme": deepLinkSchemeValue,
|
||||
])
|
||||
// Use custom default allowed addon list
|
||||
|
@ -676,8 +676,8 @@ dependencies {
|
|||
implementation ComponentsDependencies.androidx_paging
|
||||
implementation ComponentsDependencies.androidx_preferences
|
||||
implementation ComponentsDependencies.androidx_fragment
|
||||
implementation FenixDependencies.androidx_navigation_fragment
|
||||
implementation FenixDependencies.androidx_navigation_ui
|
||||
implementation ComponentsDependencies.androidx_navigation_fragment
|
||||
implementation ComponentsDependencies.androidx_navigation_ui
|
||||
implementation ComponentsDependencies.androidx_compose_navigation
|
||||
implementation ComponentsDependencies.androidx_recyclerview
|
||||
|
||||
|
|
|
@ -1101,6 +1101,16 @@
|
|||
column="1"/>
|
||||
</issue>
|
||||
|
||||
<issue id="UnusedResources"
|
||||
message="The resource R.drawable.ic_onboarding_key_features appears to be unused">
|
||||
<location file="src/main/res/drawable/ic_onboarding_key_features.xml" />
|
||||
</issue>
|
||||
|
||||
<issue id="UnusedResources"
|
||||
message="The resource R.drawable.ic_onboarding_key_features_icons_only appears to be unused">
|
||||
<location file="src/main/res/drawable/ic_onboarding_key_features_icons_only.xml" />
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="IconXmlAndPng"
|
||||
message="The following images appear both as density independent `.xml` files and as bitmap files: /Users/oracle/Projects/fenix/app/src/main/res/drawable-hdpi/ic_logo_wordmark_normal.png, /Users/oracle/Projects/fenix/app/src/main/res/drawable-night/ic_logo_wordmark_normal.xml">
|
||||
|
|
|
@ -25,6 +25,7 @@ import:
|
|||
- value:
|
||||
messages:
|
||||
default-browser:
|
||||
title: default_browser_experiment_card_title
|
||||
text: default_browser_experiment_card_text
|
||||
surface: homescreen
|
||||
action: "MAKE_DEFAULT_BROWSER"
|
||||
|
|
150
app/metrics.yaml
|
@ -843,6 +843,17 @@ events:
|
|||
metadata:
|
||||
tags:
|
||||
- Search
|
||||
first_session_ping_cancelled:
|
||||
type: event
|
||||
description: |
|
||||
First session ping cancelled because Adjust metrics were empty.
|
||||
bugs:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1875514
|
||||
data_reviews:
|
||||
- https://github.com/mozilla-mobile/firefox-android/pull/5223
|
||||
notification_emails:
|
||||
- android-probes@mozilla.com
|
||||
expires: never
|
||||
|
||||
splash_screen:
|
||||
first_launch_extended:
|
||||
|
@ -1061,78 +1072,6 @@ onboarding:
|
|||
metadata:
|
||||
tags:
|
||||
- Onboarding
|
||||
notif_ppp_impression:
|
||||
type: event
|
||||
description: |
|
||||
Notification pre permission prompt was shown to the user.
|
||||
bugs:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1810115
|
||||
data_reviews:
|
||||
- https://github.com/mozilla-mobile/fenix/pull/28529
|
||||
- https://github.com/mozilla-mobile/firefox-android/pull/4039
|
||||
data_sensitivity:
|
||||
- interaction
|
||||
notification_emails:
|
||||
- android-probes@mozilla.com
|
||||
expires: never
|
||||
metadata:
|
||||
tags:
|
||||
- Notifications
|
||||
- Onboarding
|
||||
notif_ppp_close_click:
|
||||
type: event
|
||||
description: |
|
||||
User clicked the close button on the notification pre permission prompt.
|
||||
bugs:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1810115
|
||||
data_reviews:
|
||||
- https://github.com/mozilla-mobile/fenix/pull/28529
|
||||
- https://github.com/mozilla-mobile/firefox-android/pull/4039
|
||||
data_sensitivity:
|
||||
- interaction
|
||||
notification_emails:
|
||||
- android-probes@mozilla.com
|
||||
expires: never
|
||||
metadata:
|
||||
tags:
|
||||
- Notifications
|
||||
- Onboarding
|
||||
notif_ppp_positive_btn_click:
|
||||
type: event
|
||||
description: |
|
||||
User clicked the positive button on notification pre permission prompt.
|
||||
bugs:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1810115
|
||||
data_reviews:
|
||||
- https://github.com/mozilla-mobile/fenix/pull/28529
|
||||
- https://github.com/mozilla-mobile/firefox-android/pull/4039
|
||||
data_sensitivity:
|
||||
- interaction
|
||||
notification_emails:
|
||||
- android-probes@mozilla.com
|
||||
expires: never
|
||||
metadata:
|
||||
tags:
|
||||
- Notifications
|
||||
- Onboarding
|
||||
notif_ppp_negative_btn_click:
|
||||
type: event
|
||||
description: |
|
||||
User clicked the negative button on notification pre permission prompt.
|
||||
bugs:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1810115
|
||||
data_reviews:
|
||||
- https://github.com/mozilla-mobile/fenix/pull/28529
|
||||
- https://github.com/mozilla-mobile/firefox-android/pull/4039
|
||||
data_sensitivity:
|
||||
- interaction
|
||||
notification_emails:
|
||||
- android-probes@mozilla.com
|
||||
expires: never
|
||||
metadata:
|
||||
tags:
|
||||
- Notifications
|
||||
- Onboarding
|
||||
set_to_default_card:
|
||||
type: event
|
||||
description: |
|
||||
|
@ -9265,8 +9204,10 @@ awesomebar:
|
|||
A sponsored suggestion was visible when the user finished interacting with the awesomebar.
|
||||
bugs:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1871156
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1878434
|
||||
data_reviews:
|
||||
- https://github.com/mozilla-mobile/firefox-android/pull/4914#issuecomment-1874271848
|
||||
- https://github.com/mozilla-mobile/firefox-android/pull/5438#issuecomment-1930970336
|
||||
data_sensitivity:
|
||||
- interaction
|
||||
notification_emails:
|
||||
|
@ -9277,12 +9218,6 @@ awesomebar:
|
|||
expires: never
|
||||
extra_keys:
|
||||
provider: *sponsored_suggestion_provider
|
||||
engagement_abandoned: &awesomebar_engagement_abandoned
|
||||
description: |
|
||||
If `true`, the user dismissed the awesomebar without navigating to a destination. If
|
||||
`false`, the user finished engaging with the awesomebar by navigating to a destination,
|
||||
like a URL, a search results page, or a suggestion.
|
||||
type: boolean
|
||||
metadata:
|
||||
tags:
|
||||
- Search
|
||||
|
@ -9292,8 +9227,10 @@ awesomebar:
|
|||
A non-sponsored suggestion was visible when the user finished interacting with the awesomebar.
|
||||
bugs:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1871156
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1878434
|
||||
data_reviews:
|
||||
- https://github.com/mozilla-mobile/firefox-android/pull/4914#issuecomment-1874271848
|
||||
- https://github.com/mozilla-mobile/firefox-android/pull/5438#issuecomment-1930970336
|
||||
data_sensitivity:
|
||||
- interaction
|
||||
notification_emails:
|
||||
|
@ -9304,10 +9241,49 @@ awesomebar:
|
|||
expires: never
|
||||
extra_keys:
|
||||
provider: *non_sponsored_suggestion_provider
|
||||
engagement_abandoned: *awesomebar_engagement_abandoned
|
||||
metadata:
|
||||
tags:
|
||||
- Search
|
||||
engagement:
|
||||
type: event
|
||||
description: |
|
||||
The user completed their search session by tapping a search result,
|
||||
or entering a URL or a search term.
|
||||
bugs:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1878434
|
||||
data_reviews:
|
||||
- https://github.com/mozilla-mobile/firefox-android/pull/5438#issuecomment-1930970336
|
||||
data_sensitivity:
|
||||
- interaction
|
||||
notification_emails:
|
||||
- android-probes@mozilla.com
|
||||
- lina@mozilla.com
|
||||
- ttran@mozilla.com
|
||||
- najiang@mozilla.com
|
||||
expires: never
|
||||
metadata:
|
||||
tags:
|
||||
- Search
|
||||
abandonment:
|
||||
type: event
|
||||
description: |
|
||||
The user dismissed the awesomebar without completing their search.
|
||||
bugs:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1878434
|
||||
data_reviews:
|
||||
- https://github.com/mozilla-mobile/firefox-android/pull/5438#issuecomment-1930970336
|
||||
data_sensitivity:
|
||||
- interaction
|
||||
notification_emails:
|
||||
- android-probes@mozilla.com
|
||||
- lina@mozilla.com
|
||||
- ttran@mozilla.com
|
||||
- najiang@mozilla.com
|
||||
expires: never
|
||||
metadata:
|
||||
tags:
|
||||
- Search
|
||||
|
||||
android_autofill:
|
||||
supported:
|
||||
type: boolean
|
||||
|
@ -11414,3 +11390,19 @@ fx_suggest:
|
|||
expires: never
|
||||
send_in_pings:
|
||||
- fx-suggest
|
||||
debug_drawer:
|
||||
debug_drawer_enabled:
|
||||
type: boolean
|
||||
description: |
|
||||
Whether or not the user has enabled the Debug Drawer feature.
|
||||
send_in_pings:
|
||||
- metrics
|
||||
bugs:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1876596
|
||||
data_reviews:
|
||||
- https://github.com/mozilla-mobile/firefox-android/pull/5356
|
||||
data_sensitivity:
|
||||
- interaction
|
||||
notification_emails:
|
||||
- android-probes@mozilla.com
|
||||
expires: never
|
||||
|
|
|
@ -32,6 +32,7 @@ import:
|
|||
- value:
|
||||
available-suggestion-types: {
|
||||
"amp": true,
|
||||
"ampMobile": false,
|
||||
"wikipedia": true,
|
||||
}
|
||||
|
||||
|
@ -238,14 +239,6 @@ features:
|
|||
type: Int
|
||||
default: 0
|
||||
|
||||
pre-permission-notification-prompt:
|
||||
description: A feature that shows the pre-permission notification prompt.
|
||||
variables:
|
||||
enabled:
|
||||
description: if true, the pre-permission notification prompt is shown to the user.
|
||||
type: Boolean
|
||||
default: false
|
||||
|
||||
onboarding:
|
||||
description: "A feature that configures the new user onboarding page.
|
||||
Note that onboarding is a **first run** feature, and should only be modified by first run experiments."
|
||||
|
|
|
@ -14,11 +14,11 @@ import android.content.pm.PackageManager
|
|||
import android.content.res.Configuration
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Environment
|
||||
import android.os.storage.StorageManager
|
||||
import android.os.storage.StorageVolume
|
||||
import android.provider.Settings
|
||||
import android.util.Log
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.test.espresso.Espresso
|
||||
import androidx.test.espresso.IdlingRegistry
|
||||
|
@ -33,6 +33,7 @@ import androidx.test.uiautomator.UiObject
|
|||
import androidx.test.uiautomator.UiSelector
|
||||
import androidx.test.uiautomator.Until
|
||||
import junit.framework.AssertionFailedError
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.Assert
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.mozilla.fenix.Config
|
||||
|
@ -60,46 +61,88 @@ object AppAndSystemHelper {
|
|||
}
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.R)
|
||||
/**
|
||||
* Checks if a specific download file is inside the device storage and deletes it.
|
||||
* Different implementation needed for newer API levels,
|
||||
* as Environment.getExternalStorageDirectory() is deprecated starting with API 29.
|
||||
*
|
||||
*/
|
||||
fun deleteDownloadedFileOnStorage(fileName: String) {
|
||||
val storageManager: StorageManager? = TestHelper.appContext.getSystemService(Context.STORAGE_SERVICE) as StorageManager?
|
||||
val storageVolumes = storageManager!!.storageVolumes
|
||||
val storageVolume: StorageVolume = storageVolumes[0]
|
||||
val file = File(storageVolume.directory!!.path + "/Download/" + fileName)
|
||||
try {
|
||||
if (file.exists()) {
|
||||
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.Q) {
|
||||
val storageManager: StorageManager? =
|
||||
TestHelper.appContext.getSystemService(Context.STORAGE_SERVICE) as StorageManager?
|
||||
val storageVolumes = storageManager!!.storageVolumes
|
||||
val storageVolume: StorageVolume = storageVolumes[0]
|
||||
val file = File(storageVolume.directory!!.path + "/Download/" + fileName)
|
||||
try {
|
||||
if (file.exists()) {
|
||||
file.delete()
|
||||
Log.d("TestLog", "File delete try 1")
|
||||
Assert.assertFalse("The file was not deleted", file.exists())
|
||||
}
|
||||
} catch (e: AssertionError) {
|
||||
file.delete()
|
||||
Log.d("TestLog", "File delete try 1")
|
||||
Log.d("TestLog", "File delete retried")
|
||||
Assert.assertFalse("The file was not deleted", file.exists())
|
||||
}
|
||||
} catch (e: AssertionError) {
|
||||
file.delete()
|
||||
Log.d("TestLog", "File delete retried")
|
||||
Assert.assertFalse("The file was not deleted", file.exists())
|
||||
} else {
|
||||
runBlocking {
|
||||
val downloadedFile = File(
|
||||
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS),
|
||||
fileName,
|
||||
)
|
||||
|
||||
if (downloadedFile.exists()) {
|
||||
Log.i(TAG, "deleteDownloadedFileOnStorage: Verifying if $downloadedFile exists.")
|
||||
downloadedFile.delete()
|
||||
Log.i(TAG, "deleteDownloadedFileOnStorage: $downloadedFile deleted.")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.R)
|
||||
/**
|
||||
* Checks if there are download files inside the device storage and deletes all of them.
|
||||
* Different implementation needed for newer API levels, as
|
||||
* Environment.getExternalStorageDirectory() is deprecated starting with API 29.
|
||||
*/
|
||||
fun clearDownloadsFolder() {
|
||||
val storageManager: StorageManager? = TestHelper.appContext.getSystemService(Context.STORAGE_SERVICE) as StorageManager?
|
||||
val storageVolumes = storageManager!!.storageVolumes
|
||||
val storageVolume: StorageVolume = storageVolumes[0]
|
||||
val downloadsFolder = File(storageVolume.directory!!.path + "/Download/")
|
||||
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.Q) {
|
||||
Log.i(TAG, "clearDownloadsFolder: API > 29")
|
||||
val storageManager: StorageManager? =
|
||||
TestHelper.appContext.getSystemService(Context.STORAGE_SERVICE) as StorageManager?
|
||||
val storageVolumes = storageManager!!.storageVolumes
|
||||
val storageVolume: StorageVolume = storageVolumes[0]
|
||||
val downloadsFolder = File(storageVolume.directory!!.path + "/Download/")
|
||||
|
||||
// Check if the downloads folder exists
|
||||
if (downloadsFolder.exists() && downloadsFolder.isDirectory) {
|
||||
Log.i(TAG, "clearDownloadsFolder: Verified that \"DOWNLOADS\" folder exists")
|
||||
val files = downloadsFolder.listFiles()
|
||||
// Check if the downloads folder exists
|
||||
if (downloadsFolder.exists() && downloadsFolder.isDirectory) {
|
||||
Log.i(TAG, "clearDownloadsFolder: Verified that \"DOWNLOADS\" folder exists")
|
||||
val files = downloadsFolder.listFiles()
|
||||
|
||||
// Check if the folder is not empty
|
||||
if (files != null && files.isNotEmpty()) {
|
||||
Log.i(TAG, "clearDownloadsFolder: Verified that \"DOWNLOADS\" folder is not empty")
|
||||
// Delete all files in the folder
|
||||
for (file in files) {
|
||||
file.delete()
|
||||
Log.i(TAG, "clearDownloadsFolder: Deleted $file from \"DOWNLOADS\" folder")
|
||||
// Check if the folder is not empty
|
||||
if (files != null && files.isNotEmpty()) {
|
||||
Log.i(
|
||||
TAG,
|
||||
"clearDownloadsFolder: Verified that \"DOWNLOADS\" folder is not empty",
|
||||
)
|
||||
// Delete all files in the folder
|
||||
for (file in files) {
|
||||
file.delete()
|
||||
Log.i(TAG, "clearDownloadsFolder: Deleted $file from \"DOWNLOADS\" folder")
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
runBlocking {
|
||||
Log.i(TAG, "clearDownloadsFolder: API <= 29")
|
||||
Log.i(TAG, "clearDownloadsFolder: Verifying if any download files exist.")
|
||||
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
|
||||
.listFiles()?.forEach {
|
||||
it.delete()
|
||||
Log.i(TAG, "clearDownloadsFolder: Download file $it deleted.")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -135,11 +178,12 @@ object AppAndSystemHelper {
|
|||
}
|
||||
|
||||
fun isPackageInstalled(packageName: String): Boolean {
|
||||
Log.i(TAG, "isPackageInstalled: Trying to verify that $packageName is installed")
|
||||
return try {
|
||||
val packageManager = InstrumentationRegistry.getInstrumentation().context.packageManager
|
||||
packageManager.getApplicationInfo(packageName, 0).enabled
|
||||
} catch (e: PackageManager.NameNotFoundException) {
|
||||
Log.i(TAG, "isPackageInstalled: Catch block - ${e.message}")
|
||||
Log.i(TAG, "isPackageInstalled: $packageName is not installed - ${e.message}")
|
||||
false
|
||||
}
|
||||
}
|
||||
|
@ -183,6 +227,7 @@ object AppAndSystemHelper {
|
|||
* @return Boolean value that helps us know if the current activity supports custom tabs or PWAs.
|
||||
*/
|
||||
fun isExternalAppBrowserActivityInCurrentTask(): Boolean {
|
||||
Log.i(TAG, "Trying to verify that the latest activity of the application is used for custom tabs or PWAs")
|
||||
val activityManager = TestHelper.appContext.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
|
||||
|
||||
mDevice.waitForIdle(TestAssetHelper.waitingTimeShort)
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
package org.mozilla.fenix.helpers
|
||||
|
||||
import org.mozilla.experiments.nimbus.GleanPlumbMessageHelper
|
||||
import org.mozilla.experiments.nimbus.NimbusMessagingHelperInterface
|
||||
import org.mozilla.fenix.ext.components
|
||||
import org.mozilla.fenix.helpers.TestHelper.appContext
|
||||
|
||||
|
@ -12,7 +12,7 @@ object Experimentation {
|
|||
val experiments =
|
||||
appContext.components.analytics.experiments
|
||||
|
||||
fun withHelper(block: GleanPlumbMessageHelper.() -> Unit) {
|
||||
fun withHelper(block: NimbusMessagingHelperInterface.() -> Unit) {
|
||||
val helper = experiments.createMessageHelper()
|
||||
block(helper)
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ object TestAssetHelper {
|
|||
val waitingTime: Long = TimeUnit.SECONDS.toMillis(15)
|
||||
val waitingTimeLong = TimeUnit.SECONDS.toMillis(25)
|
||||
val waitingTimeShort: Long = TimeUnit.SECONDS.toMillis(3)
|
||||
val waitingTimeVeryShort: Long = TimeUnit.SECONDS.toMillis(1)
|
||||
|
||||
data class TestAsset(val url: Uri, val content: String, val title: String)
|
||||
|
||||
|
|
|
@ -34,9 +34,12 @@ import org.junit.Assert.assertFalse
|
|||
import org.junit.Assert.assertTrue
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.helpers.Constants.TAG
|
||||
import org.mozilla.fenix.helpers.MatcherHelper.assertUIObjectExists
|
||||
import org.mozilla.fenix.helpers.MatcherHelper.itemContainingText
|
||||
import org.mozilla.fenix.helpers.MatcherHelper.itemWithResIdAndText
|
||||
import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime
|
||||
import org.mozilla.fenix.helpers.TestAssetHelper.waitingTimeShort
|
||||
import org.mozilla.fenix.helpers.TestAssetHelper.waitingTimeVeryShort
|
||||
import org.mozilla.fenix.helpers.ext.waitNotNull
|
||||
import org.mozilla.fenix.ui.robots.clickPageObject
|
||||
|
||||
|
@ -49,8 +52,10 @@ object TestHelper {
|
|||
|
||||
fun scrollToElementByText(text: String): UiScrollable {
|
||||
val appView = UiScrollable(UiSelector().scrollable(true))
|
||||
Log.i(TAG, "scrollToElementByText: Waiting for app view")
|
||||
appView.waitForExists(waitingTime)
|
||||
appView.scrollTextIntoView(text)
|
||||
Log.i(TAG, "scrollToElementByText: Scrolled to element with text: $text")
|
||||
return appView
|
||||
}
|
||||
|
||||
|
@ -101,14 +106,7 @@ object TestHelper {
|
|||
).waitUntilGone(waitingTime)
|
||||
}
|
||||
|
||||
fun verifySnackBarText(expectedText: String) {
|
||||
assertTrue(
|
||||
mDevice.findObject(
|
||||
UiSelector()
|
||||
.textContains(expectedText),
|
||||
).waitForExists(waitingTime),
|
||||
)
|
||||
}
|
||||
fun verifySnackBarText(expectedText: String) = assertUIObjectExists(itemContainingText(expectedText))
|
||||
|
||||
fun verifyUrl(urlSubstring: String, resourceName: String, resId: Int) {
|
||||
waitUntilObjectIsFound(resourceName)
|
||||
|
@ -145,4 +143,10 @@ object TestHelper {
|
|||
assertFalse("Light theme not selected", expected)
|
||||
|
||||
fun verifyDarkThemeApplied(expected: Boolean) = assertTrue("Dark theme not selected", expected)
|
||||
|
||||
fun waitForAppWindowToBeUpdated() {
|
||||
Log.i(TAG, "waitForAppWindowToBeUpdated: Waiting for $waitingTimeVeryShort ms for $packageName window to be updated")
|
||||
mDevice.waitForWindowUpdate(packageName, waitingTimeVeryShort)
|
||||
Log.i(TAG, "waitForAppWindowToBeUpdated: Waited for $waitingTimeVeryShort ms for $packageName window to be updated")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
package org.mozilla.fenix.helpers
|
||||
|
||||
import android.util.Log
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import mozilla.appservices.places.BookmarkRoot
|
||||
import mozilla.components.browser.storage.sync.PlacesBookmarksStorage
|
||||
import okhttp3.mockwebserver.MockWebServer
|
||||
import org.junit.Before
|
||||
import org.mozilla.fenix.helpers.Constants.TAG
|
||||
import org.mozilla.fenix.helpers.TestHelper.appContext
|
||||
import org.mozilla.fenix.ui.robots.notificationShade
|
||||
|
||||
open class TestSetup {
|
||||
lateinit var mockWebServer: MockWebServer
|
||||
private val bookmarksStorage = PlacesBookmarksStorage(appContext.applicationContext)
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
Log.i(TAG, "TestSetup: Starting the @Before setup")
|
||||
// Clear pre-existing notifications
|
||||
notificationShade {
|
||||
cancelAllShownNotifications()
|
||||
}
|
||||
runBlocking {
|
||||
// Reset locale to EN-US if needed.
|
||||
AppAndSystemHelper.resetSystemLocaleToEnUS()
|
||||
// Check and clear the downloads folder
|
||||
AppAndSystemHelper.clearDownloadsFolder()
|
||||
// Make sure the Wifi and Mobile Data connections are on
|
||||
AppAndSystemHelper.setNetworkEnabled(true)
|
||||
// Clear bookmarks left after a failed test
|
||||
val bookmarks = bookmarksStorage.getTree(BookmarkRoot.Mobile.id)?.children
|
||||
Log.i(TAG, "Before cleanup: Bookmarks storage contains: $bookmarks")
|
||||
bookmarks?.forEach {
|
||||
bookmarksStorage.deleteNode(it.guid)
|
||||
// TODO: Follow-up with a method to handle the DB update; the logs will still show the bookmarks in the storage before the test starts.
|
||||
Log.i(TAG, "After cleanup: Bookmarks storage contains: $bookmarks")
|
||||
}
|
||||
}
|
||||
mockWebServer = MockWebServer().apply {
|
||||
dispatcher = AndroidAssetDispatcher()
|
||||
}
|
||||
try {
|
||||
Log.i(TAG, "Try starting mockWebServer")
|
||||
mockWebServer.start()
|
||||
} catch (e: Exception) {
|
||||
Log.i(TAG, "Exception caught. Re-starting mockWebServer")
|
||||
mockWebServer.shutdown()
|
||||
mockWebServer.start()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -95,7 +95,7 @@
|
|||
"sha256:fa3a0128b152627161ce47201262d3140edb5a5c3da88d73a1b790a959126956",
|
||||
"sha256:fcc8eb6d5902bb1cf6dc4f187ee3ea80a1eba0a89aba40a5cb20a5087d961357"
|
||||
],
|
||||
"markers": "python_version >= '3.8'",
|
||||
"markers": "platform_python_implementation != 'PyPy'",
|
||||
"version": "==1.16.0"
|
||||
},
|
||||
"charset-normalizer": {
|
||||
|
@ -196,33 +196,42 @@
|
|||
},
|
||||
"cryptography": {
|
||||
"hashes": [
|
||||
"sha256:068bc551698c234742c40049e46840843f3d98ad7ce265fd2bd4ec0d11306596",
|
||||
"sha256:0f27acb55a4e77b9be8d550d762b0513ef3fc658cd3eb15110ebbcbd626db12c",
|
||||
"sha256:2132d5865eea673fe6712c2ed5fb4fa49dba10768bb4cc798345748380ee3660",
|
||||
"sha256:3288acccef021e3c3c10d58933f44e8602cf04dba96d9796d70d537bb2f4bbc4",
|
||||
"sha256:35f3f288e83c3f6f10752467c48919a7a94b7d88cc00b0668372a0d2ad4f8ead",
|
||||
"sha256:398ae1fc711b5eb78e977daa3cbf47cec20f2c08c5da129b7a296055fbb22aed",
|
||||
"sha256:422e3e31d63743855e43e5a6fcc8b4acab860f560f9321b0ee6269cc7ed70cc3",
|
||||
"sha256:48783b7e2bef51224020efb61b42704207dde583d7e371ef8fc2a5fb6c0aabc7",
|
||||
"sha256:4d03186af98b1c01a4eda396b137f29e4e3fb0173e30f885e27acec8823c1b09",
|
||||
"sha256:5daeb18e7886a358064a68dbcaf441c036cbdb7da52ae744e7b9207b04d3908c",
|
||||
"sha256:60e746b11b937911dc70d164060d28d273e31853bb359e2b2033c9e93e6f3c43",
|
||||
"sha256:742ae5e9a2310e9dade7932f9576606836ed174da3c7d26bc3d3ab4bd49b9f65",
|
||||
"sha256:7e00fb556bda398b99b0da289ce7053639d33b572847181d6483ad89835115f6",
|
||||
"sha256:85abd057699b98fce40b41737afb234fef05c67e116f6f3650782c10862c43da",
|
||||
"sha256:8efb2af8d4ba9dbc9c9dd8f04d19a7abb5b49eab1f3694e7b5a16a5fc2856f5c",
|
||||
"sha256:ae236bb8760c1e55b7a39b6d4d32d2279bc6c7c8500b7d5a13b6fb9fc97be35b",
|
||||
"sha256:afda76d84b053923c27ede5edc1ed7d53e3c9f475ebaf63c68e69f1403c405a8",
|
||||
"sha256:b27a7fd4229abef715e064269d98a7e2909ebf92eb6912a9603c7e14c181928c",
|
||||
"sha256:b648fe2a45e426aaee684ddca2632f62ec4613ef362f4d681a9a6283d10e079d",
|
||||
"sha256:c5a550dc7a3b50b116323e3d376241829fd326ac47bc195e04eb33a8170902a9",
|
||||
"sha256:da46e2b5df770070412c46f87bac0849b8d685c5f2679771de277a422c7d0b86",
|
||||
"sha256:f39812f70fc5c71a15aa3c97b2bbe213c3f2a460b79bd21c40d033bb34a9bf36",
|
||||
"sha256:ff369dd19e8fe0528b02e8df9f2aeb2479f89b1270d90f96a63500afe9af5cae"
|
||||
"sha256:0a68bfcf57a6887818307600c3c0ebc3f62fbb6ccad2240aa21887cda1f8df1b",
|
||||
"sha256:146e971e92a6dd042214b537a726c9750496128453146ab0ee8971a0299dc9bd",
|
||||
"sha256:14e4b909373bc5bf1095311fa0f7fcabf2d1a160ca13f1e9e467be1ac4cbdf94",
|
||||
"sha256:206aaf42e031b93f86ad60f9f5d9da1b09164f25488238ac1dc488334eb5e221",
|
||||
"sha256:3005166a39b70c8b94455fdbe78d87a444da31ff70de3331cdec2c568cf25b7e",
|
||||
"sha256:324721d93b998cb7367f1e6897370644751e5580ff9b370c0a50dc60a2003513",
|
||||
"sha256:33588310b5c886dfb87dba5f013b8d27df7ffd31dc753775342a1e5ab139e59d",
|
||||
"sha256:35cf6ed4c38f054478a9df14f03c1169bb14bd98f0b1705751079b25e1cb58bc",
|
||||
"sha256:3ca482ea80626048975360c8e62be3ceb0f11803180b73163acd24bf014133a0",
|
||||
"sha256:56ce0c106d5c3fec1038c3cca3d55ac320a5be1b44bf15116732d0bc716979a2",
|
||||
"sha256:5a217bca51f3b91971400890905a9323ad805838ca3fa1e202a01844f485ee87",
|
||||
"sha256:678cfa0d1e72ef41d48993a7be75a76b0725d29b820ff3cfd606a5b2b33fda01",
|
||||
"sha256:69fd009a325cad6fbfd5b04c711a4da563c6c4854fc4c9544bff3088387c77c0",
|
||||
"sha256:6cf9b76d6e93c62114bd19485e5cb003115c134cf9ce91f8ac924c44f8c8c3f4",
|
||||
"sha256:74f18a4c8ca04134d2052a140322002fef535c99cdbc2a6afc18a8024d5c9d5b",
|
||||
"sha256:85f759ed59ffd1d0baad296e72780aa62ff8a71f94dc1ab340386a1207d0ea81",
|
||||
"sha256:87086eae86a700307b544625e3ba11cc600c3c0ef8ab97b0fda0705d6db3d4e3",
|
||||
"sha256:8814722cffcfd1fbd91edd9f3451b88a8f26a5fd41b28c1c9193949d1c689dc4",
|
||||
"sha256:8fedec73d590fd30c4e3f0d0f4bc961aeca8390c72f3eaa1a0874d180e868ddf",
|
||||
"sha256:9515ea7f596c8092fdc9902627e51b23a75daa2c7815ed5aa8cf4f07469212ec",
|
||||
"sha256:988b738f56c665366b1e4bfd9045c3efae89ee366ca3839cd5af53eaa1401bce",
|
||||
"sha256:a2a8d873667e4fd2f34aedab02ba500b824692c6542e017075a2efc38f60a4c0",
|
||||
"sha256:bd7cf7a8d9f34cc67220f1195884151426ce616fdc8285df9054bfa10135925f",
|
||||
"sha256:bdce70e562c69bb089523e75ef1d9625b7417c6297a76ac27b1b8b1eb51b7d0f",
|
||||
"sha256:be14b31eb3a293fc6e6aa2807c8a3224c71426f7c4e3639ccf1a2f3ffd6df8c3",
|
||||
"sha256:be41b0c7366e5549265adf2145135dca107718fa44b6e418dc7499cfff6b4689",
|
||||
"sha256:c310767268d88803b653fffe6d6f2f17bb9d49ffceb8d70aed50ad45ea49ab08",
|
||||
"sha256:c58115384bdcfe9c7f644c72f10f6f42bed7cf59f7b52fe1bf7ae0a622b3a139",
|
||||
"sha256:c640b0ef54138fde761ec99a6c7dc4ce05e80420262c20fa239e694ca371d434",
|
||||
"sha256:ca20550bb590db16223eb9ccc5852335b48b8f597e2f6f0878bbfd9e7314eb17",
|
||||
"sha256:d97aae66b7de41cdf5b12087b5509e4e9805ed6f562406dfcf60e8481a9a28f8",
|
||||
"sha256:e9326ca78111e4c645f7e49cbce4ed2f3f85e17b61a563328c85a5208cf34440"
|
||||
],
|
||||
"index": "pypi",
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==41.0.6"
|
||||
"version": "==42.0.0"
|
||||
},
|
||||
"distro": {
|
||||
"hashes": [
|
||||
|
|
|
@ -4,27 +4,22 @@
|
|||
|
||||
package org.mozilla.fenix.ui
|
||||
|
||||
import okhttp3.mockwebserver.MockWebServer
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
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.MatcherHelper.itemWithResId
|
||||
import org.mozilla.fenix.helpers.MatcherHelper.itemWithResIdContainingText
|
||||
import org.mozilla.fenix.helpers.TestAssetHelper
|
||||
import org.mozilla.fenix.helpers.TestHelper.exitMenu
|
||||
import org.mozilla.fenix.helpers.TestHelper.packageName
|
||||
import org.mozilla.fenix.helpers.TestSetup
|
||||
import org.mozilla.fenix.ui.robots.autofillScreen
|
||||
import org.mozilla.fenix.ui.robots.clickPageObject
|
||||
import org.mozilla.fenix.ui.robots.homeScreen
|
||||
import org.mozilla.fenix.ui.robots.navigationToolbar
|
||||
|
||||
class AddressAutofillTest {
|
||||
private lateinit var mockWebServer: MockWebServer
|
||||
|
||||
class AddressAutofillTest : TestSetup() {
|
||||
object FirstAddressAutofillDetails {
|
||||
var navigateToAutofillSettings = true
|
||||
var isAddressAutofillEnabled = true
|
||||
|
@ -58,19 +53,6 @@ class AddressAutofillTest {
|
|||
@get:Rule
|
||||
val activityIntentTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides()
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
mockWebServer = MockWebServer().apply {
|
||||
dispatcher = AndroidAssetDispatcher()
|
||||
start()
|
||||
}
|
||||
}
|
||||
|
||||
@After
|
||||
fun tearDown() {
|
||||
mockWebServer.shutdown()
|
||||
}
|
||||
|
||||
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1836845
|
||||
@SmokeTest
|
||||
@Test
|
||||
|
|
|
@ -8,20 +8,13 @@ import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
|||
import androidx.test.espresso.Espresso.openActionBarOverflowOrOptionsMenu
|
||||
import androidx.test.espresso.Espresso.pressBack
|
||||
import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
|
||||
import androidx.test.uiautomator.UiDevice
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import mozilla.appservices.places.BookmarkRoot
|
||||
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.R
|
||||
import org.mozilla.fenix.customannotations.SmokeTest
|
||||
import org.mozilla.fenix.ext.bookmarkStorage
|
||||
import org.mozilla.fenix.ext.settings
|
||||
import org.mozilla.fenix.helpers.AndroidAssetDispatcher
|
||||
import org.mozilla.fenix.helpers.AppAndSystemHelper.registerAndCleanupIdlingResources
|
||||
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
|
||||
import org.mozilla.fenix.helpers.MockBrowserDataHelper.createBookmarkItem
|
||||
|
@ -31,7 +24,10 @@ import org.mozilla.fenix.helpers.TestAssetHelper
|
|||
import org.mozilla.fenix.helpers.TestHelper.appContext
|
||||
import org.mozilla.fenix.helpers.TestHelper.clickSnackbarButton
|
||||
import org.mozilla.fenix.helpers.TestHelper.longTapSelectItem
|
||||
import org.mozilla.fenix.helpers.TestHelper.mDevice
|
||||
import org.mozilla.fenix.helpers.TestHelper.restartApp
|
||||
import org.mozilla.fenix.helpers.TestHelper.verifySnackBarText
|
||||
import org.mozilla.fenix.helpers.TestSetup
|
||||
import org.mozilla.fenix.ui.robots.bookmarksMenu
|
||||
import org.mozilla.fenix.ui.robots.browserScreen
|
||||
import org.mozilla.fenix.ui.robots.homeScreen
|
||||
|
@ -41,9 +37,7 @@ import org.mozilla.fenix.ui.robots.navigationToolbar
|
|||
/**
|
||||
* Tests for verifying basic functionality of bookmarks
|
||||
*/
|
||||
class BookmarksTest {
|
||||
private lateinit var mockWebServer: MockWebServer
|
||||
private lateinit var mDevice: UiDevice
|
||||
class BookmarksTest : TestSetup() {
|
||||
private val bookmarksFolderName = "New Folder"
|
||||
private val testBookmark = object {
|
||||
var title: String = "Bookmark title"
|
||||
|
@ -60,26 +54,6 @@ class BookmarksTest {
|
|||
@JvmField
|
||||
val retryTestRule = RetryTestRule(3)
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
mDevice = UiDevice.getInstance(getInstrumentation())
|
||||
mockWebServer = MockWebServer().apply {
|
||||
dispatcher = AndroidAssetDispatcher()
|
||||
start()
|
||||
}
|
||||
}
|
||||
|
||||
@After
|
||||
fun tearDown() {
|
||||
mockWebServer.shutdown()
|
||||
// Clearing all bookmarks data after each test to avoid overlapping data
|
||||
val bookmarksStorage = activityTestRule.activity?.bookmarkStorage
|
||||
runBlocking {
|
||||
val bookmarks = bookmarksStorage?.getTree(BookmarkRoot.Mobile.id)?.children
|
||||
bookmarks?.forEach { bookmarksStorage.deleteNode(it.guid) }
|
||||
}
|
||||
}
|
||||
|
||||
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/522919
|
||||
@Test
|
||||
fun verifyEmptyBookmarksMenuTest() {
|
||||
|
@ -137,7 +111,7 @@ class BookmarksTest {
|
|||
clickAddFolderButton()
|
||||
addNewFolderName(bookmarksFolderName)
|
||||
navigateUp()
|
||||
verifyKeyboardHidden()
|
||||
verifyKeyboardHidden(isExpectedToBeVisible = false)
|
||||
verifyBookmarkFolderIsNotCreated(bookmarksFolderName)
|
||||
}
|
||||
}
|
||||
|
@ -209,7 +183,7 @@ class BookmarksTest {
|
|||
) {}
|
||||
}.openThreeDotMenu(defaultWebPage.title) {
|
||||
}.clickCopy {
|
||||
verifyCopySnackBarText()
|
||||
verifySnackBarText(expectedText = "URL copied")
|
||||
navigateUp()
|
||||
}
|
||||
|
||||
|
@ -496,7 +470,7 @@ class BookmarksTest {
|
|||
}
|
||||
|
||||
bookmarksMenu {
|
||||
verifyDeleteMultipleBookmarksSnackBar()
|
||||
verifySnackBarText(expectedText = "Bookmarks deleted")
|
||||
clickUndoDeleteButton()
|
||||
verifyBookmarkedURL(firstWebPage.url.toString())
|
||||
verifyBookmarkedURL(secondWebPage.url.toString())
|
||||
|
@ -514,7 +488,7 @@ class BookmarksTest {
|
|||
}
|
||||
|
||||
bookmarksMenu {
|
||||
verifyDeleteMultipleBookmarksSnackBar()
|
||||
verifySnackBarText(expectedText = "Bookmarks deleted")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -602,7 +576,7 @@ class BookmarksTest {
|
|||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list)),
|
||||
) {
|
||||
longTapDesktopFolder("Desktop Bookmarks")
|
||||
verifySelectDefaultFolderSnackBarText()
|
||||
verifySnackBarText(expectedText = "Can’t edit default folders")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -625,7 +599,7 @@ class BookmarksTest {
|
|||
cancelDeletion()
|
||||
clickDeleteInEditModeButton()
|
||||
confirmDeletion()
|
||||
verifyDeleteSnackBarText()
|
||||
verifySnackBarText(expectedText = "Deleted")
|
||||
verifyBookmarkIsDeleted("Test_Page_1")
|
||||
}
|
||||
}
|
||||
|
@ -786,13 +760,13 @@ class BookmarksTest {
|
|||
}.openThreeDotMenu("My Folder") {
|
||||
}.clickDelete {
|
||||
confirmDeletion()
|
||||
verifyDeleteSnackBarText()
|
||||
verifySnackBarText(expectedText = "Deleted")
|
||||
clickUndoDeleteButton()
|
||||
verifyFolderTitle("My Folder")
|
||||
}.openThreeDotMenu("My Folder") {
|
||||
}.clickDelete {
|
||||
confirmDeletion()
|
||||
verifyDeleteSnackBarText()
|
||||
verifySnackBarText(expectedText = "Deleted")
|
||||
verifyBookmarkIsDeleted("My Folder")
|
||||
verifyBookmarkIsDeleted("My Folder 2")
|
||||
verifyBookmarkIsDeleted("Test_Page_1")
|
||||
|
|
|
@ -5,20 +5,17 @@
|
|||
package org.mozilla.fenix.ui
|
||||
|
||||
import androidx.core.net.toUri
|
||||
import okhttp3.mockwebserver.MockWebServer
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.customannotations.SmokeTest
|
||||
import org.mozilla.fenix.helpers.AndroidAssetDispatcher
|
||||
import org.mozilla.fenix.helpers.AppAndSystemHelper.setNetworkEnabled
|
||||
import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource
|
||||
import org.mozilla.fenix.helpers.HomeActivityTestRule
|
||||
import org.mozilla.fenix.helpers.MatcherHelper.itemWithResId
|
||||
import org.mozilla.fenix.helpers.RetryTestRule
|
||||
import org.mozilla.fenix.helpers.TestAssetHelper.getGenericAsset
|
||||
import org.mozilla.fenix.helpers.TestSetup
|
||||
import org.mozilla.fenix.ui.robots.browserScreen
|
||||
import org.mozilla.fenix.ui.robots.clickPageObject
|
||||
import org.mozilla.fenix.ui.robots.navigationToolbar
|
||||
|
@ -26,13 +23,12 @@ import org.mozilla.fenix.ui.robots.navigationToolbar
|
|||
/**
|
||||
* Tests that verify errors encountered while browsing websites: unsafe pages, connection errors, etc
|
||||
*/
|
||||
class BrowsingErrorPagesTest {
|
||||
class BrowsingErrorPagesTest : TestSetup() {
|
||||
private val malwareWarning = getStringResource(R.string.mozac_browser_errorpages_safe_browsing_malware_uri_title)
|
||||
private val phishingWarning = getStringResource(R.string.mozac_browser_errorpages_safe_phishing_uri_title)
|
||||
private val unwantedSoftwareWarning =
|
||||
getStringResource(R.string.mozac_browser_errorpages_safe_browsing_unwanted_uri_title)
|
||||
private val harmfulSiteWarning = getStringResource(R.string.mozac_browser_errorpages_safe_harmful_uri_title)
|
||||
private lateinit var mockWebServer: MockWebServer
|
||||
|
||||
@get: Rule
|
||||
val mActivityTestRule = HomeActivityTestRule.withDefaultSettingsOverrides()
|
||||
|
@ -41,21 +37,6 @@ class BrowsingErrorPagesTest {
|
|||
@JvmField
|
||||
val retryTestRule = RetryTestRule(3)
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
mockWebServer = MockWebServer().apply {
|
||||
dispatcher = AndroidAssetDispatcher()
|
||||
start()
|
||||
}
|
||||
}
|
||||
|
||||
@After
|
||||
fun tearDown() {
|
||||
// Restoring network connection
|
||||
setNetworkEnabled(true)
|
||||
mockWebServer.shutdown()
|
||||
}
|
||||
|
||||
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2326774
|
||||
@SmokeTest
|
||||
@Test
|
||||
|
|
|
@ -5,19 +5,16 @@
|
|||
package org.mozilla.fenix.ui
|
||||
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.test.uiautomator.UiDevice
|
||||
import okhttp3.mockwebserver.MockWebServer
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.mozilla.fenix.customannotations.SmokeTest
|
||||
import org.mozilla.fenix.helpers.AndroidAssetDispatcher
|
||||
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
|
||||
import org.mozilla.fenix.helpers.TestAssetHelper
|
||||
import org.mozilla.fenix.helpers.TestAssetHelper.getGenericAsset
|
||||
import org.mozilla.fenix.helpers.TestHelper.clickSnackbarButton
|
||||
import org.mozilla.fenix.helpers.TestHelper.mDevice
|
||||
import org.mozilla.fenix.helpers.TestHelper.verifySnackBarText
|
||||
import org.mozilla.fenix.helpers.TestSetup
|
||||
import org.mozilla.fenix.ui.robots.browserScreen
|
||||
import org.mozilla.fenix.ui.robots.collectionRobot
|
||||
import org.mozilla.fenix.ui.robots.homeScreen
|
||||
|
@ -29,9 +26,7 @@ import org.mozilla.fenix.ui.robots.tabDrawer
|
|||
*
|
||||
*/
|
||||
|
||||
class CollectionTest {
|
||||
private lateinit var mDevice: UiDevice
|
||||
private lateinit var mockWebServer: MockWebServer
|
||||
class CollectionTest : TestSetup() {
|
||||
private val firstCollectionName = "testcollection_1"
|
||||
private val secondCollectionName = "testcollection_2"
|
||||
private val collectionName = "First Collection"
|
||||
|
@ -50,20 +45,6 @@ class CollectionTest {
|
|||
),
|
||||
) { it.activity }
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
|
||||
mockWebServer = MockWebServer().apply {
|
||||
dispatcher = AndroidAssetDispatcher()
|
||||
start()
|
||||
}
|
||||
}
|
||||
|
||||
@After
|
||||
fun tearDown() {
|
||||
mockWebServer.shutdown()
|
||||
}
|
||||
|
||||
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/353823
|
||||
@SmokeTest
|
||||
@Test
|
||||
|
@ -490,7 +471,7 @@ class CollectionTest {
|
|||
selectTab(secondWebPage.title, numOfTabs = 2)
|
||||
}.clickSaveCollection {
|
||||
typeCollectionNameAndSave(collectionName)
|
||||
verifySnackBarText("Tabs saved!")
|
||||
verifySnackBarText("Collection saved!")
|
||||
}
|
||||
|
||||
tabDrawer {
|
||||
|
|
|
@ -28,6 +28,7 @@ import org.mozilla.fenix.helpers.TestAssetHelper
|
|||
import org.mozilla.fenix.helpers.TestHelper.clickSnackbarButton
|
||||
import org.mozilla.fenix.helpers.TestHelper.exitMenu
|
||||
import org.mozilla.fenix.helpers.TestHelper.longTapSelectItem
|
||||
import org.mozilla.fenix.helpers.TestHelper.verifySnackBarText
|
||||
import org.mozilla.fenix.ui.robots.bookmarksMenu
|
||||
import org.mozilla.fenix.ui.robots.browserScreen
|
||||
import org.mozilla.fenix.ui.robots.homeScreen
|
||||
|
@ -111,7 +112,7 @@ class ComposeBookmarksTest {
|
|||
clickAddFolderButton()
|
||||
addNewFolderName(bookmarksFolderName)
|
||||
navigateUp()
|
||||
verifyKeyboardHidden()
|
||||
verifyKeyboardHidden(isExpectedToBeVisible = false)
|
||||
verifyBookmarkFolderIsNotCreated(bookmarksFolderName)
|
||||
}
|
||||
}
|
||||
|
@ -183,7 +184,7 @@ class ComposeBookmarksTest {
|
|||
) {}
|
||||
}.openThreeDotMenu(defaultWebPage.title) {
|
||||
}.clickCopy {
|
||||
verifyCopySnackBarText()
|
||||
verifySnackBarText(expectedText = "URL copied")
|
||||
navigateUp()
|
||||
}
|
||||
|
||||
|
@ -469,7 +470,7 @@ class ComposeBookmarksTest {
|
|||
}
|
||||
|
||||
bookmarksMenu {
|
||||
verifyDeleteMultipleBookmarksSnackBar()
|
||||
verifySnackBarText(expectedText = "Bookmarks deleted")
|
||||
clickUndoDeleteButton()
|
||||
verifyBookmarkedURL(firstWebPage.url.toString())
|
||||
verifyBookmarkedURL(secondWebPage.url.toString())
|
||||
|
@ -487,7 +488,7 @@ class ComposeBookmarksTest {
|
|||
}
|
||||
|
||||
bookmarksMenu {
|
||||
verifyDeleteMultipleBookmarksSnackBar()
|
||||
verifySnackBarText(expectedText = "Bookmarks deleted")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -575,7 +576,7 @@ class ComposeBookmarksTest {
|
|||
RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.bookmark_list)),
|
||||
) {
|
||||
longTapDesktopFolder("Desktop Bookmarks")
|
||||
verifySelectDefaultFolderSnackBarText()
|
||||
verifySnackBarText(expectedText = "Can’t edit default folders")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -598,7 +599,7 @@ class ComposeBookmarksTest {
|
|||
cancelDeletion()
|
||||
clickDeleteInEditModeButton()
|
||||
confirmDeletion()
|
||||
verifyDeleteSnackBarText()
|
||||
verifySnackBarText(expectedText = "Deleted")
|
||||
verifyBookmarkIsDeleted("Test_Page_1")
|
||||
}
|
||||
}
|
||||
|
@ -764,13 +765,13 @@ class ComposeBookmarksTest {
|
|||
}.openThreeDotMenu("My Folder") {
|
||||
}.clickDelete {
|
||||
confirmDeletion()
|
||||
verifyDeleteSnackBarText()
|
||||
verifySnackBarText(expectedText = "Deleted")
|
||||
clickUndoDeleteButton()
|
||||
verifyFolderTitle("My Folder")
|
||||
}.openThreeDotMenu("My Folder") {
|
||||
}.clickDelete {
|
||||
confirmDeletion()
|
||||
verifyDeleteSnackBarText()
|
||||
verifySnackBarText(expectedText = "Deleted")
|
||||
verifyBookmarkIsDeleted("My Folder")
|
||||
verifyBookmarkIsDeleted("My Folder 2")
|
||||
verifyBookmarkIsDeleted("Test_Page_1")
|
||||
|
|
|
@ -475,7 +475,7 @@ class ComposeCollectionTest {
|
|||
verifyTabsMultiSelectionCounter(2)
|
||||
}.clickSaveCollection {
|
||||
typeCollectionNameAndSave(collectionName)
|
||||
verifySnackBarText("Tabs saved!")
|
||||
verifySnackBarText("Collection saved!")
|
||||
}
|
||||
|
||||
composeTabDrawer(composeTestRule) {
|
||||
|
|
|
@ -23,6 +23,7 @@ import org.mozilla.fenix.helpers.MatcherHelper.itemWithText
|
|||
import org.mozilla.fenix.helpers.RetryTestRule
|
||||
import org.mozilla.fenix.helpers.TestAssetHelper
|
||||
import org.mozilla.fenix.helpers.TestHelper.clickSnackbarButton
|
||||
import org.mozilla.fenix.helpers.TestHelper.verifySnackBarText
|
||||
import org.mozilla.fenix.ui.robots.clickContextMenuItem
|
||||
import org.mozilla.fenix.ui.robots.clickPageObject
|
||||
import org.mozilla.fenix.ui.robots.downloadRobot
|
||||
|
|
|
@ -28,6 +28,7 @@ import org.mozilla.fenix.helpers.RecyclerViewIdlingResource
|
|||
import org.mozilla.fenix.helpers.TestAssetHelper
|
||||
import org.mozilla.fenix.helpers.TestHelper.exitMenu
|
||||
import org.mozilla.fenix.helpers.TestHelper.longTapSelectItem
|
||||
import org.mozilla.fenix.helpers.TestHelper.verifySnackBarText
|
||||
import org.mozilla.fenix.ui.robots.browserScreen
|
||||
import org.mozilla.fenix.ui.robots.historyMenu
|
||||
import org.mozilla.fenix.ui.robots.homeScreen
|
||||
|
@ -128,7 +129,7 @@ class ComposeHistoryTest {
|
|||
) {
|
||||
clickDeleteHistoryButton(firstWebPage.url.toString())
|
||||
}
|
||||
verifyDeleteSnackbarText("Deleted")
|
||||
verifySnackBarText(expectedText = "Deleted")
|
||||
verifyEmptyHistoryView()
|
||||
}
|
||||
}
|
||||
|
@ -153,7 +154,7 @@ class ComposeHistoryTest {
|
|||
verifyDeleteConfirmationMessage()
|
||||
selectEverythingOption()
|
||||
confirmDeleteAllHistory()
|
||||
verifyDeleteSnackbarText("Browsing data deleted")
|
||||
verifySnackBarText(expectedText = "Browsing data deleted")
|
||||
verifyEmptyHistoryView()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ import org.mozilla.fenix.helpers.SearchDispatcher
|
|||
import org.mozilla.fenix.helpers.TestAssetHelper
|
||||
import org.mozilla.fenix.helpers.TestHelper
|
||||
import org.mozilla.fenix.helpers.TestHelper.exitMenu
|
||||
import org.mozilla.fenix.helpers.TestHelper.verifySnackBarText
|
||||
import org.mozilla.fenix.ui.robots.clickContextMenuItem
|
||||
import org.mozilla.fenix.ui.robots.clickPageObject
|
||||
import org.mozilla.fenix.ui.robots.homeScreen
|
||||
|
@ -472,7 +473,7 @@ class ComposeSearchTest {
|
|||
}.openRecentlyVisitedSearchGroupHistoryList(queryString) {
|
||||
clickDeleteAllHistoryButton()
|
||||
confirmDeleteAllHistory()
|
||||
verifyDeleteSnackbarText("Group deleted")
|
||||
verifySnackBarText(expectedText = "Group deleted")
|
||||
verifyHistoryItemExists(shouldExist = false, firstPageUrl.toString())
|
||||
}.goBack {}
|
||||
homeScreen {
|
||||
|
|
|
@ -20,8 +20,10 @@ import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource
|
|||
import org.mozilla.fenix.helpers.HomeActivityTestRule
|
||||
import org.mozilla.fenix.helpers.TestAssetHelper.getGenericAsset
|
||||
import org.mozilla.fenix.helpers.TestHelper.clickSnackbarButton
|
||||
import org.mozilla.fenix.helpers.TestHelper.verifySnackBarText
|
||||
import org.mozilla.fenix.helpers.TestHelper.waitUntilSnackbarGone
|
||||
import org.mozilla.fenix.ui.robots.browserScreen
|
||||
import org.mozilla.fenix.ui.robots.homeScreen
|
||||
import org.mozilla.fenix.ui.robots.homeScreenWithComposeTopSites
|
||||
import org.mozilla.fenix.ui.robots.navigationToolbar
|
||||
|
||||
|
@ -66,8 +68,12 @@ class ComposeTopSitesTest {
|
|||
fun addAWebsiteAsATopSiteTest() {
|
||||
val defaultWebPage = getGenericAsset(mockWebServer, 1)
|
||||
|
||||
homeScreenWithComposeTopSites(composeTestRule) {
|
||||
verifyExistingTopSitesList()
|
||||
}
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(defaultWebPage.url) {
|
||||
verifyPageContent(defaultWebPage.content)
|
||||
}.openThreeDotMenu {
|
||||
expandMenu()
|
||||
verifyAddToShortcutsButton(true)
|
||||
|
@ -84,8 +90,12 @@ class ComposeTopSitesTest {
|
|||
fun openTopSiteInANewTabTest() {
|
||||
val defaultWebPage = getGenericAsset(mockWebServer, 1)
|
||||
|
||||
homeScreenWithComposeTopSites(composeTestRule) {
|
||||
verifyExistingTopSitesList()
|
||||
}
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(defaultWebPage.url) {
|
||||
verifyPageContent(defaultWebPage.content)
|
||||
}.openThreeDotMenu {
|
||||
expandMenu()
|
||||
verifyAddToShortcutsButton(true)
|
||||
|
@ -112,8 +122,12 @@ class ComposeTopSitesTest {
|
|||
fun openTopSiteInANewPrivateTabTest() {
|
||||
val defaultWebPage = getGenericAsset(mockWebServer, 1)
|
||||
|
||||
homeScreenWithComposeTopSites(composeTestRule) {
|
||||
verifyExistingTopSitesList()
|
||||
}
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(defaultWebPage.url) {
|
||||
verifyPageContent(defaultWebPage.content)
|
||||
}.openThreeDotMenu {
|
||||
expandMenu()
|
||||
verifyAddToShortcutsButton(true)
|
||||
|
@ -135,6 +149,9 @@ class ComposeTopSitesTest {
|
|||
val defaultWebPage = getGenericAsset(mockWebServer, 1)
|
||||
val newPageTitle = generateRandomString(5)
|
||||
|
||||
homeScreenWithComposeTopSites(composeTestRule) {
|
||||
verifyExistingTopSitesList()
|
||||
}
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(defaultWebPage.url) {
|
||||
waitForPageToLoad()
|
||||
|
@ -159,8 +176,12 @@ class ComposeTopSitesTest {
|
|||
fun removeTopSiteUsingMenuButtonTest() {
|
||||
val defaultWebPage = getGenericAsset(mockWebServer, 1)
|
||||
|
||||
homeScreenWithComposeTopSites(composeTestRule) {
|
||||
verifyExistingTopSitesList()
|
||||
}
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(defaultWebPage.url) {
|
||||
verifyPageContent(defaultWebPage.content)
|
||||
}.openThreeDotMenu {
|
||||
expandMenu()
|
||||
verifyAddToShortcutsButton(true)
|
||||
|
@ -186,8 +207,12 @@ class ComposeTopSitesTest {
|
|||
fun removeTopSiteFromMainMenuTest() {
|
||||
val defaultWebPage = getGenericAsset(mockWebServer, 1)
|
||||
|
||||
homeScreenWithComposeTopSites(composeTestRule) {
|
||||
verifyExistingTopSitesList()
|
||||
}
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(defaultWebPage.url) {
|
||||
verifyPageContent(defaultWebPage.content)
|
||||
}.openThreeDotMenu {
|
||||
expandMenu()
|
||||
verifyAddToShortcutsButton(true)
|
||||
|
@ -236,9 +261,11 @@ class ComposeTopSitesTest {
|
|||
verifyExistingTopSitesList()
|
||||
verifyExistingTopSiteItem(defaultWebPage.title)
|
||||
}.openContextMenuOnTopSitesWithTitle(defaultWebPage.title) {
|
||||
}.deleteTopSiteFromHistory {
|
||||
}.removeTopSite {
|
||||
verifySnackBarText(getStringResource(R.string.snackbar_top_site_removed))
|
||||
waitUntilSnackbarGone()
|
||||
}
|
||||
homeScreen {
|
||||
}.openThreeDotMenu {
|
||||
}.openHistory {
|
||||
verifyEmptyHistoryView()
|
||||
|
|
|
@ -5,15 +5,8 @@
|
|||
package org.mozilla.fenix.ui
|
||||
|
||||
import androidx.core.net.toUri
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.test.uiautomator.UiDevice
|
||||
import okhttp3.mockwebserver.MockWebServer
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.mozilla.fenix.ext.settings
|
||||
import org.mozilla.fenix.helpers.AndroidAssetDispatcher
|
||||
import org.mozilla.fenix.helpers.AppAndSystemHelper.assertExternalAppOpens
|
||||
import org.mozilla.fenix.helpers.Constants.PackageName.YOUTUBE_APP
|
||||
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
|
||||
|
@ -22,6 +15,9 @@ import org.mozilla.fenix.helpers.MatcherHelper.itemWithText
|
|||
import org.mozilla.fenix.helpers.RetryTestRule
|
||||
import org.mozilla.fenix.helpers.TestAssetHelper
|
||||
import org.mozilla.fenix.helpers.TestHelper.clickSnackbarButton
|
||||
import org.mozilla.fenix.helpers.TestHelper.mDevice
|
||||
import org.mozilla.fenix.helpers.TestHelper.verifySnackBarText
|
||||
import org.mozilla.fenix.helpers.TestSetup
|
||||
import org.mozilla.fenix.ui.robots.clickContextMenuItem
|
||||
import org.mozilla.fenix.ui.robots.clickPageObject
|
||||
import org.mozilla.fenix.ui.robots.downloadRobot
|
||||
|
@ -43,32 +39,15 @@ import org.mozilla.fenix.ui.robots.shareOverlay
|
|||
*
|
||||
*/
|
||||
|
||||
class ContextMenusTest {
|
||||
private lateinit var mDevice: UiDevice
|
||||
private lateinit var mockWebServer: MockWebServer
|
||||
class ContextMenusTest : TestSetup() {
|
||||
|
||||
@get:Rule
|
||||
val activityIntentTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides()
|
||||
val activityIntentTestRule = HomeActivityIntentTestRule(isJumpBackInCFREnabled = false)
|
||||
|
||||
@Rule
|
||||
@JvmField
|
||||
val retryTestRule = RetryTestRule(3)
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
activityIntentTestRule.activity.applicationContext.settings().shouldShowJumpBackInCFR = false
|
||||
mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
|
||||
mockWebServer = MockWebServer().apply {
|
||||
dispatcher = AndroidAssetDispatcher()
|
||||
start()
|
||||
}
|
||||
}
|
||||
|
||||
@After
|
||||
fun tearDown() {
|
||||
mockWebServer.shutdown()
|
||||
}
|
||||
|
||||
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/243837
|
||||
@Test
|
||||
fun verifyOpenLinkNewTabContextMenuOptionTest() {
|
||||
|
|
|
@ -12,13 +12,14 @@ import org.mozilla.fenix.ext.settings
|
|||
import org.mozilla.fenix.helpers.AppAndSystemHelper.runWithCondition
|
||||
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
|
||||
import org.mozilla.fenix.helpers.TestHelper.appContext
|
||||
import org.mozilla.fenix.helpers.TestSetup
|
||||
import org.mozilla.fenix.ui.robots.homeScreen
|
||||
import org.mozilla.fenix.ui.robots.navigationToolbar
|
||||
|
||||
/**
|
||||
* Tests for verifying the new Cookie banner blocker option and functionality.
|
||||
*/
|
||||
class CookieBannerBlockerTest {
|
||||
class CookieBannerBlockerTest : TestSetup() {
|
||||
@get:Rule
|
||||
val activityTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides(skipOnboarding = true)
|
||||
|
||||
|
|
|
@ -5,29 +5,23 @@
|
|||
package org.mozilla.fenix.ui
|
||||
|
||||
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.test.uiautomator.UiDevice
|
||||
import okhttp3.mockwebserver.MockWebServer
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Ignore
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.customannotations.SmokeTest
|
||||
import org.mozilla.fenix.helpers.AndroidAssetDispatcher
|
||||
import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource
|
||||
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
|
||||
import org.mozilla.fenix.helpers.MatcherHelper.itemWithResId
|
||||
import org.mozilla.fenix.helpers.TestAssetHelper
|
||||
import org.mozilla.fenix.helpers.TestHelper.mDevice
|
||||
import org.mozilla.fenix.helpers.TestHelper.packageName
|
||||
import org.mozilla.fenix.helpers.TestSetup
|
||||
import org.mozilla.fenix.ui.robots.clickPageObject
|
||||
import org.mozilla.fenix.ui.robots.homeScreen
|
||||
import org.mozilla.fenix.ui.robots.navigationToolbar
|
||||
|
||||
class CrashReportingTest {
|
||||
private lateinit var mDevice: UiDevice
|
||||
private lateinit var mockWebServer: MockWebServer
|
||||
class CrashReportingTest : TestSetup() {
|
||||
private val tabCrashMessage = getStringResource(R.string.tab_crash_title_2)
|
||||
|
||||
@get:Rule
|
||||
|
@ -40,20 +34,6 @@ class CrashReportingTest {
|
|||
),
|
||||
) { it.activity }
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
|
||||
mockWebServer = MockWebServer().apply {
|
||||
dispatcher = AndroidAssetDispatcher()
|
||||
start()
|
||||
}
|
||||
}
|
||||
|
||||
@After
|
||||
fun tearDown() {
|
||||
mockWebServer.shutdown()
|
||||
}
|
||||
|
||||
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/308906
|
||||
@Test
|
||||
fun closeTabFromCrashedTabReporterTest() {
|
||||
|
@ -105,7 +85,7 @@ class CrashReportingTest {
|
|||
verifyPageContent(tabCrashMessage)
|
||||
}.openTabDrawer {
|
||||
verifyExistingOpenTabs(firstWebPage.title)
|
||||
verifyExistingOpenTabs(secondWebPage.title)
|
||||
verifyExistingOpenTabs("about:crashcontent")
|
||||
}.closeTabDrawer {
|
||||
}.goToHomescreen {
|
||||
verifyExistingTopSitesList()
|
||||
|
|
|
@ -4,13 +4,9 @@
|
|||
|
||||
package org.mozilla.fenix.ui
|
||||
|
||||
import okhttp3.mockwebserver.MockWebServer
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
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.AppAndSystemHelper.bringAppToForeground
|
||||
import org.mozilla.fenix.helpers.AppAndSystemHelper.putAppToBackground
|
||||
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
|
||||
|
@ -19,14 +15,13 @@ import org.mozilla.fenix.helpers.MatcherHelper.itemWithResIdContainingText
|
|||
import org.mozilla.fenix.helpers.TestAssetHelper
|
||||
import org.mozilla.fenix.helpers.TestHelper.exitMenu
|
||||
import org.mozilla.fenix.helpers.TestHelper.packageName
|
||||
import org.mozilla.fenix.helpers.TestSetup
|
||||
import org.mozilla.fenix.ui.robots.clickPageObject
|
||||
import org.mozilla.fenix.ui.robots.homeScreen
|
||||
import org.mozilla.fenix.ui.robots.navigationToolbar
|
||||
import java.time.LocalDate
|
||||
|
||||
class CreditCardAutofillTest {
|
||||
private lateinit var mockWebServer: MockWebServer
|
||||
|
||||
class CreditCardAutofillTest : TestSetup() {
|
||||
object MockCreditCard1 {
|
||||
const val MOCK_CREDIT_CARD_NUMBER = "5555555555554444"
|
||||
const val MOCK_LAST_CARD_DIGITS = "4444"
|
||||
|
@ -48,19 +43,6 @@ class CreditCardAutofillTest {
|
|||
@get:Rule
|
||||
val activityIntentTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides()
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
mockWebServer = MockWebServer().apply {
|
||||
dispatcher = AndroidAssetDispatcher()
|
||||
start()
|
||||
}
|
||||
}
|
||||
|
||||
@After
|
||||
fun tearDown() {
|
||||
mockWebServer.shutdown()
|
||||
}
|
||||
|
||||
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/1512792
|
||||
@SmokeTest
|
||||
@Test
|
||||
|
|
|
@ -7,25 +7,20 @@
|
|||
package org.mozilla.fenix.ui
|
||||
|
||||
import androidx.core.net.toUri
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.test.rule.ActivityTestRule
|
||||
import androidx.test.uiautomator.UiDevice
|
||||
import okhttp3.mockwebserver.MockWebServer
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.mozilla.fenix.IntentReceiverActivity
|
||||
import org.mozilla.fenix.customannotations.SmokeTest
|
||||
import org.mozilla.fenix.helpers.AndroidAssetDispatcher
|
||||
import org.mozilla.fenix.helpers.AppAndSystemHelper.openAppFromExternalLink
|
||||
import org.mozilla.fenix.helpers.DataGenerationHelper.createCustomTabIntent
|
||||
import org.mozilla.fenix.helpers.FeatureSettingsHelperDelegate
|
||||
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
|
||||
import org.mozilla.fenix.helpers.MatcherHelper.itemWithResIdAndText
|
||||
import org.mozilla.fenix.helpers.MatcherHelper.itemWithText
|
||||
import org.mozilla.fenix.helpers.TestAssetHelper
|
||||
import org.mozilla.fenix.helpers.TestHelper.exitMenu
|
||||
import org.mozilla.fenix.helpers.TestHelper.mDevice
|
||||
import org.mozilla.fenix.helpers.TestSetup
|
||||
import org.mozilla.fenix.ui.robots.browserScreen
|
||||
import org.mozilla.fenix.ui.robots.clickPageObject
|
||||
import org.mozilla.fenix.ui.robots.customTabScreen
|
||||
|
@ -36,9 +31,7 @@ import org.mozilla.fenix.ui.robots.notificationShade
|
|||
import org.mozilla.fenix.ui.robots.openEditURLView
|
||||
import org.mozilla.fenix.ui.robots.searchScreen
|
||||
|
||||
class CustomTabsTest {
|
||||
private lateinit var mDevice: UiDevice
|
||||
private lateinit var mockWebServer: MockWebServer
|
||||
class CustomTabsTest : TestSetup() {
|
||||
private val customMenuItem = "TestMenuItem"
|
||||
private val customTabActionButton = "CustomActionButton"
|
||||
|
||||
|
@ -58,23 +51,6 @@ class CustomTabsTest {
|
|||
false,
|
||||
)
|
||||
|
||||
private val featureSettingsHelper = FeatureSettingsHelperDelegate()
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
|
||||
mockWebServer = MockWebServer().apply {
|
||||
dispatcher = AndroidAssetDispatcher()
|
||||
start()
|
||||
}
|
||||
}
|
||||
|
||||
@After
|
||||
fun tearDown() {
|
||||
mockWebServer.shutdown()
|
||||
featureSettingsHelper.resetAllFeatureFlags()
|
||||
}
|
||||
|
||||
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/249659
|
||||
@SmokeTest
|
||||
@Test
|
||||
|
|
|
@ -48,9 +48,9 @@ class FirefoxSuggestTest {
|
|||
"Nike.com - Official Site",
|
||||
"nike.com/?cp=16423867261_search_318370984us128${getSponsoredFxSuggestPlaceHolder()}&mfadid=adm",
|
||||
),
|
||||
"Macy" to listOf(
|
||||
"macys.com - Official Site",
|
||||
"macys.com/?cm_mmc=Google_AdMarketPlace-_-Privacy_Instant%20Suggest-_-319101130_Broad-_-kclickid__kenshoo_clickid_&m_sc=sem&m_sb=Admarketplace&m_tp=Search&m_ac=Admarketplace&m_ag=Instant%20Suggest&m_cn=Privacy&m_pi=kclickid__kenshoo_clickid__319101130us1201${getSponsoredFxSuggestPlaceHolder()}&mfadid=adm",
|
||||
"Houzz" to listOf(
|
||||
"Houzz.com - Official Site",
|
||||
"houzz.com/products?m_refid=us-dsp-mpl-admp-219577_15416306_kwd-353208810&adcid=319104989us1287${getSponsoredFxSuggestPlaceHolder()}&mfadid=adm",
|
||||
),
|
||||
"Spanx" to listOf(
|
||||
"SPANX® - Official Site",
|
||||
|
@ -101,7 +101,7 @@ class FirefoxSuggestTest {
|
|||
private val nonSponsoredKeyWord = nonSponsoredKeyWords.keys.random()
|
||||
|
||||
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2348361
|
||||
@Ignore("Failing, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1874831")
|
||||
// Known bug that might affect this UI test: https://bugzilla.mozilla.org/show_bug.cgi?id=1813587
|
||||
@SmokeTest
|
||||
@Test
|
||||
fun verifyFirefoxSuggestSponsoredSearchResultsTest() {
|
||||
|
@ -123,7 +123,7 @@ class FirefoxSuggestTest {
|
|||
}
|
||||
|
||||
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2348362
|
||||
@Ignore("Failing, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1874831")
|
||||
// Known bug that might affect this UI test: https://bugzilla.mozilla.org/show_bug.cgi?id=1813587
|
||||
@Test
|
||||
fun verifyFirefoxSuggestSponsoredSearchResultsWithPartialKeywordTest() {
|
||||
runWithCondition(TestHelper.appContext.settings().enableFxSuggest) {
|
||||
|
@ -144,7 +144,7 @@ class FirefoxSuggestTest {
|
|||
}
|
||||
|
||||
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2348363
|
||||
@Ignore("Failing, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1874831")
|
||||
// Known bug that might affect this UI test: https://bugzilla.mozilla.org/show_bug.cgi?id=1813587
|
||||
@Test
|
||||
fun openFirefoxSuggestSponsoredSearchResultsTest() {
|
||||
runWithCondition(TestHelper.appContext.settings().enableFxSuggest) {
|
||||
|
@ -168,7 +168,7 @@ class FirefoxSuggestTest {
|
|||
}
|
||||
|
||||
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2348369
|
||||
@Ignore("Failing, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1874831")
|
||||
// Known bug that might affect this UI test: https://bugzilla.mozilla.org/show_bug.cgi?id=1813587
|
||||
@Test
|
||||
fun verifyFirefoxSuggestSponsoredSearchResultsWithEditedKeywordTest() {
|
||||
runWithCondition(TestHelper.appContext.settings().enableFxSuggest) {
|
||||
|
@ -192,6 +192,8 @@ class FirefoxSuggestTest {
|
|||
}
|
||||
|
||||
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2348374
|
||||
// Known bug that might affect this UI test: https://bugzilla.mozilla.org/show_bug.cgi?id=1813587
|
||||
@Ignore("Failing, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1882035")
|
||||
@SmokeTest
|
||||
@Test
|
||||
fun verifyFirefoxSuggestNonSponsoredSearchResultsTest() {
|
||||
|
@ -218,6 +220,8 @@ class FirefoxSuggestTest {
|
|||
}
|
||||
|
||||
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2348375
|
||||
// Known bug that might affect this UI test: https://bugzilla.mozilla.org/show_bug.cgi?id=1813587
|
||||
@Ignore("Failing, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1882035")
|
||||
@Test
|
||||
fun verifyFirefoxSuggestNonSponsoredSearchResultsWithPartialKeywordTest() {
|
||||
runWithCondition(TestHelper.appContext.settings().enableFxSuggest) {
|
||||
|
@ -237,6 +241,8 @@ class FirefoxSuggestTest {
|
|||
}
|
||||
|
||||
// TestRail link: https://testrail.stage.mozaws.net/index.php?/cases/view/2348376
|
||||
// Known bug that might affect this UI test: https://bugzilla.mozilla.org/show_bug.cgi?id=1813587
|
||||
@Ignore("Failing, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1882035")
|
||||
@Test
|
||||
fun openFirefoxSuggestNonSponsoredSearchResultsTest() {
|
||||
runWithCondition(TestHelper.appContext.settings().enableFxSuggest) {
|
||||
|
|
|
@ -29,6 +29,7 @@ import org.mozilla.fenix.helpers.RecyclerViewIdlingResource
|
|||
import org.mozilla.fenix.helpers.TestAssetHelper
|
||||
import org.mozilla.fenix.helpers.TestHelper.exitMenu
|
||||
import org.mozilla.fenix.helpers.TestHelper.longTapSelectItem
|
||||
import org.mozilla.fenix.helpers.TestHelper.verifySnackBarText
|
||||
import org.mozilla.fenix.ui.robots.browserScreen
|
||||
import org.mozilla.fenix.ui.robots.historyMenu
|
||||
import org.mozilla.fenix.ui.robots.homeScreen
|
||||
|
@ -131,7 +132,7 @@ class HistoryTest {
|
|||
clickUndoDeleteButton()
|
||||
verifyHistoryItemExists(true, firstWebPage.url.toString())
|
||||
clickDeleteHistoryButton(firstWebPage.url.toString())
|
||||
verifyDeleteSnackbarText("Deleted")
|
||||
verifySnackBarText(expectedText = "Deleted")
|
||||
verifyEmptyHistoryView()
|
||||
}
|
||||
}
|
||||
|
@ -161,7 +162,7 @@ class HistoryTest {
|
|||
verifyDeleteConfirmationMessage()
|
||||
selectEverythingOption()
|
||||
confirmDeleteAllHistory()
|
||||
verifyDeleteSnackbarText("Browsing data deleted")
|
||||
verifySnackBarText(expectedText = "Browsing data deleted")
|
||||
verifyEmptyHistoryView()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ import org.mozilla.fenix.helpers.TestHelper.packageName
|
|||
import org.mozilla.fenix.helpers.TestHelper.restartApp
|
||||
import org.mozilla.fenix.helpers.TestHelper.scrollToElementByText
|
||||
import org.mozilla.fenix.helpers.TestHelper.verifySnackBarText
|
||||
import org.mozilla.fenix.helpers.TestHelper.waitForAppWindowToBeUpdated
|
||||
import org.mozilla.fenix.ui.robots.browserScreen
|
||||
import org.mozilla.fenix.ui.robots.clearTextFieldItem
|
||||
import org.mozilla.fenix.ui.robots.clickPageObject
|
||||
|
@ -260,12 +261,16 @@ class LoginsTest {
|
|||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(loginPage.toUri()) {
|
||||
setPageObjectText(itemWithResId("username"), firstUser)
|
||||
waitForAppWindowToBeUpdated()
|
||||
setPageObjectText(itemWithResId("password"), firstPass)
|
||||
waitForAppWindowToBeUpdated()
|
||||
clickPageObject(itemWithResId("submit"))
|
||||
verifySaveLoginPromptIsDisplayed()
|
||||
clickPageObject(itemWithText("Save"))
|
||||
setPageObjectText(itemWithResId("username"), secondUser)
|
||||
waitForAppWindowToBeUpdated()
|
||||
setPageObjectText(itemWithResId("password"), secondPass)
|
||||
waitForAppWindowToBeUpdated()
|
||||
clickPageObject(itemWithResId("submit"))
|
||||
verifySaveLoginPromptIsDisplayed()
|
||||
clickPageObject(itemWithText("Save"))
|
||||
|
@ -505,9 +510,13 @@ class LoginsTest {
|
|||
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(loginPage.toUri()) {
|
||||
waitForPageToLoad()
|
||||
setPageObjectText(itemWithResId("username"), "mozilla")
|
||||
waitForAppWindowToBeUpdated()
|
||||
setPageObjectText(itemWithResId("password"), "firefox")
|
||||
waitForAppWindowToBeUpdated()
|
||||
clickPageObject(itemWithResId("submit"))
|
||||
waitForPageToLoad()
|
||||
verifySaveLoginPromptIsDisplayed()
|
||||
clickPageObject(itemWithText("Save"))
|
||||
}.openTabDrawer {
|
||||
|
@ -516,6 +525,8 @@ class LoginsTest {
|
|||
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(loginPage.toUri()) {
|
||||
waitForPageToLoad()
|
||||
clickPageObject(itemWithResId("togglePassword"))
|
||||
verifyPrefilledLoginCredentials("mozilla", "firefox", true)
|
||||
}.openTabDrawer {
|
||||
closeTab()
|
||||
|
|
|
@ -175,21 +175,21 @@ class MainMenuTest {
|
|||
verifyFindInPagePrevButton()
|
||||
verifyFindInPageCloseButton()
|
||||
enterFindInPageQuery("a")
|
||||
verifyFindNextInPageResult("1/3")
|
||||
verifyFindInPageResult("1/3")
|
||||
clickFindInPageNextButton()
|
||||
verifyFindNextInPageResult("2/3")
|
||||
verifyFindInPageResult("2/3")
|
||||
clickFindInPageNextButton()
|
||||
verifyFindNextInPageResult("3/3")
|
||||
verifyFindInPageResult("3/3")
|
||||
clickFindInPagePrevButton()
|
||||
verifyFindPrevInPageResult("2/3")
|
||||
verifyFindInPageResult("2/3")
|
||||
clickFindInPagePrevButton()
|
||||
verifyFindPrevInPageResult("1/3")
|
||||
verifyFindInPageResult("1/3")
|
||||
}.closeFindInPageWithCloseButton {
|
||||
verifyFindInPageBar(false)
|
||||
}.openThreeDotMenu {
|
||||
}.openFindInPage {
|
||||
enterFindInPageQuery("3")
|
||||
verifyFindNextInPageResult("1/1")
|
||||
verifyFindInPageResult("1/1")
|
||||
}.closeFindInPageWithBackButton {
|
||||
verifyFindInPageBar(false)
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ import org.mozilla.fenix.helpers.HomeActivityTestRule
|
|||
import org.mozilla.fenix.helpers.MatcherHelper.itemWithText
|
||||
import org.mozilla.fenix.helpers.RetryTestRule
|
||||
import org.mozilla.fenix.helpers.TestAssetHelper
|
||||
import org.mozilla.fenix.helpers.TestHelper.verifySnackBarText
|
||||
import org.mozilla.fenix.ui.robots.browserScreen
|
||||
import org.mozilla.fenix.ui.robots.clickPageObject
|
||||
import org.mozilla.fenix.ui.robots.homeScreen
|
||||
|
|
|
@ -117,17 +117,17 @@ class PDFViewerTest {
|
|||
verifyFindInPagePrevButton()
|
||||
verifyFindInPageCloseButton()
|
||||
enterFindInPageQuery("l")
|
||||
verifyFindNextInPageResult("1/2")
|
||||
verifyFindInPageResult("1/2")
|
||||
clickFindInPageNextButton()
|
||||
verifyFindNextInPageResult("2/2")
|
||||
verifyFindInPageResult("2/2")
|
||||
clickFindInPagePrevButton()
|
||||
verifyFindPrevInPageResult("1/2")
|
||||
verifyFindInPageResult("1/2")
|
||||
}.closeFindInPageWithCloseButton {
|
||||
verifyFindInPageBar(false)
|
||||
}.openThreeDotMenu {
|
||||
}.openFindInPage {
|
||||
enterFindInPageQuery("p")
|
||||
verifyFindNextInPageResult("1/1")
|
||||
verifyFindInPageResult("1/1")
|
||||
}.closeFindInPageWithBackButton {
|
||||
verifyFindInPageBar(false)
|
||||
}
|
||||
|
|
|
@ -44,6 +44,7 @@ import org.mozilla.fenix.helpers.TestHelper.clickSnackbarButton
|
|||
import org.mozilla.fenix.helpers.TestHelper.exitMenu
|
||||
import org.mozilla.fenix.helpers.TestHelper.longTapSelectItem
|
||||
import org.mozilla.fenix.helpers.TestHelper.mDevice
|
||||
import org.mozilla.fenix.helpers.TestHelper.verifySnackBarText
|
||||
import org.mozilla.fenix.ui.robots.clickContextMenuItem
|
||||
import org.mozilla.fenix.ui.robots.clickPageObject
|
||||
import org.mozilla.fenix.ui.robots.homeScreen
|
||||
|
@ -487,7 +488,7 @@ class SearchTest {
|
|||
}.openRecentlyVisitedSearchGroupHistoryList(queryString) {
|
||||
clickDeleteAllHistoryButton()
|
||||
confirmDeleteAllHistory()
|
||||
verifyDeleteSnackbarText("Group deleted")
|
||||
verifySnackBarText("Group deleted")
|
||||
verifyHistoryItemExists(shouldExist = false, firstPageUrl.toString())
|
||||
}.goBack {}
|
||||
homeScreen {
|
||||
|
|
|
@ -38,7 +38,6 @@ class SettingsAdvancedTest {
|
|||
private val youTubeFullLink = itemContainingText("Youtube full link")
|
||||
private val playStoreLink = itemContainingText("Playstore link")
|
||||
private val playStoreUrl = "play.google.com"
|
||||
private val youTubePage = "vnd.youtube://".toUri()
|
||||
|
||||
@get:Rule
|
||||
val activityIntentTestRule = HomeActivityIntentTestRule.withDefaultSettingsOverrides()
|
||||
|
@ -159,11 +158,10 @@ class SettingsAdvancedTest {
|
|||
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(externalLinksPage.url) {
|
||||
clickPageObject(youTubeFullLink)
|
||||
clickPageObject(youTubeSchemaLink)
|
||||
verifyOpenLinkInAnotherAppPrompt()
|
||||
clickPageObject(itemWithResIdAndText("android:id/button2", "CANCEL"))
|
||||
waitForPageToLoad()
|
||||
verifyUrl("youtube")
|
||||
verifyUrl(externalLinksPage.url.toString())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -226,14 +224,13 @@ class SettingsAdvancedTest {
|
|||
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(externalLinksPage.url) {
|
||||
clickPageObject(youTubeFullLink)
|
||||
clickPageObject(youTubeSchemaLink)
|
||||
verifyPrivateBrowsingOpenLinkInAnotherAppPrompt(
|
||||
url = "youtube",
|
||||
pageObject = youTubeFullLink,
|
||||
pageObject = youTubeSchemaLink,
|
||||
)
|
||||
clickPageObject(itemWithResIdAndText("android:id/button2", "CANCEL"))
|
||||
waitForPageToLoad()
|
||||
verifyUrl("youtube")
|
||||
verifyUrl(externalLinksPage.url.toString())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -311,7 +308,7 @@ class SettingsAdvancedTest {
|
|||
}
|
||||
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(youTubePage) {
|
||||
}.enterURLAndEnterToBrowser("https://m.youtube.com/".toUri()) {
|
||||
waitForPageToLoad()
|
||||
verifyOpenLinksInAppsCFRExists(true)
|
||||
clickOpenLinksInAppsDismissCFRButton()
|
||||
|
|
|
@ -18,6 +18,7 @@ import org.mozilla.fenix.helpers.RetryTestRule
|
|||
import org.mozilla.fenix.helpers.TestAssetHelper.getGenericAsset
|
||||
import org.mozilla.fenix.helpers.TestHelper.mDevice
|
||||
import org.mozilla.fenix.helpers.TestHelper.restartApp
|
||||
import org.mozilla.fenix.helpers.TestHelper.verifySnackBarText
|
||||
import org.mozilla.fenix.ui.robots.browserScreen
|
||||
import org.mozilla.fenix.ui.robots.homeScreen
|
||||
import org.mozilla.fenix.ui.robots.navigationToolbar
|
||||
|
|
|
@ -41,6 +41,7 @@ class SettingsSearchTest {
|
|||
listOf(
|
||||
"LeOSearch",
|
||||
"DuckDuckGo",
|
||||
"Google",
|
||||
)
|
||||
|
||||
@get:Rule
|
||||
|
|
|
@ -23,6 +23,7 @@ import org.mozilla.fenix.helpers.RetryTestRule
|
|||
import org.mozilla.fenix.helpers.TestAssetHelper
|
||||
import org.mozilla.fenix.helpers.TestHelper.closeApp
|
||||
import org.mozilla.fenix.helpers.TestHelper.restartApp
|
||||
import org.mozilla.fenix.helpers.TestHelper.verifySnackBarText
|
||||
import org.mozilla.fenix.ui.robots.browserScreen
|
||||
import org.mozilla.fenix.ui.robots.clickPageObject
|
||||
import org.mozilla.fenix.ui.robots.homeScreen
|
||||
|
|
|
@ -20,6 +20,7 @@ import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource
|
|||
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
|
||||
import org.mozilla.fenix.helpers.TestAssetHelper.getGenericAsset
|
||||
import org.mozilla.fenix.helpers.TestHelper.clickSnackbarButton
|
||||
import org.mozilla.fenix.helpers.TestHelper.verifySnackBarText
|
||||
import org.mozilla.fenix.helpers.TestHelper.waitUntilSnackbarGone
|
||||
import org.mozilla.fenix.ui.robots.browserScreen
|
||||
import org.mozilla.fenix.ui.robots.homeScreen
|
||||
|
@ -61,8 +62,12 @@ class TopSitesTest {
|
|||
fun addAWebsiteAsATopSiteTest() {
|
||||
val defaultWebPage = getGenericAsset(mockWebServer, 1)
|
||||
|
||||
homeScreen {
|
||||
verifyExistingTopSitesList()
|
||||
}
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(defaultWebPage.url) {
|
||||
verifyPageContent(defaultWebPage.content)
|
||||
}.openThreeDotMenu {
|
||||
expandMenu()
|
||||
verifyAddToShortcutsButton(shouldExist = true)
|
||||
|
@ -79,8 +84,12 @@ class TopSitesTest {
|
|||
fun openTopSiteInANewTabTest() {
|
||||
val defaultWebPage = getGenericAsset(mockWebServer, 1)
|
||||
|
||||
homeScreen {
|
||||
verifyExistingTopSitesList()
|
||||
}
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(defaultWebPage.url) {
|
||||
verifyPageContent(defaultWebPage.content)
|
||||
}.openThreeDotMenu {
|
||||
expandMenu()
|
||||
verifyAddToShortcutsButton(shouldExist = true)
|
||||
|
@ -107,8 +116,12 @@ class TopSitesTest {
|
|||
fun openTopSiteInANewPrivateTabTest() {
|
||||
val defaultWebPage = getGenericAsset(mockWebServer, 1)
|
||||
|
||||
homeScreen {
|
||||
verifyExistingTopSitesList()
|
||||
}
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(defaultWebPage.url) {
|
||||
verifyPageContent(defaultWebPage.content)
|
||||
}.openThreeDotMenu {
|
||||
expandMenu()
|
||||
verifyAddToShortcutsButton(shouldExist = true)
|
||||
|
@ -130,6 +143,9 @@ class TopSitesTest {
|
|||
val defaultWebPage = getGenericAsset(mockWebServer, 1)
|
||||
val newPageTitle = generateRandomString(5)
|
||||
|
||||
homeScreen {
|
||||
verifyExistingTopSitesList()
|
||||
}
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(defaultWebPage.url) {
|
||||
waitForPageToLoad()
|
||||
|
@ -154,8 +170,12 @@ class TopSitesTest {
|
|||
fun removeTopSiteUsingMenuButtonTest() {
|
||||
val defaultWebPage = getGenericAsset(mockWebServer, 1)
|
||||
|
||||
homeScreen {
|
||||
verifyExistingTopSitesList()
|
||||
}
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(defaultWebPage.url) {
|
||||
verifyPageContent(defaultWebPage.content)
|
||||
}.openThreeDotMenu {
|
||||
expandMenu()
|
||||
verifyAddToShortcutsButton(shouldExist = true)
|
||||
|
@ -181,8 +201,12 @@ class TopSitesTest {
|
|||
fun removeTopSiteFromMainMenuTest() {
|
||||
val defaultWebPage = getGenericAsset(mockWebServer, 1)
|
||||
|
||||
homeScreen {
|
||||
verifyExistingTopSitesList()
|
||||
}
|
||||
navigationToolbar {
|
||||
}.enterURLAndEnterToBrowser(defaultWebPage.url) {
|
||||
verifyPageContent(defaultWebPage.content)
|
||||
}.openThreeDotMenu {
|
||||
expandMenu()
|
||||
verifyAddToShortcutsButton(shouldExist = true)
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
package org.mozilla.fenix.ui.robots
|
||||
|
||||
import android.os.Build
|
||||
import android.util.Log
|
||||
import androidx.compose.ui.test.assertIsDisplayed
|
||||
import androidx.compose.ui.test.junit4.ComposeTestRule
|
||||
import androidx.compose.ui.test.onNodeWithTag
|
||||
|
@ -13,6 +14,7 @@ import androidx.test.uiautomator.By
|
|||
import androidx.test.uiautomator.UiScrollable
|
||||
import androidx.test.uiautomator.UiSelector
|
||||
import androidx.test.uiautomator.Until
|
||||
import org.mozilla.fenix.helpers.Constants.TAG
|
||||
import org.mozilla.fenix.helpers.MatcherHelper.assertUIObjectExists
|
||||
import org.mozilla.fenix.helpers.MatcherHelper.itemContainingText
|
||||
import org.mozilla.fenix.helpers.MatcherHelper.itemWithResId
|
||||
|
@ -27,27 +29,47 @@ import java.util.regex.Pattern
|
|||
*/
|
||||
class AddToHomeScreenRobot {
|
||||
|
||||
fun verifyAddPrivateBrowsingShortcutButton(composeTestRule: ComposeTestRule) =
|
||||
fun verifyAddPrivateBrowsingShortcutButton(composeTestRule: ComposeTestRule) {
|
||||
Log.i(TAG, "verifyAddPrivateBrowsingShortcutButton: Trying to verify \"Add to Home screen\" private browsing shortcut dialog button is displayed")
|
||||
composeTestRule.onNodeWithTag("private.add").assertIsDisplayed()
|
||||
Log.i(TAG, "verifyAddPrivateBrowsingShortcutButton: Verified \"Add to Home screen\" private browsing shortcut dialog button is displayed")
|
||||
}
|
||||
|
||||
fun verifyNoThanksPrivateBrowsingShortcutButton(composeTestRule: ComposeTestRule) =
|
||||
fun verifyNoThanksPrivateBrowsingShortcutButton(composeTestRule: ComposeTestRule) {
|
||||
Log.i(TAG, "verifyNoThanksPrivateBrowsingShortcutButton: Trying to verify \"No thanks\" private browsing shortcut dialog button is displayed")
|
||||
composeTestRule.onNodeWithTag("private.cancel").assertIsDisplayed()
|
||||
Log.i(TAG, "verifyNoThanksPrivateBrowsingShortcutButton: Verified \"No thanks\" private browsing shortcut dialog button is displayed")
|
||||
}
|
||||
|
||||
fun clickAddPrivateBrowsingShortcutButton(composeTestRule: ComposeTestRule) =
|
||||
fun clickAddPrivateBrowsingShortcutButton(composeTestRule: ComposeTestRule) {
|
||||
Log.i(TAG, "clickAddPrivateBrowsingShortcutButton: Trying to click \"Add to Home screen\" private browsing shortcut dialog button")
|
||||
composeTestRule.onNodeWithTag("private.add").performClick()
|
||||
Log.i(TAG, "clickAddPrivateBrowsingShortcutButton: Clicked \"Add to Home screen\" private browsing shortcut dialog button")
|
||||
}
|
||||
|
||||
fun addShortcutName(title: String) = shortcutTextField.setText(title)
|
||||
fun addShortcutName(title: String) {
|
||||
Log.i(TAG, "addShortcutName: Trying to set shortcut name to: $title")
|
||||
shortcutTextField().setText(title)
|
||||
Log.i(TAG, "addShortcutName: Set shortcut name to: $title")
|
||||
}
|
||||
|
||||
fun verifyShortcutTextFieldTitle(title: String) = assertUIObjectExists(shortcutTitle(title))
|
||||
|
||||
fun clickAddShortcutButton() =
|
||||
confirmAddToHomeScreenButton.clickAndWaitForNewWindow(waitingTime)
|
||||
fun clickAddShortcutButton() {
|
||||
Log.i(TAG, "clickAddShortcutButton: Trying to click \"Add\" button from \"Add to home screen\" dialog and wait for $waitingTime ms for a new window")
|
||||
confirmAddToHomeScreenButton().clickAndWaitForNewWindow(waitingTime)
|
||||
Log.i(TAG, "clickAddShortcutButton: Clicked \"Add\" button from \"Add to home screen\" dialog and waited for $waitingTime ms for a new window")
|
||||
}
|
||||
|
||||
fun clickCancelShortcutButton() =
|
||||
cancelAddToHomeScreenButton.click()
|
||||
fun clickCancelShortcutButton() {
|
||||
Log.i(TAG, "clickCancelShortcutButton: Trying to click \"Cancel\" button from \"Add to home screen\" dialog")
|
||||
cancelAddToHomeScreenButton().click()
|
||||
Log.i(TAG, "clickCancelShortcutButton: Clicked \"Cancel\" button from \"Add to home screen\" dialog")
|
||||
}
|
||||
|
||||
fun clickAddAutomaticallyButton() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
Log.i(TAG, "clickAddAutomaticallyButton: Waiting for $waitingTime ms until finding \"Add automatically\" system dialog button")
|
||||
mDevice.wait(
|
||||
Until.findObject(
|
||||
By.text(
|
||||
|
@ -56,7 +78,10 @@ class AddToHomeScreenRobot {
|
|||
),
|
||||
waitingTime,
|
||||
)
|
||||
Log.i(TAG, "clickAddAutomaticallyButton: Waited for $waitingTime ms until \"Add automatically\" system dialog button was found")
|
||||
Log.i(TAG, "clickAddAutomaticallyButton: Trying to click \"Add automatically\" system dialog button")
|
||||
addAutomaticallyButton().click()
|
||||
Log.i(TAG, "clickAddAutomaticallyButton: Clicked \"Add automatically\" system dialog button")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -65,27 +90,37 @@ class AddToHomeScreenRobot {
|
|||
|
||||
class Transition {
|
||||
fun openHomeScreenShortcut(title: String, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition {
|
||||
Log.i(TAG, "openHomeScreenShortcut: Waiting for $waitingTime ms until finding $title home screen shortcut")
|
||||
mDevice.wait(
|
||||
Until.findObject(By.text(title)),
|
||||
waitingTime,
|
||||
)
|
||||
Log.i(TAG, "openHomeScreenShortcut: Waited for $waitingTime ms until $title home screen shortcut was found")
|
||||
Log.i(TAG, "openHomeScreenShortcut: Trying to click $title home screen shortcut and wait for $waitingTime ms for a new window")
|
||||
mDevice.findObject((UiSelector().text(title))).clickAndWaitForNewWindow(waitingTime)
|
||||
Log.i(TAG, "openHomeScreenShortcut: Clicked $title home screen shortcut and waited for $waitingTime ms for a new window")
|
||||
|
||||
BrowserRobot().interact()
|
||||
return BrowserRobot.Transition()
|
||||
}
|
||||
|
||||
fun searchAndOpenHomeScreenShortcut(title: String, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition {
|
||||
Log.i(TAG, "searchAndOpenHomeScreenShortcut: Trying to press device home button")
|
||||
mDevice.pressHome()
|
||||
Log.i(TAG, "searchAndOpenHomeScreenShortcut: Pressed device home button")
|
||||
|
||||
fun homeScreenView() = UiScrollable(UiSelector().scrollable(true))
|
||||
Log.i(TAG, "searchAndOpenHomeScreenShortcut: Waiting for $waitingTime ms for home screen view to exist")
|
||||
homeScreenView().waitForExists(waitingTime)
|
||||
Log.i(TAG, "searchAndOpenHomeScreenShortcut: Waited for $waitingTime ms for home screen view to exist")
|
||||
|
||||
fun shortcut() =
|
||||
homeScreenView()
|
||||
.setAsHorizontalList()
|
||||
.getChildByText(UiSelector().textContains(title), title, true)
|
||||
Log.i(TAG, "searchAndOpenHomeScreenShortcut: Trying to click home screen shortcut: $title and wait for a new window")
|
||||
shortcut().clickAndWaitForNewWindow()
|
||||
Log.i(TAG, "searchAndOpenHomeScreenShortcut: Clicked home screen shortcut: $title and waited for a new window")
|
||||
|
||||
BrowserRobot().interact()
|
||||
return BrowserRobot.Transition()
|
||||
|
@ -101,11 +136,11 @@ fun addToHomeScreen(interact: AddToHomeScreenRobot.() -> Unit): AddToHomeScreenR
|
|||
private fun addAutomaticallyButton() =
|
||||
mDevice.findObject(UiSelector().textContains("add automatically"))
|
||||
|
||||
private val cancelAddToHomeScreenButton =
|
||||
private fun cancelAddToHomeScreenButton() =
|
||||
itemWithResId("$packageName:id/cancel_button")
|
||||
private val confirmAddToHomeScreenButton =
|
||||
private fun confirmAddToHomeScreenButton() =
|
||||
itemWithResId("$packageName:id/add_button")
|
||||
private val shortcutTextField =
|
||||
private fun shortcutTextField() =
|
||||
itemWithResId("$packageName:id/shortcut_text")
|
||||
private fun shortcutTitle(title: String) =
|
||||
itemWithResIdAndText("$packageName:id/shortcut_text", title)
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
package org.mozilla.fenix.ui.robots
|
||||
|
||||
import android.net.Uri
|
||||
import android.util.Log
|
||||
import androidx.test.espresso.Espresso.onView
|
||||
import androidx.test.espresso.action.ViewActions.clearText
|
||||
import androidx.test.espresso.action.ViewActions.longClick
|
||||
|
@ -32,6 +33,7 @@ import org.hamcrest.Matchers.allOf
|
|||
import org.hamcrest.Matchers.containsString
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.helpers.Constants.TAG
|
||||
import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource
|
||||
import org.mozilla.fenix.helpers.MatcherHelper.assertUIObjectExists
|
||||
import org.mozilla.fenix.helpers.MatcherHelper.itemContainingText
|
||||
|
@ -40,7 +42,6 @@ import org.mozilla.fenix.helpers.MatcherHelper.itemWithResId
|
|||
import org.mozilla.fenix.helpers.MatcherHelper.itemWithResIdAndText
|
||||
import org.mozilla.fenix.helpers.MatcherHelper.itemWithResIdContainingText
|
||||
import org.mozilla.fenix.helpers.MatcherHelper.itemWithText
|
||||
import org.mozilla.fenix.helpers.TestAssetHelper
|
||||
import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime
|
||||
import org.mozilla.fenix.helpers.TestAssetHelper.waitingTimeShort
|
||||
import org.mozilla.fenix.helpers.TestHelper.mDevice
|
||||
|
@ -54,51 +55,114 @@ import org.mozilla.fenix.helpers.ext.waitNotNull
|
|||
class BookmarksRobot {
|
||||
|
||||
fun verifyBookmarksMenuView() {
|
||||
Log.i(TAG, "verifyBookmarksMenuView: Waiting for $waitingTime ms for bookmarks view to exist")
|
||||
mDevice.findObject(
|
||||
UiSelector().text("Bookmarks"),
|
||||
).waitForExists(waitingTime)
|
||||
|
||||
assertBookmarksView()
|
||||
Log.i(TAG, "verifyBookmarksMenuView: Waited for $waitingTime ms for bookmarks view to exist")
|
||||
Log.i(TAG, "verifyBookmarksMenuView: Trying to verify bookmarks view is displayed")
|
||||
onView(
|
||||
allOf(
|
||||
withText("Bookmarks"),
|
||||
withParent(withId(R.id.navigationToolbar)),
|
||||
),
|
||||
).check(matches(isDisplayed()))
|
||||
Log.i(TAG, "verifyBookmarksMenuView: Verified bookmarks view is displayed")
|
||||
}
|
||||
|
||||
fun verifyAddFolderButton() = assertAddFolderButton()
|
||||
fun verifyAddFolderButton() {
|
||||
Log.i(TAG, "verifyAddFolderButton: Trying to verify add bookmarks folder button is visible")
|
||||
addFolderButton().check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
|
||||
Log.i(TAG, "verifyAddFolderButton: Verified add bookmarks folder button is visible")
|
||||
}
|
||||
|
||||
fun verifyCloseButton() = assertCloseButton()
|
||||
fun verifyCloseButton() {
|
||||
Log.i(TAG, "verifyCloseButton: Trying to verify close bookmarks section button is visible")
|
||||
closeButton().check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
|
||||
Log.i(TAG, "verifyCloseButton: Verified close bookmarks section button is visible")
|
||||
}
|
||||
|
||||
fun verifyDeleteMultipleBookmarksSnackBar() = assertSnackBarText("Bookmarks deleted")
|
||||
fun verifyBookmarkFavicon(forUrl: Uri) {
|
||||
Log.i(TAG, "verifyBookmarkFavicon: Trying to verify bookmarks favicon for $forUrl is visible")
|
||||
bookmarkFavicon(forUrl.toString()).check(
|
||||
matches(
|
||||
withEffectiveVisibility(
|
||||
ViewMatchers.Visibility.VISIBLE,
|
||||
),
|
||||
),
|
||||
)
|
||||
Log.i(TAG, "verifyBookmarkFavicon: Verified bookmarks favicon for $forUrl is visible")
|
||||
}
|
||||
|
||||
fun verifyBookmarkFavicon(forUrl: Uri) = assertBookmarkFavicon(forUrl)
|
||||
|
||||
fun verifyBookmarkedURL(url: String) = assertBookmarkURL(url)
|
||||
fun verifyBookmarkedURL(url: String) {
|
||||
Log.i(TAG, "verifyBookmarkedURL: Trying to verify bookmarks url: $url is displayed")
|
||||
bookmarkURL(url).check(matches(isDisplayed()))
|
||||
Log.i(TAG, "verifyBookmarkedURL: Verified bookmarks url: $url is displayed")
|
||||
}
|
||||
|
||||
fun verifyFolderTitle(title: String) {
|
||||
Log.i(TAG, "verifyFolderTitle: Waiting for $waitingTime ms for bookmarks folder with title: $title to exist")
|
||||
mDevice.findObject(UiSelector().text(title)).waitForExists(waitingTime)
|
||||
assertFolderTitle(title)
|
||||
Log.i(TAG, "verifyFolderTitle: Waited for $waitingTime ms for bookmarks folder with title: $title to exist")
|
||||
Log.i(TAG, "verifyFolderTitle: Trying to verify bookmarks folder with title: $title is displayed")
|
||||
onView(withText(title)).check(matches(isDisplayed()))
|
||||
Log.i(TAG, "verifyFolderTitle: Verified bookmarks folder with title: $title is displayed")
|
||||
}
|
||||
|
||||
fun verifyBookmarkFolderIsNotCreated(title: String) = assertBookmarkFolderIsNotCreated(title)
|
||||
fun verifyBookmarkFolderIsNotCreated(title: String) {
|
||||
Log.i(TAG, "verifyBookmarkFolderIsNotCreated: Waiting for $waitingTime ms for bookmarks folder with title: $title to exist")
|
||||
mDevice.findObject(
|
||||
UiSelector()
|
||||
.resourceId("$packageName:id/bookmarks_wrapper"),
|
||||
).waitForExists(waitingTime)
|
||||
Log.i(TAG, "verifyBookmarkFolderIsNotCreated: Waited for $waitingTime ms for bookmarks folder with title: $title to exist")
|
||||
|
||||
assertUIObjectExists(itemContainingText(title), exists = false)
|
||||
}
|
||||
|
||||
fun verifyBookmarkTitle(title: String) {
|
||||
Log.i(TAG, "verifyBookmarkTitle: Waiting for $waitingTime ms for bookmark with title: $title to exist")
|
||||
mDevice.findObject(UiSelector().text(title)).waitForExists(waitingTime)
|
||||
assertBookmarkTitle(title)
|
||||
Log.i(TAG, "verifyBookmarkTitle: Waited for $waitingTime ms for bookmark with title: $title to exist")
|
||||
Log.i(TAG, "verifyBookmarkTitle: Trying to verify bookmark with title: $title is displayed")
|
||||
onView(withText(title)).check(matches(isDisplayed()))
|
||||
Log.i(TAG, "verifyBookmarkTitle: Verified bookmark with title: $title is displayed")
|
||||
}
|
||||
|
||||
fun verifyBookmarkIsDeleted(expectedTitle: String) = assertBookmarkIsDeleted(expectedTitle)
|
||||
fun verifyBookmarkIsDeleted(expectedTitle: String) {
|
||||
Log.i(TAG, "verifyBookmarkIsDeleted: Waiting for $waitingTime ms for bookmarks view to exist")
|
||||
mDevice.findObject(
|
||||
UiSelector()
|
||||
.resourceId("$packageName:id/bookmarks_wrapper"),
|
||||
).waitForExists(waitingTime)
|
||||
Log.i(TAG, "verifyBookmarkIsDeleted: Waited for $waitingTime ms for bookmarks view to exist")
|
||||
assertUIObjectExists(
|
||||
itemWithResIdContainingText(
|
||||
"$packageName:id/title",
|
||||
expectedTitle,
|
||||
),
|
||||
exists = false,
|
||||
)
|
||||
}
|
||||
|
||||
fun verifyDeleteSnackBarText() = assertSnackBarText("Deleted")
|
||||
|
||||
fun verifyUndoDeleteSnackBarButton() = assertUndoDeleteSnackBarButton()
|
||||
fun verifyUndoDeleteSnackBarButton() {
|
||||
Log.i(TAG, "verifyUndoDeleteSnackBarButton: Trying to verify bookmark deletion undo snack bar button")
|
||||
snackBarUndoButton().check(matches(withText("UNDO")))
|
||||
Log.i(TAG, "verifyUndoDeleteSnackBarButton: Verified bookmark deletion undo snack bar button")
|
||||
}
|
||||
|
||||
fun verifySnackBarHidden() {
|
||||
Log.i(TAG, "verifySnackBarHidden: Waiting until undo snack bar button is gone")
|
||||
mDevice.waitNotNull(
|
||||
Until.gone(By.text("UNDO")),
|
||||
TestAssetHelper.waitingTime,
|
||||
waitingTime,
|
||||
)
|
||||
Log.i(TAG, "verifySnackBarHidden: Waited until undo snack bar button was gone")
|
||||
Log.i(TAG, "verifySnackBarHidden: Trying to verify bookmark snack bar does not exist")
|
||||
onView(withId(R.id.snackbar_layout)).check(doesNotExist())
|
||||
Log.i(TAG, "verifySnackBarHidden: Verified bookmark snack bar does not exist")
|
||||
}
|
||||
|
||||
fun verifyCopySnackBarText() = assertSnackBarText("URL copied")
|
||||
|
||||
fun verifyEditBookmarksView() =
|
||||
assertUIObjectExists(
|
||||
itemWithDescription("Navigate up"),
|
||||
|
@ -110,27 +174,50 @@ class BookmarksRobot {
|
|||
itemWithResId("$packageName:id/bookmarkParentFolderSelector"),
|
||||
)
|
||||
|
||||
fun verifyKeyboardHidden() = assertKeyboardVisibility(isExpectedToBeVisible = false)
|
||||
fun verifyKeyboardHidden(isExpectedToBeVisible: Boolean) {
|
||||
Log.i(TAG, "assertKeyboardVisibility: Trying to verify that the keyboard is visible: $isExpectedToBeVisible")
|
||||
assertEquals(
|
||||
isExpectedToBeVisible,
|
||||
mDevice
|
||||
.executeShellCommand("dumpsys input_method | grep mInputShown")
|
||||
.contains("mInputShown=true"),
|
||||
)
|
||||
Log.i(TAG, "assertKeyboardVisibility: Verified that the keyboard is visible: $isExpectedToBeVisible")
|
||||
}
|
||||
|
||||
fun verifyKeyboardVisible() = assertKeyboardVisibility(isExpectedToBeVisible = true)
|
||||
fun verifyShareOverlay() {
|
||||
Log.i(TAG, "verifyShareOverlay: Trying to verify bookmarks sharing overlay is displayed")
|
||||
onView(withId(R.id.shareWrapper)).check(matches(isDisplayed()))
|
||||
Log.i(TAG, "verifyShareOverlay: Verified bookmarks sharing overlay is displayed")
|
||||
}
|
||||
|
||||
fun verifyShareOverlay() = assertShareOverlay()
|
||||
fun verifyShareBookmarkFavicon() {
|
||||
Log.i(TAG, "verifyShareBookmarkFavicon: Trying to verify shared bookmarks favicon is displayed")
|
||||
onView(withId(R.id.share_tab_favicon)).check(matches(isDisplayed()))
|
||||
Log.i(TAG, "verifyShareBookmarkFavicon: Verified shared bookmarks favicon is displayed")
|
||||
}
|
||||
|
||||
fun verifyShareBookmarkFavicon() = assertShareBookmarkFavicon()
|
||||
fun verifyShareBookmarkTitle() {
|
||||
Log.i(TAG, "verifyShareBookmarkTitle: Trying to verify shared bookmarks title is displayed")
|
||||
onView(withId(R.id.share_tab_title)).check(matches(isDisplayed()))
|
||||
Log.i(TAG, "verifyShareBookmarkTitle: Verified shared bookmarks title is displayed")
|
||||
}
|
||||
|
||||
fun verifyShareBookmarkTitle() = assertShareBookmarkTitle()
|
||||
|
||||
fun verifyShareBookmarkUrl() = assertShareBookmarkUrl()
|
||||
|
||||
fun verifySelectDefaultFolderSnackBarText() = assertSnackBarText("Can’t edit default folders")
|
||||
fun verifyShareBookmarkUrl() {
|
||||
Log.i(TAG, "verifyShareBookmarkUrl: Trying to verify shared bookmarks url is displayed")
|
||||
onView(withId(R.id.share_tab_url)).check(matches(isDisplayed()))
|
||||
Log.i(TAG, "verifyShareBookmarkUrl: Verified shared bookmarks url is displayed")
|
||||
}
|
||||
|
||||
fun verifyCurrentFolderTitle(title: String) {
|
||||
Log.i(TAG, "verifyCurrentFolderTitle: Waiting for $waitingTime ms for bookmark with title: $title to exist")
|
||||
mDevice.findObject(
|
||||
UiSelector().resourceId("$packageName:id/navigationToolbar")
|
||||
.textContains(title),
|
||||
)
|
||||
.waitForExists(waitingTime)
|
||||
|
||||
Log.i(TAG, "verifyCurrentFolderTitle: Waited for $waitingTime ms for bookmark with title: $title to exist")
|
||||
Log.i(TAG, "verifyCurrentFolderTitle: Trying to verify bookmark with title: $title is displayed")
|
||||
onView(
|
||||
allOf(
|
||||
withText(title),
|
||||
|
@ -138,28 +225,34 @@ class BookmarksRobot {
|
|||
),
|
||||
)
|
||||
.check(matches(isDisplayed()))
|
||||
Log.i(TAG, "verifyCurrentFolderTitle: Verified bookmark with title: $title is displayed")
|
||||
}
|
||||
|
||||
fun waitForBookmarksFolderContentToExist(parentFolderName: String, childFolderName: String) {
|
||||
Log.i(TAG, "waitForBookmarksFolderContentToExist: Waiting for $waitingTime ms for navigation toolbar containing bookmark folder with title: $parentFolderName to exist")
|
||||
mDevice.findObject(
|
||||
UiSelector().resourceId("$packageName:id/navigationToolbar")
|
||||
.textContains(parentFolderName),
|
||||
)
|
||||
.waitForExists(waitingTime)
|
||||
Log.i(TAG, "waitForBookmarksFolderContentToExist: Waited for $waitingTime ms for navigation toolbar containing bookmark folder with title: $parentFolderName to exist")
|
||||
|
||||
mDevice.waitNotNull(Until.findObject(By.text(childFolderName)), waitingTime)
|
||||
}
|
||||
|
||||
fun verifySyncSignInButton() =
|
||||
fun verifySyncSignInButton() {
|
||||
Log.i(TAG, "verifySyncSignInButton: Trying to verify sign in to sync button is visible")
|
||||
syncSignInButton().check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
|
||||
|
||||
fun verifyDeleteFolderConfirmationMessage() = assertDeleteFolderConfirmationMessage()
|
||||
Log.i(TAG, "verifySyncSignInButton: Verified sign in to sync button is visible")
|
||||
}
|
||||
|
||||
fun cancelFolderDeletion() {
|
||||
Log.i(TAG, "cancelFolderDeletion: Trying to click \"Cancel\" bookmarks folder deletion dialog button")
|
||||
onView(withText("CANCEL"))
|
||||
.inRoot(RootMatchers.isDialog())
|
||||
.check(matches(isDisplayed()))
|
||||
.click()
|
||||
Log.i(TAG, "cancelFolderDeletion: Clicked \"Cancel\" bookmarks folder deletion dialog button")
|
||||
}
|
||||
|
||||
fun createFolder(name: String, parent: String? = null) {
|
||||
|
@ -180,90 +273,127 @@ class BookmarksRobot {
|
|||
fun clickAddFolderButton() {
|
||||
mDevice.waitNotNull(
|
||||
Until.findObject(By.desc("Add folder")),
|
||||
TestAssetHelper.waitingTime,
|
||||
waitingTime,
|
||||
)
|
||||
Log.i(TAG, "clickAddFolderButton: Trying to click add bookmarks folder button")
|
||||
addFolderButton().click()
|
||||
Log.i(TAG, "clickAddFolderButton: Clicked add bookmarks folder button")
|
||||
}
|
||||
|
||||
fun clickAddNewFolderButtonFromSelectFolderView() =
|
||||
fun clickAddNewFolderButtonFromSelectFolderView() {
|
||||
itemWithResId("$packageName:id/add_folder_button")
|
||||
.also {
|
||||
Log.i(TAG, "clickAddNewFolderButtonFromSelectFolderView: Waiting for $waitingTime ms for add bookmarks folder button from folder selection view to exist")
|
||||
it.waitForExists(waitingTime)
|
||||
Log.i(TAG, "clickAddNewFolderButtonFromSelectFolderView: Waited for $waitingTime ms for add bookmarks folder button from folder selection view to exist")
|
||||
Log.i(TAG, "clickAddNewFolderButtonFromSelectFolderView: Trying to click add bookmarks folder button from folder selection view")
|
||||
it.click()
|
||||
Log.i(TAG, "clickAddNewFolderButtonFromSelectFolderView: Clicked add bookmarks folder button from folder selection view")
|
||||
}
|
||||
}
|
||||
|
||||
fun addNewFolderName(name: String) {
|
||||
addFolderTitleField()
|
||||
.click()
|
||||
.perform(replaceText(name))
|
||||
Log.i(TAG, "addNewFolderName: Trying to click add folder name field")
|
||||
addFolderTitleField().click()
|
||||
Log.i(TAG, "addNewFolderName: Clicked to click add folder name field")
|
||||
Log.i(TAG, "addNewFolderName: Trying to set bookmarks folder name to: $name")
|
||||
addFolderTitleField().perform(replaceText(name))
|
||||
Log.i(TAG, "addNewFolderName: Bookmarks folder name was set to: $name")
|
||||
}
|
||||
|
||||
fun saveNewFolder() {
|
||||
Log.i(TAG, "saveNewFolder: Trying to click save folder button")
|
||||
saveFolderButton().click()
|
||||
Log.i(TAG, "saveNewFolder: Clicked save folder button")
|
||||
}
|
||||
|
||||
fun navigateUp() {
|
||||
Log.i(TAG, "navigateUp: Trying to click navigate up toolbar button")
|
||||
goBackButton().click()
|
||||
Log.i(TAG, "navigateUp: Clicked navigate up toolbar button")
|
||||
}
|
||||
|
||||
fun clickUndoDeleteButton() {
|
||||
Log.i(TAG, "clickUndoDeleteButton: Trying to click undo snack bar button")
|
||||
snackBarUndoButton().click()
|
||||
Log.i(TAG, "clickUndoDeleteButton: Clicked undo snack bar button")
|
||||
}
|
||||
|
||||
fun changeBookmarkTitle(newTitle: String) {
|
||||
bookmarkNameEditBox()
|
||||
.perform(clearText())
|
||||
.perform(typeText(newTitle))
|
||||
Log.i(TAG, "changeBookmarkTitle: Trying to clear bookmark name text box")
|
||||
bookmarkNameEditBox().perform(clearText())
|
||||
Log.i(TAG, "changeBookmarkTitle: Cleared bookmark name text box")
|
||||
Log.i(TAG, "changeBookmarkTitle: Trying to set bookmark title to: $newTitle")
|
||||
bookmarkNameEditBox().perform(typeText(newTitle))
|
||||
Log.i(TAG, "changeBookmarkTitle: Bookmark title was set to: $newTitle")
|
||||
}
|
||||
|
||||
fun changeBookmarkUrl(newUrl: String) {
|
||||
bookmarkURLEditBox()
|
||||
.perform(clearText())
|
||||
.perform(typeText(newUrl))
|
||||
Log.i(TAG, "changeBookmarkUrl: Trying to clear bookmark url text box")
|
||||
bookmarkURLEditBox().perform(clearText())
|
||||
Log.i(TAG, "changeBookmarkUrl: Cleared bookmark url text box")
|
||||
Log.i(TAG, "changeBookmarkUrl: Trying to set bookmark url to: $newUrl")
|
||||
bookmarkURLEditBox().perform(typeText(newUrl))
|
||||
Log.i(TAG, "changeBookmarkUrl: Bookmark url was set to: $newUrl")
|
||||
}
|
||||
|
||||
fun saveEditBookmark() {
|
||||
Log.i(TAG, "saveEditBookmark: Trying to click save bookmark button")
|
||||
saveBookmarkButton().click()
|
||||
Log.i(TAG, "saveEditBookmark: Clicked save bookmark button")
|
||||
Log.i(TAG, "saveEditBookmark: Waiting for $waitingTime ms for bookmarks list to exist")
|
||||
mDevice.findObject(UiSelector().resourceId("org.mozilla.fenix.debug:id/bookmark_list")).waitForExists(waitingTime)
|
||||
Log.i(TAG, "saveEditBookmark: Waited for $waitingTime ms for bookmarks list to exist")
|
||||
}
|
||||
|
||||
fun clickParentFolderSelector() = bookmarkFolderSelector().click()
|
||||
fun clickParentFolderSelector() {
|
||||
Log.i(TAG, "clickParentFolderSelector: Trying to click folder selector")
|
||||
bookmarkFolderSelector().click()
|
||||
Log.i(TAG, "clickParentFolderSelector: Clicked folder selector")
|
||||
}
|
||||
|
||||
fun selectFolder(title: String) = onView(withText(title)).click()
|
||||
fun selectFolder(title: String) {
|
||||
Log.i(TAG, "selectFolder: Trying to click folder with title: $title")
|
||||
onView(withText(title)).click()
|
||||
Log.i(TAG, "selectFolder: Clicked folder with title: $title")
|
||||
}
|
||||
|
||||
fun longTapDesktopFolder(title: String) = onView(withText(title)).perform(longClick())
|
||||
fun longTapDesktopFolder(title: String) {
|
||||
Log.i(TAG, "longTapDesktopFolder: Trying to long tap folder with title: $title")
|
||||
onView(withText(title)).perform(longClick())
|
||||
Log.i(TAG, "longTapDesktopFolder: Long tapped folder with title: $title")
|
||||
}
|
||||
|
||||
fun cancelDeletion() {
|
||||
val cancelButton = mDevice.findObject(UiSelector().textContains("CANCEL"))
|
||||
Log.i(TAG, "cancelDeletion: Waiting for $waitingTime ms for \"Cancel\" bookmarks deletion button to exist")
|
||||
cancelButton.waitForExists(waitingTime)
|
||||
Log.i(TAG, "cancelDeletion: Waited for $waitingTime ms for \"Cancel\" bookmarks deletion button to exist")
|
||||
Log.i(TAG, "cancelDeletion: Trying to click \"Cancel\" bookmarks deletion button")
|
||||
cancelButton.click()
|
||||
Log.i(TAG, "cancelDeletion: Clicked \"Cancel\" bookmarks deletion button")
|
||||
}
|
||||
|
||||
fun confirmDeletion() {
|
||||
Log.i(TAG, "confirmDeletion: Trying to click \"Delete\" bookmarks deletion button")
|
||||
onView(withText(R.string.delete_browsing_data_prompt_allow))
|
||||
.inRoot(RootMatchers.isDialog())
|
||||
.check(matches(isDisplayed()))
|
||||
.click()
|
||||
Log.i(TAG, "confirmDeletion: Clicked \"Delete\" bookmarks deletion button")
|
||||
}
|
||||
|
||||
fun clickDeleteInEditModeButton() = deleteInEditModeButton().click()
|
||||
|
||||
fun searchBookmarkedItem(bookmarkedItem: String) {
|
||||
itemWithResId("$packageName:id/mozac_browser_toolbar_edit_url_view").also {
|
||||
it.waitForExists(waitingTime)
|
||||
it.setText(bookmarkedItem)
|
||||
}
|
||||
mDevice.waitForWindowUpdate(packageName, waitingTimeShort)
|
||||
fun clickDeleteInEditModeButton() {
|
||||
Log.i(TAG, "clickDeleteInEditModeButton: Trying to click delete bookmarks button while in edit mode")
|
||||
deleteInEditModeButton().click()
|
||||
Log.i(TAG, "clickDeleteInEditModeButton: Clicked delete bookmarks button while in edit mode")
|
||||
}
|
||||
|
||||
fun verifySearchedBookmarkExists(bookmarkUrl: String, exists: Boolean = true) =
|
||||
assertUIObjectExists(itemContainingText(bookmarkUrl), exists = exists)
|
||||
|
||||
fun dismissBookmarksSearchBar() = mDevice.pressBack()
|
||||
|
||||
class Transition {
|
||||
fun closeMenu(interact: HomeScreenRobot.() -> Unit): Transition {
|
||||
Log.i(TAG, "closeMenu: Trying to click close bookmarks section button")
|
||||
closeButton().click()
|
||||
Log.i(TAG, "closeMenu: Clicked close bookmarks section button")
|
||||
|
||||
HomeScreenRobot().interact()
|
||||
return Transition()
|
||||
|
@ -271,35 +401,45 @@ class BookmarksRobot {
|
|||
|
||||
fun openThreeDotMenu(bookmark: String, interact: ThreeDotMenuBookmarksRobot.() -> Unit): ThreeDotMenuBookmarksRobot.Transition {
|
||||
mDevice.waitNotNull(Until.findObject(res("$packageName:id/overflow_menu")))
|
||||
Log.i(TAG, "openThreeDotMenu: Trying to click three dot button for bookmark item: $bookmark")
|
||||
threeDotMenu(bookmark).click()
|
||||
Log.i(TAG, "openThreeDotMenu: Clicked three dot button for bookmark item: $bookmark")
|
||||
|
||||
ThreeDotMenuBookmarksRobot().interact()
|
||||
return ThreeDotMenuBookmarksRobot.Transition()
|
||||
}
|
||||
|
||||
fun clickSingInToSyncButton(interact: SettingsTurnOnSyncRobot.() -> Unit): SettingsTurnOnSyncRobot.Transition {
|
||||
Log.i(TAG, "clickSingInToSyncButton: Trying to click sign in to sync button")
|
||||
syncSignInButton().click()
|
||||
Log.i(TAG, "clickSingInToSyncButton: Clicked sign in to sync button")
|
||||
|
||||
SettingsTurnOnSyncRobot().interact()
|
||||
return SettingsTurnOnSyncRobot.Transition()
|
||||
}
|
||||
|
||||
fun goBack(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition {
|
||||
Log.i(TAG, "goBack: Trying to click go back button")
|
||||
goBackButton().click()
|
||||
Log.i(TAG, "goBack: Clicked go back button")
|
||||
|
||||
HomeScreenRobot().interact()
|
||||
return HomeScreenRobot.Transition()
|
||||
}
|
||||
|
||||
fun goBackToBrowserScreen(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition {
|
||||
Log.i(TAG, "goBackToBrowserScreen: Trying to click go back button")
|
||||
goBackButton().click()
|
||||
Log.i(TAG, "goBackToBrowserScreen: Clicked go back button")
|
||||
|
||||
BrowserRobot().interact()
|
||||
return BrowserRobot.Transition()
|
||||
}
|
||||
|
||||
fun closeEditBookmarkSection(interact: BookmarksRobot.() -> Unit): Transition {
|
||||
Log.i(TAG, "goBackToBrowserScreen: Trying to click go back button")
|
||||
goBackButton().click()
|
||||
Log.i(TAG, "goBackToBrowserScreen: Clicked go back button")
|
||||
|
||||
BookmarksRobot().interact()
|
||||
return Transition()
|
||||
|
@ -308,8 +448,12 @@ class BookmarksRobot {
|
|||
fun openBookmarkWithTitle(bookmarkTitle: String, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition {
|
||||
itemWithResIdAndText("$packageName:id/title", bookmarkTitle)
|
||||
.also {
|
||||
Log.i(TAG, "openBookmarkWithTitle: Waiting for $waitingTime ms for bookmark with title: $bookmarkTitle")
|
||||
it.waitForExists(waitingTime)
|
||||
Log.i(TAG, "openBookmarkWithTitle: Waited for $waitingTime ms for bookmark with title: $bookmarkTitle")
|
||||
Log.i(TAG, "openBookmarkWithTitle: Trying to click bookmark with title: $bookmarkTitle and wait for $waitingTimeShort ms for a new window")
|
||||
it.clickAndWaitForNewWindow(waitingTimeShort)
|
||||
Log.i(TAG, "openBookmarkWithTitle: Clicked bookmark with title: $bookmarkTitle and waited for $waitingTimeShort ms for a new window")
|
||||
}
|
||||
|
||||
BrowserRobot().interact()
|
||||
|
@ -317,7 +461,9 @@ class BookmarksRobot {
|
|||
}
|
||||
|
||||
fun clickSearchButton(interact: SearchRobot.() -> Unit): SearchRobot.Transition {
|
||||
Log.i(TAG, "clickSearchButton: Trying to click search bookmarks button")
|
||||
itemWithResId("$packageName:id/bookmark_search").click()
|
||||
Log.i(TAG, "clickSearchButton: Clicked search bookmarks button")
|
||||
|
||||
SearchRobot().interact()
|
||||
return SearchRobot.Transition()
|
||||
|
@ -375,92 +521,3 @@ private fun saveBookmarkButton() = onView(withId(R.id.save_bookmark_button))
|
|||
private fun deleteInEditModeButton() = onView(withId(R.id.delete_bookmark_button))
|
||||
|
||||
private fun syncSignInButton() = onView(withId(R.id.bookmark_folders_sign_in))
|
||||
|
||||
private fun assertBookmarksView() {
|
||||
onView(
|
||||
allOf(
|
||||
withText("Bookmarks"),
|
||||
withParent(withId(R.id.navigationToolbar)),
|
||||
),
|
||||
)
|
||||
.check(matches(isDisplayed()))
|
||||
}
|
||||
|
||||
private fun assertAddFolderButton() =
|
||||
addFolderButton().check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
|
||||
|
||||
private fun assertCloseButton() = closeButton().check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
|
||||
|
||||
private fun assertEmptyBookmarksList() =
|
||||
onView(withId(R.id.bookmarks_empty_view)).check(matches(withText("No bookmarks here")))
|
||||
|
||||
private fun assertBookmarkFolderIsNotCreated(title: String) {
|
||||
mDevice.findObject(
|
||||
UiSelector()
|
||||
.resourceId("$packageName:id/bookmarks_wrapper"),
|
||||
).waitForExists(waitingTime)
|
||||
|
||||
assertUIObjectExists(itemContainingText(title), exists = false)
|
||||
}
|
||||
|
||||
private fun assertBookmarkFavicon(forUrl: Uri) = bookmarkFavicon(forUrl.toString()).check(
|
||||
matches(
|
||||
withEffectiveVisibility(
|
||||
ViewMatchers.Visibility.VISIBLE,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
private fun assertBookmarkURL(expectedURL: String) =
|
||||
bookmarkURL(expectedURL).check(matches(isDisplayed()))
|
||||
|
||||
private fun assertFolderTitle(expectedTitle: String) =
|
||||
onView(withText(expectedTitle)).check(matches(isDisplayed()))
|
||||
|
||||
private fun assertBookmarkTitle(expectedTitle: String) =
|
||||
onView(withText(expectedTitle)).check(matches(isDisplayed()))
|
||||
|
||||
private fun assertBookmarkIsDeleted(expectedTitle: String) {
|
||||
mDevice.findObject(
|
||||
UiSelector()
|
||||
.resourceId("$packageName:id/bookmarks_wrapper"),
|
||||
).waitForExists(waitingTime)
|
||||
|
||||
assertUIObjectExists(
|
||||
itemWithResIdContainingText(
|
||||
"$packageName:id/title",
|
||||
expectedTitle,
|
||||
),
|
||||
exists = false,
|
||||
)
|
||||
}
|
||||
private fun assertUndoDeleteSnackBarButton() =
|
||||
snackBarUndoButton().check(matches(withText("UNDO")))
|
||||
|
||||
private fun assertSnackBarText(text: String) =
|
||||
snackBarText().check(matches(withText(containsString(text))))
|
||||
|
||||
private fun assertKeyboardVisibility(isExpectedToBeVisible: Boolean) =
|
||||
assertEquals(
|
||||
isExpectedToBeVisible,
|
||||
mDevice
|
||||
.executeShellCommand("dumpsys input_method | grep mInputShown")
|
||||
.contains("mInputShown=true"),
|
||||
)
|
||||
|
||||
private fun assertShareOverlay() =
|
||||
onView(withId(R.id.shareWrapper)).check(matches(isDisplayed()))
|
||||
|
||||
private fun assertShareBookmarkTitle() =
|
||||
onView(withId(R.id.share_tab_title)).check(matches(isDisplayed()))
|
||||
|
||||
private fun assertShareBookmarkFavicon() =
|
||||
onView(withId(R.id.share_tab_favicon)).check(matches(isDisplayed()))
|
||||
|
||||
private fun assertShareBookmarkUrl() =
|
||||
onView(withId(R.id.share_tab_url)).check(matches(isDisplayed()))
|
||||
|
||||
private fun assertDeleteFolderConfirmationMessage() =
|
||||
onView(withText(R.string.bookmark_delete_folder_confirmation_dialog))
|
||||
.inRoot(RootMatchers.isDialog())
|
||||
.check(matches(isDisplayed()))
|
||||
|
|
|
@ -15,17 +15,14 @@ import androidx.compose.ui.test.assertIsDisplayed
|
|||
import androidx.compose.ui.test.onNodeWithTag
|
||||
import androidx.compose.ui.test.performClick
|
||||
import androidx.test.espresso.Espresso.onView
|
||||
import androidx.test.espresso.ViewInteraction
|
||||
import androidx.test.espresso.action.ViewActions.click
|
||||
import androidx.test.espresso.action.ViewActions.longClick
|
||||
import androidx.test.espresso.assertion.ViewAssertions.matches
|
||||
import androidx.test.espresso.contrib.PickerActions
|
||||
import androidx.test.espresso.matcher.RootMatchers.isDialog
|
||||
import androidx.test.espresso.matcher.ViewMatchers
|
||||
import androidx.test.espresso.matcher.ViewMatchers.isAssignableFrom
|
||||
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
|
||||
import androidx.test.espresso.matcher.ViewMatchers.withContentDescription
|
||||
import androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility
|
||||
import androidx.test.espresso.matcher.ViewMatchers.withId
|
||||
import androidx.test.uiautomator.By
|
||||
import androidx.test.uiautomator.By.text
|
||||
|
@ -74,7 +71,9 @@ class BrowserRobot {
|
|||
|
||||
fun verifyCurrentPrivateSession(context: Context) {
|
||||
val selectedTab = context.components.core.store.state.selectedTab
|
||||
Log.i(TAG, "verifyCurrentPrivateSession: Trying to verify that current browsing session is private")
|
||||
assertTrue("Current session is private", selectedTab?.content?.private ?: false)
|
||||
Log.i(TAG, "verifyCurrentPrivateSession: Verified that current browsing session is private")
|
||||
}
|
||||
|
||||
fun verifyUrl(url: String) {
|
||||
|
@ -165,11 +164,6 @@ class BrowserRobot {
|
|||
),
|
||||
)
|
||||
|
||||
fun verifySnackBarText(expectedText: String) {
|
||||
mDevice.waitForObjects(mDevice.findObject(UiSelector().textContains(expectedText)))
|
||||
assertUIObjectExists(itemContainingText(expectedText))
|
||||
}
|
||||
|
||||
fun verifyContextMenuForLocalHostLinks(containsURL: Uri) {
|
||||
// If the link is directing to another local asset the "Download link" option is not available
|
||||
// If the link is not re-directing to an external app the "Open link in external app" option is not available
|
||||
|
@ -234,11 +228,11 @@ class BrowserRobot {
|
|||
|
||||
fun verifyNavURLBarHidden() = assertUIObjectIsGone(navURLBar())
|
||||
|
||||
fun verifySecureConnectionLockIcon() =
|
||||
onView(withId(R.id.mozac_browser_toolbar_security_indicator))
|
||||
.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
|
||||
|
||||
fun verifyMenuButton() = threeDotButton().check(matches(isDisplayed()))
|
||||
fun verifyMenuButton() {
|
||||
Log.i(TAG, "verifyMenuButton: Trying to verify main menu button is displayed")
|
||||
threeDotButton().check(matches(isDisplayed()))
|
||||
Log.i(TAG, "verifyMenuButton: Verified main menu button is displayed")
|
||||
}
|
||||
|
||||
fun verifyNoLinkImageContextMenuItems(containsURL: Uri) {
|
||||
mDevice.waitNotNull(Until.findObject(By.textContains(containsURL.toString())))
|
||||
|
@ -256,13 +250,10 @@ class BrowserRobot {
|
|||
fun verifyNotificationDotOnMainMenu() =
|
||||
assertUIObjectExists(itemWithResId("$packageName:id/notification_dot"))
|
||||
|
||||
fun verifyHomeScreenButton() =
|
||||
homeScreenButton().check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
|
||||
|
||||
fun verifySearchBar() = assertUIObjectExists(searchBar())
|
||||
|
||||
fun dismissContentContextMenu() {
|
||||
Log.i(TAG, "dismissContentContextMenu: Trying to click device back button")
|
||||
mDevice.pressBack()
|
||||
Log.i(TAG, "dismissContentContextMenu: Clicked device back button")
|
||||
assertUIObjectExists(itemWithResId("$packageName:id/engineView"))
|
||||
}
|
||||
|
||||
|
@ -292,7 +283,9 @@ class BrowserRobot {
|
|||
fun clickSubmitLoginButton() {
|
||||
clickPageObject(itemWithResId("submit"))
|
||||
assertUIObjectIsGone(itemWithResId("submit"))
|
||||
Log.i(TAG, "clickSubmitLoginButton: Waiting for device to be idle for $waitingTimeLong ms")
|
||||
mDevice.waitForIdle(waitingTimeLong)
|
||||
Log.i(TAG, "clickSubmitLoginButton: Waited for device to be idle for $waitingTimeLong ms")
|
||||
}
|
||||
|
||||
fun enterPassword(password: String) {
|
||||
|
@ -334,10 +327,16 @@ class BrowserRobot {
|
|||
fun swipeNavBarRight(tabUrl: String) {
|
||||
// failing to swipe on Firebase sometimes, so it tries again
|
||||
try {
|
||||
Log.i(TAG, "swipeNavBarRight: Try block")
|
||||
Log.i(TAG, "swipeNavBarRight: Trying to perform swipe right action on navigation toolbar")
|
||||
navURLBar().swipeRight(2)
|
||||
Log.i(TAG, "swipeNavBarRight: Performed swipe right action on navigation toolbar")
|
||||
assertUIObjectIsGone(itemWithText(tabUrl))
|
||||
} catch (e: AssertionError) {
|
||||
Log.i(TAG, "swipeNavBarRight: AssertionError caught, executing fallback methods")
|
||||
Log.i(TAG, "swipeNavBarRight: Trying to perform swipe right action on navigation toolbar")
|
||||
navURLBar().swipeRight(2)
|
||||
Log.i(TAG, "swipeNavBarRight: Performed swipe right action on navigation toolbar")
|
||||
assertUIObjectIsGone(itemWithText(tabUrl))
|
||||
}
|
||||
}
|
||||
|
@ -345,10 +344,16 @@ class BrowserRobot {
|
|||
fun swipeNavBarLeft(tabUrl: String) {
|
||||
// failing to swipe on Firebase sometimes, so it tries again
|
||||
try {
|
||||
Log.i(TAG, "swipeNavBarLeft: Try block")
|
||||
Log.i(TAG, "swipeNavBarLeft: Trying to perform swipe left action on navigation toolbar")
|
||||
navURLBar().swipeLeft(2)
|
||||
Log.i(TAG, "swipeNavBarLeft: Performed swipe left action on navigation toolbar")
|
||||
assertUIObjectIsGone(itemWithText(tabUrl))
|
||||
} catch (e: AssertionError) {
|
||||
Log.i(TAG, "swipeNavBarLeft: AssertionError caught, executing fallback methods")
|
||||
Log.i(TAG, "swipeNavBarLeft: Trying to perform swipe left action on navigation toolbar")
|
||||
navURLBar().swipeLeft(2)
|
||||
Log.i(TAG, "swipeNavBarLeft: Performed swipe left action on navigation toolbar")
|
||||
assertUIObjectIsGone(itemWithText(tabUrl))
|
||||
}
|
||||
}
|
||||
|
@ -356,11 +361,15 @@ class BrowserRobot {
|
|||
fun clickSuggestedLoginsButton() {
|
||||
for (i in 1..RETRY_COUNT) {
|
||||
try {
|
||||
Log.i(TAG, "clickSuggestedLoginsButton: Started try #$i")
|
||||
mDevice.waitForObjects(suggestedLogins())
|
||||
Log.i(TAG, "clickSuggestedLoginsButton: Trying to click suggested logins button")
|
||||
suggestedLogins().click()
|
||||
Log.i(TAG, "clickSuggestedLoginsButton: Clicked suggested logins button")
|
||||
mDevice.waitForObjects(suggestedLogins())
|
||||
break
|
||||
} catch (e: UiObjectNotFoundException) {
|
||||
Log.i(TAG, "clickSuggestedLoginsButton: UiObjectNotFoundException caught, executing fallback methods")
|
||||
if (i == RETRY_COUNT) {
|
||||
throw e
|
||||
} else {
|
||||
|
@ -370,8 +379,11 @@ class BrowserRobot {
|
|||
}
|
||||
}
|
||||
|
||||
fun setTextForApartmentTextBox(apartment: String) =
|
||||
fun setTextForApartmentTextBox(apartment: String) {
|
||||
Log.i(TAG, "setTextForApartmentTextBox: Trying to set the text for the apartment text box to: $apartment")
|
||||
itemWithResId("apartment").setText(apartment)
|
||||
Log.i(TAG, "setTextForApartmentTextBox: The text for the apartment text box was set to: $apartment")
|
||||
}
|
||||
|
||||
fun clearAddressForm() {
|
||||
clearTextFieldItem(itemWithResId("streetAddress"))
|
||||
|
@ -385,11 +397,15 @@ class BrowserRobot {
|
|||
fun clickSelectAddressButton() {
|
||||
for (i in 1..RETRY_COUNT) {
|
||||
try {
|
||||
Log.i(TAG, "clickSelectAddressButton: Started try #$i")
|
||||
assertUIObjectExists(selectAddressButton())
|
||||
Log.i(TAG, "clickSelectAddressButton: Trying to click the select address button and wait for $waitingTime ms for a new window")
|
||||
selectAddressButton().clickAndWaitForNewWindow(waitingTime)
|
||||
Log.i(TAG, "clickSelectAddressButton: Clicked the select address button and waited for $waitingTime ms for a new window")
|
||||
|
||||
break
|
||||
} catch (e: AssertionError) {
|
||||
Log.i(TAG, "clickSelectAddressButton: AssertionError caught, executing fallback methods")
|
||||
// Retrying to trigger the prompt, in case we hit https://bugzilla.mozilla.org/show_bug.cgi?id=1816869
|
||||
// This should be removed when the bug is fixed.
|
||||
if (i == RETRY_COUNT) {
|
||||
|
@ -404,28 +420,52 @@ class BrowserRobot {
|
|||
|
||||
fun verifySelectAddressButtonExists(exists: Boolean) = assertUIObjectExists(selectAddressButton(), exists = exists)
|
||||
|
||||
fun changeCreditCardExpiryDate(expiryDate: String) =
|
||||
fun changeCreditCardExpiryDate(expiryDate: String) {
|
||||
Log.i(TAG, "changeCreditCardExpiryDate: Trying to set credit card expiry date to: $expiryDate")
|
||||
itemWithResId("expiryMonthAndYear").setText(expiryDate)
|
||||
|
||||
fun clickCreditCardNumberTextBox() {
|
||||
mDevice.wait(Until.findObject(By.res("cardNumber")), waitingTime)
|
||||
mDevice.findObject(By.res("cardNumber")).click()
|
||||
mDevice.waitForWindowUpdate(appName, waitingTimeShort)
|
||||
Log.i(TAG, "changeCreditCardExpiryDate: Credit card expiry date was set to: $expiryDate")
|
||||
}
|
||||
|
||||
fun clickCreditCardFormSubmitButton() =
|
||||
fun clickCreditCardNumberTextBox() {
|
||||
Log.i(TAG, "clickCreditCardNumberTextBox: Waiting for $waitingTime ms until finding the credit card number text box")
|
||||
mDevice.wait(Until.findObject(By.res("cardNumber")), waitingTime)
|
||||
Log.i(TAG, "clickCreditCardNumberTextBox: Waited for $waitingTime ms until the credit card number text box was found")
|
||||
Log.i(TAG, "clickCreditCardNumberTextBox: Trying to click the credit card number text box")
|
||||
mDevice.findObject(By.res("cardNumber")).click()
|
||||
Log.i(TAG, "clickCreditCardNumberTextBox: Clicked the credit card number text box")
|
||||
Log.i(TAG, "clickCreditCardNumberTextBox: Waiting for $waitingTimeShort ms for $appName window to be updated")
|
||||
mDevice.waitForWindowUpdate(appName, waitingTimeShort)
|
||||
Log.i(TAG, "clickCreditCardNumberTextBox: Waited for $waitingTimeShort ms for $appName window to be updated")
|
||||
}
|
||||
|
||||
fun clickCreditCardFormSubmitButton() {
|
||||
Log.i(TAG, "clickCreditCardFormSubmitButton: Trying to click the credit card form submit button and wait for $waitingTime ms for a new window")
|
||||
itemWithResId("submit").clickAndWaitForNewWindow(waitingTime)
|
||||
Log.i(TAG, "clickCreditCardFormSubmitButton: Clicked the credit card form submit button and waited for $waitingTime ms for a new window")
|
||||
}
|
||||
|
||||
fun fillAndSaveCreditCard(cardNumber: String, cardName: String, expiryMonthAndYear: String) {
|
||||
Log.i(TAG, "fillAndSaveCreditCard: Tying to set credit card number to: $cardNumber")
|
||||
itemWithResId("cardNumber").setText(cardNumber)
|
||||
Log.i(TAG, "fillAndSaveCreditCard: Credit card number was set to: $cardNumber")
|
||||
mDevice.waitForIdle(waitingTime)
|
||||
Log.i(TAG, "fillAndSaveCreditCard: Trying to set credit card name to: $cardName")
|
||||
itemWithResId("nameOnCard").setText(cardName)
|
||||
Log.i(TAG, "fillAndSaveCreditCard: Credit card name was set to: $cardName")
|
||||
mDevice.waitForIdle(waitingTime)
|
||||
Log.i(TAG, "fillAndSaveCreditCard: Trying to set credit card expiry month and year to: $expiryMonthAndYear")
|
||||
itemWithResId("expiryMonthAndYear").setText(expiryMonthAndYear)
|
||||
Log.i(TAG, "fillAndSaveCreditCard: Credit card expiry month and year were set to: $expiryMonthAndYear")
|
||||
Log.i(TAG, "fillAndSaveCreditCard: Waiting for device to be idle for $waitingTime ms")
|
||||
mDevice.waitForIdle(waitingTime)
|
||||
Log.i(TAG, "fillAndSaveCreditCard: Waited for device to be idle for $waitingTime ms")
|
||||
Log.i(TAG, "fillAndSaveCreditCard: Trying to click the credit card form submit button and wait for $waitingTime ms for a new window")
|
||||
itemWithResId("submit").clickAndWaitForNewWindow(waitingTime)
|
||||
Log.i(TAG, "fillAndSaveCreditCard: Clicked the credit card form submit button and waited for $waitingTime ms for a new window")
|
||||
waitForPageToLoad()
|
||||
Log.i(TAG, "fillAndSaveCreditCard: Waiting for $waitingTime ms for $packageName window to be updated")
|
||||
mDevice.waitForWindowUpdate(packageName, waitingTime)
|
||||
Log.i(TAG, "fillAndSaveCreditCard: Waited for $waitingTime ms for $packageName window to be updated")
|
||||
}
|
||||
|
||||
fun verifyUpdateOrSaveCreditCardPromptExists(exists: Boolean) =
|
||||
|
@ -449,10 +489,9 @@ class BrowserRobot {
|
|||
}
|
||||
|
||||
fun verifySuggestedUserName(userName: String) {
|
||||
mDevice.findObject(
|
||||
UiSelector()
|
||||
.resourceId("$packageName:id/mozac_feature_login_multiselect_expand"),
|
||||
).waitForExists(waitingTime)
|
||||
Log.i(TAG, "verifySuggestedUserName: Waiting for $waitingTime ms for suggested logins fragment to exist")
|
||||
itemWithResId("$packageName:id/mozac_feature_login_multiselect_expand").waitForExists(waitingTime)
|
||||
Log.i(TAG, "verifySuggestedUserName: Waited for $waitingTime ms for suggested logins fragment to exist")
|
||||
assertUIObjectExists(itemContainingText(userName))
|
||||
}
|
||||
|
||||
|
@ -460,6 +499,7 @@ class BrowserRobot {
|
|||
// Sometimes the assertion of the pre-filled logins fails so we are re-trying after refreshing the page
|
||||
for (i in 1..RETRY_COUNT) {
|
||||
try {
|
||||
Log.i(TAG, "verifyPrefilledLoginCredentials: Started try #$i")
|
||||
mDevice.waitForObjects(itemWithResId("username"))
|
||||
assertItemTextEquals(itemWithResId("username"), expectedText = userName, isEqual = credentialsArePrefilled)
|
||||
mDevice.waitForObjects(itemWithResId("password"))
|
||||
|
@ -467,6 +507,7 @@ class BrowserRobot {
|
|||
|
||||
break
|
||||
} catch (e: AssertionError) {
|
||||
Log.i(TAG, "verifyPrefilledLoginCredentials: AssertionError caught, executing fallback methods")
|
||||
if (i == RETRY_COUNT) {
|
||||
throw e
|
||||
} else {
|
||||
|
@ -499,23 +540,6 @@ class BrowserRobot {
|
|||
assertUIObjectExists(itemWithResIdAndText("cardNumber", creditCardNumber))
|
||||
}
|
||||
|
||||
fun verifyPrefilledPWALoginCredentials(userName: String, shortcutTitle: String) {
|
||||
mDevice.waitForIdle(waitingTime)
|
||||
|
||||
var currentTries = 0
|
||||
while (currentTries++ < 3) {
|
||||
try {
|
||||
assertUIObjectExists(itemWithResId("submit"))
|
||||
itemWithResId("submit").click()
|
||||
assertItemTextEquals(itemWithResId("username"), expectedText = userName)
|
||||
break
|
||||
} catch (e: AssertionError) {
|
||||
addToHomeScreen {
|
||||
}.searchAndOpenHomeScreenShortcut(shortcutTitle) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun verifySaveLoginPromptIsDisplayed() =
|
||||
assertUIObjectExists(
|
||||
itemWithResId("$packageName:id/feature_prompt_login_fragment"),
|
||||
|
@ -530,14 +554,16 @@ class BrowserRobot {
|
|||
fun verifyTrackingProtectionWebContent(state: String) {
|
||||
for (i in 1..RETRY_COUNT) {
|
||||
try {
|
||||
Log.i(TAG, "verifyTrackingProtectionWebContent: Started try #$i")
|
||||
assertUIObjectExists(itemContainingText(state))
|
||||
|
||||
break
|
||||
} catch (e: AssertionError) {
|
||||
Log.i(TAG, "verifyTrackingProtectionWebContent: AssertionError caught, executing fallback methods")
|
||||
if (i == RETRY_COUNT) {
|
||||
throw e
|
||||
} else {
|
||||
Log.e("TestLog", "On try $i, trackers are not: $state")
|
||||
Log.e(TAG, "On try $i, trackers are not: $state")
|
||||
|
||||
navigationToolbar {
|
||||
}.openThreeDotMenu {
|
||||
|
@ -550,38 +576,61 @@ class BrowserRobot {
|
|||
|
||||
fun verifyCookiesProtectionHintIsDisplayed(composeTestRule: HomeActivityComposeTestRule, isDisplayed: Boolean) {
|
||||
if (isDisplayed) {
|
||||
Log.i(TAG, "verifyCookiesProtectionHintIsDisplayed: Trying to verify that the total cookie protection message is displayed")
|
||||
composeTestRule.onNodeWithTag("tcp_cfr.message").assertIsDisplayed()
|
||||
Log.i(TAG, "verifyCookiesProtectionHintIsDisplayed: Verified total cookie protection message is displayed")
|
||||
Log.i(TAG, "verifyCookiesProtectionHintIsDisplayed: Trying to verify that the total cookie protection learn more link is displayed")
|
||||
composeTestRule.onNodeWithTag("tcp_cfr.action").assertIsDisplayed()
|
||||
Log.i(TAG, "verifyCookiesProtectionHintIsDisplayed: Verified that the total cookie protection learn more link is displayed")
|
||||
Log.i(TAG, "verifyCookiesProtectionHintIsDisplayed: Trying to verify that the total cookie protection dismiss button is displayed")
|
||||
composeTestRule.onNodeWithTag("cfr.dismiss").assertIsDisplayed()
|
||||
Log.i(TAG, "verifyCookiesProtectionHintIsDisplayed: Verified total cookie protection dismiss button is displayed")
|
||||
} else {
|
||||
Log.i(TAG, "verifyCookiesProtectionHintIsDisplayed: Trying to verify that the total cookie protection message does not exist")
|
||||
composeTestRule.onNodeWithTag("tcp_cfr.message").assertDoesNotExist()
|
||||
Log.i(TAG, "verifyCookiesProtectionHintIsDisplayed: Verified that the total cookie protection message does not exist")
|
||||
Log.i(TAG, "verifyCookiesProtectionHintIsDisplayed: Trying to verify that the total cookie protection learn more link does not exist")
|
||||
composeTestRule.onNodeWithTag("tcp_cfr.action").assertDoesNotExist()
|
||||
Log.i(TAG, "verifyCookiesProtectionHintIsDisplayed: Verified total cookie protection learn more link does not exist")
|
||||
Log.i(TAG, "verifyCookiesProtectionHintIsDisplayed: Trying to verify that the total cookie protection dismiss button does not exist")
|
||||
composeTestRule.onNodeWithTag("cfr.dismiss").assertDoesNotExist()
|
||||
Log.i(TAG, "verifyCookiesProtectionHintIsDisplayed: Verified that the total cookie protection dismiss button does not exist")
|
||||
}
|
||||
}
|
||||
|
||||
fun clickTCPCFRLearnMore(composeTestRule: HomeActivityComposeTestRule) {
|
||||
Log.i(TAG, "clickTCPCFRLearnMore: Trying to click the total cookie protection learn more link")
|
||||
composeTestRule.onNodeWithTag("tcp_cfr.action").performClick()
|
||||
Log.i(TAG, "clickTCPCFRLearnMore: Clicked total cookie protection learn more link")
|
||||
}
|
||||
|
||||
fun dismissTCPCFRPopup(composeTestRule: HomeActivityComposeTestRule) {
|
||||
Log.i(TAG, "dismissTCPCFRPopup: Trying to click the total cookie protection dismiss button")
|
||||
composeTestRule.onNodeWithTag("cfr.dismiss").performClick()
|
||||
Log.i(TAG, "dismissTCPCFRPopup: Clicked total cookie protection dismiss button")
|
||||
}
|
||||
|
||||
fun verifyShouldShowCFRTCP(shouldShow: Boolean, settings: Settings) {
|
||||
if (shouldShow) {
|
||||
Log.i(TAG, "verifyShouldShowCFRTCP: Trying to verify that the TCP CFR should be shown")
|
||||
assertTrue(settings.shouldShowTotalCookieProtectionCFR)
|
||||
Log.i(TAG, "verifyShouldShowCFRTCP: Verified that the TCP CFR should be shown")
|
||||
} else {
|
||||
Log.i(TAG, "verifyShouldShowCFRTCP: Trying to verify that the TCP CFR should not be shown")
|
||||
assertFalse(settings.shouldShowTotalCookieProtectionCFR)
|
||||
Log.i(TAG, "verifyShouldShowCFRTCP: Verified that the TCP CFR should not be shown")
|
||||
}
|
||||
}
|
||||
|
||||
fun selectTime(hour: Int, minute: Int): ViewInteraction =
|
||||
fun selectTime(hour: Int, minute: Int) {
|
||||
Log.i(TAG, "selectTime: Trying to select time picker hour: $hour and minute: $minute")
|
||||
onView(
|
||||
isAssignableFrom(TimePicker::class.java),
|
||||
).inRoot(
|
||||
isDialog(),
|
||||
).perform(PickerActions.setTime(hour, minute))
|
||||
Log.i(TAG, "selectTime: Selected time picker hour: $hour and minute: $minute")
|
||||
}
|
||||
|
||||
fun verifySelectedDate() {
|
||||
val currentDate = LocalDate.now()
|
||||
|
@ -591,11 +640,13 @@ class BrowserRobot {
|
|||
|
||||
for (i in 1..RETRY_COUNT) {
|
||||
try {
|
||||
Log.i(TAG, "verifySelectedDate: Started try #$i")
|
||||
assertUIObjectExists(itemContainingText("Selected date is: $currentDate"))
|
||||
|
||||
break
|
||||
} catch (e: AssertionError) {
|
||||
Log.e("TestLog", "Selected time isn't displayed ${e.localizedMessage}")
|
||||
Log.i(TAG, "verifySelectedDate: AssertionError caught, executing fallback methods")
|
||||
Log.e(TAG, "Selected time isn't displayed ${e.localizedMessage}")
|
||||
|
||||
clickPageObject(itemWithResId("calendar"))
|
||||
clickPageObject(itemWithDescription("$currentDay $currentMonth $currentYear"))
|
||||
|
@ -618,11 +669,13 @@ class BrowserRobot {
|
|||
fun verifySelectedTime(hour: Int, minute: Int) {
|
||||
for (i in 1..RETRY_COUNT) {
|
||||
try {
|
||||
Log.i(TAG, "verifySelectedTime: Started try #$i")
|
||||
assertUIObjectExists(itemContainingText("Selected time is: $hour:$minute"))
|
||||
|
||||
break
|
||||
} catch (e: AssertionError) {
|
||||
Log.e("TestLog", "Selected time isn't displayed ${e.localizedMessage}")
|
||||
Log.i(TAG, "verifySelectedTime: AssertionError caught, executing fallback methods")
|
||||
Log.e(TAG, "Selected time isn't displayed ${e.localizedMessage}")
|
||||
|
||||
clickPageObject(itemWithResId("clock"))
|
||||
clickPageObject(itemContainingText("CLEAR"))
|
||||
|
@ -638,11 +691,13 @@ class BrowserRobot {
|
|||
fun verifySelectedColor(hexValue: String) {
|
||||
for (i in 1..RETRY_COUNT) {
|
||||
try {
|
||||
Log.i(TAG, "verifySelectedColor: Started try #$i")
|
||||
assertUIObjectExists(itemContainingText("Selected color is: $hexValue"))
|
||||
|
||||
break
|
||||
} catch (e: AssertionError) {
|
||||
Log.e("TestLog", "Selected color isn't displayed ${e.localizedMessage}")
|
||||
Log.i(TAG, "verifySelectedColor: AssertionError caught, executing fallback methods")
|
||||
Log.e(TAG, "Selected color isn't displayed ${e.localizedMessage}")
|
||||
|
||||
clickPageObject(itemWithResId("colorPicker"))
|
||||
clickPageObject(itemWithDescription(hexValue))
|
||||
|
@ -657,17 +712,20 @@ class BrowserRobot {
|
|||
fun verifySelectedDropDownOption(optionName: String) {
|
||||
for (i in 1..RETRY_COUNT) {
|
||||
try {
|
||||
Log.i(TAG, "verifySelectedDropDownOption: Started try #$i")
|
||||
Log.i(TAG, "verifySelectedDropDownOption: Waiting for $waitingTime ms for \"Submit drop down option\" form button to exist")
|
||||
mDevice.findObject(
|
||||
UiSelector()
|
||||
.textContains("Submit drop down option")
|
||||
.resourceId("submitOption"),
|
||||
).waitForExists(waitingTime)
|
||||
|
||||
Log.i(TAG, "verifySelectedDropDownOption: Waited for $waitingTime ms for \"Submit drop down option\" form button to exist")
|
||||
assertUIObjectExists(itemContainingText("Selected option is: $optionName"))
|
||||
|
||||
break
|
||||
} catch (e: AssertionError) {
|
||||
Log.e("TestLog", "Selected option isn't displayed ${e.localizedMessage}")
|
||||
Log.i(TAG, "verifySelectedDropDownOption: AssertionError caught, executing fallback methods")
|
||||
Log.e(TAG, "Selected option isn't displayed ${e.localizedMessage}")
|
||||
|
||||
clickPageObject(itemWithResId("dropDown"))
|
||||
clickPageObject(itemContainingText(optionName))
|
||||
|
@ -686,16 +744,18 @@ class BrowserRobot {
|
|||
|
||||
fun verifyCookieBannerExists(exists: Boolean) {
|
||||
for (i in 1..RETRY_COUNT) {
|
||||
Log.i(TAG, "verifyCookieBannerExists: For loop: $i")
|
||||
Log.i(TAG, "verifyCookieBannerExists: Started try #$i")
|
||||
try {
|
||||
// Wait for the blocker to kick-in and make the cookie banner disappear
|
||||
Log.i(TAG, "verifyCookieBannerExists: Waiting for $waitingTime ms for cookie banner to be gone")
|
||||
itemWithResId("CybotCookiebotDialog").waitUntilGone(waitingTime)
|
||||
Log.i(TAG, "verifyCookieBannerExists: Waiting for window update")
|
||||
Log.i(TAG, "verifyCookieBannerExists: Waited for $waitingTime ms for cookie banner to be gone")
|
||||
// Assert that the blocker properly dismissed the cookie banner
|
||||
assertUIObjectExists(itemWithResId("CybotCookiebotDialog"), exists = exists)
|
||||
|
||||
break
|
||||
} catch (e: AssertionError) {
|
||||
Log.i(TAG, "verifyCookieBannerExists: AssertionError caught, executing fallback methods")
|
||||
if (i == RETRY_COUNT) {
|
||||
throw e
|
||||
}
|
||||
|
@ -724,6 +784,7 @@ class BrowserRobot {
|
|||
fun verifyPrivateBrowsingOpenLinkInAnotherAppPrompt(url: String, pageObject: UiObject) {
|
||||
for (i in 1..RETRY_COUNT) {
|
||||
try {
|
||||
Log.i(TAG, "verifyPrivateBrowsingOpenLinkInAnotherAppPrompt: Started try #$i")
|
||||
assertUIObjectExists(
|
||||
itemContainingText(
|
||||
getStringResource(R.string.mozac_feature_applinks_confirm_dialog_title),
|
||||
|
@ -733,6 +794,7 @@ class BrowserRobot {
|
|||
|
||||
break
|
||||
} catch (e: AssertionError) {
|
||||
Log.i(TAG, "verifyPrivateBrowsingOpenLinkInAnotherAppPrompt: AssertionError caught, executing fallback methods")
|
||||
if (i == RETRY_COUNT) {
|
||||
throw e
|
||||
} else {
|
||||
|
@ -774,6 +836,7 @@ class BrowserRobot {
|
|||
fun verifyOpenLinksInAppsCFRExists(exists: Boolean) {
|
||||
for (i in 1..RETRY_COUNT) {
|
||||
try {
|
||||
Log.i(TAG, "verifyOpenLinksInAppsCFRExists: Started try #$i")
|
||||
assertUIObjectExists(
|
||||
itemWithResId("$packageName:id/banner_container"),
|
||||
itemWithResIdContainingText(
|
||||
|
@ -791,6 +854,7 @@ class BrowserRobot {
|
|||
exists = exists,
|
||||
)
|
||||
} catch (e: AssertionError) {
|
||||
Log.i(TAG, "verifyOpenLinksInAppsCFRExists: AssertionError caught, executing fallback methods")
|
||||
if (i == RETRY_COUNT) {
|
||||
throw e
|
||||
} else {
|
||||
|
@ -817,11 +881,14 @@ class BrowserRobot {
|
|||
fun verifyHomeScreenSurveyCloseButton() =
|
||||
assertUIObjectExists(itemWithDescription("Close"))
|
||||
|
||||
fun clickOpenLinksInAppsDismissCFRButton() =
|
||||
fun clickOpenLinksInAppsDismissCFRButton() {
|
||||
Log.i(TAG, "clickOpenLinksInAppsDismissCFRButton: Trying to click the open links in apps banner \"Dismiss\" button")
|
||||
itemWithResIdContainingText(
|
||||
"$packageName:id/dismiss",
|
||||
getStringResource(R.string.open_in_app_cfr_negative_button_text),
|
||||
).click()
|
||||
Log.i(TAG, "clickOpenLinksInAppsDismissCFRButton: Clicked the open links in apps banner \"Dismiss\" button")
|
||||
}
|
||||
|
||||
fun clickTakeSurveyButton() {
|
||||
val button = mDevice.findObject(
|
||||
|
@ -846,7 +913,11 @@ class BrowserRobot {
|
|||
button.click()
|
||||
}
|
||||
|
||||
fun longClickToolbar() = onView(withId(R.id.mozac_browser_toolbar_url_view)).perform(longClick())
|
||||
fun longClickToolbar() {
|
||||
Log.i(TAG, "longClickToolbar: Trying to long click the toolbar")
|
||||
onView(withId(R.id.mozac_browser_toolbar_url_view)).perform(longClick())
|
||||
Log.i(TAG, "longClickToolbar: Long clicked the toolbar")
|
||||
}
|
||||
|
||||
fun verifyDownloadPromptIsDismissed() =
|
||||
assertUIObjectExists(
|
||||
|
@ -876,27 +947,31 @@ class BrowserRobot {
|
|||
}
|
||||
|
||||
fun clickStayInPrivateBrowsingPromptButton() {
|
||||
Log.i(TAG, "clickStayInPrivateBrowsingPromptButton: Trying to click the \"STAY IN PRIVATE BROWSING\" prompt button")
|
||||
itemWithResIdContainingText(
|
||||
"$packageName:id/deny_button",
|
||||
getStringResource(R.string.mozac_feature_downloads_cancel_active_private_downloads_deny),
|
||||
).click()
|
||||
Log.i(TAG, "clickStayInPrivateBrowsingPromptButton: Clicked \"STAY IN PRIVATE BROWSING\" prompt button")
|
||||
Log.i(TAG, "clickStayInPrivateBrowsingPromptButton: Clicked the \"STAY IN PRIVATE BROWSING\" prompt button")
|
||||
}
|
||||
|
||||
fun clickCancelPrivateDownloadsPromptButton() {
|
||||
Log.i(TAG, "clickCancelPrivateDownloadsPromptButton: Trying to click the \"CANCEL DOWNLOADS\" prompt button")
|
||||
itemWithResIdContainingText(
|
||||
"$packageName:id/accept_button",
|
||||
getStringResource(R.string.mozac_feature_downloads_cancel_active_downloads_accept),
|
||||
).click()
|
||||
Log.i(TAG, "clickCancelPrivateDownloadsPromptButton: Clicked \"CANCEL DOWNLOADS\" prompt button")
|
||||
|
||||
Log.i(TAG, "clickCancelPrivateDownloadsPromptButton: Clicked the \"CANCEL DOWNLOADS\" prompt button")
|
||||
Log.i(TAG, "clickCancelPrivateDownloadsPromptButton: Waiting for $waitingTime ms for $packageName window to be updated")
|
||||
mDevice.waitForWindowUpdate(packageName, waitingTime)
|
||||
Log.i(TAG, "clickCancelPrivateDownloadsPromptButton: Waited for $waitingTime ms for $packageName window to be updated")
|
||||
}
|
||||
|
||||
fun fillPdfForm(name: String) {
|
||||
// Set PDF form text for the text box
|
||||
Log.i(TAG, "fillPdfForm: Trying to set the text of the PDF form text box to: $name")
|
||||
itemWithResId("pdfjs_internal_id_10R").setText(name)
|
||||
Log.i(TAG, "fillPdfForm: Set PDF form text box text to: $name")
|
||||
Log.i(TAG, "fillPdfForm: PDF form text box text was set to: $name")
|
||||
mDevice.waitForWindowUpdate(packageName, waitingTime)
|
||||
if (
|
||||
!itemWithResId("pdfjs_internal_id_11R").exists() &&
|
||||
|
@ -905,18 +980,22 @@ class BrowserRobot {
|
|||
.contains("mInputShown=true")
|
||||
) {
|
||||
// Close the keyboard
|
||||
Log.i(TAG, "fillPdfForm: Trying to close the keyboard using device back button")
|
||||
mDevice.pressBack()
|
||||
Log.i(TAG, "fillPdfForm: Closing the keyboard using device back button")
|
||||
Log.i(TAG, "fillPdfForm: Closed the keyboard using device back button")
|
||||
}
|
||||
// Click PDF form check box
|
||||
Log.i(TAG, "fillPdfForm: Trying to click the PDF form check box")
|
||||
itemWithResId("pdfjs_internal_id_11R").click()
|
||||
Log.i(TAG, "fillPdfForm: Clicked PDF form check box")
|
||||
}
|
||||
|
||||
class Transition {
|
||||
fun openThreeDotMenu(interact: ThreeDotMenuMainRobot.() -> Unit): ThreeDotMenuMainRobot.Transition {
|
||||
Log.i(TAG, "openThreeDotMenu: Waiting for device to be idle for $waitingTime ms")
|
||||
mDevice.waitForIdle(waitingTime)
|
||||
Log.i(TAG, "openThreeDotMenu: Device was idle for $waitingTime ms")
|
||||
Log.i(TAG, "openThreeDotMenu: Trying to click the main menu button")
|
||||
threeDotButton().perform(click())
|
||||
Log.i(TAG, "openThreeDotMenu: Clicked the main menu button")
|
||||
|
||||
|
@ -926,7 +1005,9 @@ class BrowserRobot {
|
|||
|
||||
fun openNavigationToolbar(interact: NavigationToolbarRobot.() -> Unit): NavigationToolbarRobot.Transition {
|
||||
clickPageObject(navURLBar())
|
||||
Log.i(TAG, "openNavigationToolbar: Waiting for $waitingTime ms for for search bar to exist")
|
||||
searchBar().waitForExists(waitingTime)
|
||||
Log.i(TAG, "openNavigationToolbar: Waited for $waitingTime ms for for search bar to exist")
|
||||
|
||||
NavigationToolbarRobot().interact()
|
||||
return NavigationToolbarRobot.Transition()
|
||||
|
@ -935,6 +1016,7 @@ class BrowserRobot {
|
|||
fun openTabDrawer(interact: TabDrawerRobot.() -> Unit): TabDrawerRobot.Transition {
|
||||
for (i in 1..RETRY_COUNT) {
|
||||
try {
|
||||
Log.i(TAG, "openTabDrawer: Started try #$i")
|
||||
mDevice.waitForObjects(
|
||||
mDevice.findObject(
|
||||
UiSelector()
|
||||
|
@ -942,16 +1024,20 @@ class BrowserRobot {
|
|||
),
|
||||
waitingTime,
|
||||
)
|
||||
|
||||
Log.i(TAG, "openTabDrawer: Trying to click the tab counter button")
|
||||
tabsCounter().click()
|
||||
Log.i(TAG, "openTabDrawer: Clicked the tab counter button")
|
||||
assertUIObjectExists(itemWithResId("$packageName:id/new_tab_button"))
|
||||
|
||||
break
|
||||
} catch (e: AssertionError) {
|
||||
Log.i(TAG, "openTabDrawer: AssertionError caught, executing fallback methods")
|
||||
if (i == RETRY_COUNT) {
|
||||
throw e
|
||||
} else {
|
||||
Log.i(TAG, "openTabDrawer: Waiting for device to be idle")
|
||||
mDevice.waitForIdle()
|
||||
Log.i(TAG, "openTabDrawer: Waited for device to be idle")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -965,6 +1051,7 @@ class BrowserRobot {
|
|||
fun openComposeTabDrawer(composeTestRule: HomeActivityComposeTestRule, interact: ComposeTabDrawerRobot.() -> Unit): ComposeTabDrawerRobot.Transition {
|
||||
for (i in 1..RETRY_COUNT) {
|
||||
try {
|
||||
Log.i(TAG, "openComposeTabDrawer: Started try #$i")
|
||||
mDevice.waitForObjects(
|
||||
mDevice.findObject(
|
||||
UiSelector()
|
||||
|
@ -972,30 +1059,37 @@ class BrowserRobot {
|
|||
),
|
||||
waitingTime,
|
||||
)
|
||||
|
||||
Log.i(TAG, "openComposeTabDrawer: Trying to click the tab counter button")
|
||||
tabsCounter().click()
|
||||
|
||||
Log.i(TAG, "openComposeTabDrawer: Clicked the tab counter button")
|
||||
Log.i(TAG, "openComposeTabDrawer: Trying to verify the tabs tray exists")
|
||||
composeTestRule.onNodeWithTag(TabsTrayTestTag.tabsTray).assertExists()
|
||||
Log.i(TAG, "openComposeTabDrawer: Verified the tabs tray exists")
|
||||
|
||||
break
|
||||
} catch (e: AssertionError) {
|
||||
Log.i(TAG, "openComposeTabDrawer: AssertionError caught, executing fallback methods")
|
||||
if (i == RETRY_COUNT) {
|
||||
throw e
|
||||
} else {
|
||||
Log.i(TAG, "openComposeTabDrawer: Waiting for device to be idle")
|
||||
mDevice.waitForIdle()
|
||||
Log.i(TAG, "openComposeTabDrawer: Waited for device to be idle")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Log.i(TAG, "openComposeTabDrawer: Trying to verify the tabs tray new tab FAB button exists")
|
||||
composeTestRule.onNodeWithTag(TabsTrayTestTag.fab).assertExists()
|
||||
Log.i(TAG, "openComposeTabDrawer: Verified the tabs tray new tab FAB button exists")
|
||||
|
||||
ComposeTabDrawerRobot(composeTestRule).interact()
|
||||
return ComposeTabDrawerRobot.Transition(composeTestRule)
|
||||
}
|
||||
|
||||
fun openNotificationShade(interact: NotificationRobot.() -> Unit): NotificationRobot.Transition {
|
||||
Log.i(TAG, "openNotificationShade: Trying to open the notification tray")
|
||||
mDevice.openNotification()
|
||||
Log.i(TAG, "openNotificationShade: Opened notification tray")
|
||||
Log.i(TAG, "openNotificationShade: Opened the notification tray")
|
||||
|
||||
NotificationRobot().interact()
|
||||
return NotificationRobot.Transition()
|
||||
|
@ -1003,7 +1097,7 @@ class BrowserRobot {
|
|||
|
||||
fun goToHomescreen(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition {
|
||||
clickPageObject(itemWithDescription("Home screen"))
|
||||
|
||||
Log.i(TAG, "goToHomescreen: Waiting for $waitingTime ms for for home screen layout or jump back in contextual hint to exist")
|
||||
mDevice.findObject(UiSelector().resourceId("$packageName:id/homeLayout"))
|
||||
.waitForExists(waitingTime) ||
|
||||
mDevice.findObject(
|
||||
|
@ -1011,6 +1105,7 @@ class BrowserRobot {
|
|||
getStringResource(R.string.onboarding_home_screen_jump_back_contextual_hint_2),
|
||||
),
|
||||
).waitForExists(waitingTime)
|
||||
Log.i(TAG, "goToHomescreen: Waited for $waitingTime ms for for home screen layout or jump back in contextual hint to exist")
|
||||
|
||||
HomeScreenRobot().interact()
|
||||
return HomeScreenRobot.Transition()
|
||||
|
@ -1019,6 +1114,7 @@ class BrowserRobot {
|
|||
fun goToHomescreenWithComposeTopSites(composeTestRule: HomeActivityComposeTestRule, interact: ComposeTopSitesRobot.() -> Unit): ComposeTopSitesRobot.Transition {
|
||||
clickPageObject(itemWithDescription("Home screen"))
|
||||
|
||||
Log.i(TAG, "goToHomescreenWithComposeTopSites: Waiting for $waitingTime ms for for home screen layout or jump back in contextual hint to exist")
|
||||
mDevice.findObject(UiSelector().resourceId("$packageName:id/homeLayout"))
|
||||
.waitForExists(waitingTime) ||
|
||||
mDevice.findObject(
|
||||
|
@ -1026,13 +1122,16 @@ class BrowserRobot {
|
|||
getStringResource(R.string.onboarding_home_screen_jump_back_contextual_hint_2),
|
||||
),
|
||||
).waitForExists(waitingTime)
|
||||
Log.i(TAG, "goToHomescreenWithComposeTopSites: Waited for $waitingTime ms for for home screen layout or jump back in contextual hint to exist")
|
||||
|
||||
ComposeTopSitesRobot(composeTestRule).interact()
|
||||
return ComposeTopSitesRobot.Transition(composeTestRule)
|
||||
}
|
||||
|
||||
fun goBack(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition {
|
||||
Log.i(TAG, "goBack: Trying to click device back button")
|
||||
mDevice.pressBack()
|
||||
Log.i(TAG, "goBack: Clicked device back button")
|
||||
|
||||
HomeScreenRobot().interact()
|
||||
return HomeScreenRobot.Transition()
|
||||
|
@ -1040,7 +1139,9 @@ class BrowserRobot {
|
|||
|
||||
fun clickTabCrashedCloseButton(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition {
|
||||
clickPageObject(itemWithText("Close tab"))
|
||||
Log.i(TAG, "clickTabCrashedCloseButton: Waiting for device to be idle")
|
||||
mDevice.waitForIdle()
|
||||
Log.i(TAG, "clickTabCrashedCloseButton: Waited for device to be idle")
|
||||
|
||||
HomeScreenRobot().interact()
|
||||
return HomeScreenRobot.Transition()
|
||||
|
@ -1126,45 +1227,56 @@ class BrowserRobot {
|
|||
}
|
||||
|
||||
fun openSiteSecuritySheet(interact: SiteSecurityRobot.() -> Unit): SiteSecurityRobot.Transition {
|
||||
Log.i(TAG, "openSiteSecuritySheet: Waiting for $waitingTime ms for site security toolbar button to exist")
|
||||
siteSecurityToolbarButton().waitForExists(waitingTime)
|
||||
Log.i(TAG, "openSiteSecuritySheet: Waited for $waitingTime ms for site security toolbar button to exist")
|
||||
Log.i(TAG, "openSiteSecuritySheet: Trying to click the site security toolbar button and wait for $waitingTime ms for a new window")
|
||||
siteSecurityToolbarButton().clickAndWaitForNewWindow(waitingTime)
|
||||
Log.i(TAG, "openSiteSecuritySheet: Clicked the site security toolbar button and waited for $waitingTime ms for a new window")
|
||||
|
||||
SiteSecurityRobot().interact()
|
||||
return SiteSecurityRobot.Transition()
|
||||
}
|
||||
|
||||
fun clickManageAddressButton(interact: SettingsSubMenuAutofillRobot.() -> Unit): SettingsSubMenuAutofillRobot.Transition {
|
||||
Log.i(TAG, "clickManageAddressButton: Trying to click the manage address button and wait for $waitingTime ms for a new window")
|
||||
itemWithResId("$packageName:id/manage_addresses")
|
||||
.clickAndWaitForNewWindow(waitingTime)
|
||||
Log.i(TAG, "clickManageAddressButton: Clicked the manage address button and waited for $waitingTime ms for a new window")
|
||||
|
||||
SettingsSubMenuAutofillRobot().interact()
|
||||
return SettingsSubMenuAutofillRobot.Transition()
|
||||
}
|
||||
|
||||
fun clickManageCreditCardsButton(interact: SettingsSubMenuAutofillRobot.() -> Unit): SettingsSubMenuAutofillRobot.Transition {
|
||||
Log.i(TAG, "clickManageCreditCardsButton: Trying to click the manage credit cards button and wait for $waitingTime ms for a new window")
|
||||
itemWithResId("$packageName:id/manage_credit_cards")
|
||||
.clickAndWaitForNewWindow(waitingTime)
|
||||
Log.i(TAG, "clickManageCreditCardsButton: Clicked the manage credit cards button and waited for $waitingTime ms for a new window")
|
||||
|
||||
SettingsSubMenuAutofillRobot().interact()
|
||||
return SettingsSubMenuAutofillRobot.Transition()
|
||||
}
|
||||
|
||||
fun clickOpenLinksInAppsGoToSettingsCFRButton(interact: SettingsRobot.() -> Unit): SettingsRobot.Transition {
|
||||
Log.i(TAG, "clickOpenLinksInAppsGoToSettingsCFRButton: Trying to click the \"Go to settings\" open links in apps CFR button and wait for $waitingTime ms for a new window")
|
||||
itemWithResIdContainingText(
|
||||
"$packageName:id/action",
|
||||
getStringResource(R.string.open_in_app_cfr_positive_button_text),
|
||||
).clickAndWaitForNewWindow(waitingTime)
|
||||
Log.i(TAG, "clickOpenLinksInAppsGoToSettingsCFRButton: Clicked \"Go to settings\" open links in apps CFR button")
|
||||
Log.i(TAG, "clickOpenLinksInAppsGoToSettingsCFRButton: Clicked the \"Go to settings\" open links in apps CFR button and waited for $waitingTime ms for a new window")
|
||||
|
||||
SettingsRobot().interact()
|
||||
return SettingsRobot.Transition()
|
||||
}
|
||||
|
||||
fun clickDownloadPDFButton(interact: DownloadRobot.() -> Unit): DownloadRobot.Transition {
|
||||
Log.i(TAG, "clickDownloadPDFButton: Trying to click the download PDF button")
|
||||
itemWithResIdContainingText(
|
||||
"download",
|
||||
"Download",
|
||||
).click()
|
||||
Log.i(TAG, "clickDownloadPDFButton: Clicked the download PDF button")
|
||||
|
||||
DownloadRobot().interact()
|
||||
return DownloadRobot.Transition()
|
||||
|
@ -1205,8 +1317,6 @@ private fun navURLBar() = itemWithResId("$packageName:id/toolbar")
|
|||
|
||||
private fun searchBar() = itemWithResId("$packageName:id/mozac_browser_toolbar_url_view")
|
||||
|
||||
fun homeScreenButton() = onView(withContentDescription(R.string.browser_toolbar_home))
|
||||
|
||||
private fun threeDotButton() = onView(withContentDescription("Menu"))
|
||||
|
||||
private fun tabsCounter() =
|
||||
|
@ -1224,26 +1334,25 @@ private fun siteSecurityToolbarButton() =
|
|||
|
||||
fun clickPageObject(item: UiObject) {
|
||||
for (i in 1..RETRY_COUNT) {
|
||||
Log.i(TAG, "clickPageObject: For loop i = $i")
|
||||
try {
|
||||
Log.i(TAG, "clickPageObject: Try block")
|
||||
Log.i(TAG, "clickPageObject: Started try #$i")
|
||||
Log.i(TAG, "clickPageObject: Waiting for $waitingTime ms for ${item.selector} to exist")
|
||||
item.waitForExists(waitingTime)
|
||||
Log.i(TAG, "clickPageObject: Waited for $waitingTime ms for ${item.selector} to exist")
|
||||
Log.i(TAG, "clickPageObject: Trying to click ${item.selector}")
|
||||
item.click()
|
||||
Log.i(TAG, "clickPageObject: Clicked ${item.selector}")
|
||||
|
||||
break
|
||||
} catch (e: UiObjectNotFoundException) {
|
||||
Log.i(TAG, "clickPageObject: Catch block")
|
||||
Log.i(TAG, "clickPageObject: UiObjectNotFoundException caught, executing fallback methods")
|
||||
if (i == RETRY_COUNT) {
|
||||
throw e
|
||||
} else {
|
||||
browserScreen {
|
||||
Log.i(TAG, "clickPageObject: Browser screen")
|
||||
}.openThreeDotMenu {
|
||||
Log.i(TAG, "clickPageObject: Opened main menu")
|
||||
}.refreshPage {
|
||||
waitForPageToLoad()
|
||||
Log.i(TAG, "clickPageObject: Page refreshed, progress bar is gone")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1253,11 +1362,17 @@ fun clickPageObject(item: UiObject) {
|
|||
fun longClickPageObject(item: UiObject) {
|
||||
for (i in 1..RETRY_COUNT) {
|
||||
try {
|
||||
Log.i(TAG, "longClickPageObject: Started try #$i")
|
||||
Log.i(TAG, "longClickPageObject: Waiting for $waitingTime ms for ${item.selector} to exist")
|
||||
item.waitForExists(waitingTime)
|
||||
Log.i(TAG, "longClickPageObject: Waited for $waitingTime ms for ${item.selector} to exist")
|
||||
Log.i(TAG, "longClickPageObject: Trying to long click ${item.selector}")
|
||||
item.longClick()
|
||||
Log.i(TAG, "longClickPageObject: Long clicked ${item.selector}")
|
||||
|
||||
break
|
||||
} catch (e: UiObjectNotFoundException) {
|
||||
Log.i(TAG, "longClickPageObject: UiObjectNotFoundException caught, executing fallback methods")
|
||||
if (i == RETRY_COUNT) {
|
||||
throw e
|
||||
} else {
|
||||
|
@ -1276,20 +1391,30 @@ fun clickContextMenuItem(item: String) {
|
|||
Until.findObject(text(item)),
|
||||
waitingTime,
|
||||
)
|
||||
Log.i(TAG, "clickContextMenuItem: Trying to click context menu item: $item")
|
||||
mDevice.findObject(text(item)).click()
|
||||
Log.i(TAG, "clickContextMenuItem: Clicked context menu item: $item")
|
||||
}
|
||||
|
||||
fun setPageObjectText(webPageItem: UiObject, text: String) {
|
||||
for (i in 1..RETRY_COUNT) {
|
||||
Log.i(TAG, "setPageObjectText: Started try #$i")
|
||||
try {
|
||||
webPageItem.also {
|
||||
Log.i(TAG, "setPageObjectText: Waiting for $waitingTime ms for ${webPageItem.selector} to exist")
|
||||
it.waitForExists(waitingTime)
|
||||
Log.i(TAG, "setPageObjectText: Waited for $waitingTime ms for ${webPageItem.selector} to exist")
|
||||
Log.i(TAG, "setPageObjectText: Trying to clear ${webPageItem.selector} text field")
|
||||
it.clearTextField()
|
||||
Log.i(TAG, "setPageObjectText: Cleared ${webPageItem.selector} text field")
|
||||
Log.i(TAG, "setPageObjectText: Trying to set ${webPageItem.selector} text to $text")
|
||||
it.text = text
|
||||
Log.i(TAG, "setPageObjectText: ${webPageItem.selector} text was set to $text")
|
||||
}
|
||||
|
||||
break
|
||||
} catch (e: UiObjectNotFoundException) {
|
||||
Log.i(TAG, "setPageObjectText: UiObjectNotFoundException caught, executing fallback methods")
|
||||
if (i == RETRY_COUNT) {
|
||||
throw e
|
||||
} else {
|
||||
|
@ -1304,8 +1429,12 @@ fun setPageObjectText(webPageItem: UiObject, text: String) {
|
|||
}
|
||||
|
||||
fun clearTextFieldItem(item: UiObject) {
|
||||
Log.i(TAG, "clearTextFieldItem: Waiting for $waitingTime ms for ${item.selector} to exist")
|
||||
item.waitForExists(waitingTime)
|
||||
Log.i(TAG, "clearTextFieldItem: Waited for $waitingTime ms for ${item.selector} to exist")
|
||||
Log.i(TAG, "clearTextFieldItem: Trying to clear ${item.selector} text field")
|
||||
item.clearTextField()
|
||||
Log.i(TAG, "clearTextFieldItem: Cleared ${item.selector} text field")
|
||||
}
|
||||
|
||||
// Context menu items
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
package org.mozilla.fenix.ui.robots
|
||||
|
||||
import android.util.Log
|
||||
import androidx.compose.ui.test.assertIsDisplayed
|
||||
import androidx.compose.ui.test.hasContentDescription
|
||||
import androidx.compose.ui.test.hasText
|
||||
|
@ -17,10 +18,10 @@ import androidx.test.espresso.action.ViewActions.pressImeActionButton
|
|||
import androidx.test.espresso.matcher.RootMatchers
|
||||
import androidx.test.espresso.matcher.ViewMatchers.withId
|
||||
import androidx.test.uiautomator.By
|
||||
import androidx.test.uiautomator.UiScrollable
|
||||
import androidx.test.uiautomator.UiSelector
|
||||
import androidx.test.uiautomator.Until
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.helpers.Constants.TAG
|
||||
import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource
|
||||
import org.mozilla.fenix.helpers.MatcherHelper.assertItemTextEquals
|
||||
import org.mozilla.fenix.helpers.MatcherHelper.assertUIObjectExists
|
||||
|
@ -46,29 +47,45 @@ class CollectionRobot {
|
|||
itemWithResId("$packageName:id/collections_list"),
|
||||
)
|
||||
|
||||
fun clickAddNewCollection() = addNewCollectionButton().click()
|
||||
fun clickAddNewCollection() {
|
||||
Log.i(TAG, "clickAddNewCollection: Trying to click the add new collection button")
|
||||
addNewCollectionButton().click()
|
||||
Log.i(TAG, "clickAddNewCollection: Clicked the add new collection button")
|
||||
}
|
||||
|
||||
fun verifyCollectionNameTextField() = assertUIObjectExists(mainMenuEditCollectionNameField())
|
||||
|
||||
// names a collection saved from tab drawer
|
||||
fun typeCollectionNameAndSave(collectionName: String) {
|
||||
Log.i(TAG, "typeCollectionNameAndSave: Trying to set collection name text field to: $collectionName")
|
||||
collectionNameTextField().text = collectionName
|
||||
addCollectionButtonPanel.waitForExists(waitingTime)
|
||||
addCollectionOkButton.click()
|
||||
Log.i(TAG, "typeCollectionNameAndSave: Collection name text field set to: $collectionName")
|
||||
Log.i(TAG, "typeCollectionNameAndSave: Waiting for $waitingTime ms for add collection button panel to exist")
|
||||
addCollectionButtonPanel().waitForExists(waitingTime)
|
||||
Log.i(TAG, "typeCollectionNameAndSave: Waited for $waitingTime ms for add collection button panel to exist")
|
||||
Log.i(TAG, "typeCollectionNameAndSave: Trying to click \"OK\" panel button")
|
||||
addCollectionOkButton().click()
|
||||
Log.i(TAG, "typeCollectionNameAndSave: Clicked \"OK\" panel button")
|
||||
}
|
||||
|
||||
fun verifyTabsSelectedCounterText(numOfTabs: Int) {
|
||||
Log.i(TAG, "verifyTabsSelectedCounterText: Waiting for $waitingTime ms for \"Select tabs to save\" prompt to be gone")
|
||||
itemWithText("Select tabs to save").waitUntilGone(waitingTime)
|
||||
Log.i(TAG, "verifyTabsSelectedCounterText: Waited for $waitingTime ms for \"Select tabs to save\" prompt to be gone")
|
||||
|
||||
val tabsCounter = mDevice.findObject(UiSelector().resourceId("$packageName:id/bottom_bar_text"))
|
||||
Log.i(TAG, "verifyTabsSelectedCounterText: Trying to assert that number of tabs selected is: $numOfTabs")
|
||||
when (numOfTabs) {
|
||||
1 -> assertItemTextEquals(tabsCounter, expectedText = "$numOfTabs tab selected")
|
||||
2 -> assertItemTextEquals(tabsCounter, expectedText = "$numOfTabs tabs selected")
|
||||
}
|
||||
Log.i(TAG, "verifyTabsSelectedCounterText: Asserted number of tabs selected is: $numOfTabs")
|
||||
}
|
||||
|
||||
fun saveTabsSelectedForCollection() {
|
||||
mDevice.findObject(UiSelector().resourceId("$packageName:id/save_button")).click()
|
||||
Log.i(TAG, "saveTabsSelectedForCollection: Trying to click \"Save\" button")
|
||||
itemWithResId("$packageName:id/save_button").click()
|
||||
Log.i(TAG, "saveTabsSelectedForCollection: Clicked \"Save\" button")
|
||||
}
|
||||
|
||||
fun verifyTabSavedInCollection(title: String, visible: Boolean = true) {
|
||||
|
@ -88,83 +105,114 @@ class CollectionRobot {
|
|||
|
||||
fun verifyCollectionMenuIsVisible(visible: Boolean, rule: ComposeTestRule) {
|
||||
if (visible) {
|
||||
collectionThreeDotButton(rule)
|
||||
.assertExists()
|
||||
.assertIsDisplayed()
|
||||
Log.i(TAG, "verifyCollectionMenuIsVisible: Trying to verify collection three dot button exists")
|
||||
collectionThreeDotButton(rule).assertExists()
|
||||
Log.i(TAG, "verifyCollectionMenuIsVisible: Verified collection three dot button exists")
|
||||
Log.i(TAG, "verifyCollectionMenuIsVisible: Trying to verify collection three dot button is displayed")
|
||||
collectionThreeDotButton(rule).assertIsDisplayed()
|
||||
Log.i(TAG, "verifyCollectionMenuIsVisible: Verified collection three dot button is displayed")
|
||||
} else {
|
||||
Log.i(TAG, "verifyCollectionMenuIsVisible: Trying to verify collection three dot button does not exist")
|
||||
collectionThreeDotButton(rule)
|
||||
.assertDoesNotExist()
|
||||
Log.i(TAG, "verifyCollectionMenuIsVisible: Verified collection three dot button does not exist")
|
||||
}
|
||||
}
|
||||
|
||||
fun clickCollectionThreeDotButton(rule: ComposeTestRule) {
|
||||
collectionThreeDotButton(rule)
|
||||
.assertIsDisplayed()
|
||||
.performClick()
|
||||
Log.i(TAG, "clickCollectionThreeDotButton: Trying to verify three dot button is displayed")
|
||||
collectionThreeDotButton(rule).assertIsDisplayed()
|
||||
Log.i(TAG, "clickCollectionThreeDotButton: Verified three dot button is displayed")
|
||||
Log.i(TAG, "clickCollectionThreeDotButton: Trying to click three dot button")
|
||||
collectionThreeDotButton(rule).performClick()
|
||||
Log.i(TAG, "clickCollectionThreeDotButton: Clicked three dot button")
|
||||
}
|
||||
|
||||
fun selectOpenTabs(rule: ComposeTestRule) {
|
||||
rule.onNode(hasText("Open tabs"))
|
||||
.assertIsDisplayed()
|
||||
.performClick()
|
||||
Log.i(TAG, "selectOpenTabs: Trying to verify \"Open tabs\" menu option is displayed")
|
||||
rule.onNode(hasText("Open tabs")).assertIsDisplayed()
|
||||
Log.i(TAG, "selectOpenTabs: Verified \"Open tabs\" menu option is displayed")
|
||||
Log.i(TAG, "selectOpenTabs: Trying to click \"Open tabs\" menu option")
|
||||
rule.onNode(hasText("Open tabs")).performClick()
|
||||
Log.i(TAG, "selectOpenTabs: Clicked \"Open tabs\" menu option")
|
||||
}
|
||||
|
||||
fun selectRenameCollection(rule: ComposeTestRule) {
|
||||
rule.onNode(hasText("Rename collection"))
|
||||
.assertIsDisplayed()
|
||||
.performClick()
|
||||
Log.i(TAG, "selectRenameCollection: Trying to verify \"Rename collection\" menu option is displayed")
|
||||
rule.onNode(hasText("Rename collection")).assertIsDisplayed()
|
||||
Log.i(TAG, "selectRenameCollection: Verified \"Rename collection\" menu option is displayed")
|
||||
Log.i(TAG, "selectRenameCollection: Trying to click \"Rename collection\" menu option")
|
||||
rule.onNode(hasText("Rename collection")).performClick()
|
||||
Log.i(TAG, "selectRenameCollection: Clicked \"Rename collection\" menu option")
|
||||
Log.i(TAG, "selectRenameCollection: Waiting for $waitingTime ms for collection name text field to exist")
|
||||
mainMenuEditCollectionNameField().waitForExists(waitingTime)
|
||||
Log.i(TAG, "selectRenameCollection: Waited for $waitingTime ms for collection name text field to exist")
|
||||
}
|
||||
|
||||
fun selectAddTabToCollection(rule: ComposeTestRule) {
|
||||
rule.onNode(hasText("Add tab"))
|
||||
.assertIsDisplayed()
|
||||
.performClick()
|
||||
Log.i(TAG, "selectAddTabToCollection: Trying to verify \"Add tab\" menu option is displayed")
|
||||
rule.onNode(hasText("Add tab")).assertIsDisplayed()
|
||||
Log.i(TAG, "selectAddTabToCollection: Verified \"Add tab\" menu option is displayed")
|
||||
Log.i(TAG, "selectAddTabToCollection: Trying to click \"Add tab\" menu option")
|
||||
rule.onNode(hasText("Add tab")).performClick()
|
||||
Log.i(TAG, "selectAddTabToCollection: Clicked \"Add tab\" menu option")
|
||||
|
||||
mDevice.waitNotNull(Until.findObject(By.text("Select Tabs")))
|
||||
}
|
||||
|
||||
fun selectDeleteCollection(rule: ComposeTestRule) {
|
||||
rule.onNode(hasText("Delete collection"))
|
||||
.assertIsDisplayed()
|
||||
.performClick()
|
||||
Log.i(TAG, "selectDeleteCollection: Trying to verify \"Delete collection\" menu option is displayed")
|
||||
rule.onNode(hasText("Delete collection")).assertIsDisplayed()
|
||||
Log.i(TAG, "selectDeleteCollection: Verified \"Delete collection\" menu option is displayed")
|
||||
Log.i(TAG, "selectDeleteCollection: Trying to click \"Delete collection\" menu option")
|
||||
rule.onNode(hasText("Delete collection")).performClick()
|
||||
Log.i(TAG, "selectDeleteCollection: Clicked \"Delete collection\" menu option")
|
||||
}
|
||||
|
||||
fun verifyCollectionItemRemoveButtonIsVisible(title: String, visible: Boolean) =
|
||||
assertUIObjectExists(removeTabFromCollectionButton(title), exists = visible)
|
||||
|
||||
fun removeTabFromCollection(title: String) = removeTabFromCollectionButton(title).click()
|
||||
fun removeTabFromCollection(title: String) {
|
||||
Log.i(TAG, "removeTabFromCollection: Trying to click remove button for tab: $title")
|
||||
removeTabFromCollectionButton(title).click()
|
||||
Log.i(TAG, "removeTabFromCollection: Clicked remove button for tab: $title")
|
||||
}
|
||||
|
||||
fun swipeTabLeft(title: String, rule: ComposeTestRule) {
|
||||
Log.i(TAG, "swipeTabLeft: Trying to remove tab: $title using swipe left action")
|
||||
rule.onNode(hasText(title), useUnmergedTree = true)
|
||||
.performTouchInput { swipeLeft() }
|
||||
Log.i(TAG, "swipeTabLeft: Removed tab: $title using swipe left action")
|
||||
Log.i(TAG, "swipeTabLeft: Waiting for rule to be idle")
|
||||
rule.waitForIdle()
|
||||
Log.i(TAG, "swipeTabLeft: Waited for rule to be idle")
|
||||
}
|
||||
|
||||
fun swipeTabRight(title: String, rule: ComposeTestRule) {
|
||||
Log.i(TAG, "swipeTabRight: Trying to remove tab: $title using swipe right action")
|
||||
rule.onNode(hasText(title), useUnmergedTree = true)
|
||||
.performTouchInput { swipeRight() }
|
||||
Log.i(TAG, "swipeTabRight: Removed tab: $title using swipe right action")
|
||||
Log.i(TAG, "swipeTabRight: Waiting for rule to be idle")
|
||||
rule.waitForIdle()
|
||||
Log.i(TAG, "swipeTabRight: Waited for rule to be idle")
|
||||
}
|
||||
|
||||
fun verifySnackBarText(expectedText: String) {
|
||||
mDevice.findObject(UiSelector().text(expectedText)).waitForExists(waitingTime)
|
||||
fun goBackInCollectionFlow() {
|
||||
Log.i(TAG, "goBackInCollectionFlow: Trying to click collection creation flow back button")
|
||||
backButton().click()
|
||||
Log.i(TAG, "goBackInCollectionFlow: Clicked collection creation flow back button")
|
||||
}
|
||||
|
||||
fun goBackInCollectionFlow() = backButton().click()
|
||||
|
||||
fun swipeToBottom() =
|
||||
UiScrollable(
|
||||
UiSelector().resourceId("$packageName:id/sessionControlRecyclerView"),
|
||||
).scrollToEnd(3)
|
||||
|
||||
class Transition {
|
||||
fun collapseCollection(
|
||||
title: String,
|
||||
interact: HomeScreenRobot.() -> Unit,
|
||||
): HomeScreenRobot.Transition {
|
||||
assertUIObjectExists(itemContainingText(title))
|
||||
Log.i(TAG, "collapseCollection: Trying to click collection $title and wait for $waitingTimeShort ms for a new window")
|
||||
itemContainingText(title).clickAndWaitForNewWindow(waitingTimeShort)
|
||||
Log.i(TAG, "collapseCollection: Clicked collection $title and waited for $waitingTimeShort ms for a new window")
|
||||
assertUIObjectExists(itemWithDescription(getStringResource(R.string.remove_tab_from_collection)), exists = false)
|
||||
|
||||
HomeScreenRobot().interact()
|
||||
|
@ -176,9 +224,15 @@ class CollectionRobot {
|
|||
name: String,
|
||||
interact: BrowserRobot.() -> Unit,
|
||||
): BrowserRobot.Transition {
|
||||
Log.i(TAG, "typeCollectionNameAndSave: Waiting for $waitingTime ms for collection name text field to exist")
|
||||
mainMenuEditCollectionNameField().waitForExists(waitingTime)
|
||||
Log.i(TAG, "typeCollectionNameAndSave: Waited for $waitingTime ms for collection name text field to exist")
|
||||
Log.i(TAG, "typeCollectionNameAndSave: Trying to set collection name text field to: $name")
|
||||
mainMenuEditCollectionNameField().text = name
|
||||
Log.i(TAG, "typeCollectionNameAndSave: Collection name text field set to: $name")
|
||||
Log.i(TAG, "typeCollectionNameAndSave: Trying to press done action button")
|
||||
onView(withId(R.id.name_collection_edittext)).perform(pressImeActionButton())
|
||||
Log.i(TAG, "typeCollectionNameAndSave: Pressed done action button")
|
||||
|
||||
// wait for the collection creation wrapper to be dismissed
|
||||
mDevice.waitNotNull(Until.gone(By.res("$packageName:id/createCollectionWrapper")))
|
||||
|
@ -191,16 +245,24 @@ class CollectionRobot {
|
|||
title: String,
|
||||
interact: BrowserRobot.() -> Unit,
|
||||
): BrowserRobot.Transition {
|
||||
Log.i(TAG, "selectExistingCollection: Waiting for $waitingTime ms for collection with title: $title to exist")
|
||||
collectionTitle(title).waitForExists(waitingTime)
|
||||
Log.i(TAG, "selectExistingCollection: Waited for $waitingTime ms for collection with title: $title to exist")
|
||||
Log.i(TAG, "selectExistingCollection: Trying to click collection with title: $title")
|
||||
collectionTitle(title).click()
|
||||
Log.i(TAG, "selectExistingCollection: Clicked collection with title: $title")
|
||||
|
||||
BrowserRobot().interact()
|
||||
return BrowserRobot.Transition()
|
||||
}
|
||||
|
||||
fun clickShareCollectionButton(interact: ShareOverlayRobot.() -> Unit): ShareOverlayRobot.Transition {
|
||||
Log.i(TAG, "clickShareCollectionButton: Waiting for $waitingTime ms for share collection button to exist")
|
||||
shareCollectionButton().waitForExists(waitingTime)
|
||||
Log.i(TAG, "clickShareCollectionButton: Waited for $waitingTime ms for share collection button to exist")
|
||||
Log.i(TAG, "clickShareCollectionButton: Trying to click share collection button")
|
||||
shareCollectionButton().click()
|
||||
Log.i(TAG, "clickShareCollectionButton: Clicked share collection button")
|
||||
|
||||
ShareOverlayRobot().interact()
|
||||
return ShareOverlayRobot.Transition()
|
||||
|
@ -213,21 +275,14 @@ fun collectionRobot(interact: CollectionRobot.() -> Unit): CollectionRobot.Trans
|
|||
return CollectionRobot.Transition()
|
||||
}
|
||||
|
||||
private fun collectionTitle(title: String) =
|
||||
mDevice.findObject(
|
||||
UiSelector()
|
||||
.text(title),
|
||||
)
|
||||
private fun collectionTitle(title: String) = itemWithText(title)
|
||||
|
||||
private fun collectionThreeDotButton(rule: ComposeTestRule) =
|
||||
rule.onNode(hasContentDescription("Collection menu"))
|
||||
|
||||
private fun collectionListItem(title: String) = mDevice.findObject(UiSelector().text(title))
|
||||
|
||||
private fun shareCollectionButton() =
|
||||
mDevice.findObject(
|
||||
UiSelector().description("Share"),
|
||||
)
|
||||
private fun shareCollectionButton() = itemWithDescription("Share")
|
||||
|
||||
private fun removeTabFromCollectionButton(title: String) =
|
||||
mDevice.findObject(
|
||||
|
@ -245,9 +300,7 @@ private fun collectionNameTextField() =
|
|||
|
||||
// collection name text field, when saving from the main menu option
|
||||
private fun mainMenuEditCollectionNameField() =
|
||||
mDevice.findObject(
|
||||
UiSelector().resourceId("$packageName:id/name_collection_edittext"),
|
||||
)
|
||||
itemWithResId("$packageName:id/name_collection_edittext")
|
||||
|
||||
private fun addNewCollectionButton() =
|
||||
mDevice.findObject(UiSelector().text("Add new collection"))
|
||||
|
@ -256,7 +309,7 @@ private fun backButton() =
|
|||
mDevice.findObject(
|
||||
UiSelector().resourceId("$packageName:id/back_button"),
|
||||
)
|
||||
private val addCollectionButtonPanel =
|
||||
private fun addCollectionButtonPanel() =
|
||||
itemWithResId("$packageName:id/buttonPanel")
|
||||
|
||||
private val addCollectionOkButton = onView(withId(android.R.id.button1)).inRoot(RootMatchers.isDialog())
|
||||
private fun addCollectionOkButton() = onView(withId(android.R.id.button1)).inRoot(RootMatchers.isDialog())
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
package org.mozilla.fenix.ui.robots
|
||||
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import androidx.compose.ui.semantics.SemanticsActions
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
|
@ -42,12 +43,13 @@ import com.google.android.material.bottomsheet.BottomSheetBehavior
|
|||
import org.hamcrest.Matcher
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.helpers.Constants
|
||||
import org.mozilla.fenix.helpers.Constants.TAG
|
||||
import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource
|
||||
import org.mozilla.fenix.helpers.HomeActivityComposeTestRule
|
||||
import org.mozilla.fenix.helpers.MatcherHelper.assertUIObjectExists
|
||||
import org.mozilla.fenix.helpers.MatcherHelper.itemContainingText
|
||||
import org.mozilla.fenix.helpers.TestAssetHelper
|
||||
import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime
|
||||
import org.mozilla.fenix.helpers.TestAssetHelper.waitingTimeShort
|
||||
import org.mozilla.fenix.helpers.TestHelper.mDevice
|
||||
import org.mozilla.fenix.helpers.clickAtLocationInView
|
||||
import org.mozilla.fenix.helpers.idlingresource.BottomSheetBehaviorStateIdlingResource
|
||||
|
@ -62,25 +64,37 @@ class ComposeTabDrawerRobot(private val composeTestRule: HomeActivityComposeTest
|
|||
|
||||
fun verifyNormalBrowsingButtonIsSelected(isSelected: Boolean = true) {
|
||||
if (isSelected) {
|
||||
Log.i(TAG, "verifyNormalBrowsingButtonIsSelected: Trying to verify that the normal browsing button is selected")
|
||||
composeTestRule.normalBrowsingButton().assertIsSelected()
|
||||
Log.i(TAG, "verifyNormalBrowsingButtonIsSelected: Verified that the normal browsing button is selected")
|
||||
} else {
|
||||
Log.i(TAG, "verifyNormalBrowsingButtonIsSelected: Trying to verify that the normal browsing button is not selected")
|
||||
composeTestRule.normalBrowsingButton().assertIsNotSelected()
|
||||
Log.i(TAG, "verifyNormalBrowsingButtonIsSelected: Verified that the normal browsing button is not selected")
|
||||
}
|
||||
}
|
||||
|
||||
fun verifyPrivateBrowsingButtonIsSelected(isSelected: Boolean = true) {
|
||||
if (isSelected) {
|
||||
Log.i(TAG, "verifyPrivateBrowsingButtonIsSelected: Trying to verify that the private browsing button is selected")
|
||||
composeTestRule.privateBrowsingButton().assertIsSelected()
|
||||
Log.i(TAG, "verifyPrivateBrowsingButtonIsSelected: Verified that the private browsing button is selected")
|
||||
} else {
|
||||
Log.i(TAG, "verifyPrivateBrowsingButtonIsSelected: Trying to verify that the private browsing button is not selected")
|
||||
composeTestRule.privateBrowsingButton().assertIsNotSelected()
|
||||
Log.i(TAG, "verifyPrivateBrowsingButtonIsSelected: Verified that the private browsing button is not selected")
|
||||
}
|
||||
}
|
||||
|
||||
fun verifySyncedTabsButtonIsSelected(isSelected: Boolean = true) {
|
||||
if (isSelected) {
|
||||
Log.i(TAG, "verifySyncedTabsButtonIsSelected: Trying to verify that the synced tabs button is selected")
|
||||
composeTestRule.syncedTabsButton().assertIsSelected()
|
||||
Log.i(TAG, "verifySyncedTabsButtonIsSelected: Verified that the synced tabs button is selected")
|
||||
} else {
|
||||
Log.i(TAG, "verifySyncedTabsButtonIsSelected: Trying to verify that the synced tabs button is not selected")
|
||||
composeTestRule.syncedTabsButton().assertIsNotSelected()
|
||||
Log.i(TAG, "verifySyncedTabsButtonIsSelected: Verified that the synced tabs button is not selected")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -95,16 +109,23 @@ class ComposeTabDrawerRobot(private val composeTestRule: HomeActivityComposeTest
|
|||
|
||||
fun verifyExistingOpenTabs(vararg titles: String) {
|
||||
titles.forEach { title ->
|
||||
Log.i(TAG, "verifyExistingOpenTabs: Waiting for $waitingTime ms for tab with title: $title to exist")
|
||||
itemContainingText(title).waitForExists(waitingTime)
|
||||
Log.i(TAG, "verifyExistingOpenTabs: Waited for $waitingTime ms for tab with title: $title to exist")
|
||||
Log.i(TAG, "verifyExistingOpenTabs: Trying to verify that the open tab with title: $title exists")
|
||||
composeTestRule.tabItem(title).assertExists()
|
||||
Log.i(TAG, "verifyExistingOpenTabs: Verified that the open tab with title: $title exists")
|
||||
}
|
||||
}
|
||||
|
||||
fun verifyOpenTabsOrder(title: String, position: Int) =
|
||||
fun verifyOpenTabsOrder(title: String, position: Int) {
|
||||
Log.i(TAG, "verifyOpenTabsOrder: Trying to verify that the open tab at position: $position has title: $title")
|
||||
composeTestRule.normalTabsList()
|
||||
.onChildAt(position - 1)
|
||||
.assert(hasTestTag(TabsTrayTestTag.tabItemRoot))
|
||||
.assert(hasAnyChild(hasText(title)))
|
||||
Log.i(TAG, "verifyOpenTabsOrder: Verified that the open tab at position: $position has title: $title")
|
||||
}
|
||||
|
||||
fun verifyNoExistingOpenTabs(vararg titles: String) {
|
||||
titles.forEach { title ->
|
||||
|
@ -116,110 +137,163 @@ class ComposeTabDrawerRobot(private val composeTestRule: HomeActivityComposeTest
|
|||
}
|
||||
|
||||
fun verifyNormalTabsList() {
|
||||
Log.i(TAG, "verifyNormalTabsList: Trying to verify that the normal tabs list exists")
|
||||
composeTestRule.normalTabsList().assertExists()
|
||||
Log.i(TAG, "verifyNormalTabsList: Verified that the normal tabs list exists")
|
||||
}
|
||||
|
||||
fun verifyPrivateTabsList() {
|
||||
Log.i(TAG, "verifyPrivateTabsList: Trying to verify that the private tabs list exists")
|
||||
composeTestRule.privateTabsList().assertExists()
|
||||
Log.i(TAG, "verifyPrivateTabsList: Verified that the private tabs list exists")
|
||||
}
|
||||
|
||||
fun verifySyncedTabsList() {
|
||||
Log.i(TAG, "verifySyncedTabsList: Trying to verify that the synced tabs list exists")
|
||||
composeTestRule.syncedTabsList().assertExists()
|
||||
Log.i(TAG, "verifySyncedTabsList: Verified that the synced tabs list exists")
|
||||
}
|
||||
|
||||
fun verifyNoOpenTabsInNormalBrowsing() {
|
||||
Log.i(TAG, "verifyNoOpenTabsInNormalBrowsing: Trying to verify that the empty normal tabs list exists")
|
||||
composeTestRule.emptyNormalTabsList().assertExists()
|
||||
Log.i(TAG, "verifyNoOpenTabsInNormalBrowsing: Verified that the empty normal tabs list exists")
|
||||
}
|
||||
|
||||
fun verifyNoOpenTabsInPrivateBrowsing() {
|
||||
Log.i(TAG, "verifyNoOpenTabsInPrivateBrowsing: Trying to verify that the empty private tabs list exists")
|
||||
composeTestRule.emptyPrivateTabsList().assertExists()
|
||||
Log.i(TAG, "verifyNoOpenTabsInPrivateBrowsing: Verified that the empty private tabs list exists")
|
||||
}
|
||||
|
||||
fun verifyAccountSettingsButton() {
|
||||
Log.i(TAG, "verifyAccountSettingsButton: Trying to verify that the \"Account settings\" menu button exists")
|
||||
composeTestRule.dropdownMenuItemAccountSettings().assertExists()
|
||||
Log.i(TAG, "verifyAccountSettingsButton: Verified that the \"Account settings\" menu button exists")
|
||||
}
|
||||
|
||||
fun verifyCloseAllTabsButton() {
|
||||
Log.i(TAG, "verifyCloseAllTabsButton: Trying to verify that the \"Close all tabs\" menu button exists")
|
||||
composeTestRule.dropdownMenuItemCloseAllTabs().assertExists()
|
||||
Log.i(TAG, "verifyCloseAllTabsButton: Verified that the \"Close all tabs\" menu button exists")
|
||||
}
|
||||
|
||||
fun verifySelectTabsButton() {
|
||||
Log.i(TAG, "verifySelectTabsButton: Trying to verify that the \"Select tabs\" menu button exists")
|
||||
composeTestRule.dropdownMenuItemSelectTabs().assertExists()
|
||||
Log.i(TAG, "verifySelectTabsButton: Verified that the \"Select tabs\" menu button exists")
|
||||
}
|
||||
|
||||
fun verifyShareAllTabsButton() {
|
||||
Log.i(TAG, "verifyShareAllTabsButton: Trying to verify that the \"Share all tabs\" menu button exists")
|
||||
composeTestRule.dropdownMenuItemShareAllTabs().assertExists()
|
||||
Log.i(TAG, "verifyShareAllTabsButton: Verified that the \"Share all tabs\" menu button exists")
|
||||
}
|
||||
|
||||
fun verifyRecentlyClosedTabsButton() {
|
||||
Log.i(TAG, "verifyRecentlyClosedTabsButton: Trying to verify that the \"Recently closed tabs\" menu button exists")
|
||||
composeTestRule.dropdownMenuItemRecentlyClosedTabs().assertExists()
|
||||
Log.i(TAG, "verifyRecentlyClosedTabsButton: Verified that the \"Recently closed tabs\" menu button exists")
|
||||
}
|
||||
|
||||
fun verifyTabSettingsButton() {
|
||||
Log.i(TAG, "verifyTabSettingsButton: Trying to verify that the \"Tab settings\" menu button exists")
|
||||
composeTestRule.dropdownMenuItemTabSettings().assertExists()
|
||||
Log.i(TAG, "verifyTabSettingsButton: Verified that the \"Tab settings\" menu button exists")
|
||||
}
|
||||
|
||||
fun verifyThreeDotButton() {
|
||||
Log.i(TAG, "verifyThreeDotButton: Trying to verify that the three dot button exists")
|
||||
composeTestRule.threeDotButton().assertExists()
|
||||
Log.i(TAG, "verifyThreeDotButton: Verified that the three dot button exists")
|
||||
}
|
||||
|
||||
fun verifyFab() {
|
||||
Log.i(TAG, "verifyFab: Trying to verify that the new tab FAB button exists")
|
||||
composeTestRule.tabsTrayFab().assertExists()
|
||||
Log.i(TAG, "verifyFab: Verified that the new tab FAB button exists")
|
||||
}
|
||||
|
||||
fun verifyNormalTabCounter() {
|
||||
Log.i(TAG, "verifyNormalTabCounter: Trying to verify that the normal tabs list counter exists")
|
||||
composeTestRule.normalTabsCounter().assertExists()
|
||||
Log.i(TAG, "verifyNormalTabCounter: Verified that the normal tabs list counter exists")
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies a tab's thumbnail when there is only one tab open.
|
||||
*/
|
||||
fun verifyTabThumbnail() {
|
||||
Log.i(TAG, "verifyTabThumbnail: Trying to verify that the tab thumbnail exists")
|
||||
composeTestRule.tabThumbnail().assertExists()
|
||||
Log.i(TAG, "verifyTabThumbnail: Verified that the tab thumbnail exists")
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies a tab's close button when there is only one tab open.
|
||||
*/
|
||||
fun verifyTabCloseButton() {
|
||||
Log.i(TAG, "verifyTabCloseButton: Trying to verify that the close tab button exists")
|
||||
composeTestRule.closeTabButton().assertExists()
|
||||
Log.i(TAG, "verifyTabCloseButton: Verified that the close tab button exists")
|
||||
}
|
||||
|
||||
fun verifyTabsTrayBehaviorState(expectedState: Int) {
|
||||
Log.i(TAG, "verifyTabsTrayBehaviorState: Trying to verify that the tabs tray state matches: $expectedState")
|
||||
tabsTrayView().check(ViewAssertions.matches(BottomSheetBehaviorStateMatcher(expectedState)))
|
||||
Log.i(TAG, "verifyTabsTrayBehaviorState: Verified that the tabs tray state matches: $expectedState")
|
||||
}
|
||||
|
||||
fun verifyMinusculeHalfExpandedRatio() {
|
||||
Log.i(TAG, "verifyMinusculeHalfExpandedRatio: Trying to verify the tabs tray half expanded ratio")
|
||||
tabsTrayView().check(ViewAssertions.matches(BottomSheetBehaviorHalfExpandedMaxRatioMatcher(0.001f)))
|
||||
Log.i(TAG, "verifyMinusculeHalfExpandedRatio: Verified the tabs tray half expanded ratio")
|
||||
}
|
||||
|
||||
fun verifyTabTrayIsOpen() {
|
||||
Log.i(TAG, "verifyTabTrayIsOpen: Trying to verify that the tabs tray exists")
|
||||
composeTestRule.tabsTray().assertExists()
|
||||
Log.i(TAG, "verifyTabTrayIsOpen: Verified that the tabs tray exists")
|
||||
}
|
||||
|
||||
fun verifyTabTrayIsClosed() {
|
||||
Log.i(TAG, "verifyTabTrayIsClosed: Trying to verify that the tabs tray does not exist")
|
||||
composeTestRule.tabsTray().assertDoesNotExist()
|
||||
Log.i(TAG, "verifyTabTrayIsClosed: Verified that the tabs tray does not exist")
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes a tab when there is only one tab open.
|
||||
*/
|
||||
@OptIn(ExperimentalTestApi::class)
|
||||
fun closeTab() {
|
||||
Log.i(TAG, "closeTab: Waiting until the close tab button exists")
|
||||
composeTestRule.waitUntilAtLeastOneExists(hasTestTag(TabsTrayTestTag.tabItemClose))
|
||||
Log.i(TAG, "closeTab: Waited until the close tab button exists")
|
||||
Log.i(TAG, "closeTab: Trying to verify that the close tab button exists")
|
||||
composeTestRule.closeTabButton().assertExists()
|
||||
Log.i(TAG, "closeTab: Verified that the close tab button exists")
|
||||
Log.i(TAG, "closeTab: Trying to click the close tab button")
|
||||
composeTestRule.closeTabButton().performClick()
|
||||
Log.i(TAG, "closeTab: Clicked the close tab button")
|
||||
}
|
||||
|
||||
/**
|
||||
* Swipes a tab with [title] left.
|
||||
*/
|
||||
fun swipeTabLeft(title: String) {
|
||||
Log.i(TAG, "swipeTabLeft: Trying to perform swipe left action on tab: $title")
|
||||
composeTestRule.tabItem(title).performTouchInput { swipeLeft() }
|
||||
Log.i(TAG, "swipeTabLeft: Performed swipe left action on tab: $title")
|
||||
}
|
||||
|
||||
/**
|
||||
* Swipes a tab with [title] right.
|
||||
*/
|
||||
fun swipeTabRight(title: String) {
|
||||
Log.i(TAG, "swipeTabRight: Trying to perform swipe right action on tab: $title")
|
||||
composeTestRule.tabItem(title).performTouchInput { swipeRight() }
|
||||
Log.i(TAG, "swipeTabRight: Performed swipe right action on tab: $title")
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -230,8 +304,12 @@ class ComposeTabDrawerRobot(private val composeTestRule: HomeActivityComposeTest
|
|||
collectionName: String,
|
||||
firstCollection: Boolean = true,
|
||||
) {
|
||||
Log.i(TAG, "createCollection: Trying to click the three dot button")
|
||||
composeTestRule.threeDotButton().performClick()
|
||||
Log.i(TAG, "createCollection: Clicked the three dot button")
|
||||
Log.i(TAG, "createCollection: Trying to click the \"Select tabs\" menu button")
|
||||
composeTestRule.dropdownMenuItemSelectTabs().performClick()
|
||||
Log.i(TAG, "createCollection: Clicked the \"Select tabs\" menu button")
|
||||
|
||||
for (tab in tabTitles) {
|
||||
selectTab(tab)
|
||||
|
@ -250,24 +328,32 @@ class ComposeTabDrawerRobot(private val composeTestRule: HomeActivityComposeTest
|
|||
*/
|
||||
@OptIn(ExperimentalTestApi::class)
|
||||
fun selectTab(title: String) {
|
||||
composeTestRule.waitUntilExactlyOneExists(hasText(title), TestAssetHelper.waitingTime)
|
||||
Log.i(TAG, "selectTab: Waiting for $waitingTime ms until the tab with title: $title exists")
|
||||
composeTestRule.waitUntilExactlyOneExists(hasText(title), waitingTime)
|
||||
Log.i(TAG, "selectTab: Waited for $waitingTime ms until the tab with title: $title exists")
|
||||
Log.i(TAG, "selectTab: Trying to click tab with title: $title")
|
||||
composeTestRule.tabItem(title).performClick()
|
||||
Log.i(TAG, "selectTab: Clicked tab with title: $title")
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a long click on a tab with [title].
|
||||
*/
|
||||
fun longClickTab(title: String) {
|
||||
Log.i(TAG, "longClickTab: Trying to long click tab with title: $title")
|
||||
composeTestRule.tabItem(title)
|
||||
.performTouchInput { longClick(durationMillis = Constants.LONG_CLICK_DURATION) }
|
||||
Log.i(TAG, "longClickTab: Long clicked tab with title: $title")
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies the multi selection counter displays [numOfTabs].
|
||||
*/
|
||||
fun verifyTabsMultiSelectionCounter(numOfTabs: Int) {
|
||||
Log.i(TAG, "verifyTabsMultiSelectionCounter: Trying to verify that $numOfTabs tabs are selected")
|
||||
composeTestRule.multiSelectionCounter()
|
||||
.assert(hasText("$numOfTabs selected"))
|
||||
Log.i(TAG, "verifyTabsMultiSelectionCounter: Verified that $numOfTabs tabs are selected")
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -275,9 +361,13 @@ class ComposeTabDrawerRobot(private val composeTestRule: HomeActivityComposeTest
|
|||
*/
|
||||
@OptIn(ExperimentalTestApi::class)
|
||||
fun verifyTabMediaControlButtonState(action: String) {
|
||||
Log.i(TAG, "verifyTabMediaControlButtonStateTab: Waiting for $waitingTime ms until the media tab control button: $action exists")
|
||||
composeTestRule.waitUntilAtLeastOneExists(hasContentDescription(action), waitingTime)
|
||||
Log.i(TAG, "verifyTabMediaControlButtonStateTab: Waited for $waitingTime ms until the media tab control button: $action exists")
|
||||
Log.i(TAG, "verifyTabMediaControlButtonStateTab: Trying to verify that the tab media control button: $action exists")
|
||||
composeTestRule.tabMediaControlButton(action)
|
||||
.assertExists()
|
||||
Log.i(TAG, "verifyTabMediaControlButtonStateTab: Verified tab media control button: $action exists")
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -285,90 +375,118 @@ class ComposeTabDrawerRobot(private val composeTestRule: HomeActivityComposeTest
|
|||
*/
|
||||
@OptIn(ExperimentalTestApi::class)
|
||||
fun clickTabMediaControlButton(action: String) {
|
||||
Log.i(TAG, "clickTabMediaControlButton: Waiting for $waitingTime ms until the media tab control button: $action exists")
|
||||
composeTestRule.waitUntilAtLeastOneExists(hasContentDescription(action), waitingTime)
|
||||
Log.i(TAG, "clickTabMediaControlButton: Waited for $waitingTime ms until the media tab control button: $action exists")
|
||||
Log.i(TAG, "clickTabMediaControlButton: Trying to click the tab media control button: $action")
|
||||
composeTestRule.tabMediaControlButton(action)
|
||||
.performClick()
|
||||
Log.i(TAG, "clickTabMediaControlButton: Clicked the tab media control button: $action")
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes a tab with a given [title].
|
||||
*/
|
||||
fun closeTabWithTitle(title: String) {
|
||||
Log.i(TAG, "closeTabWithTitle: Trying to click the close button for tab with title: $title")
|
||||
composeTestRule.onAllNodesWithTag(TabsTrayTestTag.tabItemClose)
|
||||
.filter(hasParent(hasText(title)))
|
||||
.onFirst()
|
||||
.performClick()
|
||||
Log.i(TAG, "closeTabWithTitle: Clicked the close button for tab with title: $title")
|
||||
}
|
||||
|
||||
class Transition(private val composeTestRule: HomeActivityComposeTestRule) {
|
||||
|
||||
fun openNewTab(interact: SearchRobot.() -> Unit): SearchRobot.Transition {
|
||||
Log.i(TAG, "openNewTab: Waiting for device to be idle")
|
||||
mDevice.waitForIdle()
|
||||
|
||||
Log.i(TAG, "openNewTab: Waited for device to be idle")
|
||||
Log.i(TAG, "openNewTab: Trying to click the new tab FAB button")
|
||||
composeTestRule.tabsTrayFab().performClick()
|
||||
Log.i(TAG, "openNewTab: Clicked the new tab FAB button")
|
||||
SearchRobot().interact()
|
||||
return SearchRobot.Transition()
|
||||
}
|
||||
|
||||
fun toggleToNormalTabs(interact: ComposeTabDrawerRobot.() -> Unit): Transition {
|
||||
Log.i(TAG, "toggleToNormalTabs: Trying to click the normal browsing button")
|
||||
composeTestRule.normalBrowsingButton().performClick()
|
||||
Log.i(TAG, "toggleToNormalTabs: Clicked the normal browsing button")
|
||||
ComposeTabDrawerRobot(composeTestRule).interact()
|
||||
return Transition(composeTestRule)
|
||||
}
|
||||
|
||||
fun toggleToPrivateTabs(interact: ComposeTabDrawerRobot.() -> Unit): Transition {
|
||||
Log.i(TAG, "toggleToPrivateTabs: Trying to click the private browsing button")
|
||||
composeTestRule.privateBrowsingButton().performClick()
|
||||
Log.i(TAG, "toggleToPrivateTabs: Clicked the private browsing button")
|
||||
ComposeTabDrawerRobot(composeTestRule).interact()
|
||||
return Transition(composeTestRule)
|
||||
}
|
||||
|
||||
fun toggleToSyncedTabs(interact: ComposeTabDrawerRobot.() -> Unit): Transition {
|
||||
Log.i(TAG, "toggleToSyncedTabs: Trying to click the synced tabs button")
|
||||
composeTestRule.syncedTabsButton().performClick()
|
||||
Log.i(TAG, "toggleToSyncedTabs: Clicked the synced tabs button")
|
||||
ComposeTabDrawerRobot(composeTestRule).interact()
|
||||
return Transition(composeTestRule)
|
||||
}
|
||||
|
||||
fun clickSignInToSyncButton(interact: SyncSignInRobot.() -> Unit): SyncSignInRobot.Transition {
|
||||
Log.i(TAG, "clickSignInToSyncButton: Trying to click the sign in to sync button and wait for $waitingTimeShort ms for a new window")
|
||||
itemContainingText(getStringResource(R.string.sync_sign_in))
|
||||
.clickAndWaitForNewWindow(TestAssetHelper.waitingTimeShort)
|
||||
.clickAndWaitForNewWindow(waitingTimeShort)
|
||||
Log.i(TAG, "clickSignInToSyncButton: Clicked the sign in to sync button and waited for $waitingTimeShort ms for a new window")
|
||||
SyncSignInRobot().interact()
|
||||
return SyncSignInRobot.Transition()
|
||||
}
|
||||
|
||||
fun openThreeDotMenu(interact: ComposeTabDrawerRobot.() -> Unit): Transition {
|
||||
Log.i(TAG, "openThreeDotMenu: Trying to click the three dot button")
|
||||
composeTestRule.threeDotButton().performClick()
|
||||
Log.i(TAG, "openThreeDotMenu: Clicked three dot button")
|
||||
ComposeTabDrawerRobot(composeTestRule).interact()
|
||||
return Transition(composeTestRule)
|
||||
}
|
||||
|
||||
fun closeAllTabs(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition {
|
||||
Log.i(TAG, "closeAllTabs: Trying to click the \"Close all tabs\" menu button")
|
||||
composeTestRule.dropdownMenuItemCloseAllTabs().performClick()
|
||||
Log.i(TAG, "closeAllTabs: Clicked the \"Close all tabs\" menu button")
|
||||
HomeScreenRobot().interact()
|
||||
return HomeScreenRobot.Transition()
|
||||
}
|
||||
|
||||
fun openTab(title: String, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition {
|
||||
composeTestRule.tabItem(title)
|
||||
.performScrollTo()
|
||||
.performClick()
|
||||
Log.i(TAG, "openTab: Trying to scroll to tab with title: $title")
|
||||
composeTestRule.tabItem(title).performScrollTo()
|
||||
Log.i(TAG, "openTab: Scrolled to tab with title: $title")
|
||||
Log.i(TAG, "openTab: Trying to click tab with title: $title")
|
||||
composeTestRule.tabItem(title).performClick()
|
||||
Log.i(TAG, "openTab: Clicked tab with title: $title")
|
||||
|
||||
BrowserRobot().interact()
|
||||
return BrowserRobot.Transition()
|
||||
}
|
||||
|
||||
fun openPrivateTab(position: Int, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition {
|
||||
Log.i(TAG, "openPrivateTab: Trying to click private tab at position: ${position + 1}")
|
||||
composeTestRule.privateTabsList()
|
||||
.onChildren()[position]
|
||||
.performClick()
|
||||
Log.i(TAG, "openPrivateTab: Clicked private tab at position: ${position + 1}")
|
||||
|
||||
BrowserRobot().interact()
|
||||
return BrowserRobot.Transition()
|
||||
}
|
||||
|
||||
fun openNormalTab(position: Int, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition {
|
||||
Log.i(TAG, "openNormalTab: Trying to click tab at position: ${position + 1}")
|
||||
composeTestRule.normalTabsList()
|
||||
.onChildren()[position]
|
||||
.performClick()
|
||||
Log.i(TAG, "openNormalTab: Clicked tab at position: ${position + 1}")
|
||||
|
||||
BrowserRobot().interact()
|
||||
return BrowserRobot.Transition()
|
||||
|
@ -377,7 +495,9 @@ class ComposeTabDrawerRobot(private val composeTestRule: HomeActivityComposeTest
|
|||
fun clickTopBar(interact: ComposeTabDrawerRobot.() -> Unit): Transition {
|
||||
// The topBar contains other views.
|
||||
// Don't do the default click in the middle, rather click in some free space - top right.
|
||||
Log.i(TAG, "clickTopBar: Trying to click the tabs tray top bar")
|
||||
Espresso.onView(ViewMatchers.withId(R.id.topBar)).clickAtLocationInView(GeneralLocation.TOP_RIGHT)
|
||||
Log.i(TAG, "clickTopBar: Clicked the tabs tray top bar")
|
||||
ComposeTabDrawerRobot(composeTestRule).interact()
|
||||
return Transition(composeTestRule)
|
||||
}
|
||||
|
@ -434,21 +554,27 @@ class ComposeTabDrawerRobot(private val composeTestRule: HomeActivityComposeTest
|
|||
}
|
||||
|
||||
fun closeTabDrawer(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition {
|
||||
Log.i(TAG, "closeTabDrawer: Trying to close the tabs tray by clicking the handle")
|
||||
composeTestRule.bannerHandle().performSemanticsAction(SemanticsActions.OnClick)
|
||||
Log.i(TAG, "closeTabDrawer: Closed the tabs tray by clicking the handle")
|
||||
|
||||
BrowserRobot().interact()
|
||||
return BrowserRobot.Transition()
|
||||
}
|
||||
|
||||
fun clickSaveCollection(interact: CollectionRobot.() -> Unit): CollectionRobot.Transition {
|
||||
Log.i(TAG, "clickSaveCollection: Trying to click the collections button")
|
||||
composeTestRule.collectionsButton().performClick()
|
||||
Log.i(TAG, "clickSaveCollection: Clicked collections button")
|
||||
|
||||
CollectionRobot().interact()
|
||||
return CollectionRobot.Transition()
|
||||
}
|
||||
|
||||
fun clickShareAllTabsButton(interact: ShareOverlayRobot.() -> Unit): ShareOverlayRobot.Transition {
|
||||
Log.i(TAG, "clickShareAllTabsButton: Trying to click the \"Share all tabs\" menu button button")
|
||||
composeTestRule.dropdownMenuItemShareAllTabs().performClick()
|
||||
Log.i(TAG, "clickShareAllTabsButton: Clicked the \"Share all tabs\" menu button button")
|
||||
|
||||
ShareOverlayRobot().interact()
|
||||
return ShareOverlayRobot.Transition()
|
||||
|
@ -468,7 +594,9 @@ fun composeTabDrawer(composeTestRule: HomeActivityComposeTestRule, interact: Com
|
|||
* Clicks on the Collections button in the Tabs Tray banner and opens a transition in the [CollectionRobot].
|
||||
*/
|
||||
private fun clickCollectionsButton(composeTestRule: HomeActivityComposeTestRule, interact: CollectionRobot.() -> Unit): CollectionRobot.Transition {
|
||||
Log.i(TAG, "clickCollectionsButton: Trying to click the collections button")
|
||||
composeTestRule.collectionsButton().performClick()
|
||||
Log.i(TAG, "clickCollectionsButton: Clicked the collections button")
|
||||
|
||||
CollectionRobot().interact()
|
||||
return CollectionRobot.Transition()
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
package org.mozilla.fenix.ui.robots
|
||||
|
||||
import android.util.Log
|
||||
import androidx.compose.ui.test.ExperimentalTestApi
|
||||
import androidx.compose.ui.test.filter
|
||||
import androidx.compose.ui.test.hasAnyChild
|
||||
|
@ -16,14 +17,13 @@ import androidx.compose.ui.test.onFirst
|
|||
import androidx.compose.ui.test.performClick
|
||||
import androidx.compose.ui.test.performScrollTo
|
||||
import androidx.compose.ui.test.performTouchInput
|
||||
import androidx.test.uiautomator.UiSelector
|
||||
import org.mozilla.fenix.helpers.Constants.TAG
|
||||
import org.mozilla.fenix.helpers.HomeActivityComposeTestRule
|
||||
import org.mozilla.fenix.helpers.MatcherHelper.itemContainingText
|
||||
import org.mozilla.fenix.helpers.MatcherHelper.itemWithResId
|
||||
import org.mozilla.fenix.helpers.MatcherHelper.itemWithResIdContainingText
|
||||
import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime
|
||||
import org.mozilla.fenix.helpers.TestAssetHelper.waitingTimeShort
|
||||
import org.mozilla.fenix.helpers.TestHelper.mDevice
|
||||
import org.mozilla.fenix.helpers.TestHelper.packageName
|
||||
import org.mozilla.fenix.home.topsites.TopSitesTestTag
|
||||
|
||||
|
@ -34,21 +34,31 @@ class ComposeTopSitesRobot(private val composeTestRule: HomeActivityComposeTestR
|
|||
|
||||
@OptIn(ExperimentalTestApi::class)
|
||||
fun verifyExistingTopSitesList() {
|
||||
composeTestRule.waitUntilExactlyOneExists(hasTestTag(TopSitesTestTag.topSites), timeoutMillis = waitingTime)
|
||||
Log.i(TAG, "verifyExistingTopSitesList: Waiting for $waitingTime ms until the top sites list exists")
|
||||
composeTestRule.waitUntilAtLeastOneExists(hasTestTag(TopSitesTestTag.topSites), timeoutMillis = waitingTime)
|
||||
Log.i(TAG, "verifyExistingTopSitesList: Waited for $waitingTime ms until the top sites list to exists")
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalTestApi::class)
|
||||
fun verifyExistingTopSiteItem(vararg titles: String) {
|
||||
titles.forEach { title ->
|
||||
mDevice.findObject(UiSelector().textContains(title)).waitForExists(waitingTimeShort)
|
||||
Log.i(TAG, "verifyExistingTopSiteItem: Waiting for $waitingTime ms until the top site with title: $title exists")
|
||||
composeTestRule.waitUntilAtLeastOneExists(hasText(title), timeoutMillis = waitingTime)
|
||||
Log.i(TAG, "verifyExistingTopSiteItem: Waited for $waitingTime ms until the top site with title: $title exists")
|
||||
Log.i(TAG, "verifyExistingTopSiteItem: Trying to verify that the top site with title: $title exists")
|
||||
composeTestRule.topSiteItem(title).assertExists()
|
||||
Log.i(TAG, "verifyExistingTopSiteItem: Verified that the top site with title: $title exists")
|
||||
}
|
||||
}
|
||||
|
||||
fun verifyNotExistingTopSiteItem(vararg titles: String) {
|
||||
titles.forEach { title ->
|
||||
Log.i(TAG, "verifyNotExistingTopSiteItem: Waiting for $waitingTime ms for top site with title: $title to exist")
|
||||
itemContainingText(title).waitForExists(waitingTime)
|
||||
Log.i(TAG, "verifyNotExistingTopSiteItem: Waited for $waitingTime ms for top site with title: $title to exist")
|
||||
Log.i(TAG, "verifyNotExistingTopSiteItem: Trying to verify that top site with title: $title does not exist")
|
||||
composeTestRule.topSiteItem(title).assertDoesNotExist()
|
||||
Log.i(TAG, "verifyNotExistingTopSiteItem: Verified that top site with title: $title does not exist")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -59,15 +69,21 @@ class ComposeTopSitesRobot(private val composeTestRule: HomeActivityComposeTestR
|
|||
}
|
||||
|
||||
fun verifyTopSiteContextMenuOpenInPrivateTabButton() {
|
||||
Log.i(TAG, "verifyTopSiteContextMenuOpenInPrivateTabButton: Trying to verify that the \"Open in private tab\" menu button exists")
|
||||
composeTestRule.contextMenuItemOpenInPrivateTab().assertExists()
|
||||
Log.i(TAG, "verifyTopSiteContextMenuOpenInPrivateTabButton: Verified that the \"Open in private tab\" menu button exists")
|
||||
}
|
||||
|
||||
fun verifyTopSiteContextMenuRenameButton() {
|
||||
Log.i(TAG, "verifyTopSiteContextMenuRenameButton: Trying to verify that the \"Rename\" menu button exists")
|
||||
composeTestRule.contextMenuItemRename().assertExists()
|
||||
Log.i(TAG, "verifyTopSiteContextMenuRenameButton: Verified that the \"Rename\" menu button exists")
|
||||
}
|
||||
|
||||
fun verifyTopSiteContextMenuRemoveButton() {
|
||||
Log.i(TAG, "verifyTopSiteContextMenuRemoveButton: Trying to verify that the \"Remove\" menu button exists")
|
||||
composeTestRule.contextMenuItemRemove().assertExists()
|
||||
Log.i(TAG, "verifyTopSiteContextMenuRemoveButton: Verified that the \"Remove\" menu button exists")
|
||||
}
|
||||
|
||||
class Transition(private val composeTestRule: HomeActivityComposeTestRule) {
|
||||
|
@ -76,7 +92,12 @@ class ComposeTopSitesRobot(private val composeTestRule: HomeActivityComposeTestR
|
|||
title: String,
|
||||
interact: BrowserRobot.() -> Unit,
|
||||
): BrowserRobot.Transition {
|
||||
composeTestRule.topSiteItem(title).performScrollTo().performClick()
|
||||
Log.i(TAG, "openTopSiteTabWithTitle: Trying to scroll to top site with title: $title")
|
||||
composeTestRule.topSiteItem(title).performScrollTo()
|
||||
Log.i(TAG, "openTopSiteTabWithTitle: Scrolled to top site with title: $title")
|
||||
Log.i(TAG, "openTopSiteTabWithTitle: Trying to click top site with title: $title")
|
||||
composeTestRule.topSiteItem(title).performClick()
|
||||
Log.i(TAG, "openTopSiteTabWithTitle: Clicked top site with title: $title")
|
||||
|
||||
BrowserRobot().interact()
|
||||
return BrowserRobot.Transition()
|
||||
|
@ -85,7 +106,9 @@ class ComposeTopSitesRobot(private val composeTestRule: HomeActivityComposeTestR
|
|||
fun openTopSiteInPrivate(
|
||||
interact: BrowserRobot.() -> Unit,
|
||||
): BrowserRobot.Transition {
|
||||
Log.i(TAG, "openTopSiteInPrivate: Trying to click the \"Open in private tab\" menu button")
|
||||
composeTestRule.contextMenuItemOpenInPrivateTab().performClick()
|
||||
Log.i(TAG, "openTopSiteInPrivate: Clicked the \"Open in private tab\" menu button")
|
||||
composeTestRule.waitForIdle()
|
||||
|
||||
BrowserRobot().interact()
|
||||
|
@ -96,9 +119,12 @@ class ComposeTopSitesRobot(private val composeTestRule: HomeActivityComposeTestR
|
|||
title: String,
|
||||
interact: ComposeTopSitesRobot.() -> Unit,
|
||||
): Transition {
|
||||
composeTestRule.topSiteItem(title).performScrollTo().performTouchInput {
|
||||
longClick()
|
||||
}
|
||||
Log.i(TAG, "openContextMenuOnTopSitesWithTitle: Trying to scroll to top site with title: $title")
|
||||
composeTestRule.topSiteItem(title).performScrollTo()
|
||||
Log.i(TAG, "openContextMenuOnTopSitesWithTitle: Scrolled to top site with title: $title")
|
||||
Log.i(TAG, "openContextMenuOnTopSitesWithTitle: Trying to long click top site with title: $title")
|
||||
composeTestRule.topSiteItem(title).performTouchInput { longClick() }
|
||||
Log.i(TAG, "openContextMenuOnTopSitesWithTitle: Long clicked top site with title: $title")
|
||||
|
||||
ComposeTopSitesRobot(composeTestRule).interact()
|
||||
return Transition(composeTestRule)
|
||||
|
@ -108,13 +134,21 @@ class ComposeTopSitesRobot(private val composeTestRule: HomeActivityComposeTestR
|
|||
title: String,
|
||||
interact: ComposeTopSitesRobot.() -> Unit,
|
||||
): Transition {
|
||||
Log.i(TAG, "renameTopSite: Trying to click the \"Rename\" menu button")
|
||||
composeTestRule.contextMenuItemRename().performClick()
|
||||
Log.i(TAG, "renameTopSite: Clicked the \"Rename\" menu button")
|
||||
itemWithResId("$packageName:id/top_site_title")
|
||||
.also {
|
||||
Log.i(TAG, "renameTopSite: Waiting for $waitingTimeShort ms for top site rename text box to exist")
|
||||
it.waitForExists(waitingTimeShort)
|
||||
Log.i(TAG, "renameTopSite: Waited for $waitingTimeShort ms for top site rename text box to exist")
|
||||
Log.i(TAG, "renameTopSite: Trying to set top site rename text box text to: $title")
|
||||
it.setText(title)
|
||||
Log.i(TAG, "renameTopSite: Top site rename text box text was set to: $title")
|
||||
}
|
||||
Log.i(TAG, "renameTopSite: Trying to click the \"Ok\" dialog button")
|
||||
itemWithResIdContainingText("android:id/button1", "OK").click()
|
||||
Log.i(TAG, "renameTopSite: Clicked the \"Ok\" dialog button")
|
||||
|
||||
ComposeTopSitesRobot(composeTestRule).interact()
|
||||
return Transition(composeTestRule)
|
||||
|
@ -124,23 +158,16 @@ class ComposeTopSitesRobot(private val composeTestRule: HomeActivityComposeTestR
|
|||
fun removeTopSite(
|
||||
interact: ComposeTopSitesRobot.() -> Unit,
|
||||
): Transition {
|
||||
Log.i(TAG, "removeTopSite: Trying to click the \"Remove\" menu button")
|
||||
composeTestRule.contextMenuItemRemove().performClick()
|
||||
Log.i(TAG, "removeTopSite: Clicked the \"Remove\" menu button")
|
||||
Log.i(TAG, "removeTopSite: Waiting for $waitingTime ms until the \"Remove\" menu button does not exist")
|
||||
composeTestRule.waitUntilDoesNotExist(hasTestTag(TopSitesTestTag.remove), waitingTime)
|
||||
Log.i(TAG, "removeTopSite: Waited for $waitingTime ms until the \"Remove\" menu button does not exist")
|
||||
|
||||
ComposeTopSitesRobot(composeTestRule).interact()
|
||||
return Transition(composeTestRule)
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalTestApi::class)
|
||||
fun deleteTopSiteFromHistory(
|
||||
interact: BrowserRobot.() -> Unit,
|
||||
): BrowserRobot.Transition {
|
||||
composeTestRule.contextMenuItemRemove().performClick()
|
||||
composeTestRule.waitUntilDoesNotExist(hasTestTag(TopSitesTestTag.remove), waitingTime)
|
||||
|
||||
BrowserRobot().interact()
|
||||
return BrowserRobot.Transition()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
package org.mozilla.fenix.ui.robots
|
||||
|
||||
import android.util.Log
|
||||
import androidx.test.espresso.Espresso.onView
|
||||
import androidx.test.espresso.action.ViewActions.click
|
||||
import androidx.test.espresso.assertion.ViewAssertions.matches
|
||||
|
@ -14,6 +15,7 @@ import androidx.test.uiautomator.By
|
|||
import androidx.test.uiautomator.UiSelector
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.helpers.Constants.LONG_CLICK_DURATION
|
||||
import org.mozilla.fenix.helpers.Constants.TAG
|
||||
import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource
|
||||
import org.mozilla.fenix.helpers.MatcherHelper.assertUIObjectExists
|
||||
import org.mozilla.fenix.helpers.MatcherHelper.itemContainingText
|
||||
|
@ -43,21 +45,27 @@ class CustomTabRobot {
|
|||
itemWithDescription(getStringResource(R.string.mozac_feature_customtabs_share_link)),
|
||||
)
|
||||
|
||||
fun verifyMainMenuButton() = assertUIObjectExists(mainMenuButton)
|
||||
fun verifyMainMenuButton() = assertUIObjectExists(mainMenuButton())
|
||||
|
||||
fun verifyDesktopSiteButtonExists() {
|
||||
Log.i(TAG, "verifyDesktopSiteButtonExists: Trying to verify that the request desktop site button is displayed")
|
||||
desktopSiteButton().check(matches(isDisplayed()))
|
||||
Log.i(TAG, "verifyDesktopSiteButtonExists: Verified that the request desktop site button is displayed")
|
||||
}
|
||||
|
||||
fun verifyFindInPageButtonExists() {
|
||||
Log.i(TAG, "verifyFindInPageButtonExists: Trying to verify that the find in page button is displayed")
|
||||
findInPageButton().check(matches(isDisplayed()))
|
||||
Log.i(TAG, "verifyFindInPageButtonExists: Verified that the find in page button is displayed")
|
||||
}
|
||||
|
||||
fun verifyPoweredByTextIsDisplayed() =
|
||||
assertUIObjectExists(itemContainingText("POWERED BY $appName"))
|
||||
|
||||
fun verifyOpenInBrowserButtonExists() {
|
||||
Log.i(TAG, "verifyOpenInBrowserButtonExists: Trying to verify that the \"Open in Firefox\" button is displayed")
|
||||
openInBrowserButton().check(matches(isDisplayed()))
|
||||
Log.i(TAG, "verifyOpenInBrowserButtonExists: Verified that the \"Open in Firefox\" button is displayed")
|
||||
}
|
||||
|
||||
fun verifyBackButtonExists() = assertUIObjectExists(itemWithDescription("Back"))
|
||||
|
@ -69,7 +77,9 @@ class CustomTabRobot {
|
|||
fun verifyCustomMenuItem(label: String) = assertUIObjectExists(itemContainingText(label))
|
||||
|
||||
fun verifyCustomTabCloseButton() {
|
||||
Log.i(TAG, "verifyCustomTabCloseButton: Trying to verify that the close custom tab button is displayed")
|
||||
closeButton().check(matches(isDisplayed()))
|
||||
Log.i(TAG, "verifyCustomTabCloseButton: Verified that the close custom tab button is displayed")
|
||||
}
|
||||
|
||||
fun verifyCustomTabToolbarTitle(title: String) {
|
||||
|
@ -103,12 +113,16 @@ class CustomTabRobot {
|
|||
mDevice.findObject(UiSelector().resourceId("$packageName:id/toolbar")),
|
||||
waitingTime,
|
||||
)
|
||||
Log.i(TAG, "longCLickAndCopyToolbarUrl: Trying to long click the custom tab toolbar")
|
||||
customTabToolbar().click(LONG_CLICK_DURATION)
|
||||
Log.i(TAG, "longCLickAndCopyToolbarUrl: Long clicked the custom tab toolbar")
|
||||
clickContextMenuItem("Copy")
|
||||
}
|
||||
|
||||
fun fillAndSubmitLoginCredentials(userName: String, password: String) {
|
||||
Log.i(TAG, "fillAndSubmitLoginCredentials: Waiting for device to be idle for $waitingTime ms")
|
||||
mDevice.waitForIdle(waitingTime)
|
||||
Log.i(TAG, "fillAndSubmitLoginCredentials: Waited for device to be idle for $waitingTime ms")
|
||||
setPageObjectText(itemWithResId("username"), userName)
|
||||
setPageObjectText(itemWithResId("password"), password)
|
||||
clickPageObject(itemWithResId("submit"))
|
||||
|
@ -118,9 +132,17 @@ class CustomTabRobot {
|
|||
)
|
||||
}
|
||||
|
||||
fun waitForPageToLoad() = progressBar.waitUntilGone(waitingTime)
|
||||
fun waitForPageToLoad() {
|
||||
Log.i(TAG, "waitForPageToLoad: Waiting for $waitingTime ms until progress bar is gone")
|
||||
progressBar().waitUntilGone(waitingTime)
|
||||
Log.i(TAG, "waitForPageToLoad: Waited for $waitingTime ms until progress bar was gone")
|
||||
}
|
||||
|
||||
fun clickCustomTabCloseButton() = closeButton().click()
|
||||
fun clickCustomTabCloseButton() {
|
||||
Log.i(TAG, "clickCustomTabCloseButton: Trying to click close custom tab button")
|
||||
closeButton().click()
|
||||
Log.i(TAG, "clickCustomTabCloseButton: Clicked close custom tab button")
|
||||
}
|
||||
|
||||
fun verifyCustomTabActionButton(customTabActionButtonDescription: String) =
|
||||
assertUIObjectExists(itemWithDescription(customTabActionButtonDescription))
|
||||
|
@ -133,9 +155,13 @@ class CustomTabRobot {
|
|||
|
||||
class Transition {
|
||||
fun openMainMenu(interact: CustomTabRobot.() -> Unit): Transition {
|
||||
mainMenuButton.also {
|
||||
mainMenuButton().also {
|
||||
Log.i(TAG, "openMainMenu: Waiting for $waitingTime ms for the main menu button to exist")
|
||||
it.waitForExists(waitingTime)
|
||||
Log.i(TAG, "openMainMenu: Waited for $waitingTime ms for the main menu button to exist")
|
||||
Log.i(TAG, "openMainMenu: Trying to click the main menu button")
|
||||
it.click()
|
||||
Log.i(TAG, "openMainMenu: Clicked the main menu button")
|
||||
}
|
||||
|
||||
CustomTabRobot().interact()
|
||||
|
@ -143,14 +169,18 @@ class CustomTabRobot {
|
|||
}
|
||||
|
||||
fun clickOpenInBrowserButton(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition {
|
||||
Log.i(TAG, "clickOpenInBrowserButton: Trying to click the \"Open in Firefox\" button")
|
||||
openInBrowserButton().perform(click())
|
||||
Log.i(TAG, "clickOpenInBrowserButton: Clicked the \"Open in Firefox\" button")
|
||||
|
||||
BrowserRobot().interact()
|
||||
return BrowserRobot.Transition()
|
||||
}
|
||||
|
||||
fun clickShareButton(interact: ShareOverlayRobot.() -> Unit): ShareOverlayRobot.Transition {
|
||||
Log.i(TAG, "clickShareButton: Trying to click the share button")
|
||||
itemWithDescription(getStringResource(R.string.mozac_feature_customtabs_share_link)).click()
|
||||
Log.i(TAG, "clickShareButton: Clicked the share button")
|
||||
|
||||
ShareOverlayRobot().interact()
|
||||
return ShareOverlayRobot.Transition()
|
||||
|
@ -163,7 +193,7 @@ fun customTabScreen(interact: CustomTabRobot.() -> Unit): CustomTabRobot.Transit
|
|||
return CustomTabRobot.Transition()
|
||||
}
|
||||
|
||||
private val mainMenuButton = itemWithResId("$packageName:id/mozac_browser_toolbar_menu")
|
||||
private fun mainMenuButton() = itemWithResId("$packageName:id/mozac_browser_toolbar_menu")
|
||||
|
||||
private fun desktopSiteButton() = onView(withId(R.id.switch_widget))
|
||||
|
||||
|
@ -175,7 +205,7 @@ private fun closeButton() = onView(withContentDescription("Return to previous ap
|
|||
|
||||
private fun customTabToolbar() = mDevice.findObject(By.res("$packageName:id/toolbar"))
|
||||
|
||||
private val progressBar =
|
||||
private fun progressBar() =
|
||||
mDevice.findObject(
|
||||
UiSelector().resourceId("$packageName:id/mozac_browser_toolbar_progress"),
|
||||
)
|
||||
|
|
|
@ -51,9 +51,8 @@ class DownloadRobot {
|
|||
fun verifyDownloadPrompt(fileName: String) {
|
||||
var currentTries = 0
|
||||
while (currentTries++ < 3) {
|
||||
Log.i(TAG, "verifyDownloadPrompt: While loop currentTries = $currentTries")
|
||||
Log.i(TAG, "verifyDownloadPrompt: Started try #$currentTries")
|
||||
try {
|
||||
Log.i(TAG, "verifyDownloadPrompt: Try block")
|
||||
assertUIObjectExists(
|
||||
itemWithResId("$packageName:id/download_button"),
|
||||
itemContainingText(fileName),
|
||||
|
@ -61,7 +60,7 @@ class DownloadRobot {
|
|||
|
||||
break
|
||||
} catch (e: AssertionError) {
|
||||
Log.i(TAG, "verifyDownloadPrompt: Catch block")
|
||||
Log.i(TAG, "verifyDownloadPrompt: AssertionError caught, executing fallback methods")
|
||||
Log.e("DOWNLOAD_ROBOT", "Failed to find locator: ${e.localizedMessage}")
|
||||
|
||||
browserScreen {
|
||||
|
@ -96,11 +95,12 @@ class DownloadRobot {
|
|||
)
|
||||
|
||||
fun clickTryAgainButton() {
|
||||
Log.i(TAG, "clickTryAgainButton: Trying to click the \"TRY AGAIN\" in app prompt button")
|
||||
itemWithResIdAndText(
|
||||
"$packageName:id/download_dialog_action_button",
|
||||
"Try Again",
|
||||
).click()
|
||||
Log.i(TAG, "clickTryAgainButton: Clicked \"TRY AGAIN\" in app prompt button")
|
||||
Log.i(TAG, "clickTryAgainButton: Clicked the \"TRY AGAIN\" in app prompt button")
|
||||
}
|
||||
|
||||
fun verifyPhotosAppOpens() = assertExternalAppOpens(GOOGLE_APPS_PHOTOS)
|
||||
|
@ -111,34 +111,40 @@ class DownloadRobot {
|
|||
fun verifyDownloadedFileIcon() = assertUIObjectExists(itemWithResId("$packageName:id/favicon"))
|
||||
|
||||
fun verifyEmptyDownloadsList() {
|
||||
Log.i(TAG, "verifyEmptyDownloadsList: Looking for empty download list")
|
||||
Log.i(TAG, "verifyEmptyDownloadsList: Waiting for $waitingTime ms for for empty download list to exist")
|
||||
mDevice.findObject(UiSelector().resourceId("$packageName:id/download_empty_view"))
|
||||
.waitForExists(waitingTime)
|
||||
Log.i(TAG, "verifyEmptyDownloadsList: Waited for $waitingTime ms for for empty download list to exist")
|
||||
Log.i(TAG, "verifyEmptyDownloadsList: Trying to verify that the \"No downloaded files\" list message is displayed")
|
||||
onView(withText("No downloaded files")).check(matches(isDisplayed()))
|
||||
Log.i(TAG, "verifyEmptyDownloadsList: Verified \"No downloaded files\" list message")
|
||||
Log.i(TAG, "verifyEmptyDownloadsList: Verified that the \"No downloaded files\" list message is displayed")
|
||||
}
|
||||
|
||||
fun waitForDownloadsListToExist() =
|
||||
assertUIObjectExists(itemWithResId("$packageName:id/download_list"))
|
||||
|
||||
fun openDownloadedFile(fileName: String) {
|
||||
downloadedFile(fileName)
|
||||
.check(matches(isDisplayed()))
|
||||
.click()
|
||||
Log.i(TAG, "openDownloadedFile: Trying to verify that the downloaded file: $fileName is displayed")
|
||||
downloadedFile(fileName).check(matches(isDisplayed()))
|
||||
Log.i(TAG, "openDownloadedFile: Verified that the downloaded file: $fileName is displayed")
|
||||
Log.i(TAG, "openDownloadedFile: Trying to click downloaded file: $fileName")
|
||||
downloadedFile(fileName).click()
|
||||
Log.i(TAG, "openDownloadedFile: Clicked downloaded file: $fileName")
|
||||
}
|
||||
|
||||
fun deleteDownloadedItem(fileName: String) {
|
||||
Log.i(TAG, "deleteDownloadedItem: Trying to click the trash bin icon to delete downloaded file: $fileName")
|
||||
onView(
|
||||
allOf(
|
||||
withId(R.id.overflow_menu),
|
||||
hasSibling(withText(fileName)),
|
||||
),
|
||||
).click()
|
||||
Log.i(TAG, "deleteDownloadedItem: Deleted downloaded file: $fileName using trash bin icon")
|
||||
Log.i(TAG, "deleteDownloadedItem: Clicked the trash bin icon to delete downloaded file: $fileName")
|
||||
}
|
||||
|
||||
fun longClickDownloadedItem(title: String) {
|
||||
Log.i(TAG, "longClickDownloadedItem: Trying to long click downloaded file: $title")
|
||||
onView(
|
||||
allOf(
|
||||
withId(R.id.title),
|
||||
|
@ -149,21 +155,24 @@ class DownloadRobot {
|
|||
}
|
||||
|
||||
fun selectDownloadedItem(title: String) {
|
||||
Log.i(TAG, "selectDownloadedItem: Trying click downloaded file: $title to select it")
|
||||
onView(
|
||||
allOf(
|
||||
withId(R.id.title),
|
||||
withText(title),
|
||||
),
|
||||
).perform(click())
|
||||
Log.i(TAG, "selectDownloadedItem: Selected downloaded file: $title")
|
||||
Log.i(TAG, "selectDownloadedItem: Clicked downloaded file: $title to select it")
|
||||
}
|
||||
|
||||
fun openMultiSelectMoreOptionsMenu() {
|
||||
Log.i(TAG, "openMultiSelectMoreOptionsMenu: Trying to click multi-select more options button")
|
||||
itemWithDescription(getStringResource(R.string.content_description_menu)).click()
|
||||
Log.i(TAG, "openMultiSelectMoreOptionsMenu: Clicked multi-select more options button")
|
||||
}
|
||||
|
||||
fun clickMultiSelectRemoveButton() {
|
||||
Log.i(TAG, "clickMultiSelectRemoveButton: Trying to click multi-select remove button")
|
||||
itemWithResIdContainingText("$packageName:id/title", "Remove").click()
|
||||
Log.i(TAG, "clickMultiSelectRemoveButton: Clicked multi-select remove button")
|
||||
}
|
||||
|
@ -180,27 +189,31 @@ class DownloadRobot {
|
|||
|
||||
class Transition {
|
||||
fun clickDownload(interact: DownloadRobot.() -> Unit): Transition {
|
||||
Log.i(TAG, "clickDownload: Trying to click the \"Download\" download prompt button")
|
||||
downloadButton().click()
|
||||
Log.i(TAG, "clickDownload: Clicked \"DOWNLOAD\" button from prompt")
|
||||
Log.i(TAG, "clickDownload: Clicked the \"Download\" download prompt button")
|
||||
|
||||
DownloadRobot().interact()
|
||||
return Transition()
|
||||
}
|
||||
|
||||
fun closeDownloadPrompt(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition {
|
||||
Log.i(TAG, "closeDownloadPrompt: Trying to click the close download prompt button")
|
||||
itemWithResId("$packageName:id/download_dialog_close_button").click()
|
||||
Log.i(TAG, "closeDownloadPrompt: Dismissed download prompt by clicking close prompt button")
|
||||
Log.i(TAG, "closeDownloadPrompt: Clicked the close download prompt button")
|
||||
|
||||
BrowserRobot().interact()
|
||||
return BrowserRobot.Transition()
|
||||
}
|
||||
|
||||
fun clickOpen(type: String, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition {
|
||||
Log.i(TAG, "clickOpen: Looking for \"OPEN\" download prompt button")
|
||||
Log.i(TAG, "clickOpen: Waiting for $waitingTime ms for the for \"OPEN\" download prompt button to exist")
|
||||
openDownloadButton().waitForExists(waitingTime)
|
||||
Log.i(TAG, "clickOpen: Waited for $waitingTime ms for the for \"OPEN\" download prompt button to exist")
|
||||
Log.i(TAG, "clickOpen: Trying to click the \"OPEN\" download prompt button")
|
||||
openDownloadButton().click()
|
||||
Log.i(TAG, "clickOpen: Clicked \"OPEN\" download prompt button")
|
||||
|
||||
Log.i(TAG, "clickOpen: Clicked the \"OPEN\" download prompt button")
|
||||
Log.i(TAG, "clickOpen: Trying to verify that the open intent is matched with associated data type")
|
||||
// verify open intent is matched with associated data type
|
||||
Intents.intended(
|
||||
allOf(
|
||||
|
@ -208,37 +221,38 @@ class DownloadRobot {
|
|||
IntentMatchers.hasType(type),
|
||||
),
|
||||
)
|
||||
Log.i(TAG, "clickOpen: Verified that open intent is matched with associated data type")
|
||||
Log.i(TAG, "clickOpen: Verified that the open intent is matched with associated data type")
|
||||
|
||||
BrowserRobot().interact()
|
||||
return BrowserRobot.Transition()
|
||||
}
|
||||
|
||||
fun clickAllowPermission(interact: DownloadRobot.() -> Unit): Transition {
|
||||
Log.i(TAG, "clickAllowPermission: Looking for \"ALLOW\" permission button")
|
||||
mDevice.waitNotNull(
|
||||
Until.findObject(By.res(getPermissionAllowID() + ":id/permission_allow_button")),
|
||||
waitingTime,
|
||||
)
|
||||
|
||||
Log.i(TAG, "clickAllowPermission: Trying to click the \"ALLOW\" permission button")
|
||||
mDevice.findObject(By.res(getPermissionAllowID() + ":id/permission_allow_button")).click()
|
||||
Log.i(TAG, "clickAllowPermission: Clicked \"ALLOW\" permission button")
|
||||
Log.i(TAG, "clickAllowPermission: Clicked the \"ALLOW\" permission button")
|
||||
|
||||
DownloadRobot().interact()
|
||||
return Transition()
|
||||
}
|
||||
|
||||
fun exitDownloadsManagerToBrowser(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition {
|
||||
Log.i(TAG, "exitDownloadsManagerToBrowser: Trying to click the navigate up toolbar button")
|
||||
onView(withContentDescription("Navigate up")).click()
|
||||
Log.i(TAG, "exitDownloadsManagerToBrowser: Exited download manager to browser by clicking the navigate up toolbar button")
|
||||
Log.i(TAG, "exitDownloadsManagerToBrowser: Clicked the navigate up toolbar button")
|
||||
|
||||
BrowserRobot().interact()
|
||||
return BrowserRobot.Transition()
|
||||
}
|
||||
|
||||
fun goBack(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition {
|
||||
Log.i(TAG, "goBack: Trying to click the navigate up toolbar button")
|
||||
goBackButton().click()
|
||||
Log.i(TAG, "exitDownloadsManagerToBrowser: Exited download manager to home screen by clicking the navigate up toolbar button")
|
||||
Log.i(TAG, "goBack: Clicked the navigate up toolbar button")
|
||||
|
||||
HomeScreenRobot().interact()
|
||||
return HomeScreenRobot.Transition()
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
package org.mozilla.fenix.ui.robots
|
||||
|
||||
import android.util.Log
|
||||
import androidx.test.espresso.Espresso.onView
|
||||
import androidx.test.espresso.assertion.ViewAssertions.matches
|
||||
import androidx.test.espresso.matcher.RootMatchers
|
||||
|
@ -21,6 +22,7 @@ import org.hamcrest.Matchers.allOf
|
|||
import org.hamcrest.Matchers.containsString
|
||||
import org.hamcrest.Matchers.not
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.helpers.Constants.TAG
|
||||
import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource
|
||||
import org.mozilla.fenix.helpers.MatcherHelper.assertUIObjectExists
|
||||
import org.mozilla.fenix.helpers.MatcherHelper.itemWithResId
|
||||
|
@ -36,15 +38,40 @@ import org.mozilla.fenix.helpers.isChecked
|
|||
* Implementation of Robot Pattern for Enhanced Tracking Protection UI.
|
||||
*/
|
||||
class EnhancedTrackingProtectionRobot {
|
||||
fun verifyEnhancedTrackingProtectionSheetStatus(status: String, state: Boolean) =
|
||||
assertEnhancedTrackingProtectionSheetStatus(status, state)
|
||||
fun verifyEnhancedTrackingProtectionSheetStatus(status: String, state: Boolean) {
|
||||
mDevice.waitNotNull(Until.findObjects(By.text("Protections are $status for this site")))
|
||||
Log.i(TAG, "verifyEnhancedTrackingProtectionSheetStatus: Trying to check ETP toggle is checked: $state")
|
||||
onView(ViewMatchers.withResourceName("switch_widget")).check(
|
||||
matches(
|
||||
isChecked(
|
||||
state,
|
||||
),
|
||||
),
|
||||
)
|
||||
Log.i(TAG, "verifyEnhancedTrackingProtectionSheetStatus: Verified ETP toggle is checked: $state")
|
||||
}
|
||||
|
||||
fun verifyETPSwitchVisibility(visible: Boolean) = assertETPSwitchVisibility(visible)
|
||||
fun verifyETPSwitchVisibility(visible: Boolean) {
|
||||
if (visible) {
|
||||
Log.i(TAG, "verifyETPSwitchVisibility: Trying to verify ETP toggle is displayed")
|
||||
enhancedTrackingProtectionSwitch()
|
||||
.check(matches(isDisplayed()))
|
||||
Log.i(TAG, "verifyETPSwitchVisibility: Verified ETP toggle is displayed")
|
||||
} else {
|
||||
Log.i(TAG, "verifyETPSwitchVisibility: Trying to verify ETP toggle is not displayed")
|
||||
enhancedTrackingProtectionSwitch()
|
||||
.check(matches(not(isDisplayed())))
|
||||
Log.i(TAG, "verifyETPSwitchVisibility: Verified ETP toggle is not displayed")
|
||||
}
|
||||
}
|
||||
|
||||
fun verifyCrossSiteCookiesBlocked(isBlocked: Boolean) {
|
||||
assertUIObjectExists(itemWithResId("$packageName:id/cross_site_tracking"))
|
||||
crossSiteCookiesBlockListButton.click()
|
||||
Log.i(TAG, "verifyCrossSiteCookiesBlocked: Trying to click cross site cookies block list button")
|
||||
crossSiteCookiesBlockListButton().click()
|
||||
Log.i(TAG, "verifyCrossSiteCookiesBlocked: Clicked cross site cookies block list button")
|
||||
// Verifies the trackers block/allow list
|
||||
Log.i(TAG, "verifyCrossSiteCookiesBlocked: Trying to verify cross site cookies are blocked: $isBlocked")
|
||||
onView(withId(R.id.details_blocking_header))
|
||||
.check(
|
||||
matches(
|
||||
|
@ -57,12 +84,16 @@ class EnhancedTrackingProtectionRobot {
|
|||
),
|
||||
),
|
||||
)
|
||||
Log.i(TAG, "verifyCrossSiteCookiesBlocked: Verified cross site cookies are blocked: $isBlocked")
|
||||
}
|
||||
|
||||
fun verifySocialMediaTrackersBlocked(isBlocked: Boolean) {
|
||||
assertUIObjectExists(itemWithResId("$packageName:id/social_media_trackers"))
|
||||
socialTrackersBlockListButton.click()
|
||||
Log.i(TAG, "verifySocialMediaTrackersBlocked: Trying to click social trackers block list button")
|
||||
socialTrackersBlockListButton().click()
|
||||
Log.i(TAG, "verifySocialMediaTrackersBlocked: Clicked social trackers block list button")
|
||||
// Verifies the trackers block/allow list
|
||||
Log.i(TAG, "verifySocialMediaTrackersBlocked: Trying to verify social trackers are blocked: $isBlocked")
|
||||
onView(withId(R.id.details_blocking_header))
|
||||
.check(
|
||||
matches(
|
||||
|
@ -75,13 +106,19 @@ class EnhancedTrackingProtectionRobot {
|
|||
),
|
||||
),
|
||||
)
|
||||
Log.i(TAG, "verifySocialMediaTrackersBlocked: Verified social trackers are blocked: $isBlocked")
|
||||
Log.i(TAG, "verifySocialMediaTrackersBlocked: Trying to verify blocked social trackers list is displayed")
|
||||
onView(withId(R.id.blocking_text_list)).check(matches(isDisplayed()))
|
||||
Log.i(TAG, "verifySocialMediaTrackersBlocked: Verified blocked social trackers list is displayed")
|
||||
}
|
||||
|
||||
fun verifyFingerprintersBlocked(isBlocked: Boolean) {
|
||||
assertUIObjectExists(itemWithResId("$packageName:id/fingerprinters"))
|
||||
fingerprintersBlockListButton.click()
|
||||
Log.i(TAG, "verifyFingerprintersBlocked: Trying to click fingerprinters block list button")
|
||||
fingerprintersBlockListButton().click()
|
||||
Log.i(TAG, "verifyFingerprintersBlocked: Clicked fingerprinters block list button")
|
||||
// Verifies the trackers block/allow list
|
||||
Log.i(TAG, "verifyFingerprintersBlocked: Trying to verify fingerprinters are blocked: $isBlocked")
|
||||
onView(withId(R.id.details_blocking_header))
|
||||
.check(
|
||||
matches(
|
||||
|
@ -94,13 +131,19 @@ class EnhancedTrackingProtectionRobot {
|
|||
),
|
||||
),
|
||||
)
|
||||
Log.i(TAG, "verifyFingerprintersBlocked: Verified fingerprinters are blocked: $isBlocked")
|
||||
Log.i(TAG, "verifyFingerprintersBlocked: Trying to verify blocked fingerprinter trackers list is displayed")
|
||||
onView(withId(R.id.blocking_text_list)).check(matches(isDisplayed()))
|
||||
Log.i(TAG, "verifyFingerprintersBlocked: Verified blocked fingerprinter trackers list is displayed")
|
||||
}
|
||||
|
||||
fun verifyCryptominersBlocked(isBlocked: Boolean) {
|
||||
assertUIObjectExists(itemWithResId("$packageName:id/cryptominers"))
|
||||
cryptominersBlockListButton.click()
|
||||
Log.i(TAG, "verifyCryptominersBlocked: Trying to click cryptominers block list button")
|
||||
cryptominersBlockListButton().click()
|
||||
Log.i(TAG, "verifyCryptominersBlocked: Clicked cryptominers block list button")
|
||||
// Verifies the trackers block/allow list
|
||||
Log.i(TAG, "verifyCryptominersBlocked: Trying to verify cryptominers are blocked: $isBlocked")
|
||||
onView(withId(R.id.details_blocking_header))
|
||||
.check(
|
||||
matches(
|
||||
|
@ -113,13 +156,19 @@ class EnhancedTrackingProtectionRobot {
|
|||
),
|
||||
),
|
||||
)
|
||||
Log.i(TAG, "verifyCryptominersBlocked: Verified cryptominers are blocked: $isBlocked")
|
||||
Log.i(TAG, "verifyCryptominersBlocked: Trying to verify blocked cryptominers trackers list is displayed")
|
||||
onView(withId(R.id.blocking_text_list)).check(matches(isDisplayed()))
|
||||
Log.i(TAG, "verifyCryptominersBlocked: Verified blocked cryptominers trackers list is displayed")
|
||||
}
|
||||
|
||||
fun verifyTrackingContentBlocked(isBlocked: Boolean) {
|
||||
assertUIObjectExists(itemWithText("Tracking Content"))
|
||||
trackingContentBlockListButton.click()
|
||||
Log.i(TAG, "verifyTrackingContentBlocked: Trying to click tracking content block list button")
|
||||
trackingContentBlockListButton().click()
|
||||
Log.i(TAG, "verifyTrackingContentBlocked: Clicked tracking content block list button")
|
||||
// Verifies the trackers block/allow list
|
||||
Log.i(TAG, "verifyTrackingContentBlocked: Trying to verify tracking content is blocked: $isBlocked")
|
||||
onView(withId(R.id.details_blocking_header))
|
||||
.check(
|
||||
matches(
|
||||
|
@ -132,10 +181,14 @@ class EnhancedTrackingProtectionRobot {
|
|||
),
|
||||
),
|
||||
)
|
||||
Log.i(TAG, "verifyTrackingContentBlocked: Verified tracking content is blocked: $isBlocked")
|
||||
Log.i(TAG, "verifyTrackingContentBlocked: Trying to verify blocked tracking content trackers list is displayed")
|
||||
onView(withId(R.id.blocking_text_list)).check(matches(isDisplayed()))
|
||||
Log.i(TAG, "verifyTrackingContentBlocked: Verified blocked tracking content trackers list is displayed")
|
||||
}
|
||||
|
||||
fun viewTrackingContentBlockList() {
|
||||
Log.i(TAG, "viewTrackingContentBlockList: Trying to verify blocked tracking content trackers")
|
||||
onView(withId(R.id.blocking_text_list))
|
||||
.check(
|
||||
matches(
|
||||
|
@ -148,6 +201,7 @@ class EnhancedTrackingProtectionRobot {
|
|||
),
|
||||
),
|
||||
)
|
||||
Log.i(TAG, "viewTrackingContentBlockList: Verified blocked tracking content trackers")
|
||||
}
|
||||
|
||||
fun verifyETPSectionIsDisplayedInQuickSettingsSheet(isDisplayed: Boolean) =
|
||||
|
@ -157,14 +211,24 @@ class EnhancedTrackingProtectionRobot {
|
|||
)
|
||||
|
||||
fun navigateBackToDetails() {
|
||||
Log.i(TAG, "navigateBackToDetails: Trying to click details list back button")
|
||||
onView(withId(R.id.details_back)).click()
|
||||
Log.i(TAG, "navigateBackToDetails: Clicked details list back button")
|
||||
}
|
||||
|
||||
class Transition {
|
||||
fun openEnhancedTrackingProtectionSheet(interact: EnhancedTrackingProtectionRobot.() -> Unit): Transition {
|
||||
Log.i(TAG, "openEnhancedTrackingProtectionSheet: Waiting for $waitingTime ms for site security button to exist")
|
||||
pageSecurityIndicator().waitForExists(waitingTime)
|
||||
Log.i(TAG, "openEnhancedTrackingProtectionSheet: Waited for $waitingTime ms for site security button to exist")
|
||||
Log.i(TAG, "openEnhancedTrackingProtectionSheet: Trying to click site security button")
|
||||
pageSecurityIndicator().click()
|
||||
assertSecuritySheetIsCompletelyDisplayed()
|
||||
Log.i(TAG, "openEnhancedTrackingProtectionSheet: Clicked site security button")
|
||||
Log.i(TAG, "openEnhancedTrackingProtectionSheet: Waiting for $waitingTime ms for quick actions sheet to exits")
|
||||
mDevice.findObject(UiSelector().description(getStringResource(R.string.quick_settings_sheet)))
|
||||
.waitForExists(waitingTime)
|
||||
Log.i(TAG, "openEnhancedTrackingProtectionSheet: Waited for $waitingTime ms for quick actions sheet to exits")
|
||||
assertUIObjectExists(itemWithResId("$packageName:id/quick_action_sheet"))
|
||||
|
||||
EnhancedTrackingProtectionRobot().interact()
|
||||
return Transition()
|
||||
|
@ -172,31 +236,45 @@ class EnhancedTrackingProtectionRobot {
|
|||
|
||||
fun closeEnhancedTrackingProtectionSheet(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition {
|
||||
// Back out of the Enhanced Tracking Protection sheet
|
||||
Log.i(TAG, "closeEnhancedTrackingProtectionSheet: Trying to click device back button")
|
||||
mDevice.pressBack()
|
||||
Log.i(TAG, "closeEnhancedTrackingProtectionSheet: Clicked device back button")
|
||||
|
||||
BrowserRobot().interact()
|
||||
return BrowserRobot.Transition()
|
||||
}
|
||||
|
||||
fun toggleEnhancedTrackingProtectionFromSheet(interact: EnhancedTrackingProtectionRobot.() -> Unit): Transition {
|
||||
Log.i(TAG, "toggleEnhancedTrackingProtectionFromSheet: Trying to click ETP switch")
|
||||
enhancedTrackingProtectionSwitch().click()
|
||||
Log.i(TAG, "toggleEnhancedTrackingProtectionFromSheet: Clicked ETP switch")
|
||||
|
||||
EnhancedTrackingProtectionRobot().interact()
|
||||
return Transition()
|
||||
}
|
||||
|
||||
fun openProtectionSettings(interact: SettingsSubMenuEnhancedTrackingProtectionRobot.() -> Unit): SettingsSubMenuEnhancedTrackingProtectionRobot.Transition {
|
||||
Log.i(TAG, "openProtectionSettings: Waiting for $waitingTime ms for ETP sheet \"Details\" button to exist")
|
||||
openEnhancedTrackingProtectionDetails().waitForExists(waitingTime)
|
||||
Log.i(TAG, "openProtectionSettings: Waited for $waitingTime ms for ETP sheet \"Details\" button to exist")
|
||||
Log.i(TAG, "openProtectionSettings: Trying to click ETP sheet \"Details\" button")
|
||||
openEnhancedTrackingProtectionDetails().click()
|
||||
Log.i(TAG, "openProtectionSettings: Clicked ETP sheet \"Details\" button")
|
||||
Log.i(TAG, "openProtectionSettings: Trying to click \"Protection Settings\" button")
|
||||
trackingProtectionSettingsButton().click()
|
||||
Log.i(TAG, "openProtectionSettings: Clicked \"Protection Settings\" button")
|
||||
|
||||
SettingsSubMenuEnhancedTrackingProtectionRobot().interact()
|
||||
return SettingsSubMenuEnhancedTrackingProtectionRobot.Transition()
|
||||
}
|
||||
|
||||
fun openDetails(interact: EnhancedTrackingProtectionRobot.() -> Unit): Transition {
|
||||
Log.i(TAG, "openDetails: Waiting for $waitingTime ms for ETP sheet \"Details\" button to exist")
|
||||
openEnhancedTrackingProtectionDetails().waitForExists(waitingTime)
|
||||
Log.i(TAG, "openDetails: Waited for $waitingTime ms for ETP sheet \"Details\" button to exist")
|
||||
Log.i(TAG, "openDetails: Trying to click ETP sheet \"Details\" button")
|
||||
openEnhancedTrackingProtectionDetails().click()
|
||||
Log.i(TAG, "openDetails: Clicked ETP sheet \"Details\" button")
|
||||
|
||||
EnhancedTrackingProtectionRobot().interact()
|
||||
return Transition()
|
||||
|
@ -209,27 +287,6 @@ fun enhancedTrackingProtection(interact: EnhancedTrackingProtectionRobot.() -> U
|
|||
return EnhancedTrackingProtectionRobot.Transition()
|
||||
}
|
||||
|
||||
private fun assertETPSwitchVisibility(visible: Boolean) {
|
||||
if (visible) {
|
||||
enhancedTrackingProtectionSwitch()
|
||||
.check(matches(isDisplayed()))
|
||||
} else {
|
||||
enhancedTrackingProtectionSwitch()
|
||||
.check(matches(not(isDisplayed())))
|
||||
}
|
||||
}
|
||||
|
||||
private fun assertEnhancedTrackingProtectionSheetStatus(status: String, state: Boolean) {
|
||||
mDevice.waitNotNull(Until.findObjects(By.text("Protections are $status for this site")))
|
||||
onView(ViewMatchers.withResourceName("switch_widget")).check(
|
||||
matches(
|
||||
isChecked(
|
||||
state,
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
private fun pageSecurityIndicator() =
|
||||
mDevice.findObject(UiSelector().resourceId("$packageName:id/mozac_browser_toolbar_security_indicator"))
|
||||
|
||||
|
@ -246,7 +303,7 @@ private fun trackingProtectionSettingsButton() =
|
|||
private fun openEnhancedTrackingProtectionDetails() =
|
||||
mDevice.findObject(UiSelector().resourceId("$packageName:id/trackingProtectionDetails"))
|
||||
|
||||
private val trackingContentBlockListButton =
|
||||
private fun trackingContentBlockListButton() =
|
||||
onView(
|
||||
allOf(
|
||||
withText("Tracking Content"),
|
||||
|
@ -254,7 +311,7 @@ private val trackingContentBlockListButton =
|
|||
),
|
||||
)
|
||||
|
||||
private val socialTrackersBlockListButton =
|
||||
private fun socialTrackersBlockListButton() =
|
||||
onView(
|
||||
allOf(
|
||||
withId(R.id.social_media_trackers),
|
||||
|
@ -262,7 +319,7 @@ private val socialTrackersBlockListButton =
|
|||
),
|
||||
)
|
||||
|
||||
private val crossSiteCookiesBlockListButton =
|
||||
private fun crossSiteCookiesBlockListButton() =
|
||||
onView(
|
||||
allOf(
|
||||
withId(R.id.cross_site_tracking),
|
||||
|
@ -270,7 +327,7 @@ private val crossSiteCookiesBlockListButton =
|
|||
),
|
||||
)
|
||||
|
||||
private val cryptominersBlockListButton =
|
||||
private fun cryptominersBlockListButton() =
|
||||
onView(
|
||||
allOf(
|
||||
withId(R.id.cryptominers),
|
||||
|
@ -278,16 +335,10 @@ private val cryptominersBlockListButton =
|
|||
),
|
||||
)
|
||||
|
||||
private val fingerprintersBlockListButton =
|
||||
private fun fingerprintersBlockListButton() =
|
||||
onView(
|
||||
allOf(
|
||||
withId(R.id.fingerprinters),
|
||||
withText("Fingerprinters"),
|
||||
),
|
||||
)
|
||||
|
||||
private fun assertSecuritySheetIsCompletelyDisplayed() {
|
||||
mDevice.findObject(UiSelector().description(getStringResource(R.string.quick_settings_sheet)))
|
||||
.waitForExists(waitingTime)
|
||||
assertUIObjectExists(itemWithResId("$packageName:id/quick_action_sheet"))
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
package org.mozilla.fenix.ui.robots
|
||||
|
||||
import android.util.Log
|
||||
import androidx.test.espresso.Espresso.onView
|
||||
import androidx.test.espresso.action.ViewActions.clearText
|
||||
import androidx.test.espresso.action.ViewActions.typeText
|
||||
|
@ -16,6 +17,7 @@ import androidx.test.espresso.matcher.ViewMatchers.withText
|
|||
import androidx.test.uiautomator.By
|
||||
import androidx.test.uiautomator.Until
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.helpers.Constants.TAG
|
||||
import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime
|
||||
import org.mozilla.fenix.helpers.TestHelper.mDevice
|
||||
import org.mozilla.fenix.helpers.click
|
||||
|
@ -25,52 +27,78 @@ import org.mozilla.fenix.helpers.ext.waitNotNull
|
|||
* Implementation of Robot Pattern for the find in page UI.
|
||||
*/
|
||||
class FindInPageRobot {
|
||||
fun verifyFindInPageQuery() = assertFindInPageQuery()!!
|
||||
fun verifyFindInPageNextButton() = assertFindInPageNextButton()!!
|
||||
fun verifyFindInPagePrevButton() = assertFindInPagePrevButton()!!
|
||||
fun verifyFindInPageCloseButton() = assertFindInPageCloseButton()!!
|
||||
fun clickFindInPageNextButton() = findInPageNextButton().click()
|
||||
fun clickFindInPagePrevButton() = findInPagePrevButton().click()
|
||||
|
||||
fun verifyFindInPageSearchBarItems() {
|
||||
verifyFindInPageQuery()
|
||||
verifyFindInPageNextButton()
|
||||
verifyFindInPagePrevButton()
|
||||
verifyFindInPageCloseButton()
|
||||
fun verifyFindInPageNextButton() {
|
||||
Log.i(TAG, "verifyFindInPageNextButton: Trying to verify find in page next result button is visible")
|
||||
findInPageNextButton()
|
||||
.check(matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
|
||||
Log.i(TAG, "verifyFindInPageNextButton: Verified find in page next result button is visible")
|
||||
}
|
||||
fun verifyFindInPagePrevButton() {
|
||||
Log.i(TAG, "verifyFindInPagePrevButton: Trying to verify find in page previous result button is visible")
|
||||
findInPagePrevButton()
|
||||
.check(matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
|
||||
Log.i(TAG, "verifyFindInPagePrevButton: Verified find in page previous result button is visible")
|
||||
}
|
||||
fun verifyFindInPageCloseButton() {
|
||||
Log.i(TAG, "verifyFindInPageCloseButton: Trying to verify find in page close button is visible")
|
||||
findInPageCloseButton()
|
||||
.check(matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
|
||||
Log.i(TAG, "verifyFindInPageCloseButton: Verified find in page close button is visible")
|
||||
}
|
||||
fun clickFindInPageNextButton() {
|
||||
Log.i(TAG, "clickFindInPageNextButton: Trying to click next result button")
|
||||
findInPageNextButton().click()
|
||||
Log.i(TAG, "clickFindInPageNextButton: Clicked next result button")
|
||||
}
|
||||
fun clickFindInPagePrevButton() {
|
||||
Log.i(TAG, "clickFindInPagePrevButton: Trying to click previous result button")
|
||||
findInPagePrevButton().click()
|
||||
Log.i(TAG, "clickFindInPagePrevButton: Clicked previous result button")
|
||||
}
|
||||
|
||||
fun enterFindInPageQuery(expectedText: String) {
|
||||
mDevice.waitNotNull(Until.findObject(By.res("org.mozilla.fenix.debug:id/find_in_page_query_text")), waitingTime)
|
||||
Log.i(TAG, "enterFindInPageQuery: Trying to clear find in page bar text")
|
||||
findInPageQuery().perform(clearText())
|
||||
Log.i(TAG, "enterFindInPageQuery: Cleared find in page bar text")
|
||||
mDevice.waitNotNull(Until.gone(By.res("org.mozilla.fenix.debug:id/find_in_page_result_text")), waitingTime)
|
||||
Log.i(TAG, "enterFindInPageQuery: Trying to type $expectedText in find in page bar")
|
||||
findInPageQuery().perform(typeText(expectedText))
|
||||
Log.i(TAG, "enterFindInPageQuery: Typed $expectedText in find page bar")
|
||||
mDevice.waitNotNull(Until.findObject(By.res("org.mozilla.fenix.debug:id/find_in_page_result_text")), waitingTime)
|
||||
}
|
||||
|
||||
fun verifyFindNextInPageResult(ratioCounter: String) {
|
||||
mDevice.waitNotNull(Until.findObject(By.text(ratioCounter)), waitingTime)
|
||||
findInPageResult().check(matches(withText((ratioCounter))))
|
||||
}
|
||||
|
||||
fun verifyFindPrevInPageResult(ratioCounter: String) {
|
||||
fun verifyFindInPageResult(ratioCounter: String) {
|
||||
mDevice.waitNotNull(Until.findObject(By.text(ratioCounter)), waitingTime)
|
||||
Log.i(TAG, "verifyFindInPageResult: Trying to verify $ratioCounter results")
|
||||
findInPageResult().check(matches(withText((ratioCounter))))
|
||||
Log.i(TAG, "verifyFindInPageResult: Verified $ratioCounter results")
|
||||
}
|
||||
|
||||
class Transition {
|
||||
fun closeFindInPageWithCloseButton(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition {
|
||||
Log.i(TAG, "closeFindInPageWithCloseButton: Waiting for device to be idle")
|
||||
mDevice.waitForIdle()
|
||||
Log.i(TAG, "closeFindInPageWithCloseButton: Device was idle")
|
||||
Log.i(TAG, "closeFindInPageWithCloseButton: Trying to close find in page button")
|
||||
findInPageCloseButton().click()
|
||||
Log.i(TAG, "closeFindInPageWithCloseButton: Clicked close find in page button")
|
||||
BrowserRobot().interact()
|
||||
return BrowserRobot.Transition()
|
||||
}
|
||||
|
||||
fun closeFindInPageWithBackButton(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition {
|
||||
Log.i(TAG, "closeFindInPageWithBackButton: Waiting for device to be idle")
|
||||
mDevice.waitForIdle()
|
||||
Log.i(TAG, "closeFindInPageWithBackButton: Device was idle")
|
||||
|
||||
// Will need to press back 2x, the first will only dismiss the keyboard
|
||||
Log.i(TAG, "closeFindInPageWithBackButton: Trying to press 1x the device back button")
|
||||
mDevice.pressBack()
|
||||
Log.i(TAG, "closeFindInPageWithBackButton: Pressed 1x the device back button")
|
||||
Log.i(TAG, "closeFindInPageWithBackButton: Trying to press 2x the device back button")
|
||||
mDevice.pressBack()
|
||||
Log.i(TAG, "closeFindInPageWithBackButton: Pressed 2x the device back button")
|
||||
|
||||
BrowserRobot().interact()
|
||||
return BrowserRobot.Transition()
|
||||
|
@ -83,15 +111,3 @@ private fun findInPageResult() = onView(withId(R.id.find_in_page_result_text))
|
|||
private fun findInPageNextButton() = onView(withId(R.id.find_in_page_next_btn))
|
||||
private fun findInPagePrevButton() = onView(withId(R.id.find_in_page_prev_btn))
|
||||
private fun findInPageCloseButton() = onView(withId(R.id.find_in_page_close_btn))
|
||||
|
||||
private fun assertFindInPageQuery() = findInPageQuery()
|
||||
.check(matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
|
||||
|
||||
private fun assertFindInPageNextButton() = findInPageNextButton()
|
||||
.check(matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
|
||||
|
||||
private fun assertFindInPagePrevButton() = findInPagePrevButton()
|
||||
.check(matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
|
||||
|
||||
private fun assertFindInPageCloseButton() = findInPageCloseButton()
|
||||
.check(matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
package org.mozilla.fenix.ui.robots
|
||||
|
||||
import android.net.Uri
|
||||
import android.util.Log
|
||||
import androidx.test.espresso.Espresso.onView
|
||||
import androidx.test.espresso.assertion.ViewAssertions.matches
|
||||
import androidx.test.espresso.matcher.RootMatchers.isDialog
|
||||
|
@ -19,9 +20,9 @@ import androidx.test.espresso.matcher.ViewMatchers.withText
|
|||
import androidx.test.uiautomator.By
|
||||
import androidx.test.uiautomator.UiSelector
|
||||
import androidx.test.uiautomator.Until
|
||||
import org.hamcrest.Matchers
|
||||
import org.hamcrest.Matchers.allOf
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.helpers.Constants.TAG
|
||||
import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource
|
||||
import org.mozilla.fenix.helpers.MatcherHelper.assertUIObjectExists
|
||||
import org.mozilla.fenix.helpers.MatcherHelper.itemContainingText
|
||||
|
@ -38,17 +39,32 @@ import org.mozilla.fenix.helpers.ext.waitNotNull
|
|||
*/
|
||||
class HistoryRobot {
|
||||
|
||||
fun verifyHistoryMenuView() = assertHistoryMenuView()
|
||||
fun verifyHistoryMenuView() {
|
||||
Log.i(TAG, "verifyHistoryMenuView: Trying to verify that history menu view is visible")
|
||||
onView(
|
||||
allOf(withText("History"), withParent(withId(R.id.navigationToolbar))),
|
||||
).check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
|
||||
Log.i(TAG, "verifyHistoryMenuView: Verified that history menu view is visible")
|
||||
}
|
||||
|
||||
fun verifyEmptyHistoryView() {
|
||||
Log.i(TAG, "verifyEmptyHistoryView: Waiting for $waitingTime ms for empty history list view to exist")
|
||||
mDevice.findObject(
|
||||
UiSelector().text("No history here"),
|
||||
).waitForExists(waitingTime)
|
||||
Log.i(TAG, "verifyEmptyHistoryView: Waited for $waitingTime ms for empty history list view to exist")
|
||||
|
||||
assertEmptyHistoryView()
|
||||
Log.i(TAG, "verifyEmptyHistoryView: Trying to verify empty history list view")
|
||||
onView(
|
||||
allOf(
|
||||
withId(R.id.history_empty_view),
|
||||
withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE),
|
||||
),
|
||||
).check(matches(withText("No history here")))
|
||||
Log.i(TAG, "verifyEmptyHistoryView: Verified empty history list view")
|
||||
}
|
||||
|
||||
fun verifyHistoryListExists() = assertHistoryListExists()
|
||||
fun verifyHistoryListExists() = assertUIObjectExists(itemWithResId("$packageName:id/history_list"))
|
||||
|
||||
fun verifyVisitedTimeTitle() {
|
||||
mDevice.waitNotNull(
|
||||
|
@ -57,53 +73,87 @@ class HistoryRobot {
|
|||
),
|
||||
waitingTime,
|
||||
)
|
||||
assertVisitedTimeTitle()
|
||||
Log.i(TAG, "verifyVisitedTimeTitle: Trying to verify \"Today\" chronological timeline title")
|
||||
onView(withId(R.id.header_title)).check(matches(withText("Today")))
|
||||
Log.i(TAG, "verifyVisitedTimeTitle: Verified \"Today\" chronological timeline title")
|
||||
}
|
||||
|
||||
fun verifyHistoryItemExists(shouldExist: Boolean, item: String) =
|
||||
assertUIObjectExists(itemContainingText(item), exists = shouldExist)
|
||||
|
||||
fun verifyFirstTestPageTitle(title: String) = assertTestPageTitle(title)
|
||||
|
||||
fun verifyTestPageUrl(expectedUrl: Uri) = pageUrl(expectedUrl.toString()).check(matches(isDisplayed()))
|
||||
|
||||
fun verifyCopySnackBarText() = assertCopySnackBarText()
|
||||
|
||||
fun verifyDeleteConfirmationMessage() = assertDeleteConfirmationMessage()
|
||||
|
||||
fun verifyHomeScreen() = HomeScreenRobot().verifyHomeScreen()
|
||||
|
||||
fun clickDeleteHistoryButton(item: String) {
|
||||
deleteButton(item).click()
|
||||
fun verifyFirstTestPageTitle(title: String) {
|
||||
Log.i(TAG, "verifyFirstTestPageTitle: Trying to verify $title page title is visible")
|
||||
testPageTitle()
|
||||
.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
|
||||
.check(matches(withText(title)))
|
||||
Log.i(TAG, "verifyFirstTestPageTitle: Verified $title page title is visible")
|
||||
}
|
||||
|
||||
fun verifyDeleteHistoryItemButton(historyItemTitle: String) =
|
||||
fun verifyTestPageUrl(expectedUrl: Uri) {
|
||||
Log.i(TAG, "verifyTestPageUrl: Trying to verify page url: $expectedUrl is displayed")
|
||||
pageUrl(expectedUrl.toString()).check(matches(isDisplayed()))
|
||||
Log.i(TAG, "verifyTestPageUrl: Verified page url: $expectedUrl is displayed")
|
||||
}
|
||||
|
||||
fun verifyDeleteConfirmationMessage() =
|
||||
assertUIObjectExists(
|
||||
itemWithResIdContainingText("$packageName:id/title", getStringResource(R.string.delete_history_prompt_title)),
|
||||
itemWithResIdContainingText("$packageName:id/body", getStringResource(R.string.delete_history_prompt_body_2)),
|
||||
)
|
||||
|
||||
fun clickDeleteHistoryButton(item: String) {
|
||||
Log.i(TAG, "clickDeleteHistoryButton: Trying to click delete history button for item: $item")
|
||||
deleteButton(item).click()
|
||||
Log.i(TAG, "clickDeleteHistoryButton: Clicked delete history button for item: $item")
|
||||
}
|
||||
|
||||
fun verifyDeleteHistoryItemButton(historyItemTitle: String) {
|
||||
Log.i(TAG, "verifyDeleteHistoryItemButton: Trying to verify delete history button for item: $historyItemTitle is visible")
|
||||
deleteButton(historyItemTitle).check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
|
||||
Log.i(TAG, "verifyDeleteHistoryItemButton: Verified delete history button for item: $historyItemTitle is visible")
|
||||
}
|
||||
|
||||
fun clickDeleteAllHistoryButton() = deleteButton().click()
|
||||
fun clickDeleteAllHistoryButton() {
|
||||
Log.i(TAG, "clickDeleteAllHistoryButton: Trying to click delete all history button")
|
||||
deleteButton().click()
|
||||
Log.i(TAG, "clickDeleteAllHistoryButton: Clicked delete all history button")
|
||||
}
|
||||
|
||||
fun selectEverythingOption() = deleteHistoryEverythingOption().click()
|
||||
fun selectEverythingOption() {
|
||||
Log.i(TAG, "selectEverythingOption: Trying to click \"Everything\" dialog option")
|
||||
deleteHistoryEverythingOption().click()
|
||||
Log.i(TAG, "selectEverythingOption: Clicked \"Everything\" dialog option")
|
||||
}
|
||||
|
||||
fun confirmDeleteAllHistory() {
|
||||
Log.i(TAG, "confirmDeleteAllHistory: Trying to click \"Delete\" dialog button")
|
||||
onView(withText("Delete"))
|
||||
.inRoot(isDialog())
|
||||
.check(matches(isDisplayed()))
|
||||
.click()
|
||||
Log.i(TAG, "confirmDeleteAllHistory: Clicked \"Delete\" dialog button")
|
||||
}
|
||||
|
||||
fun cancelDeleteHistory() =
|
||||
fun cancelDeleteHistory() {
|
||||
Log.i(TAG, "cancelDeleteHistory: Trying to click \"Cancel\" dialog button")
|
||||
mDevice
|
||||
.findObject(
|
||||
UiSelector()
|
||||
.textContains(getStringResource(R.string.delete_browsing_data_prompt_cancel)),
|
||||
).click()
|
||||
Log.i(TAG, "cancelDeleteHistory: Clicked \"Cancel\" dialog button")
|
||||
}
|
||||
|
||||
fun verifyDeleteSnackbarText(text: String) = assertSnackBarText(text)
|
||||
|
||||
fun verifyUndoDeleteSnackBarButton() = assertUndoDeleteSnackBarButton()
|
||||
fun verifyUndoDeleteSnackBarButton() {
|
||||
Log.i(TAG, "verifyUndoDeleteSnackBarButton: Trying to verify \"Undo\" snackbar button")
|
||||
snackBarUndoButton().check(matches(withText("UNDO")))
|
||||
Log.i(TAG, "verifyUndoDeleteSnackBarButton: Verified \"Undo\" snackbar button")
|
||||
}
|
||||
|
||||
fun clickUndoDeleteButton() {
|
||||
Log.i(TAG, "verifyUndoDeleteSnackBarButton: Trying to click \"Undo\" snackbar button")
|
||||
snackBarUndoButton().click()
|
||||
Log.i(TAG, "verifyUndoDeleteSnackBarButton: Clicked \"Undo\" snackbar button")
|
||||
}
|
||||
|
||||
fun verifySearchGroupDisplayed(shouldBeDisplayed: Boolean, searchTerm: String, groupSize: Int) =
|
||||
|
@ -117,36 +167,50 @@ class HistoryRobot {
|
|||
)
|
||||
|
||||
fun openSearchGroup(searchTerm: String) {
|
||||
Log.i(TAG, "openSearchGroup: Waiting for $waitingTime ms for search group: $searchTerm to exist")
|
||||
mDevice.findObject(UiSelector().text(searchTerm)).waitForExists(waitingTime)
|
||||
Log.i(TAG, "openSearchGroup: Waited for $waitingTime ms for search group: $searchTerm to exist")
|
||||
Log.i(TAG, "openSearchGroup: Trying to click search group: $searchTerm")
|
||||
mDevice.findObject(UiSelector().text(searchTerm)).click()
|
||||
Log.i(TAG, "openSearchGroup: Clicked search group: $searchTerm")
|
||||
}
|
||||
|
||||
class Transition {
|
||||
fun goBack(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition {
|
||||
Log.i(TAG, "goBack: Trying to click go back menu button")
|
||||
onView(withContentDescription("Navigate up")).click()
|
||||
Log.i(TAG, "goBack: Clicked go back menu button")
|
||||
|
||||
BrowserRobot().interact()
|
||||
return BrowserRobot.Transition()
|
||||
}
|
||||
|
||||
fun openWebsite(url: Uri, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition {
|
||||
assertHistoryListExists()
|
||||
assertUIObjectExists(itemWithResId("$packageName:id/history_list"))
|
||||
Log.i(TAG, "openWebsite: Trying to click history item with url: $url")
|
||||
onView(withText(url.toString())).click()
|
||||
Log.i(TAG, "openWebsite: Clicked history item with url: $url")
|
||||
|
||||
BrowserRobot().interact()
|
||||
return BrowserRobot.Transition()
|
||||
}
|
||||
|
||||
fun openRecentlyClosedTabs(interact: RecentlyClosedTabsRobot.() -> Unit): RecentlyClosedTabsRobot.Transition {
|
||||
recentlyClosedTabsListButton.waitForExists(waitingTime)
|
||||
recentlyClosedTabsListButton.click()
|
||||
Log.i(TAG, "openRecentlyClosedTabs: Waiting for $waitingTime ms for \"Recently closed tabs\" button to exist")
|
||||
recentlyClosedTabsListButton().waitForExists(waitingTime)
|
||||
Log.i(TAG, "openRecentlyClosedTabs: Waited for $waitingTime ms for \"Recently closed tabs\" button to exist")
|
||||
Log.i(TAG, "openRecentlyClosedTabs: Trying to click \"Recently closed tabs\" button")
|
||||
recentlyClosedTabsListButton().click()
|
||||
Log.i(TAG, "openRecentlyClosedTabs: Clicked \"Recently closed tabs\" button")
|
||||
|
||||
RecentlyClosedTabsRobot().interact()
|
||||
return RecentlyClosedTabsRobot.Transition()
|
||||
}
|
||||
|
||||
fun clickSearchButton(interact: SearchRobot.() -> Unit): SearchRobot.Transition {
|
||||
Log.i(TAG, "clickSearchButton: Trying to click search history button")
|
||||
itemWithResId("$packageName:id/history_search").click()
|
||||
Log.i(TAG, "clickSearchButton: Clicked search history button")
|
||||
|
||||
SearchRobot().interact()
|
||||
return SearchRobot.Transition()
|
||||
|
@ -168,50 +232,8 @@ private fun deleteButton(title: String) =
|
|||
|
||||
private fun deleteButton() = onView(withId(R.id.history_delete))
|
||||
|
||||
private fun snackBarText() = onView(withId(R.id.snackbar_text))
|
||||
|
||||
private fun assertHistoryMenuView() {
|
||||
onView(
|
||||
allOf(withText("History"), withParent(withId(R.id.navigationToolbar))),
|
||||
)
|
||||
.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
|
||||
}
|
||||
|
||||
private fun assertEmptyHistoryView() =
|
||||
onView(
|
||||
allOf(
|
||||
withId(R.id.history_empty_view),
|
||||
withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE),
|
||||
),
|
||||
)
|
||||
.check(matches(withText("No history here")))
|
||||
|
||||
private fun assertHistoryListExists() =
|
||||
mDevice.findObject(UiSelector().resourceId("$packageName:id/history_list")).waitForExists(waitingTime)
|
||||
|
||||
private fun assertVisitedTimeTitle() =
|
||||
onView(withId(R.id.header_title)).check(matches(withText("Today")))
|
||||
|
||||
private fun assertTestPageTitle(title: String) = testPageTitle()
|
||||
.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
|
||||
.check(matches(withText(title)))
|
||||
|
||||
private fun assertDeleteConfirmationMessage() =
|
||||
assertUIObjectExists(
|
||||
itemWithResIdContainingText("$packageName:id/title", getStringResource(R.string.delete_history_prompt_title)),
|
||||
itemWithResIdContainingText("$packageName:id/body", getStringResource(R.string.delete_history_prompt_body_2)),
|
||||
)
|
||||
|
||||
private fun assertCopySnackBarText() = snackBarText().check(matches(withText("URL copied")))
|
||||
|
||||
private fun assertSnackBarText(text: String) =
|
||||
snackBarText().check(matches(withText(Matchers.containsString(text))))
|
||||
|
||||
private fun snackBarUndoButton() = onView(withId(R.id.snackbar_btn))
|
||||
|
||||
private fun assertUndoDeleteSnackBarButton() =
|
||||
snackBarUndoButton().check(matches(withText("UNDO")))
|
||||
|
||||
private fun deleteHistoryEverythingOption() =
|
||||
mDevice
|
||||
.findObject(
|
||||
|
@ -220,5 +242,5 @@ private fun deleteHistoryEverythingOption() =
|
|||
.resourceId("$packageName:id/everything_button"),
|
||||
)
|
||||
|
||||
private val recentlyClosedTabsListButton =
|
||||
private fun recentlyClosedTabsListButton() =
|
||||
mDevice.findObject(UiSelector().resourceId("$packageName:id/recently_closed_tabs_header"))
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
package org.mozilla.fenix.ui.robots
|
||||
|
||||
import android.net.Uri
|
||||
import android.widget.TextView
|
||||
import android.util.Log
|
||||
import androidx.compose.ui.test.onNodeWithTag
|
||||
import androidx.test.espresso.Espresso.onView
|
||||
import androidx.test.espresso.assertion.ViewAssertions.matches
|
||||
|
@ -16,12 +16,12 @@ import androidx.test.espresso.matcher.ViewMatchers.withId
|
|||
import androidx.test.espresso.matcher.ViewMatchers.withParent
|
||||
import androidx.test.espresso.matcher.ViewMatchers.withText
|
||||
import androidx.test.uiautomator.By
|
||||
import androidx.test.uiautomator.UiSelector
|
||||
import androidx.test.uiautomator.Until
|
||||
import org.hamcrest.Matchers.allOf
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.helpers.Constants
|
||||
import org.mozilla.fenix.helpers.Constants.TAG
|
||||
import org.mozilla.fenix.helpers.HomeActivityComposeTestRule
|
||||
import org.mozilla.fenix.helpers.TestAssetHelper
|
||||
import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime
|
||||
import org.mozilla.fenix.helpers.TestHelper.mDevice
|
||||
import org.mozilla.fenix.helpers.TestHelper.packageName
|
||||
|
@ -34,30 +34,90 @@ import org.mozilla.fenix.tabstray.TabsTrayTestTag
|
|||
*/
|
||||
class LibrarySubMenusMultipleSelectionToolbarRobot {
|
||||
|
||||
fun verifyMultiSelectionCheckmark() = assertMultiSelectionCheckmark()
|
||||
fun verifyMultiSelectionCheckmark() {
|
||||
Log.i(TAG, "verifyMultiSelectionCheckmark: Trying to verify that the multi-selection checkmark is displayed")
|
||||
onView(withId(R.id.checkmark)).check(matches(isDisplayed()))
|
||||
Log.i(TAG, "verifyMultiSelectionCheckmark: Verified that the multi-selection checkmark is displayed")
|
||||
}
|
||||
|
||||
fun verifyMultiSelectionCheckmark(url: Uri) = assertMultiSelectionCheckmark(url)
|
||||
fun verifyMultiSelectionCheckmark(url: Uri) {
|
||||
Log.i(TAG, "verifyMultiSelectionCheckmark: Trying to verify that the multi-selection checkmark for item with url: $url is displayed")
|
||||
onView(
|
||||
allOf(
|
||||
withId(R.id.checkmark),
|
||||
withParent(
|
||||
withParent(
|
||||
withChild(
|
||||
allOf(
|
||||
withId(R.id.url),
|
||||
withText(url.toString()),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
fun verifyMultiSelectionCounter() = assertMultiSelectionCounter()
|
||||
// This is used as part of the `multiSelectionToolbarItemsTest` test. Somehow, in the view hierarchy,
|
||||
// the match above is finding two checkmark views - one visible, one hidden, which is throwing off
|
||||
// the matcher. This 'isDisplayed' check is a hacky workaround for this, we're explicitly ignoring
|
||||
// the hidden one. Why are there two to begin with, though?
|
||||
isDisplayed(),
|
||||
),
|
||||
).check(matches(isDisplayed()))
|
||||
Log.i(Constants.TAG, "verifyMultiSelectionCheckmark: Verified that the multi-selection checkmark for item with url: $url is displayed")
|
||||
}
|
||||
|
||||
fun verifyShareHistoryButton() = assertShareHistoryButton()
|
||||
fun verifyMultiSelectionCounter() {
|
||||
Log.i(TAG, "verifyMultiSelectionCounter: Trying to verify that the multi-selection toolbar containing: \"1 selected\" is displayed")
|
||||
onView(withText("1 selected")).check(matches(isDisplayed()))
|
||||
Log.i(TAG, "verifyMultiSelectionCounter: Verified that the multi-selection toolbar containing: \"1 selected\" is displayed")
|
||||
}
|
||||
|
||||
fun verifyShareBookmarksButton() = assertShareBookmarksButton()
|
||||
fun verifyShareHistoryButton() {
|
||||
Log.i(TAG, "verifyShareHistoryButton: Trying to verify that the multi-selection share history button is displayed")
|
||||
shareHistoryButton().check(matches(isDisplayed()))
|
||||
Log.i(TAG, "verifyShareHistoryButton: Verified that the multi-selection share history button is displayed")
|
||||
}
|
||||
|
||||
fun verifyShareOverlay() = assertShareOverlay()
|
||||
fun verifyShareBookmarksButton() {
|
||||
Log.i(TAG, "verifyShareBookmarksButton: Trying to verify that the multi-selection share bookmarks button is displayed")
|
||||
shareBookmarksButton().check(matches(isDisplayed()))
|
||||
Log.i(TAG, "verifyShareBookmarksButton: Verified that the multi-selection share bookmarks button is displayed")
|
||||
}
|
||||
|
||||
fun verifyShareAppsLayout() = assertShareAppsLayout()
|
||||
fun verifyShareOverlay() {
|
||||
Log.i(TAG, "verifyShareOverlay: Trying to verify that the share overlay is displayed")
|
||||
onView(withId(R.id.shareWrapper)).check(matches(isDisplayed()))
|
||||
Log.i(TAG, "verifyShareOverlay: Verified that the share overlay is displayed")
|
||||
}
|
||||
|
||||
fun verifyShareTabFavicon() = assertShareTabFavicon()
|
||||
fun verifyShareTabFavicon() {
|
||||
Log.i(TAG, "verifyShareTabFavicon: Trying to verify that the shared tab favicon is displayed")
|
||||
onView(withId(R.id.share_tab_favicon)).check(matches(isDisplayed()))
|
||||
Log.i(TAG, "verifyShareTabFavicon: Verified that the shared tab favicon is displayed")
|
||||
}
|
||||
|
||||
fun verifyShareTabTitle() = assertShareTabTitle()
|
||||
fun verifyShareTabTitle() {
|
||||
Log.i(TAG, "verifyShareTabTitle: Trying to verify that the shared tab title is displayed")
|
||||
onView(withId(R.id.share_tab_title)).check(matches(isDisplayed()))
|
||||
Log.i(TAG, "verifyShareTabTitle: Verified that the shared tab title is displayed")
|
||||
}
|
||||
|
||||
fun verifyShareTabUrl() = assertShareTabUrl()
|
||||
fun verifyShareTabUrl() {
|
||||
Log.i(TAG, "verifyShareTabUrl: Trying to verify that the shared tab url is displayed")
|
||||
onView(withId(R.id.share_tab_url)).check(matches(isDisplayed()))
|
||||
Log.i(TAG, "verifyShareTabUrl: Verified that the shared tab url is displayed")
|
||||
}
|
||||
|
||||
fun verifyCloseToolbarButton() = assertCloseToolbarButton()
|
||||
fun verifyCloseToolbarButton() {
|
||||
Log.i(TAG, "verifyCloseToolbarButton: Trying to verify that the navigate up toolbar button is displayed")
|
||||
closeToolbarButton().check(matches(isDisplayed()))
|
||||
Log.i(TAG, "verifyCloseToolbarButton: Verified that the navigate up toolbar button is displayed")
|
||||
}
|
||||
|
||||
fun clickShareHistoryButton() {
|
||||
Log.i(TAG, "clickShareHistoryButton: Trying to click the multi-selection share history button")
|
||||
shareHistoryButton().click()
|
||||
Log.i(TAG, "clickShareHistoryButton: Clicked the multi-selection share history button")
|
||||
|
||||
mDevice.waitNotNull(
|
||||
Until.findObject(
|
||||
|
@ -68,7 +128,9 @@ class LibrarySubMenusMultipleSelectionToolbarRobot {
|
|||
}
|
||||
|
||||
fun clickShareBookmarksButton() {
|
||||
Log.i(TAG, "clickShareBookmarksButton: Trying to click the multi-selection share bookmarks button")
|
||||
shareBookmarksButton().click()
|
||||
Log.i(TAG, "clickShareBookmarksButton: Clicked the multi-selection share bookmarks button")
|
||||
|
||||
mDevice.waitNotNull(
|
||||
Until.findObject(
|
||||
|
@ -79,31 +141,35 @@ class LibrarySubMenusMultipleSelectionToolbarRobot {
|
|||
}
|
||||
|
||||
fun clickMultiSelectionDelete() {
|
||||
Log.i(TAG, "clickMultiSelectionDelete: Trying to click the multi-selection delete button")
|
||||
deleteButton().click()
|
||||
Log.i(TAG, "clickMultiSelectionDelete: Clicked the multi-selection delete button")
|
||||
}
|
||||
|
||||
class Transition {
|
||||
fun closeShareDialogReturnToPage(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition {
|
||||
BrowserRobot().interact()
|
||||
return BrowserRobot.Transition()
|
||||
}
|
||||
|
||||
fun closeToolbarReturnToHistory(interact: HistoryRobot.() -> Unit): HistoryRobot.Transition {
|
||||
Log.i(TAG, "closeToolbarReturnToHistory: Trying to click the navigate up toolbar button")
|
||||
closeToolbarButton().click()
|
||||
Log.i(TAG, "closeToolbarReturnToHistory: Clicked the navigate up toolbar button")
|
||||
|
||||
HistoryRobot().interact()
|
||||
return HistoryRobot.Transition()
|
||||
}
|
||||
|
||||
fun closeToolbarReturnToBookmarks(interact: BookmarksRobot.() -> Unit): BookmarksRobot.Transition {
|
||||
Log.i(TAG, "closeToolbarReturnToBookmarks: Trying to click the navigate up toolbar button")
|
||||
closeToolbarButton().click()
|
||||
Log.i(TAG, "closeToolbarReturnToBookmarks: Clicked the navigate up toolbar button")
|
||||
|
||||
BookmarksRobot().interact()
|
||||
return BookmarksRobot.Transition()
|
||||
}
|
||||
|
||||
fun clickOpenNewTab(interact: TabDrawerRobot.() -> Unit): TabDrawerRobot.Transition {
|
||||
Log.i(TAG, "clickOpenNewTab: Trying to click the multi-select \"Open in a new tab\" context menu button")
|
||||
openInNewTabButton().click()
|
||||
Log.i(TAG, "clickOpenNewTab: Clicked the multi-select \"Open in a new tab\" context menu button")
|
||||
|
||||
mDevice.waitNotNull(
|
||||
Until.findObject(By.res("$packageName:id/tab_layout")),
|
||||
waitingTime,
|
||||
|
@ -114,15 +180,21 @@ class LibrarySubMenusMultipleSelectionToolbarRobot {
|
|||
}
|
||||
|
||||
fun clickOpenNewTab(composeTestRule: HomeActivityComposeTestRule, interact: ComposeTabDrawerRobot.() -> Unit): ComposeTabDrawerRobot.Transition {
|
||||
Log.i(TAG, "clickOpenNewTab: Trying to click the multi-select \"Open in a new tab\" context menu button")
|
||||
openInNewTabButton().click()
|
||||
Log.i(TAG, "clickOpenNewTab: Clicked the multi-select \"Open in a new tab\" context menu button")
|
||||
Log.i(TAG, "clickOpenNewTab: Trying to verify that the tabs tray exists")
|
||||
composeTestRule.onNodeWithTag(TabsTrayTestTag.tabsTray).assertExists()
|
||||
Log.i(TAG, "clickOpenNewTab: Verified that the tabs tray exists")
|
||||
|
||||
ComposeTabDrawerRobot(composeTestRule).interact()
|
||||
return ComposeTabDrawerRobot.Transition(composeTestRule)
|
||||
}
|
||||
|
||||
fun clickOpenPrivateTab(interact: TabDrawerRobot.() -> Unit): TabDrawerRobot.Transition {
|
||||
Log.i(TAG, "clickOpenPrivateTab: Trying to click the multi-select \"Open in a private tab\" context menu button")
|
||||
openInPrivateTabButton().click()
|
||||
Log.i(TAG, "clickOpenPrivateTab: Clicked the multi-select \"Open in a private tab\" context menu button")
|
||||
mDevice.waitNotNull(
|
||||
Until.findObject(By.res("$packageName:id/tab_layout")),
|
||||
waitingTime,
|
||||
|
@ -133,7 +205,9 @@ class LibrarySubMenusMultipleSelectionToolbarRobot {
|
|||
}
|
||||
|
||||
fun clickOpenPrivateTab(composeTestRule: HomeActivityComposeTestRule, interact: ComposeTabDrawerRobot.() -> Unit): ComposeTabDrawerRobot.Transition {
|
||||
Log.i(TAG, "clickOpenPrivateTab: Trying to click the multi-select \"Open in a private tab\" context menu button")
|
||||
openInPrivateTabButton().click()
|
||||
Log.i(TAG, "clickOpenPrivateTab: Clicked the multi-select \"Open in a private tab\" context menu button")
|
||||
|
||||
ComposeTabDrawerRobot(composeTestRule).interact()
|
||||
return ComposeTabDrawerRobot.Transition(composeTestRule)
|
||||
|
@ -157,53 +231,3 @@ private fun openInNewTabButton() = onView(withText("Open in new tab"))
|
|||
private fun openInPrivateTabButton() = onView(withText("Open in private tab"))
|
||||
|
||||
private fun deleteButton() = onView(withText("Delete"))
|
||||
|
||||
private fun assertMultiSelectionCheckmark() =
|
||||
onView(withId(R.id.checkmark))
|
||||
.check(matches(isDisplayed()))
|
||||
|
||||
private fun assertMultiSelectionCheckmark(url: Uri) =
|
||||
onView(
|
||||
allOf(
|
||||
withId(R.id.checkmark),
|
||||
withParent(withParent(withChild(allOf(withId(R.id.url), withText(url.toString()))))),
|
||||
|
||||
// This is used as part of the `multiSelectionToolbarItemsTest` test. Somehow, in the view hierarchy,
|
||||
// the match above is finding two checkmark views - one visible, one hidden, which is throwing off
|
||||
// the matcher. This 'isDisplayed' check is a hacky workaround for this, we're explicitly ignoring
|
||||
// the hidden one. Why are there two to begin with, though?
|
||||
isDisplayed(),
|
||||
),
|
||||
)
|
||||
.check(matches(isDisplayed()))
|
||||
|
||||
private fun assertMultiSelectionCounter() =
|
||||
onView(withText("1 selected")).check(matches(isDisplayed()))
|
||||
|
||||
private fun assertShareHistoryButton() =
|
||||
shareHistoryButton().check(matches(isDisplayed()))
|
||||
|
||||
private fun assertShareBookmarksButton() =
|
||||
shareBookmarksButton().check(matches(isDisplayed()))
|
||||
|
||||
private fun assertShareOverlay() =
|
||||
onView(withId(R.id.shareWrapper)).check(matches(isDisplayed()))
|
||||
|
||||
private fun assertShareAppsLayout() = {
|
||||
val sendToDeviceTitle = mDevice.findObject(
|
||||
UiSelector()
|
||||
.instance(0)
|
||||
.className(TextView::class.java),
|
||||
)
|
||||
sendToDeviceTitle.waitForExists(TestAssetHelper.waitingTime)
|
||||
}
|
||||
|
||||
private fun assertShareTabTitle() =
|
||||
onView(withId(R.id.share_tab_title)).check(matches(isDisplayed()))
|
||||
|
||||
private fun assertShareTabFavicon() =
|
||||
onView(withId(R.id.share_tab_favicon)).check(matches(isDisplayed()))
|
||||
|
||||
private fun assertShareTabUrl() = onView(withId(R.id.share_tab_url))
|
||||
|
||||
private fun assertCloseToolbarButton() = closeToolbarButton().check(matches(isDisplayed()))
|
||||
|
|
|
@ -31,7 +31,6 @@ import androidx.test.uiautomator.By.textContains
|
|||
import androidx.test.uiautomator.UiSelector
|
||||
import androidx.test.uiautomator.Until
|
||||
import org.hamcrest.CoreMatchers.allOf
|
||||
import org.hamcrest.CoreMatchers.not
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.helpers.Constants
|
||||
|
@ -58,27 +57,55 @@ import org.mozilla.fenix.tabstray.TabsTrayTestTag
|
|||
* Implementation of Robot Pattern for the URL toolbar.
|
||||
*/
|
||||
class NavigationToolbarRobot {
|
||||
fun verifyUrl(url: String) =
|
||||
fun verifyUrl(url: String) {
|
||||
Log.i(TAG, "verifyUrl: Trying to verify toolbar text matches $url")
|
||||
onView(withId(R.id.mozac_browser_toolbar_url_view)).check(matches(withText(url)))
|
||||
Log.i(TAG, "verifyUrl: Verified toolbar text matches $url")
|
||||
}
|
||||
|
||||
fun verifyNoHistoryBookmarks() = assertNoHistoryBookmarks()
|
||||
fun verifyTabButtonShortcutMenuItems() {
|
||||
Log.i(TAG, "verifyTabButtonShortcutMenuItems: Trying to verify tab counter shortcut options")
|
||||
onView(withId(R.id.mozac_browser_menu_recyclerView))
|
||||
.check(matches(hasDescendant(withText("Close tab"))))
|
||||
.check(matches(hasDescendant(withText("New private tab"))))
|
||||
.check(matches(hasDescendant(withText("New tab"))))
|
||||
Log.i(TAG, "verifyTabButtonShortcutMenuItems: Verified tab counter shortcut options")
|
||||
}
|
||||
|
||||
fun verifyTabButtonShortcutMenuItems() = assertTabButtonShortcutMenuItems()
|
||||
|
||||
fun verifyReaderViewDetected(visible: Boolean = false) =
|
||||
assertReaderViewDetected(visible)
|
||||
|
||||
fun verifyCloseReaderViewDetected(visible: Boolean = false) =
|
||||
assertCloseReaderViewDetected(visible)
|
||||
fun verifyReaderViewDetected(visible: Boolean = false) {
|
||||
Log.i(TAG, "verifyReaderViewDetected: Waiting for $waitingTime ms for reader view button to exist")
|
||||
mDevice.findObject(
|
||||
UiSelector()
|
||||
.description("Reader view"),
|
||||
).waitForExists(waitingTime)
|
||||
Log.i(TAG, "verifyReaderViewDetected: Waited for $waitingTime ms for reader view button to exist")
|
||||
Log.i(TAG, "verifyReaderViewDetected: Trying to verify that the reader view button is visible")
|
||||
onView(
|
||||
allOf(
|
||||
withParent(withId(R.id.mozac_browser_toolbar_page_actions)),
|
||||
withContentDescription("Reader view"),
|
||||
),
|
||||
).check(
|
||||
if (visible) {
|
||||
matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))
|
||||
} else {
|
||||
ViewAssertions.doesNotExist()
|
||||
},
|
||||
)
|
||||
Log.i(TAG, "verifyReaderViewDetected: Verified that the reader view button is visible")
|
||||
}
|
||||
|
||||
fun toggleReaderView() {
|
||||
Log.i(TAG, "toggleReaderView: Waiting for $waitingTime ms for reader view button to exist")
|
||||
mDevice.findObject(
|
||||
UiSelector()
|
||||
.resourceId("$packageName:id/mozac_browser_toolbar_page_actions"),
|
||||
)
|
||||
.waitForExists(waitingTime)
|
||||
|
||||
Log.i(TAG, "toggleReaderView: Waited for $waitingTime ms for reader view button to exist")
|
||||
Log.i(TAG, "toggleReaderView: Trying to click the reader view button")
|
||||
readerViewToggle().click()
|
||||
Log.i(TAG, "toggleReaderView: Clicked the reader view button")
|
||||
}
|
||||
|
||||
fun verifyClipboardSuggestionsAreDisplayed(link: String = "", shouldBeDisplayed: Boolean) =
|
||||
|
@ -91,35 +118,49 @@ class NavigationToolbarRobot {
|
|||
exists = shouldBeDisplayed,
|
||||
)
|
||||
|
||||
fun longClickEditModeToolbar() =
|
||||
mDevice.findObject(By.res("$packageName:id/mozac_browser_toolbar_edit_url_view")).click(LONG_CLICK_DURATION)
|
||||
fun longClickEditModeToolbar() {
|
||||
Log.i(TAG, "longClickEditModeToolbar: Trying to long click the edit mode toolbar")
|
||||
mDevice.findObject(By.res("$packageName:id/mozac_browser_toolbar_edit_url_view"))
|
||||
.click(LONG_CLICK_DURATION)
|
||||
Log.i(TAG, "longClickEditModeToolbar: Long clicked the edit mode toolbar")
|
||||
}
|
||||
|
||||
fun clickContextMenuItem(item: String) {
|
||||
mDevice.waitNotNull(
|
||||
Until.findObject(By.text(item)),
|
||||
waitingTime,
|
||||
)
|
||||
Log.i(TAG, "clickContextMenuItem: Trying click context menu item: $item")
|
||||
mDevice.findObject(By.text(item)).click()
|
||||
Log.i(TAG, "clickContextMenuItem: Clicked context menu item: $item")
|
||||
}
|
||||
|
||||
fun clickClearToolbarButton() = clearAddressBarButton().click()
|
||||
fun clickClearToolbarButton() {
|
||||
Log.i(TAG, "clickClearToolbarButton: Trying click the clear address button")
|
||||
clearAddressBarButton().click()
|
||||
Log.i(TAG, "clickClearToolbarButton: Clicked the clear address button")
|
||||
}
|
||||
|
||||
fun verifyToolbarIsEmpty() =
|
||||
itemWithResIdContainingText(
|
||||
"$packageName:id/mozac_browser_toolbar_edit_url_view",
|
||||
getStringResource(R.string.search_hint),
|
||||
assertUIObjectExists(
|
||||
itemWithResIdContainingText(
|
||||
"$packageName:id/mozac_browser_toolbar_edit_url_view",
|
||||
getStringResource(R.string.search_hint),
|
||||
),
|
||||
)
|
||||
|
||||
// New unified search UI selector
|
||||
fun verifySearchBarPlaceholder(text: String) {
|
||||
Log.i(TAG, "verifySearchBarPlaceholder: Waiting for $waitingTime ms for the toolbar to exist")
|
||||
urlBar().waitForExists(waitingTime)
|
||||
Log.i(TAG, "verifySearchBarPlaceholder: Waited for $waitingTime ms for the toolbar to exist")
|
||||
assertItemTextEquals(urlBar(), expectedText = text)
|
||||
}
|
||||
|
||||
// New unified search UI selector
|
||||
fun verifyDefaultSearchEngine(engineName: String) =
|
||||
assertUIObjectExists(
|
||||
searchSelectorButton.getChild(UiSelector().description(engineName)),
|
||||
searchSelectorButton().getChild(UiSelector().description(engineName)),
|
||||
)
|
||||
|
||||
fun verifyTextSelectionOptions(vararg textSelectionOptions: String) {
|
||||
|
@ -138,19 +179,21 @@ class NavigationToolbarRobot {
|
|||
sessionLoadedIdlingResource = SessionLoadedIdlingResource()
|
||||
|
||||
openEditURLView()
|
||||
Log.i(TAG, "enterURLAndEnterToBrowser: Opened edit mode URL view")
|
||||
|
||||
Log.i(TAG, "enterURLAndEnterToBrowser: Trying to set toolbar text to: $url")
|
||||
awesomeBar().setText(url.toString())
|
||||
Log.i(TAG, "enterURLAndEnterToBrowser: Set toolbar text to: $url")
|
||||
Log.i(TAG, "enterURLAndEnterToBrowser: Toolbar text was set to: $url")
|
||||
Log.i(TAG, "enterURLAndEnterToBrowser: Trying to press device enter button")
|
||||
mDevice.pressEnter()
|
||||
Log.i(TAG, "enterURLAndEnterToBrowser: Clicked enter on keyboard, submitted query")
|
||||
Log.i(TAG, "enterURLAndEnterToBrowser: Pressed device enter button")
|
||||
|
||||
runWithIdleRes(sessionLoadedIdlingResource) {
|
||||
Log.i(TAG, "enterURLAndEnterToBrowser: Trying to assert that home screen layout or download button or the total cookie protection contextual hint exist")
|
||||
assertTrue(
|
||||
itemWithResId("$packageName:id/browserLayout").waitForExists(waitingTime) ||
|
||||
itemWithResId("$packageName:id/download_button").waitForExists(waitingTime) ||
|
||||
itemWithResId("cfr.dismiss").waitForExists(waitingTime),
|
||||
)
|
||||
Log.i(TAG, "enterURLAndEnterToBrowser: Asserted that home screen layout or download button or the total cookie protection contextual hint exist")
|
||||
}
|
||||
|
||||
BrowserRobot().interact()
|
||||
|
@ -162,9 +205,12 @@ class NavigationToolbarRobot {
|
|||
interact: BrowserRobot.() -> Unit,
|
||||
): BrowserRobot.Transition {
|
||||
openEditURLView()
|
||||
|
||||
Log.i(TAG, "enterURLAndEnterToBrowserForTCPCFR: Trying to set toolbar text to: $url")
|
||||
awesomeBar().setText(url.toString())
|
||||
Log.i(TAG, "enterURLAndEnterToBrowserForTCPCFR: Toolbar text was set to: $url")
|
||||
Log.i(TAG, "enterURLAndEnterToBrowserForTCPCFR: Trying to press device enter button")
|
||||
mDevice.pressEnter()
|
||||
Log.i(TAG, "enterURLAndEnterToBrowserForTCPCFR: Pressed device enter button")
|
||||
|
||||
BrowserRobot().interact()
|
||||
return BrowserRobot.Transition()
|
||||
|
@ -176,12 +222,17 @@ class NavigationToolbarRobot {
|
|||
sessionLoadedIdlingResource = SessionLoadedIdlingResource()
|
||||
|
||||
openEditURLView()
|
||||
|
||||
Log.i(TAG, "openTabCrashReporter: Trying to set toolbar text to: $crashUrl")
|
||||
awesomeBar().setText(crashUrl)
|
||||
Log.i(TAG, "openTabCrashReporter: Toolbar text was set to: $crashUrl")
|
||||
Log.i(TAG, "openTabCrashReporter: Trying to press device enter button")
|
||||
mDevice.pressEnter()
|
||||
Log.i(TAG, "openTabCrashReporter: Pressed device enter button")
|
||||
|
||||
runWithIdleRes(sessionLoadedIdlingResource) {
|
||||
Log.i(TAG, "openTabCrashReporter: Trying to find the tab crasher image")
|
||||
mDevice.findObject(UiSelector().resourceId("$packageName:id/crash_tab_image"))
|
||||
Log.i(TAG, "openTabCrashReporter: Found the tab crasher image")
|
||||
}
|
||||
|
||||
BrowserRobot().interact()
|
||||
|
@ -190,15 +241,21 @@ class NavigationToolbarRobot {
|
|||
|
||||
fun openThreeDotMenu(interact: ThreeDotMenuMainRobot.() -> Unit): ThreeDotMenuMainRobot.Transition {
|
||||
mDevice.waitNotNull(Until.findObject(By.res("$packageName:id/mozac_browser_toolbar_menu")), waitingTime)
|
||||
Log.i(TAG, "openThreeDotMenu: Trying to click the main menu button")
|
||||
threeDotButton().click()
|
||||
Log.i(TAG, "openThreeDotMenu: Clicked the main menu button")
|
||||
|
||||
ThreeDotMenuMainRobot().interact()
|
||||
return ThreeDotMenuMainRobot.Transition()
|
||||
}
|
||||
|
||||
fun openTabTray(interact: TabDrawerRobot.() -> Unit): TabDrawerRobot.Transition {
|
||||
Log.i(TAG, "openTabTray: Waiting for device to be idle for $waitingTime ms")
|
||||
mDevice.waitForIdle(waitingTime)
|
||||
Log.i(TAG, "openTabTray: Waited for device to be idle for $waitingTime ms")
|
||||
Log.i(TAG, "openTabTray: Trying to click the tabs tray button")
|
||||
tabTrayButton().click()
|
||||
Log.i(TAG, "openTabTray: Clicked the tabs tray button")
|
||||
mDevice.waitNotNull(
|
||||
Until.findObject(By.res("$packageName:id/tab_layout")),
|
||||
waitingTime,
|
||||
|
@ -211,6 +268,7 @@ class NavigationToolbarRobot {
|
|||
fun openComposeTabDrawer(composeTestRule: HomeActivityComposeTestRule, interact: ComposeTabDrawerRobot.() -> Unit): ComposeTabDrawerRobot.Transition {
|
||||
for (i in 1..Constants.RETRY_COUNT) {
|
||||
try {
|
||||
Log.i(TAG, "openComposeTabDrawer: Started try #$i")
|
||||
mDevice.waitForObjects(
|
||||
mDevice.findObject(
|
||||
UiSelector()
|
||||
|
@ -218,30 +276,40 @@ class NavigationToolbarRobot {
|
|||
),
|
||||
waitingTime,
|
||||
)
|
||||
|
||||
Log.i(TAG, "openComposeTabDrawer: Trying to click the tabs tray button")
|
||||
tabTrayButton().click()
|
||||
|
||||
Log.i(TAG, "openComposeTabDrawer: Clicked the tabs tray button")
|
||||
Log.i(TAG, "openComposeTabDrawer: Trying to verify that the tabs tray exists")
|
||||
composeTestRule.onNodeWithTag(TabsTrayTestTag.tabsTray).assertExists()
|
||||
Log.i(TAG, "openComposeTabDrawer: Verified that the tabs tray exists")
|
||||
|
||||
break
|
||||
} catch (e: AssertionError) {
|
||||
Log.i(TAG, "openComposeTabDrawer: AssertionError caught, executing fallback methods")
|
||||
if (i == Constants.RETRY_COUNT) {
|
||||
throw e
|
||||
} else {
|
||||
Log.i(TAG, "openComposeTabDrawer: Waiting for device to be idle")
|
||||
mDevice.waitForIdle()
|
||||
Log.i(TAG, "openComposeTabDrawer: Waited for device to be idle")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Log.i(TAG, "openComposeTabDrawer: Trying to verify the tabs tray new tab FAB button exists")
|
||||
composeTestRule.onNodeWithTag(TabsTrayTestTag.fab).assertExists()
|
||||
Log.i(TAG, "openComposeTabDrawer: Verified the tabs tray new tab FAB button exists")
|
||||
|
||||
ComposeTabDrawerRobot(composeTestRule).interact()
|
||||
return ComposeTabDrawerRobot.Transition(composeTestRule)
|
||||
}
|
||||
|
||||
fun visitLinkFromClipboard(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition {
|
||||
Log.i(TAG, "visitLinkFromClipboard: Waiting for $waitingTimeShort ms for clear address button to exist")
|
||||
if (clearAddressBarButton().waitForExists(waitingTimeShort)) {
|
||||
Log.i(TAG, "visitLinkFromClipboard: Waited for $waitingTimeShort ms for clear address button to exist")
|
||||
Log.i(TAG, "visitLinkFromClipboard: Trying to click the clear address button")
|
||||
clearAddressBarButton().click()
|
||||
Log.i(TAG, "visitLinkFromClipboard: Clicked the clear address button")
|
||||
}
|
||||
|
||||
mDevice.waitNotNull(
|
||||
|
@ -257,26 +325,33 @@ class NavigationToolbarRobot {
|
|||
waitingTime,
|
||||
)
|
||||
}
|
||||
|
||||
Log.i(TAG, "visitLinkFromClipboard: Trying to click the fill link from clipboard button")
|
||||
fillLinkButton().click()
|
||||
Log.i(TAG, "visitLinkFromClipboard: Clicked the fill link from clipboard button")
|
||||
|
||||
BrowserRobot().interact()
|
||||
return BrowserRobot.Transition()
|
||||
}
|
||||
|
||||
fun goBackToHomeScreen(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition {
|
||||
Log.i(TAG, "goBackToHomeScreen: Trying to click the device back button")
|
||||
mDevice.pressBack()
|
||||
Log.i(TAG, "goBackToHomeScreen: Clicked the device back button")
|
||||
Log.i(TAG, "goBackToHomeScreen: Waiting for $waitingTimeShort ms for $packageName window to be updated")
|
||||
mDevice.waitForWindowUpdate(packageName, waitingTimeShort)
|
||||
Log.i(TAG, "goBackToHomeScreen: Waited for $waitingTimeShort ms for $packageName window to be updated")
|
||||
|
||||
HomeScreenRobot().interact()
|
||||
return HomeScreenRobot.Transition()
|
||||
}
|
||||
|
||||
fun goBackToBrowserScreen(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition {
|
||||
Log.i(TAG, "goBackToBrowserScreen: Trying to click the device back button")
|
||||
mDevice.pressBack()
|
||||
Log.i(TAG, "goBackToBrowserScreen: Dismiss awesome bar using device back button")
|
||||
Log.i(TAG, "goBackToBrowserScreen: Clicked the device back button")
|
||||
Log.i(TAG, "goBackToBrowserScreen: Waiting for $waitingTimeShort ms for $packageName window to be updated")
|
||||
mDevice.waitForWindowUpdate(packageName, waitingTimeShort)
|
||||
Log.i(TAG, "goBackToBrowserScreen: Waited $waitingTimeShort for window update")
|
||||
Log.i(TAG, "goBackToBrowserScreen: Waited for $waitingTimeShort ms for $packageName window to be updated")
|
||||
|
||||
BrowserRobot().interact()
|
||||
return BrowserRobot.Transition()
|
||||
|
@ -284,16 +359,19 @@ class NavigationToolbarRobot {
|
|||
|
||||
fun openTabButtonShortcutsMenu(interact: NavigationToolbarRobot.() -> Unit): Transition {
|
||||
mDevice.waitNotNull(Until.findObject(By.res("$packageName:id/counter_root")))
|
||||
Log.i(TAG, "openTabButtonShortcutsMenu: Trying to long click the tab counter button")
|
||||
tabsCounter().perform(longClick())
|
||||
Log.i(TAG, "Tabs counter long-click successful.")
|
||||
Log.i(TAG, "openTabButtonShortcutsMenu: Long clicked the tab counter button")
|
||||
|
||||
NavigationToolbarRobot().interact()
|
||||
return Transition()
|
||||
}
|
||||
|
||||
fun closeTabFromShortcutsMenu(interact: NavigationToolbarRobot.() -> Unit): Transition {
|
||||
Log.i(TAG, "closeTabFromShortcutsMenu: Waiting for device to be idle for $waitingTime ms")
|
||||
mDevice.waitForIdle(waitingTime)
|
||||
|
||||
Log.i(TAG, "closeTabFromShortcutsMenu: Waited for device to be idle for $waitingTime ms")
|
||||
Log.i(TAG, "closeTabFromShortcutsMenu: Trying to click the \"Close tab\" button")
|
||||
onView(withId(R.id.mozac_browser_menu_recyclerView))
|
||||
.perform(
|
||||
RecyclerViewActions.actionOnItem<RecyclerView.ViewHolder>(
|
||||
|
@ -303,15 +381,17 @@ class NavigationToolbarRobot {
|
|||
ViewActions.click(),
|
||||
),
|
||||
)
|
||||
Log.i(TAG, "Clicked the tab shortcut Close tab button.")
|
||||
Log.i(TAG, "closeTabFromShortcutsMenu: Clicked the \"Close tab\" button")
|
||||
|
||||
NavigationToolbarRobot().interact()
|
||||
return Transition()
|
||||
}
|
||||
|
||||
fun openNewTabFromShortcutsMenu(interact: SearchRobot.() -> Unit): SearchRobot.Transition {
|
||||
Log.i(TAG, "openNewTabFromShortcutsMenu: Waiting for device to be idle for $waitingTime ms")
|
||||
mDevice.waitForIdle(waitingTime)
|
||||
Log.i(TAG, "Looking for tab shortcut New tab button.")
|
||||
Log.i(TAG, "openNewTabFromShortcutsMenu: Waited for device to be idle for $waitingTime ms")
|
||||
Log.i(TAG, "openNewTabFromShortcutsMenu: Trying to click the \"New tab\" button")
|
||||
onView(withId(R.id.mozac_browser_menu_recyclerView))
|
||||
.perform(
|
||||
RecyclerViewActions.actionOnItem<RecyclerView.ViewHolder>(
|
||||
|
@ -321,15 +401,17 @@ class NavigationToolbarRobot {
|
|||
ViewActions.click(),
|
||||
),
|
||||
)
|
||||
Log.i(TAG, "Clicked the tab shortcut New tab button.")
|
||||
Log.i(TAG, "openNewTabFromShortcutsMenu: Clicked the \"New tab\" button")
|
||||
|
||||
SearchRobot().interact()
|
||||
return SearchRobot.Transition()
|
||||
}
|
||||
|
||||
fun openNewPrivateTabFromShortcutsMenu(interact: SearchRobot.() -> Unit): SearchRobot.Transition {
|
||||
Log.i(TAG, "openNewPrivateTabFromShortcutsMenu: Waiting for device to be idle for $waitingTime ms")
|
||||
mDevice.waitForIdle(waitingTime)
|
||||
Log.i(TAG, "Looking for tab shortcut New private tab button.")
|
||||
Log.i(TAG, "openNewPrivateTabFromShortcutsMenu: Waited for device to be idle for $waitingTime ms")
|
||||
Log.i(TAG, "openNewPrivateTabFromShortcutsMenu: Trying to click the \"New private tab\" button")
|
||||
onView(withId(R.id.mozac_browser_menu_recyclerView))
|
||||
.perform(
|
||||
RecyclerViewActions.actionOnItem<RecyclerView.ViewHolder>(
|
||||
|
@ -339,26 +421,33 @@ class NavigationToolbarRobot {
|
|||
ViewActions.click(),
|
||||
),
|
||||
)
|
||||
Log.i(TAG, "Clicked the tab shortcut New private tab button.")
|
||||
Log.i(TAG, "openNewPrivateTabFromShortcutsMenu: Clicked the \"New private tab\" button")
|
||||
|
||||
SearchRobot().interact()
|
||||
return SearchRobot.Transition()
|
||||
}
|
||||
|
||||
fun clickUrlbar(interact: SearchRobot.() -> Unit): SearchRobot.Transition {
|
||||
Log.i(TAG, "clickUrlbar: Trying to click the toolbar")
|
||||
urlBar().click()
|
||||
|
||||
Log.i(TAG, "clickUrlbar: Clicked the toolbar")
|
||||
Log.i(TAG, "clickUrlbar: Waiting for $waitingTime ms for the edit mode toolbar to exist")
|
||||
mDevice.findObject(
|
||||
UiSelector().resourceId("$packageName:id/mozac_browser_toolbar_edit_url_view"),
|
||||
).waitForExists(waitingTime)
|
||||
Log.i(TAG, "clickUrlbar: Waited for $waitingTime ms for the edit mode toolbar to exist")
|
||||
|
||||
SearchRobot().interact()
|
||||
return SearchRobot.Transition()
|
||||
}
|
||||
|
||||
fun clickSearchSelectorButton(interact: SearchRobot.() -> Unit): SearchRobot.Transition {
|
||||
searchSelectorButton.waitForExists(waitingTime)
|
||||
searchSelectorButton.click()
|
||||
Log.i(TAG, "clickSearchSelectorButton: Waiting for $waitingTime ms for the search selector button to exist")
|
||||
searchSelectorButton().waitForExists(waitingTime)
|
||||
Log.i(TAG, "clickSearchSelectorButton: Waited for $waitingTime ms for the search selector button to exist")
|
||||
Log.i(TAG, "clickSearchSelectorButton: Trying to click the search selector button")
|
||||
searchSelectorButton().click()
|
||||
Log.i(TAG, "clickSearchSelectorButton: Clicked the search selector button")
|
||||
|
||||
SearchRobot().interact()
|
||||
return SearchRobot.Transition()
|
||||
|
@ -372,25 +461,15 @@ fun navigationToolbar(interact: NavigationToolbarRobot.() -> Unit): NavigationTo
|
|||
}
|
||||
|
||||
fun openEditURLView() {
|
||||
Log.i(TAG, "openEditURLView: Waiting for $waitingTime ms for the toolbar to exist")
|
||||
urlBar().waitForExists(waitingTime)
|
||||
Log.i(TAG, "openEditURLView: Waited for $waitingTime ms for the toolbar to exist")
|
||||
Log.i(TAG, "openEditURLView: Trying to click the toolbar")
|
||||
urlBar().click()
|
||||
Log.i(TAG, "openEditURLView: URL bar clicked.")
|
||||
Log.i(TAG, "openEditURLView: Clicked the toolbar")
|
||||
Log.i(TAG, "openEditURLView: Waiting for $waitingTime ms for the edit mode toolbar to exist")
|
||||
itemWithResId("$packageName:id/mozac_browser_toolbar_edit_url_view").waitForExists(waitingTime)
|
||||
Log.i(TAG, "openEditURLView: Edit URL bar displayed.")
|
||||
}
|
||||
|
||||
private fun assertNoHistoryBookmarks() {
|
||||
onView(withId(R.id.container))
|
||||
.check(matches(not(hasDescendant(withText("Test_Page_1")))))
|
||||
.check(matches(not(hasDescendant(withText("Test_Page_2")))))
|
||||
.check(matches(not(hasDescendant(withText("Test_Page_3")))))
|
||||
}
|
||||
|
||||
private fun assertTabButtonShortcutMenuItems() {
|
||||
onView(withId(R.id.mozac_browser_menu_recyclerView))
|
||||
.check(matches(hasDescendant(withText("Close tab"))))
|
||||
.check(matches(hasDescendant(withText("New private tab"))))
|
||||
.check(matches(hasDescendant(withText("New tab"))))
|
||||
Log.i(TAG, "openEditURLView: Waited for $waitingTime ms for the edit mode toolbar to exist")
|
||||
}
|
||||
|
||||
private fun urlBar() = mDevice.findObject(UiSelector().resourceId("$packageName:id/toolbar"))
|
||||
|
@ -404,49 +483,7 @@ private fun clearAddressBarButton() = itemWithResId("$packageName:id/mozac_brows
|
|||
private fun readerViewToggle() =
|
||||
onView(withParent(withId(R.id.mozac_browser_toolbar_page_actions)))
|
||||
|
||||
private fun assertReaderViewDetected(visible: Boolean) {
|
||||
mDevice.findObject(
|
||||
UiSelector()
|
||||
.description("Reader view"),
|
||||
)
|
||||
.waitForExists(waitingTime)
|
||||
|
||||
onView(
|
||||
allOf(
|
||||
withParent(withId(R.id.mozac_browser_toolbar_page_actions)),
|
||||
withContentDescription("Reader view"),
|
||||
),
|
||||
).check(
|
||||
if (visible) {
|
||||
matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))
|
||||
} else {
|
||||
ViewAssertions.doesNotExist()
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
private fun assertCloseReaderViewDetected(visible: Boolean) {
|
||||
mDevice.findObject(
|
||||
UiSelector()
|
||||
.description("Close reader view"),
|
||||
)
|
||||
.waitForExists(waitingTime)
|
||||
|
||||
onView(
|
||||
allOf(
|
||||
withParent(withId(R.id.mozac_browser_toolbar_page_actions)),
|
||||
withContentDescription("Close reader view"),
|
||||
),
|
||||
).check(
|
||||
if (visible) {
|
||||
matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))
|
||||
} else {
|
||||
ViewAssertions.doesNotExist()
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
private val searchSelectorButton =
|
||||
private fun searchSelectorButton() =
|
||||
mDevice.findObject(UiSelector().resourceId("$packageName:id/search_selector"))
|
||||
|
||||
inline fun runWithIdleRes(ir: IdlingResource?, pendingCheck: () -> Unit) {
|
||||
|
|
|
@ -29,44 +29,48 @@ class NotificationRobot {
|
|||
var notificationFound = mDevice.findObject(notification).waitForExists(waitingTime)
|
||||
|
||||
while (!notificationFound) {
|
||||
Log.i(TAG, "verifySystemNotificationExists: Waiting for $waitingTime ms for notification: $notification to exist")
|
||||
scrollToEnd()
|
||||
Log.i(TAG, "verifySystemNotificationExists: Scrolling to the end of the notification tray")
|
||||
Log.i(TAG, "verifySystemNotificationExists: Looking for $notificationMessage notification")
|
||||
notificationFound = mDevice.findObject(notification).waitForExists(waitingTime)
|
||||
Log.i(TAG, "verifySystemNotificationExists: Waited for $waitingTime ms for notification: $notification to exist")
|
||||
}
|
||||
|
||||
assertUIObjectExists(itemWithText(notificationMessage))
|
||||
}
|
||||
|
||||
fun clearNotifications() {
|
||||
if (clearButton.exists()) {
|
||||
Log.i(TAG, "clearNotifications: Verified that clear notifications button exists")
|
||||
clearButton.click()
|
||||
Log.i(TAG, "clearNotifications: Clicked clear notifications button")
|
||||
if (clearButton().exists()) {
|
||||
Log.i(TAG, "clearNotifications:The clear notifications button exists")
|
||||
Log.i(TAG, "clearNotifications: Trying to click the clear notifications button")
|
||||
clearButton().click()
|
||||
Log.i(TAG, "clearNotifications: Clicked the clear notifications button")
|
||||
} else {
|
||||
scrollToEnd()
|
||||
Log.i(TAG, "clearNotifications: Scrolled to end of notifications tray")
|
||||
if (clearButton.exists()) {
|
||||
Log.i(TAG, "clearNotifications: Verified that clear notifications button exists")
|
||||
clearButton.click()
|
||||
Log.i(TAG, "clearNotifications: Clicked clear notifications button")
|
||||
if (clearButton().exists()) {
|
||||
Log.i(TAG, "clearNotifications:The clear notifications button exists")
|
||||
Log.i(TAG, "clearNotifications: Trying to click the clear notifications button")
|
||||
clearButton().click()
|
||||
Log.i(TAG, "clearNotifications: Clicked the clear notifications button")
|
||||
} else if (notificationTray().exists()) {
|
||||
Log.i(TAG, "clearNotifications: The notifications tray is still displayed")
|
||||
Log.i(TAG, "clearNotifications: Trying to click device back button")
|
||||
mDevice.pressBack()
|
||||
Log.i(TAG, "clearNotifications: Dismiss notifications tray by clicking device back button")
|
||||
Log.i(TAG, "clearNotifications: Clicked device back button")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun cancelAllShownNotifications() {
|
||||
Log.i(TAG, "cancelAllShownNotifications: Trying to cancel all system notifications")
|
||||
cancelAll()
|
||||
Log.i(TAG, "cancelAllShownNotifications: Canceled all system notifications")
|
||||
}
|
||||
|
||||
fun verifySystemNotificationDoesNotExist(notificationMessage: String) {
|
||||
Log.i(TAG, "verifySystemNotificationDoesNotExist: Waiting for $notificationMessage notification to be gone")
|
||||
Log.i(TAG, "verifySystemNotificationDoesNotExist: Waiting for $waitingTime ms for notification: $notificationMessage to be gone")
|
||||
mDevice.findObject(UiSelector().textContains(notificationMessage)).waitUntilGone(waitingTime)
|
||||
Log.i(TAG, "verifySystemNotificationDoesNotExist: Waited for $waitingTime ms for notification: $notificationMessage to be gone")
|
||||
assertUIObjectExists(itemContainingText(notificationMessage), exists = false)
|
||||
Log.i(TAG, "verifySystemNotificationDoesNotExist: Verified that $notificationMessage notification does not exist")
|
||||
}
|
||||
|
||||
fun verifyPrivateTabsNotification() {
|
||||
|
@ -75,17 +79,22 @@ class NotificationRobot {
|
|||
}
|
||||
|
||||
fun clickMediaNotificationControlButton(action: String) {
|
||||
Log.i(TAG, "clickMediaNotificationControlButton: Waiting for $waitingTime ms for the system media control button: $action to exist")
|
||||
mediaSystemNotificationButton(action).waitForExists(waitingTime)
|
||||
Log.i(TAG, "clickMediaNotificationControlButton: Waited for $waitingTime ms for the system media control button: $action to exist")
|
||||
Log.i(TAG, "clickMediaNotificationControlButton: Trying to click the system media control button: $action")
|
||||
mediaSystemNotificationButton(action).click()
|
||||
Log.i(TAG, "clickMediaNotificationControlButton: Clicked the system media control button: $action")
|
||||
}
|
||||
|
||||
fun clickDownloadNotificationControlButton(action: String) {
|
||||
for (i in 1..RETRY_COUNT) {
|
||||
Log.i(TAG, "clickPageObject: For loop i = $i")
|
||||
Log.i(TAG, "clickDownloadNotificationControlButton: Started try #$i")
|
||||
try {
|
||||
assertUIObjectExists(downloadSystemNotificationButton(action))
|
||||
Log.i(TAG, "clickDownloadNotificationControlButton: Trying to click the download system notification: $action button and wait for $waitingTimeShort ms for a new window")
|
||||
downloadSystemNotificationButton(action).clickAndWaitForNewWindow(waitingTimeShort)
|
||||
Log.i(TAG, "clickDownloadNotificationControlButton: Clicked app notification $action button and waits for a new window for $waitingTimeShort ms")
|
||||
Log.i(TAG, "clickDownloadNotificationControlButton: Clicked the download system notification: $action button and waited for $waitingTimeShort ms for a new window")
|
||||
assertUIObjectExists(
|
||||
downloadSystemNotificationButton(action),
|
||||
exists = false,
|
||||
|
@ -93,12 +102,13 @@ class NotificationRobot {
|
|||
|
||||
break
|
||||
} catch (e: AssertionError) {
|
||||
Log.i(TAG, "clickDownloadNotificationControlButton: Catch block")
|
||||
Log.i(TAG, "clickDownloadNotificationControlButton: AssertionError caught, executing fallback methods")
|
||||
if (i == RETRY_COUNT) {
|
||||
throw e
|
||||
}
|
||||
Log.i(TAG, "clickDownloadNotificationControlButton: Waiting for $waitingTimeShort ms for $packageName window to be updated")
|
||||
mDevice.waitForWindowUpdate(packageName, waitingTimeShort)
|
||||
Log.i(TAG, "clickDownloadNotificationControlButton: Waited $waitingTimeShort ms for window update")
|
||||
Log.i(TAG, "clickDownloadNotificationControlButton: Waited for $waitingTimeShort ms for $packageName window to be updated")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -107,15 +117,17 @@ class NotificationRobot {
|
|||
assertUIObjectExists(mediaSystemNotificationButton(action))
|
||||
|
||||
fun expandNotificationMessage() {
|
||||
while (!notificationHeader.exists()) {
|
||||
while (!notificationHeader().exists()) {
|
||||
Log.i(TAG, "expandNotificationMessage: Waiting for $appName notification to exist")
|
||||
scrollToEnd()
|
||||
Log.i(TAG, "expandNotificationMessage: Scrolled to end of notification tray")
|
||||
}
|
||||
|
||||
if (notificationHeader.exists()) {
|
||||
if (notificationHeader().exists()) {
|
||||
Log.i(TAG, "expandNotificationMessage: $appName notification exists")
|
||||
// expand the notification
|
||||
notificationHeader.click()
|
||||
Log.i(TAG, "expandNotificationMessage: Clicked the app notification")
|
||||
Log.i(TAG, "expandNotificationMessage: Trying to click $appName notification")
|
||||
notificationHeader().click()
|
||||
Log.i(TAG, "expandNotificationMessage: Clicked $appName notification")
|
||||
|
||||
// double check if notification actions are viewable by checking for action existence; otherwise scroll again
|
||||
while (!mDevice.findObject(UiSelector().resourceId("android:id/action0")).exists() &&
|
||||
|
@ -123,7 +135,6 @@ class NotificationRobot {
|
|||
) {
|
||||
Log.i(TAG, "expandNotificationMessage: App notification action buttons do not exist")
|
||||
scrollToEnd()
|
||||
Log.i(TAG, "expandNotificationMessage: Scrolled to end of notification tray")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -136,41 +147,46 @@ class NotificationRobot {
|
|||
) {
|
||||
// In case it fails, retry max 3x the swipe action on download system notifications
|
||||
for (i in 1..RETRY_COUNT) {
|
||||
Log.i(TAG, "swipeDownloadNotification: For loop i = $i")
|
||||
Log.i(TAG, "swipeDownloadNotification: Started try #$i")
|
||||
try {
|
||||
Log.i(TAG, "swipeDownloadNotification: Try block")
|
||||
var retries = 0
|
||||
while (itemContainingText(appName).exists() && retries++ < 3) {
|
||||
Log.i(TAG, "swipeDownloadNotification: While loop retries = $retries")
|
||||
// Swipe left the download system notification
|
||||
if (direction == "Left") {
|
||||
itemContainingText(appName)
|
||||
.also {
|
||||
Log.i(TAG, "swipeDownloadNotification: Waiting for $waitingTime ms for $appName notification to exist")
|
||||
it.waitForExists(waitingTime)
|
||||
Log.i(TAG, "swipeDownloadNotification: Waited for $waitingTime ms for $appName notification to exist")
|
||||
Log.i(TAG, "swipeDownloadNotification: Trying to perform swipe left action on $appName notification")
|
||||
it.swipeLeft(3)
|
||||
Log.i(TAG, "swipeDownloadNotification: Performed swipe left action on $appName notification")
|
||||
}
|
||||
Log.i(TAG, "swipeDownloadNotification: Swiped left download notification")
|
||||
} else {
|
||||
// Swipe right the download system notification
|
||||
itemContainingText(appName)
|
||||
.also {
|
||||
Log.i(TAG, "swipeDownloadNotification: Waiting for $waitingTime ms for $appName notification to exist")
|
||||
it.waitForExists(waitingTime)
|
||||
Log.i(TAG, "swipeDownloadNotification: Waited for $waitingTime ms for $appName notification to exist")
|
||||
Log.i(TAG, "swipeDownloadNotification: Trying to perform swipe right action on $appName notification")
|
||||
it.swipeRight(3)
|
||||
Log.i(TAG, "swipeDownloadNotification: Performed swipe right action on $appName notification")
|
||||
}
|
||||
Log.i(TAG, "swipeDownloadNotification: Swiped right download notification")
|
||||
}
|
||||
}
|
||||
// Not all download related system notifications can be dismissed
|
||||
if (shouldDismissNotification) {
|
||||
Log.i(TAG, "swipeDownloadNotification: $appName notification can't be dismissed: $shouldDismissNotification")
|
||||
assertUIObjectExists(itemContainingText(appName), exists = false)
|
||||
} else {
|
||||
Log.i(TAG, "swipeDownloadNotification: $appName notification can be dismissed: $shouldDismissNotification")
|
||||
assertUIObjectExists(itemContainingText(appName))
|
||||
Log.i(TAG, "swipeDownloadNotification: Verified that $appName notification exist")
|
||||
}
|
||||
|
||||
break
|
||||
} catch (e: AssertionError) {
|
||||
Log.i(TAG, "swipeDownloadNotification: Catch block")
|
||||
Log.i(TAG, "swipeDownloadNotification: AssertionError caught, executing fallback methods")
|
||||
if (i == RETRY_COUNT) {
|
||||
throw e
|
||||
} else {
|
||||
|
@ -179,11 +195,12 @@ class NotificationRobot {
|
|||
}.openNotificationShade {
|
||||
// The download complete system notification can't be expanded
|
||||
if (canExpandNotification) {
|
||||
Log.i(TAG, "swipeDownloadNotification: $appName notification can be expanded: $canExpandNotification")
|
||||
// In all cases the download system notification title will be the app name
|
||||
verifySystemNotificationExists(appName)
|
||||
Log.i(TAG, "swipeDownloadNotification: Verified that $appName notification exist")
|
||||
expandNotificationMessage()
|
||||
} else {
|
||||
Log.i(TAG, "swipeDownloadNotification: $appName notification can't be expanded: $canExpandNotification")
|
||||
// Using the download completed system notification summary to bring in to view an properly verify it
|
||||
verifySystemNotificationExists("Download completed")
|
||||
}
|
||||
|
@ -194,10 +211,12 @@ class NotificationRobot {
|
|||
}
|
||||
|
||||
fun clickNotification(notificationMessage: String) {
|
||||
Log.i(TAG, "clickNotification: Looking for $notificationMessage notification")
|
||||
Log.i(TAG, "clickNotification: Waiting for $waitingTime ms for $notificationMessage notification to exist")
|
||||
mDevice.findObject(UiSelector().text(notificationMessage)).waitForExists(waitingTime)
|
||||
Log.i(TAG, "clickNotification: Waited for $waitingTime ms for $notificationMessage notification to exist")
|
||||
Log.i(TAG, "clickNotification: Trying to click the $notificationMessage notification and wait for $waitingTimeShort ms for a new window")
|
||||
mDevice.findObject(UiSelector().text(notificationMessage)).clickAndWaitForNewWindow(waitingTimeShort)
|
||||
Log.i(TAG, "clickNotification: Clicked $notificationMessage notification and waiting for $waitingTimeShort ms for a new window")
|
||||
Log.i(TAG, "clickNotification: Clicked the $notificationMessage notification and waited for $waitingTimeShort ms for a new window")
|
||||
}
|
||||
|
||||
class Transition {
|
||||
|
@ -206,18 +225,22 @@ class NotificationRobot {
|
|||
try {
|
||||
assertUIObjectExists(closePrivateTabsNotification())
|
||||
} catch (e: AssertionError) {
|
||||
Log.i(TAG, "clickClosePrivateTabsNotification: Trying to perform fling action to the end of the notification tray")
|
||||
notificationTray().flingToEnd(1)
|
||||
Log.i(TAG, "clickClosePrivateTabsNotification: Performed fling action to the end of the notification tray")
|
||||
}
|
||||
|
||||
Log.i(TAG, "clickClosePrivateTabsNotification: Trying to click the close private tabs notification")
|
||||
closePrivateTabsNotification().click()
|
||||
Log.i(TAG, "clickClosePrivateTabsNotification: Clicked the close private tabs notification")
|
||||
|
||||
HomeScreenRobot().interact()
|
||||
return HomeScreenRobot.Transition()
|
||||
}
|
||||
|
||||
fun closeNotificationTray(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition {
|
||||
Log.i(TAG, "closeNotificationTray: Trying to click device back button")
|
||||
mDevice.pressBack()
|
||||
Log.i(TAG, "closeNotificationTray: Closed notification tray using device back button")
|
||||
Log.i(TAG, "closeNotificationTray: Clicked device back button")
|
||||
|
||||
BrowserRobot().interact()
|
||||
return BrowserRobot.Transition()
|
||||
|
@ -251,7 +274,7 @@ private fun notificationTray() = UiScrollable(
|
|||
UiSelector().resourceId("com.android.systemui:id/notification_stack_scroller"),
|
||||
).setAsVerticalList()
|
||||
|
||||
private val notificationHeader =
|
||||
private fun notificationHeader() =
|
||||
mDevice.findObject(
|
||||
UiSelector()
|
||||
.resourceId("android:id/app_name_text")
|
||||
|
@ -259,10 +282,12 @@ private val notificationHeader =
|
|||
)
|
||||
|
||||
private fun scrollToEnd() {
|
||||
Log.i(TAG, "scrollToEnd: Trying to perform scroll to the end of the notification tray action")
|
||||
notificationTray().scrollToEnd(1)
|
||||
Log.i(TAG, "scrollToEnd: Performed scroll to the end of the notification tray action")
|
||||
}
|
||||
|
||||
private val clearButton = mDevice.findObject(UiSelector().resourceId("com.android.systemui:id/dismiss_text"))
|
||||
private fun clearButton() = mDevice.findObject(UiSelector().resourceId("com.android.systemui:id/dismiss_text"))
|
||||
|
||||
private fun cancelAll() {
|
||||
val notificationManager: NotificationManager =
|
||||
|
|
|
@ -4,24 +4,30 @@
|
|||
|
||||
package org.mozilla.fenix.ui.robots
|
||||
|
||||
import android.util.Log
|
||||
import androidx.test.uiautomator.UiSelector
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.mozilla.fenix.helpers.AppAndSystemHelper.isExternalAppBrowserActivityInCurrentTask
|
||||
import org.mozilla.fenix.helpers.Constants
|
||||
import org.mozilla.fenix.helpers.Constants.TAG
|
||||
import org.mozilla.fenix.helpers.MatcherHelper.assertUIObjectExists
|
||||
import org.mozilla.fenix.helpers.MatcherHelper.itemWithResId
|
||||
import org.mozilla.fenix.helpers.TestHelper.mDevice
|
||||
import org.mozilla.fenix.helpers.TestHelper.packageName
|
||||
|
||||
class PwaRobot {
|
||||
fun verifyCustomTabToolbarIsNotDisplayed() = assertUIObjectExists(customTabToolbar(), exists = false)
|
||||
fun verifyPwaActivityInCurrentTask() = assertTrue(isExternalAppBrowserActivityInCurrentTask())
|
||||
fun verifyCustomTabToolbarIsNotDisplayed() = assertUIObjectExists(itemWithResId("$packageName:id/toolbar"), exists = false)
|
||||
fun verifyPwaActivityInCurrentTask() {
|
||||
assertTrue("$TAG: The latest activity of the application is not used for custom tabs or PWAs", isExternalAppBrowserActivityInCurrentTask())
|
||||
}
|
||||
|
||||
class Transition
|
||||
}
|
||||
|
||||
fun pwaScreen(interact: PwaRobot.() -> Unit): PwaRobot.Transition {
|
||||
Log.i(TAG, "pwaScreen: Trying to find the engine view")
|
||||
mDevice.findObject(UiSelector().resourceId("$packageName:id/engineView"))
|
||||
Log.i(Constants.TAG, "pwaScreen: Found the engine view")
|
||||
PwaRobot().interact()
|
||||
return PwaRobot.Transition()
|
||||
}
|
||||
|
||||
private fun customTabToolbar() = mDevice.findObject(UiSelector().resourceId("$packageName:id/toolbar"))
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
package org.mozilla.fenix.ui.robots
|
||||
|
||||
import android.content.Context
|
||||
import android.util.Log
|
||||
import androidx.test.espresso.Espresso.onView
|
||||
import androidx.test.espresso.ViewInteraction
|
||||
import androidx.test.espresso.assertion.ViewAssertions.matches
|
||||
import androidx.test.espresso.matcher.ViewMatchers
|
||||
import androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility
|
||||
|
@ -16,6 +16,7 @@ import androidx.test.espresso.matcher.ViewMatchers.withId
|
|||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.helpers.Constants.TAG
|
||||
import org.mozilla.fenix.helpers.TestHelper.mDevice
|
||||
import org.mozilla.fenix.helpers.click
|
||||
|
||||
|
@ -24,34 +25,98 @@ import org.mozilla.fenix.helpers.click
|
|||
*/
|
||||
class ReaderViewRobot {
|
||||
|
||||
fun verifyAppearanceFontGroup(visible: Boolean = false): ViewInteraction =
|
||||
assertAppearanceFontGroup(visible)
|
||||
fun verifyAppearanceFontGroup(visible: Boolean = false) {
|
||||
Log.i(TAG, "verifyAppearanceFontGroup: Trying to verify that the font group buttons are visible: $visible")
|
||||
onView(
|
||||
withId(R.id.mozac_feature_readerview_font_group),
|
||||
).check(
|
||||
matches(withEffectiveVisibility(visibleOrGone(visible))),
|
||||
)
|
||||
Log.i(TAG, "verifyAppearanceFontGroup: Verified that the font group buttons are visible: $visible")
|
||||
}
|
||||
|
||||
fun verifyAppearanceFontSansSerif(visible: Boolean = false): ViewInteraction =
|
||||
assertAppearanceFontSansSerif(visible)
|
||||
fun verifyAppearanceFontSansSerif(visible: Boolean = false) {
|
||||
Log.i(TAG, "verifyAppearanceFontSansSerif: Trying to verify that the sans serif font button is visible: $visible")
|
||||
onView(
|
||||
withId(R.id.mozac_feature_readerview_font_sans_serif),
|
||||
).check(
|
||||
matches(withEffectiveVisibility(visibleOrGone(visible))),
|
||||
)
|
||||
Log.i(TAG, "verifyAppearanceFontSansSerif: Verified that the sans serif font button is visible: $visible")
|
||||
}
|
||||
|
||||
fun verifyAppearanceFontSerif(visible: Boolean = false): ViewInteraction =
|
||||
assertAppearanceFontSerif(visible)
|
||||
fun verifyAppearanceFontSerif(visible: Boolean = false) {
|
||||
Log.i(TAG, "verifyAppearanceFontSerif: Trying to verify that the serif font button is visible: $visible")
|
||||
onView(
|
||||
withId(R.id.mozac_feature_readerview_font_serif),
|
||||
).check(
|
||||
matches(withEffectiveVisibility(visibleOrGone(visible))),
|
||||
)
|
||||
Log.i(TAG, "verifyAppearanceFontSerif: Verified that the serif font button is visible: $visible")
|
||||
}
|
||||
|
||||
fun verifyAppearanceFontDecrease(visible: Boolean = false): ViewInteraction =
|
||||
assertAppearanceFontDecrease(visible)
|
||||
fun verifyAppearanceFontDecrease(visible: Boolean = false) {
|
||||
Log.i(TAG, "verifyAppearanceFontDecrease: Trying to verify that the decrease font button is visible: $visible")
|
||||
onView(
|
||||
withId(R.id.mozac_feature_readerview_font_size_decrease),
|
||||
).check(
|
||||
matches(withEffectiveVisibility(visibleOrGone(visible))),
|
||||
)
|
||||
Log.i(TAG, "verifyAppearanceFontDecrease: Verified that the decrease font button is visible: $visible")
|
||||
}
|
||||
|
||||
fun verifyAppearanceFontIncrease(visible: Boolean = false): ViewInteraction =
|
||||
assertAppearanceFontIncrease(visible)
|
||||
fun verifyAppearanceFontIncrease(visible: Boolean = false) {
|
||||
Log.i(TAG, "verifyAppearanceFontIncrease: Trying to verify that the increase font button is visible: $visible")
|
||||
onView(
|
||||
withId(R.id.mozac_feature_readerview_font_size_increase),
|
||||
).check(
|
||||
matches(withEffectiveVisibility(visibleOrGone(visible))),
|
||||
)
|
||||
Log.i(TAG, "verifyAppearanceFontIncrease: Verified that the increase font button is visible: $visible")
|
||||
}
|
||||
|
||||
fun verifyAppearanceColorGroup(visible: Boolean = false): ViewInteraction =
|
||||
assertAppearanceColorGroup(visible)
|
||||
fun verifyAppearanceColorGroup(visible: Boolean = false) {
|
||||
Log.i(TAG, "verifyAppearanceColorGroup: Trying to verify that the color group buttons are visible: $visible")
|
||||
onView(
|
||||
withId(R.id.mozac_feature_readerview_color_scheme_group),
|
||||
).check(
|
||||
matches(withEffectiveVisibility(visibleOrGone(visible))),
|
||||
)
|
||||
Log.i(TAG, "verifyAppearanceColorGroup: Verified that the color group buttons are visible: $visible")
|
||||
}
|
||||
|
||||
fun verifyAppearanceColorSepia(visible: Boolean = false): ViewInteraction =
|
||||
assertAppearanceColorSepia(visible)
|
||||
fun verifyAppearanceColorSepia(visible: Boolean = false) {
|
||||
Log.i(TAG, "verifyAppearanceColorSepia: Trying to verify that the sepia color button is visible: $visible")
|
||||
onView(
|
||||
withId(R.id.mozac_feature_readerview_color_sepia),
|
||||
).check(
|
||||
matches(withEffectiveVisibility(visibleOrGone(visible))),
|
||||
)
|
||||
Log.i(TAG, "verifyAppearanceColorSepia: Verified that the sepia color button is visible: $visible")
|
||||
}
|
||||
|
||||
fun verifyAppearanceColorDark(visible: Boolean = false): ViewInteraction =
|
||||
assertAppearanceColorDark(visible)
|
||||
fun verifyAppearanceColorDark(visible: Boolean = false) {
|
||||
Log.i(TAG, "verifyAppearanceColorDark: Trying to verify that the dark color button is visible: $visible")
|
||||
onView(
|
||||
withId(R.id.mozac_feature_readerview_color_dark),
|
||||
).check(
|
||||
matches(withEffectiveVisibility(visibleOrGone(visible))),
|
||||
)
|
||||
Log.i(TAG, "verifyAppearanceColorDark: Verified that the dark color button is visible: $visible")
|
||||
}
|
||||
|
||||
fun verifyAppearanceColorLight(visible: Boolean = false): ViewInteraction =
|
||||
assertAppearanceColorLight(visible)
|
||||
fun verifyAppearanceColorLight(visible: Boolean = false) {
|
||||
Log.i(TAG, "verifyAppearanceColorLight: Trying to verify that the light color button is visible: $visible")
|
||||
onView(
|
||||
withId(R.id.mozac_feature_readerview_color_light),
|
||||
).check(
|
||||
matches(withEffectiveVisibility(visibleOrGone(visible))),
|
||||
)
|
||||
Log.i(TAG, "verifyAppearanceColorLight: Verified that the light color button is visible: $visible")
|
||||
}
|
||||
|
||||
fun verifyAppearanceFontIsActive(fontType: String) {
|
||||
Log.i(TAG, "verifyAppearanceFontIsActive: Trying to verify that the font type is: $fontType")
|
||||
val fontTypeKey: String = "mozac-readerview-fonttype"
|
||||
|
||||
val prefs = InstrumentationRegistry.getInstrumentation()
|
||||
|
@ -61,9 +126,11 @@ class ReaderViewRobot {
|
|||
)
|
||||
|
||||
assertEquals(fontType, prefs.getString(fontTypeKey, ""))
|
||||
Log.i(TAG, "verifyAppearanceFontIsActive: Verified that the font type is: $fontType")
|
||||
}
|
||||
|
||||
fun verifyAppearanceFontSize(expectedFontSize: Int) {
|
||||
Log.i(TAG, "verifyAppearanceFontSize: Trying to verify that the font size is: $expectedFontSize")
|
||||
val fontSizeKey: String = "mozac-readerview-fontsize"
|
||||
|
||||
val prefs = InstrumentationRegistry.getInstrumentation()
|
||||
|
@ -75,9 +142,11 @@ class ReaderViewRobot {
|
|||
val fontSizeKeyValue = prefs.getInt(fontSizeKey, 3)
|
||||
|
||||
assertEquals(expectedFontSize, fontSizeKeyValue)
|
||||
Log.i(TAG, "verifyAppearanceFontSize: Verified that the font size is: $expectedFontSize")
|
||||
}
|
||||
|
||||
fun verifyAppearanceColorSchemeChange(expectedColorScheme: String) {
|
||||
Log.i(TAG, "verifyAppearanceColorSchemeChange: Trying to verify that the color scheme is: $expectedColorScheme")
|
||||
val colorSchemeKey: String = "mozac-readerview-colorscheme"
|
||||
|
||||
val prefs = InstrumentationRegistry.getInstrumentation()
|
||||
|
@ -87,12 +156,15 @@ class ReaderViewRobot {
|
|||
)
|
||||
|
||||
assertEquals(expectedColorScheme, prefs.getString(colorSchemeKey, ""))
|
||||
Log.i(TAG, "verifyAppearanceColorSchemeChange: Verified that the color scheme is: $expectedColorScheme")
|
||||
}
|
||||
|
||||
class Transition {
|
||||
|
||||
fun closeAppearanceMenu(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition {
|
||||
Log.i(TAG, "closeAppearanceMenu: Trying to click device back button")
|
||||
mDevice.pressBack()
|
||||
Log.i(TAG, "closeAppearanceMenu: Clicked device back button")
|
||||
|
||||
BrowserRobot().interact()
|
||||
return BrowserRobot.Transition()
|
||||
|
@ -103,8 +175,9 @@ class ReaderViewRobot {
|
|||
onView(
|
||||
withId(R.id.mozac_feature_readerview_font_sans_serif),
|
||||
)
|
||||
|
||||
Log.i(TAG, "toggleSansSerif: Trying to click sans serif button")
|
||||
sansSerifButton().click()
|
||||
Log.i(TAG, "toggleSansSerif: Clicked sans serif button")
|
||||
|
||||
ReaderViewRobot().interact()
|
||||
return Transition()
|
||||
|
@ -115,8 +188,9 @@ class ReaderViewRobot {
|
|||
onView(
|
||||
withId(R.id.mozac_feature_readerview_font_serif),
|
||||
)
|
||||
|
||||
Log.i(TAG, "toggleSerif: Trying to click serif button")
|
||||
serifButton().click()
|
||||
Log.i(TAG, "toggleSerif: Clicked serif button")
|
||||
|
||||
ReaderViewRobot().interact()
|
||||
return Transition()
|
||||
|
@ -127,8 +201,9 @@ class ReaderViewRobot {
|
|||
onView(
|
||||
withId(R.id.mozac_feature_readerview_font_size_decrease),
|
||||
)
|
||||
|
||||
Log.i(TAG, "toggleFontSizeDecrease: Trying to click the decrease font button")
|
||||
fontSizeDecrease().click()
|
||||
Log.i(TAG, "toggleFontSizeDecrease: Clicked the decrease font button")
|
||||
|
||||
ReaderViewRobot().interact()
|
||||
return Transition()
|
||||
|
@ -139,8 +214,9 @@ class ReaderViewRobot {
|
|||
onView(
|
||||
withId(R.id.mozac_feature_readerview_font_size_increase),
|
||||
)
|
||||
|
||||
Log.i(TAG, "toggleFontSizeIncrease: Trying to click the increase font button")
|
||||
fontSizeIncrease().click()
|
||||
Log.i(TAG, "toggleFontSizeIncrease: Clicked the increase font button")
|
||||
|
||||
ReaderViewRobot().interact()
|
||||
return Transition()
|
||||
|
@ -151,8 +227,9 @@ class ReaderViewRobot {
|
|||
onView(
|
||||
withId(R.id.mozac_feature_readerview_color_light),
|
||||
)
|
||||
|
||||
Log.i(TAG, "toggleColorSchemeChangeLight: Trying to click the light color button")
|
||||
toggleLightColorSchemeButton().click()
|
||||
Log.i(TAG, "toggleColorSchemeChangeLight: Clicked the light color button")
|
||||
|
||||
ReaderViewRobot().interact()
|
||||
return Transition()
|
||||
|
@ -163,8 +240,9 @@ class ReaderViewRobot {
|
|||
onView(
|
||||
withId(R.id.mozac_feature_readerview_color_dark),
|
||||
)
|
||||
|
||||
Log.i(TAG, "toggleColorSchemeChangeDark: Trying to click the dark color button")
|
||||
toggleDarkColorSchemeButton().click()
|
||||
Log.i(TAG, "toggleColorSchemeChangeDark: Clicked the dark color button")
|
||||
|
||||
ReaderViewRobot().interact()
|
||||
return Transition()
|
||||
|
@ -175,8 +253,9 @@ class ReaderViewRobot {
|
|||
onView(
|
||||
withId(R.id.mozac_feature_readerview_color_sepia),
|
||||
)
|
||||
|
||||
Log.i(TAG, "toggleColorSchemeChangeSepia: Trying to click the sepia color button")
|
||||
toggleSepiaColorSchemeButton().click()
|
||||
Log.i(TAG, "toggleColorSchemeChangeSepia: Clicked the sepia color button")
|
||||
|
||||
ReaderViewRobot().interact()
|
||||
return Transition()
|
||||
|
@ -184,73 +263,5 @@ class ReaderViewRobot {
|
|||
}
|
||||
}
|
||||
|
||||
fun readerViewRobot(interact: ReaderViewRobot.() -> Unit): ReaderViewRobot.Transition {
|
||||
ReaderViewRobot().interact()
|
||||
return ReaderViewRobot.Transition()
|
||||
}
|
||||
|
||||
private fun assertAppearanceFontGroup(visible: Boolean) =
|
||||
onView(
|
||||
withId(R.id.mozac_feature_readerview_font_group),
|
||||
).check(
|
||||
matches(withEffectiveVisibility(visibleOrGone(visible))),
|
||||
)
|
||||
|
||||
private fun assertAppearanceFontSansSerif(visible: Boolean) =
|
||||
onView(
|
||||
withId(R.id.mozac_feature_readerview_font_sans_serif),
|
||||
).check(
|
||||
matches(withEffectiveVisibility(visibleOrGone(visible))),
|
||||
)
|
||||
|
||||
private fun assertAppearanceFontSerif(visible: Boolean) =
|
||||
onView(
|
||||
withId(R.id.mozac_feature_readerview_font_serif),
|
||||
).check(
|
||||
matches(withEffectiveVisibility(visibleOrGone(visible))),
|
||||
)
|
||||
|
||||
private fun assertAppearanceFontDecrease(visible: Boolean) =
|
||||
onView(
|
||||
withId(R.id.mozac_feature_readerview_font_size_decrease),
|
||||
).check(
|
||||
matches(withEffectiveVisibility(visibleOrGone(visible))),
|
||||
)
|
||||
|
||||
private fun assertAppearanceFontIncrease(visible: Boolean) =
|
||||
onView(
|
||||
withId(R.id.mozac_feature_readerview_font_size_increase),
|
||||
).check(
|
||||
matches(withEffectiveVisibility(visibleOrGone(visible))),
|
||||
)
|
||||
|
||||
private fun assertAppearanceColorDark(visible: Boolean) =
|
||||
onView(
|
||||
withId(R.id.mozac_feature_readerview_color_dark),
|
||||
).check(
|
||||
matches(withEffectiveVisibility(visibleOrGone(visible))),
|
||||
)
|
||||
|
||||
private fun assertAppearanceColorLight(visible: Boolean) =
|
||||
onView(
|
||||
withId(R.id.mozac_feature_readerview_color_light),
|
||||
).check(
|
||||
matches(withEffectiveVisibility(visibleOrGone(visible))),
|
||||
)
|
||||
|
||||
private fun assertAppearanceColorSepia(visible: Boolean) =
|
||||
onView(
|
||||
withId(R.id.mozac_feature_readerview_color_sepia),
|
||||
).check(
|
||||
matches(withEffectiveVisibility(visibleOrGone(visible))),
|
||||
)
|
||||
|
||||
private fun assertAppearanceColorGroup(visible: Boolean) =
|
||||
onView(
|
||||
withId(R.id.mozac_feature_readerview_color_scheme_group),
|
||||
).check(
|
||||
matches(withEffectiveVisibility(visibleOrGone(visible))),
|
||||
)
|
||||
|
||||
private fun visibleOrGone(visibility: Boolean) =
|
||||
if (visibility) ViewMatchers.Visibility.VISIBLE else ViewMatchers.Visibility.GONE
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
package org.mozilla.fenix.ui.robots
|
||||
|
||||
import android.net.Uri
|
||||
import android.util.Log
|
||||
import androidx.test.espresso.Espresso.onView
|
||||
import androidx.test.espresso.assertion.ViewAssertions.matches
|
||||
import androidx.test.espresso.matcher.ViewMatchers.Visibility
|
||||
|
@ -17,6 +18,7 @@ import androidx.test.uiautomator.UiSelector
|
|||
import org.hamcrest.Matchers
|
||||
import org.hamcrest.Matchers.allOf
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.helpers.Constants.TAG
|
||||
import org.mozilla.fenix.helpers.HomeActivityComposeTestRule
|
||||
import org.mozilla.fenix.helpers.MatcherHelper.assertUIObjectExists
|
||||
import org.mozilla.fenix.helpers.MatcherHelper.itemWithResIdContainingText
|
||||
|
@ -32,28 +34,36 @@ import org.mozilla.fenix.helpers.click
|
|||
|
||||
class RecentlyClosedTabsRobot {
|
||||
|
||||
fun waitForListToExist() =
|
||||
fun waitForListToExist() {
|
||||
Log.i(TAG, "waitForListToExist: Waiting for $waitingTime ms for recently closed tabs list to exist")
|
||||
mDevice.findObject(UiSelector().resourceId("$packageName:id/recently_closed_list"))
|
||||
.waitForExists(waitingTime)
|
||||
Log.i(TAG, "waitForListToExist: Waited for $waitingTime ms for recently closed tabs list to exist")
|
||||
}
|
||||
|
||||
fun verifyRecentlyClosedTabsMenuView() {
|
||||
Log.i(TAG, "verifyRecentlyClosedTabsMenuView: Trying to verify that the recently closed tabs menu view is visible")
|
||||
onView(
|
||||
allOf(
|
||||
withText("Recently closed tabs"),
|
||||
withParent(withId(R.id.navigationToolbar)),
|
||||
),
|
||||
).check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
Log.i(TAG, "verifyRecentlyClosedTabsMenuView: Verified that the recently closed tabs menu view is visible")
|
||||
}
|
||||
|
||||
fun verifyEmptyRecentlyClosedTabsList() {
|
||||
Log.i(TAG, "verifyEmptyRecentlyClosedTabsList: Waiting for device to be idle")
|
||||
mDevice.waitForIdle()
|
||||
|
||||
Log.i(TAG, "verifyEmptyRecentlyClosedTabsList: Waited for device to be idle")
|
||||
Log.i(TAG, "verifyEmptyRecentlyClosedTabsList: Trying to verify that the empty recently closed tabs list is visible")
|
||||
onView(
|
||||
allOf(
|
||||
withId(R.id.recently_closed_empty_view),
|
||||
withText(R.string.recently_closed_empty_message),
|
||||
),
|
||||
).check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
Log.i(TAG, "verifyEmptyRecentlyClosedTabsList: Verified that the empty recently closed tabs list is visible")
|
||||
}
|
||||
|
||||
fun verifyRecentlyClosedTabsPageTitle(title: String) =
|
||||
|
@ -62,6 +72,7 @@ class RecentlyClosedTabsRobot {
|
|||
)
|
||||
|
||||
fun verifyRecentlyClosedTabsUrl(expectedUrl: Uri) {
|
||||
Log.i(TAG, "verifyRecentlyClosedTabsUrl: Trying to verify that the recently closed tab with url: $expectedUrl is visible")
|
||||
onView(
|
||||
allOf(
|
||||
withId(R.id.url),
|
||||
|
@ -70,45 +81,64 @@ class RecentlyClosedTabsRobot {
|
|||
),
|
||||
),
|
||||
).check(matches(withText(Matchers.containsString(expectedUrl.toString()))))
|
||||
Log.i(TAG, "verifyRecentlyClosedTabsUrl: Verified that the recently closed tab with url: $expectedUrl is visible")
|
||||
}
|
||||
|
||||
fun clickDeleteRecentlyClosedTabs() = recentlyClosedTabDeleteButton().click()
|
||||
fun clickDeleteRecentlyClosedTabs() {
|
||||
Log.i(TAG, "clickDeleteRecentlyClosedTabs: Trying to click the recently closed tab item delete button")
|
||||
recentlyClosedTabDeleteButton().click()
|
||||
Log.i(TAG, "clickDeleteRecentlyClosedTabs: Clicked the recently closed tab item delete button")
|
||||
}
|
||||
|
||||
class Transition {
|
||||
fun clickRecentlyClosedItem(title: String, interact: BrowserRobot.() -> Unit): BrowserRobot.Transition {
|
||||
recentlyClosedTabsPageTitle(title).also {
|
||||
Log.i(TAG, "clickRecentlyClosedItem: Waiting for $waitingTimeShort ms for recently closed tab with title: $title to exist")
|
||||
it.waitForExists(waitingTimeShort)
|
||||
Log.i(TAG, "clickRecentlyClosedItem: Waited for $waitingTimeShort ms for recently closed tab with title: $title to exist")
|
||||
Log.i(TAG, "clickRecentlyClosedItem: Trying to click the recently closed tab with title: $title")
|
||||
it.click()
|
||||
Log.i(TAG, "clickRecentlyClosedItem: Clicked the recently closed tab with title: $title")
|
||||
}
|
||||
Log.i(TAG, "clickRecentlyClosedItem: Waiting for device to be idle")
|
||||
mDevice.waitForIdle()
|
||||
Log.i(TAG, "clickRecentlyClosedItem: Waited for device to be idle")
|
||||
|
||||
BrowserRobot().interact()
|
||||
return BrowserRobot.Transition()
|
||||
}
|
||||
|
||||
fun clickOpenInNewTab(testRule: HomeActivityComposeTestRule, interact: ComposeTabDrawerRobot.() -> Unit): ComposeTabDrawerRobot.Transition {
|
||||
openInNewTabOption.click()
|
||||
Log.i(TAG, "clickOpenInNewTab: Trying to click the multi-select \"Open in a new tab\" context menu button")
|
||||
openInNewTabOption().click()
|
||||
Log.i(TAG, "clickOpenInNewTab: Clicked the multi-select \"Open in a new tab\" context menu button")
|
||||
|
||||
ComposeTabDrawerRobot(testRule).interact()
|
||||
return ComposeTabDrawerRobot.Transition(testRule)
|
||||
}
|
||||
|
||||
fun clickOpenInPrivateTab(testRule: HomeActivityComposeTestRule, interact: ComposeTabDrawerRobot.() -> Unit): ComposeTabDrawerRobot.Transition {
|
||||
openInPrivateTabOption.click()
|
||||
Log.i(TAG, "clickOpenInPrivateTab: Trying to click the multi-select \"Open in a private tab\" context menu button")
|
||||
openInPrivateTabOption().click()
|
||||
Log.i(TAG, "clickOpenInPrivateTab: Clicked the multi-select \"Open in a private tab\" context menu button")
|
||||
|
||||
ComposeTabDrawerRobot(testRule).interact()
|
||||
return ComposeTabDrawerRobot.Transition(testRule)
|
||||
}
|
||||
|
||||
fun clickShare(interact: ShareOverlayRobot.() -> Unit): ShareOverlayRobot.Transition {
|
||||
multipleSelectionShareButton.click()
|
||||
Log.i(TAG, "clickShare: Trying to click the share recently closed tabs button")
|
||||
multipleSelectionShareButton().click()
|
||||
Log.i(TAG, "clickShare: Clicked the share recently closed tabs button")
|
||||
|
||||
ShareOverlayRobot().interact()
|
||||
return ShareOverlayRobot.Transition()
|
||||
}
|
||||
|
||||
fun goBackToHistoryMenu(interact: HistoryRobot.() -> Unit): HistoryRobot.Transition {
|
||||
Log.i(TAG, "goBackToHistoryMenu: Trying to click navigate up toolbar button")
|
||||
onView(withContentDescription("Navigate up")).click()
|
||||
Log.i(TAG, "goBackToHistoryMenu: Clicked navigate up toolbar button")
|
||||
|
||||
HistoryRobot().interact()
|
||||
return HistoryRobot.Transition()
|
||||
|
@ -132,8 +162,8 @@ private fun recentlyClosedTabDeleteButton() =
|
|||
),
|
||||
)
|
||||
|
||||
private val openInNewTabOption = onView(withText("Open in new tab"))
|
||||
private fun openInNewTabOption() = onView(withText("Open in new tab"))
|
||||
|
||||
private val openInPrivateTabOption = onView(withText("Open in private tab"))
|
||||
private fun openInPrivateTabOption() = onView(withText("Open in private tab"))
|
||||
|
||||
private val multipleSelectionShareButton = onView(withId(R.id.share_history_multi_select))
|
||||
private fun multipleSelectionShareButton() = onView(withId(R.id.share_history_multi_select))
|
||||
|
|
|
@ -11,15 +11,12 @@ import android.net.Uri
|
|||
import android.util.Log
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.test.espresso.Espresso.onView
|
||||
import androidx.test.espresso.ViewInteraction
|
||||
import androidx.test.espresso.action.ViewActions
|
||||
import androidx.test.espresso.assertion.ViewAssertions.matches
|
||||
import androidx.test.espresso.contrib.RecyclerViewActions
|
||||
import androidx.test.espresso.intent.Intents.intended
|
||||
import androidx.test.espresso.intent.matcher.IntentMatchers
|
||||
import androidx.test.espresso.intent.matcher.IntentMatchers.hasAction
|
||||
import androidx.test.espresso.intent.matcher.IntentMatchers.hasData
|
||||
import androidx.test.espresso.matcher.ViewMatchers
|
||||
import androidx.test.espresso.matcher.ViewMatchers.Visibility
|
||||
import androidx.test.espresso.matcher.ViewMatchers.hasDescendant
|
||||
import androidx.test.espresso.matcher.ViewMatchers.hasSibling
|
||||
|
@ -28,6 +25,7 @@ import androidx.test.espresso.matcher.ViewMatchers.isCompletelyDisplayed
|
|||
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
|
||||
import androidx.test.espresso.matcher.ViewMatchers.isNotChecked
|
||||
import androidx.test.espresso.matcher.ViewMatchers.withClassName
|
||||
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
|
||||
|
@ -69,20 +67,64 @@ import org.mozilla.fenix.ui.robots.SettingsRobot.Companion.DEFAULT_APPS_SETTINGS
|
|||
class SettingsRobot {
|
||||
|
||||
// BASICS SECTION
|
||||
fun verifyGeneralHeading() = assertGeneralHeading()
|
||||
fun verifyGeneralHeading() {
|
||||
scrollToElementByText("General")
|
||||
Log.i(TAG, "verifyGeneralHeading: Trying to verify that the \"General\" heading is visible")
|
||||
onView(withText("General"))
|
||||
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
Log.i(TAG, "verifyGeneralHeading: Verified that the \"General\" heading is visible")
|
||||
}
|
||||
|
||||
fun verifySearchButton() = assertSearchButton()
|
||||
fun verifyCustomizeButton() = assertCustomizeButton()
|
||||
fun verifyThemeSelected() = assertThemeSelected()
|
||||
fun verifyAccessibilityButton() = assertAccessibilityButton()
|
||||
fun verifySetAsDefaultBrowserButton() = assertSetAsDefaultBrowserButton()
|
||||
fun verifySearchButton() {
|
||||
Log.i(TAG, "verifySearchButton: Waiting for $waitingTime ms until finding the \"Search\" button")
|
||||
mDevice.wait(Until.findObject(By.text("Search")), waitingTime)
|
||||
Log.i(TAG, "verifySearchButton: Waited for $waitingTime ms until the \"Search\" button was found")
|
||||
Log.i(TAG, "verifySearchButton: Trying to verify that the \"Search\" button is visible")
|
||||
onView(withText(R.string.preferences_search))
|
||||
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
Log.i(TAG, "verifySearchButton: Verified that the \"Search\" button is visible")
|
||||
}
|
||||
fun verifyCustomizeButton() {
|
||||
Log.i(TAG, "verifyCustomizeButton: Trying to verify that the \"Customize\" button is visible")
|
||||
onView(withText("Customize"))
|
||||
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
Log.i(TAG, "verifyCustomizeButton: Verified that the \"Customize\" button is visible")
|
||||
}
|
||||
|
||||
fun verifyAccessibilityButton() {
|
||||
Log.i(TAG, "verifyAccessibilityButton: Trying to verify that the \"Accessibility\" button is visible")
|
||||
onView(withText("Accessibility"))
|
||||
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
Log.i(TAG, "verifyAccessibilityButton: Verified that the \"Accessibility\" button is visible")
|
||||
}
|
||||
fun verifySetAsDefaultBrowserButton() {
|
||||
scrollToElementByText("Set as default browser")
|
||||
Log.i(TAG, "verifySetAsDefaultBrowserButton: Trying to verify that the \"Set as default browser\" button is visible")
|
||||
onView(withText("Set as default browser"))
|
||||
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
Log.i(TAG, "verifySetAsDefaultBrowserButton: Verified that the \"Set as default browser\" button is visible")
|
||||
}
|
||||
fun verifyTabsButton() =
|
||||
assertUIObjectExists(itemContainingText(getStringResource(R.string.preferences_tabs)))
|
||||
fun verifyHomepageButton() = assertHomepageButton()
|
||||
fun verifyAutofillButton() = assertAutofillButton()
|
||||
fun verifyLanguageButton() = assertLanguageButton()
|
||||
fun verifyHomepageButton() {
|
||||
Log.i(TAG, "verifyHomepageButton: Trying to verify that the \"Homepage\" button is visible")
|
||||
onView(withText(R.string.preferences_home_2)).check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
Log.i(TAG, "verifyHomepageButton: Verified that the \"Homepage\" button is visible")
|
||||
}
|
||||
fun verifyAutofillButton() {
|
||||
Log.i(TAG, "verifyAutofillButton: Trying to verify that the \"Autofill\" button is visible")
|
||||
onView(withText(R.string.preferences_autofill)).check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
Log.i(TAG, "verifyAutofillButton: Verified that the \"Autofill\" button is visible")
|
||||
}
|
||||
fun verifyLanguageButton() {
|
||||
scrollToElementByText(getStringResource(R.string.preferences_language))
|
||||
Log.i(TAG, "verifyLanguageButton: Trying to verify that the \"Language\" button is visible")
|
||||
onView(withText(R.string.preferences_language)).check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
Log.i(TAG, "verifyLanguageButton: Verified that the \"Language\" button is visible")
|
||||
}
|
||||
fun verifyDefaultBrowserToggle(isEnabled: Boolean) {
|
||||
scrollToElementByText(getStringResource(R.string.preferences_set_as_default_browser))
|
||||
Log.i(TAG, "verifyDefaultBrowserToggle: Trying to verify that the \"Set as default browser\" toggle is enabled: $isEnabled")
|
||||
onView(withText(R.string.preferences_set_as_default_browser))
|
||||
.check(
|
||||
matches(
|
||||
|
@ -98,18 +140,36 @@ class SettingsRobot {
|
|||
),
|
||||
),
|
||||
)
|
||||
Log.i(TAG, "verifyDefaultBrowserToggle: Verified that the \"Set as default browser\" toggle is enabled: $isEnabled")
|
||||
}
|
||||
|
||||
fun clickDefaultBrowserSwitch() = toggleDefaultBrowserSwitch()
|
||||
fun verifyAndroidDefaultAppsMenuAppears() = assertAndroidDefaultAppsMenuAppears()
|
||||
fun verifyAndroidDefaultAppsMenuAppears() {
|
||||
Log.i(TAG, "verifyAndroidDefaultAppsMenuAppears: Trying to verify that default browser apps dialog appears")
|
||||
intended(hasAction(DEFAULT_APPS_SETTINGS_ACTION))
|
||||
Log.i(TAG, "verifyAndroidDefaultAppsMenuAppears: Verified that the default browser apps dialog appears")
|
||||
}
|
||||
|
||||
// PRIVACY SECTION
|
||||
fun verifyPrivacyHeading() = assertPrivacyHeading()
|
||||
|
||||
fun verifyHTTPSOnlyModeButton() = assertHTTPSOnlyModeButton()
|
||||
fun verifyPrivacyHeading() {
|
||||
scrollToElementByText("Privacy and security")
|
||||
Log.i(TAG, "verifyPrivacyHeading: Trying to verify that the \"Privacy and security\" heading is visible")
|
||||
onView(withText("Privacy and security"))
|
||||
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
Log.i(TAG, "verifyPrivacyHeading: Verified that the \"Privacy and security\" heading is visible")
|
||||
}
|
||||
fun verifyHTTPSOnlyModeButton() {
|
||||
scrollToElementByText(getStringResource(R.string.preferences_https_only_title))
|
||||
Log.i(TAG, "verifyHTTPSOnlyModeButton: Trying to verify that the \"HTTPS-Only Mode\" button is visible")
|
||||
onView(
|
||||
withText(R.string.preferences_https_only_title),
|
||||
).check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
Log.i(TAG, "verifyHTTPSOnlyModeButton: Verified that the \"HTTPS-Only Mode\" button is visible")
|
||||
}
|
||||
|
||||
fun verifyCookieBannerBlockerButton(enabled: Boolean) {
|
||||
scrollToElementByText(getStringResource(R.string.preferences_cookie_banner_reduction_private_mode))
|
||||
Log.i(TAG, "verifyCookieBannerBlockerButton: Trying to verify that the \"Cookie Banner Blocker in private browsing\" toggle is enabled: $enabled")
|
||||
onView(withText(R.string.preferences_cookie_banner_reduction_private_mode))
|
||||
.check(
|
||||
matches(
|
||||
|
@ -125,31 +185,167 @@ class SettingsRobot {
|
|||
),
|
||||
),
|
||||
)
|
||||
Log.i(TAG, "verifyCookieBannerBlockerButton: Verified if cookie banner blocker toggle is enabled: $enabled")
|
||||
Log.i(TAG, "verifyCookieBannerBlockerButton: Verified that the \"Cookie Banner Blocker in private browsing\" toggle is enabled: $enabled")
|
||||
}
|
||||
|
||||
fun verifyEnhancedTrackingProtectionButton() = assertEnhancedTrackingProtectionButton()
|
||||
fun verifyLoginsAndPasswordsButton() = assertLoginsAndPasswordsButton()
|
||||
fun verifyPrivateBrowsingButton() = assertPrivateBrowsingButton()
|
||||
fun verifySitePermissionsButton() = assertSitePermissionsButton()
|
||||
fun verifyDeleteBrowsingDataButton() = assertDeleteBrowsingDataButton()
|
||||
fun verifyDeleteBrowsingDataOnQuitButton() = assertDeleteBrowsingDataOnQuitButton()
|
||||
fun verifyNotificationsButton() = assertNotificationsButton()
|
||||
fun verifyDataCollectionButton() = assertDataCollectionButton()
|
||||
fun verifyOpenLinksInAppsButton() = assertOpenLinksInAppsButton()
|
||||
fun verifySettingsView() = assertSettingsView()
|
||||
fun verifySettingsToolbar() = assertSettingsToolbar()
|
||||
fun verifyEnhancedTrackingProtectionButton() {
|
||||
Log.i(TAG, "verifyEnhancedTrackingProtectionButton: Waiting for $waitingTime ms until finding the \"Privacy and Security\" heading")
|
||||
mDevice.wait(Until.findObject(By.text("Privacy and Security")), waitingTime)
|
||||
Log.i(TAG, "verifyEnhancedTrackingProtectionButton: Waited for $waitingTime ms until the \"Privacy and Security\" heading was found")
|
||||
Log.i(TAG, "verifyEnhancedTrackingProtectionButton: Trying to verify that the \"Enhanced Tracking Protection\" button is visible")
|
||||
onView(withId(R.id.recycler_view)).perform(
|
||||
RecyclerViewActions.scrollTo<RecyclerView.ViewHolder>(
|
||||
hasDescendant(withText("Enhanced Tracking Protection")),
|
||||
),
|
||||
).check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
Log.i(TAG, "verifyEnhancedTrackingProtectionButton: Verified that the \"Enhanced Tracking Protection\" button is visible")
|
||||
}
|
||||
fun verifyLoginsAndPasswordsButton() {
|
||||
scrollToElementByText("Logins and passwords")
|
||||
Log.i(TAG, "verifyLoginsAndPasswordsButton: Trying to verify that the \"Logins and passwords\" button is visible")
|
||||
onView(withText(R.string.preferences_passwords_logins_and_passwords))
|
||||
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
Log.i(TAG, "verifyLoginsAndPasswordsButton: Verified that the \"Logins and passwords\" button is visible")
|
||||
}
|
||||
fun verifyPrivateBrowsingButton() {
|
||||
scrollToElementByText("Private browsing")
|
||||
Log.i(TAG, "verifyPrivateBrowsingButton: Waiting for $waitingTime ms until finding the \"Private browsing\" button")
|
||||
mDevice.wait(Until.findObject(By.text("Private browsing")), waitingTime)
|
||||
Log.i(TAG, "verifyPrivateBrowsingButton: Waited for $waitingTime ms until the \"Private browsing\" button was found")
|
||||
Log.i(TAG, "verifyPrivateBrowsingButton: Trying to verify that the \"Private browsing\" button is visible")
|
||||
onView(withText("Private browsing"))
|
||||
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
Log.i(TAG, "verifyPrivateBrowsingButton: Verified that the \"Private browsing\" button is visible")
|
||||
}
|
||||
fun verifySitePermissionsButton() {
|
||||
scrollToElementByText("Site permissions")
|
||||
Log.i(TAG, "verifySitePermissionsButton: Trying to verify that the \"Site permissions\" button is visible")
|
||||
onView(withText("Site permissions"))
|
||||
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
Log.i(TAG, "verifySitePermissionsButton: Verified that the \"Site permissions\" button is visible")
|
||||
}
|
||||
fun verifyDeleteBrowsingDataButton() {
|
||||
scrollToElementByText("Delete browsing data")
|
||||
Log.i(TAG, "verifyDeleteBrowsingDataButton: Trying to verify that the \"Delete browsing data\" button is visible")
|
||||
onView(withText("Delete browsing data"))
|
||||
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
Log.i(TAG, "verifyDeleteBrowsingDataButton: Verified that the \"Delete browsing data\" button is visible")
|
||||
}
|
||||
fun verifyDeleteBrowsingDataOnQuitButton() {
|
||||
scrollToElementByText("Delete browsing data on quit")
|
||||
Log.i(TAG, "verifyDeleteBrowsingDataOnQuitButton: Trying to verify that the \"Delete browsing data on quit\" button is visible")
|
||||
onView(withText("Delete browsing data on quit"))
|
||||
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
Log.i(TAG, "verifyDeleteBrowsingDataOnQuitButton: Verified that the \"Delete browsing data on quit\" button is visible")
|
||||
}
|
||||
fun verifyNotificationsButton() {
|
||||
scrollToElementByText("Notifications")
|
||||
Log.i(TAG, "verifyNotificationsButton: Trying to verify that the \"Notifications\" button is visible")
|
||||
onView(withText("Notifications"))
|
||||
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
Log.i(TAG, "verifyNotificationsButton: Verified that the \"Notifications\" button is visible")
|
||||
}
|
||||
fun verifyDataCollectionButton() {
|
||||
scrollToElementByText("Data collection")
|
||||
Log.i(TAG, "verifyDataCollectionButton: Trying to verify that the \"Data collection\" button is visible")
|
||||
onView(withText("Data collection"))
|
||||
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
Log.i(TAG, "verifyDataCollectionButton: Verified that the \"Data collection\" button is visible")
|
||||
}
|
||||
fun verifyOpenLinksInAppsButton() {
|
||||
scrollToElementByText("Open links in apps")
|
||||
Log.i(TAG, "verifyOpenLinksInAppsButton: Trying to verify that the \"Open links in apps\" button is visible")
|
||||
openLinksInAppsButton()
|
||||
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
Log.i(TAG, "verifyOpenLinksInAppsButton: Verified that the \"Open links in apps\" button is visible")
|
||||
}
|
||||
fun verifySettingsView() {
|
||||
scrollToElementByText("General")
|
||||
Log.i(TAG, "verifySettingsView: Trying to verify that the \"General\" heading is visible")
|
||||
onView(withText("General"))
|
||||
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
Log.i(TAG, "verifySettingsView: Verified that the \"General\" heading is visible")
|
||||
scrollToElementByText("Privacy and security")
|
||||
Log.i(TAG, "verifySettingsView: Trying to verify that the \"Privacy and security\" heading is visible")
|
||||
onView(withText("Privacy and security"))
|
||||
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
Log.i(TAG, "verifySettingsView: Verified that the \"Privacy and security\" heading is visible")
|
||||
Log.i(TAG, "verifySettingsView: Trying to perform scroll to the \"Add-ons\" button")
|
||||
onView(withId(R.id.recycler_view)).perform(
|
||||
RecyclerViewActions.scrollTo<RecyclerView.ViewHolder>(
|
||||
hasDescendant(withText("Add-ons")),
|
||||
),
|
||||
)
|
||||
Log.i(TAG, "verifySettingsView: Performed scroll to the \"Add-ons\" button")
|
||||
Log.i(TAG, "verifySettingsView: Trying to verify that the \"Add-ons\" button is completely displayed")
|
||||
onView(withText("Add-ons"))
|
||||
.check(matches(isCompletelyDisplayed()))
|
||||
Log.i(TAG, "verifySettingsView: Verified that the \"Add-ons\" button is completely displayed")
|
||||
Log.i(TAG, "verifySettingsView: Trying to perform ${LISTS_MAXSWIPES}x a scroll action to the end of the settings list")
|
||||
settingsList().scrollToEnd(LISTS_MAXSWIPES)
|
||||
Log.i(TAG, "verifySettingsView: Performed ${LISTS_MAXSWIPES}x a scroll action to the end of the settings list")
|
||||
Log.i(TAG, "verifySettingsView: Trying to verify that the \"About\" heading is visible")
|
||||
onView(withText("About"))
|
||||
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
Log.i(TAG, "verifySettingsView: Verified that the \"About\" heading is visible")
|
||||
}
|
||||
fun verifySettingsToolbar() {
|
||||
Log.i(TAG, "verifySettingsToolbar: Trying to verify that the navigate up button is visible")
|
||||
onView(
|
||||
allOf(
|
||||
withId(R.id.navigationToolbar),
|
||||
hasDescendant(withContentDescription(R.string.action_bar_up_description)),
|
||||
),
|
||||
).check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
Log.i(TAG, "verifySettingsToolbar: Verified that the navigate up button is visible")
|
||||
Log.i(TAG, "verifySettingsToolbar: Trying to verify that the \"Settings\" toolbar title is visible")
|
||||
onView(
|
||||
allOf(
|
||||
withId(R.id.navigationToolbar),
|
||||
hasDescendant(withText(R.string.settings)),
|
||||
),
|
||||
).check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
Log.i(TAG, "verifySettingsToolbar: Verified that the \"Settings\" toolbar title is visible")
|
||||
}
|
||||
|
||||
// ADVANCED SECTION
|
||||
fun verifyAdvancedHeading() = assertAdvancedHeading()
|
||||
fun verifyAddons() = assertAddonsButton()
|
||||
fun verifyAdvancedHeading() {
|
||||
Log.i(TAG, "verifyAdvancedHeading: Trying to perform scroll to the \"Add-ons\" button")
|
||||
onView(withId(R.id.recycler_view)).perform(
|
||||
RecyclerViewActions.scrollTo<RecyclerView.ViewHolder>(
|
||||
hasDescendant(withText("Add-ons")),
|
||||
),
|
||||
)
|
||||
Log.i(TAG, "verifyAdvancedHeading: Performed scroll to the \"Add-ons\" button")
|
||||
Log.i(TAG, "verifyAdvancedHeading: Trying to verify that the \"Add-ons\" button is completely displayed")
|
||||
onView(withText("Add-ons"))
|
||||
.check(matches(isCompletelyDisplayed()))
|
||||
Log.i(TAG, "verifyAdvancedHeading: Verified that the \"Add-ons\" button is completely displayed")
|
||||
}
|
||||
fun verifyAddons() {
|
||||
Log.i(TAG, "verifyAddons: Trying to perform scroll to the \"Add-ons\" button")
|
||||
onView(withId(R.id.recycler_view)).perform(
|
||||
RecyclerViewActions.scrollTo<RecyclerView.ViewHolder>(
|
||||
hasDescendant(withText("Add-ons")),
|
||||
),
|
||||
)
|
||||
Log.i(TAG, "verifyAddons: Performed scroll to the \"Add-ons\" button")
|
||||
Log.i(TAG, "verifyAddons: Trying to verify that the \"Add-ons\" button is completely displayed")
|
||||
addonsManagerButton()
|
||||
.check(matches(isCompletelyDisplayed()))
|
||||
Log.i(TAG, "verifyAddons: Verified that the \"Add-ons\" button is completely displayed")
|
||||
}
|
||||
|
||||
fun verifyExternalDownloadManagerButton() =
|
||||
fun verifyExternalDownloadManagerButton() {
|
||||
Log.i(TAG, "verifyExternalDownloadManagerButton: Trying to verify that the \"External download manager\" button is visible")
|
||||
onView(
|
||||
withText(R.string.preferences_external_download_manager),
|
||||
).check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
Log.i(TAG, "verifyExternalDownloadManagerButton: Verified that the \"External download manager\" button is visible")
|
||||
}
|
||||
|
||||
fun verifyExternalDownloadManagerToggle(enabled: Boolean) =
|
||||
fun verifyExternalDownloadManagerToggle(enabled: Boolean) {
|
||||
Log.i(TAG, "verifyExternalDownloadManagerToggle: Trying to verify that the \"External download manager\" toggle is enabled: $enabled")
|
||||
onView(withText(R.string.preferences_external_download_manager))
|
||||
.check(
|
||||
matches(
|
||||
|
@ -165,8 +361,11 @@ class SettingsRobot {
|
|||
),
|
||||
),
|
||||
)
|
||||
Log.i(TAG, "verifyExternalDownloadManagerToggle: Verified that the \"External download manager\" toggle is enabled: $enabled")
|
||||
}
|
||||
|
||||
fun verifyLeakCanaryToggle(enabled: Boolean) =
|
||||
fun verifyLeakCanaryToggle(enabled: Boolean) {
|
||||
Log.i(TAG, "verifyLeakCanaryToggle: Trying to verify that the \"LeakCanary\" toggle is enabled: $enabled")
|
||||
onView(withText(R.string.preference_leakcanary))
|
||||
.check(
|
||||
matches(
|
||||
|
@ -182,8 +381,11 @@ class SettingsRobot {
|
|||
),
|
||||
),
|
||||
)
|
||||
Log.i(TAG, "verifyLeakCanaryToggle: Verified that the \"LeakCanary\" toggle is enabled: $enabled")
|
||||
}
|
||||
|
||||
fun verifyRemoteDebuggingToggle(enabled: Boolean) =
|
||||
fun verifyRemoteDebuggingToggle(enabled: Boolean) {
|
||||
Log.i(TAG, "verifyRemoteDebuggingToggle: Trying to verify that the \"Remote debugging via USB\" toggle is enabled: $enabled")
|
||||
onView(withText(R.string.preferences_remote_debugging))
|
||||
.check(
|
||||
matches(
|
||||
|
@ -199,53 +401,106 @@ class SettingsRobot {
|
|||
),
|
||||
),
|
||||
)
|
||||
Log.i(TAG, "verifyRemoteDebuggingToggle: Verified that the \"Remote debugging via USB\" toggle is enabled: $enabled")
|
||||
}
|
||||
|
||||
// DEVELOPER TOOLS SECTION
|
||||
fun verifyRemoteDebuggingButton() = assertRemoteDebuggingButton()
|
||||
fun verifyLeakCanaryButton() = assertLeakCanaryButton()
|
||||
fun verifyRemoteDebuggingButton() {
|
||||
scrollToElementByText("Remote debugging via USB")
|
||||
Log.i(TAG, "verifyRemoteDebuggingButton: Trying to verify that the \"Remote debugging via USB\" button is visible")
|
||||
onView(withText("Remote debugging via USB"))
|
||||
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
Log.i(TAG, "verifyRemoteDebuggingButton: Verified that the \"Remote debugging via USB\" button is visible")
|
||||
}
|
||||
fun verifyLeakCanaryButton() {
|
||||
scrollToElementByText("LeakCanary")
|
||||
Log.i(TAG, "verifyLeakCanaryButton: Trying to verify that the \"LeakCanary\" button is visible")
|
||||
onView(withText("LeakCanary"))
|
||||
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
Log.i(TAG, "verifyLeakCanaryButton: Verified that the \"LeakCanary\" button is visible")
|
||||
}
|
||||
|
||||
// ABOUT SECTION
|
||||
fun verifyAboutHeading() = assertAboutHeading()
|
||||
fun verifyAboutHeading() {
|
||||
Log.i(TAG, "verifyAboutHeading: Trying to perform ${LISTS_MAXSWIPES}x a scroll action to the end of the settings list")
|
||||
settingsList().scrollToEnd(LISTS_MAXSWIPES)
|
||||
Log.i(TAG, "verifyAboutHeading: Performed ${LISTS_MAXSWIPES}x a scroll action to the end of the settings list")
|
||||
Log.i(TAG, "verifyAboutHeading: Trying to verify that the \"About\" heading is visible")
|
||||
onView(withText("About"))
|
||||
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
Log.i(TAG, "verifyAboutHeading: Verified that the \"About\" heading is visible")
|
||||
}
|
||||
|
||||
fun verifyRateOnGooglePlay() = assertUIObjectExists(rateOnGooglePlayHeading())
|
||||
fun verifyAboutFirefoxPreview() = assertUIObjectExists(aboutFirefoxHeading())
|
||||
fun verifyGooglePlayRedirect() = assertGooglePlayRedirect()
|
||||
fun verifyGooglePlayRedirect() {
|
||||
if (isPackageInstalled(GOOGLE_PLAY_SERVICES)) {
|
||||
Log.i(TAG, "verifyGooglePlayRedirect: $GOOGLE_PLAY_SERVICES is installed")
|
||||
try {
|
||||
Log.i(TAG, "verifyGooglePlayRedirect: Trying to verify intent to: $GOOGLE_PLAY_SERVICES")
|
||||
intended(
|
||||
allOf(
|
||||
hasAction(Intent.ACTION_VIEW),
|
||||
hasData(Uri.parse(SupportUtils.RATE_APP_URL)),
|
||||
),
|
||||
)
|
||||
Log.i(TAG, "verifyGooglePlayRedirect: Verified intent to: $GOOGLE_PLAY_SERVICES")
|
||||
} catch (e: AssertionFailedError) {
|
||||
Log.i(TAG, "verifyGooglePlayRedirect: AssertionFailedError caught, executing fallback methods")
|
||||
BrowserRobot().verifyRateOnGooglePlayURL()
|
||||
}
|
||||
} else {
|
||||
BrowserRobot().verifyRateOnGooglePlayURL()
|
||||
}
|
||||
}
|
||||
|
||||
fun verifySettingsOptionSummary(setting: String, summary: String) {
|
||||
scrollToElementByText(setting)
|
||||
Log.i(TAG, "verifySettingsOptionSummary: Trying to verify that setting: $setting with summary:$summary is visible")
|
||||
onView(
|
||||
allOf(
|
||||
withText(setting),
|
||||
hasSibling(withText(summary)),
|
||||
),
|
||||
).check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
Log.i(TAG, "verifySettingsOptionSummary: Verified that setting: $setting with summary:$summary is visible")
|
||||
}
|
||||
|
||||
class Transition {
|
||||
fun goBack(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition {
|
||||
Log.i(TAG, "goBack: Trying to click the navigate up button")
|
||||
goBackButton().click()
|
||||
Log.i(TAG, "goBack: Clicked the navigate up button")
|
||||
|
||||
HomeScreenRobot().interact()
|
||||
return HomeScreenRobot.Transition()
|
||||
}
|
||||
|
||||
fun goBackToOnboardingScreen(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition {
|
||||
Log.i(TAG, "goBackToOnboardingScreen: Trying to click device back button")
|
||||
mDevice.pressBack()
|
||||
Log.i(TAG, "goBackToOnboardingScreen: Clicked device back button")
|
||||
Log.i(TAG, "goBackToOnboardingScreen: Waiting for device to be idle for $waitingTimeShort ms")
|
||||
mDevice.waitForIdle(waitingTimeShort)
|
||||
Log.i(TAG, "goBackToOnboardingScreen: Device was idle for $waitingTimeShort ms")
|
||||
|
||||
HomeScreenRobot().interact()
|
||||
return HomeScreenRobot.Transition()
|
||||
}
|
||||
|
||||
fun goBackToBrowser(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition {
|
||||
Log.i(TAG, "goBackToBrowser: Trying to click the navigate up button")
|
||||
goBackButton().click()
|
||||
Log.i(TAG, "goBackToBrowser: Clicked the navigate up button")
|
||||
|
||||
BrowserRobot().interact()
|
||||
return BrowserRobot.Transition()
|
||||
}
|
||||
|
||||
fun openAboutFirefoxPreview(interact: SettingsSubMenuAboutRobot.() -> Unit): SettingsSubMenuAboutRobot.Transition {
|
||||
Log.i(TAG, "openAboutFirefoxPreview: Trying to click the \"About Firefox\" button")
|
||||
aboutFirefoxHeading().click()
|
||||
Log.i(TAG, "openAboutFirefoxPreview: Clicked the \"About Firefox\" button")
|
||||
SettingsSubMenuAboutRobot().interact()
|
||||
return SettingsSubMenuAboutRobot.Transition()
|
||||
}
|
||||
|
@ -253,8 +508,12 @@ class SettingsRobot {
|
|||
fun openSearchSubMenu(interact: SettingsSubMenuSearchRobot.() -> Unit): SettingsSubMenuSearchRobot.Transition {
|
||||
itemWithText(getStringResource(R.string.preferences_search))
|
||||
.also {
|
||||
Log.i(TAG, "openSearchSubMenu: Waiting for $waitingTimeShort ms for the \"Search\" button to exist")
|
||||
it.waitForExists(waitingTimeShort)
|
||||
Log.i(TAG, "openSearchSubMenu: Waited for $waitingTimeShort ms for the \"Search\" button to exist")
|
||||
Log.i(TAG, "openSearchSubMenu: Trying to click the \"Search\" button")
|
||||
it.click()
|
||||
Log.i(TAG, "openSearchSubMenu: Clicked the \"Search\" button")
|
||||
}
|
||||
|
||||
SettingsSubMenuSearchRobot().interact()
|
||||
|
@ -262,8 +521,9 @@ class SettingsRobot {
|
|||
}
|
||||
|
||||
fun openCustomizeSubMenu(interact: SettingsSubMenuCustomizeRobot.() -> Unit): SettingsSubMenuCustomizeRobot.Transition {
|
||||
fun customizeButton() = onView(withText("Customize"))
|
||||
customizeButton().click()
|
||||
Log.i(TAG, "openCustomizeSubMenu: Trying to click the \"Customize\" button")
|
||||
onView(withText("Customize")).click()
|
||||
Log.i(TAG, "openCustomizeSubMenu: Clicked the \"Customize\" button")
|
||||
|
||||
SettingsSubMenuCustomizeRobot().interact()
|
||||
return SettingsSubMenuCustomizeRobot.Transition()
|
||||
|
@ -272,8 +532,12 @@ class SettingsRobot {
|
|||
fun openTabsSubMenu(interact: SettingsSubMenuTabsRobot.() -> Unit): SettingsSubMenuTabsRobot.Transition {
|
||||
itemWithText(getStringResource(R.string.preferences_tabs))
|
||||
.also {
|
||||
Log.i(TAG, "openTabsSubMenu: Waiting for $waitingTime ms for the \"Tabs\" button to exist")
|
||||
it.waitForExists(waitingTime)
|
||||
Log.i(TAG, "openTabsSubMenu: Waited for $waitingTime ms for the \"Tabs\" button to exist")
|
||||
Log.i(TAG, "openTabsSubMenu: Trying to click the \"Tabs\" button and wait for $waitingTimeShort ms for a new window")
|
||||
it.clickAndWaitForNewWindow(waitingTimeShort)
|
||||
Log.i(TAG, "openTabsSubMenu: Clicked the \"Tabs\" button and wait for $waitingTimeShort ms for a new window")
|
||||
}
|
||||
|
||||
SettingsSubMenuTabsRobot().interact()
|
||||
|
@ -281,8 +545,12 @@ class SettingsRobot {
|
|||
}
|
||||
|
||||
fun openHomepageSubMenu(interact: SettingsSubMenuHomepageRobot.() -> Unit): SettingsSubMenuHomepageRobot.Transition {
|
||||
Log.i(TAG, "openHomepageSubMenu: Waiting for $waitingTime ms for the \"Homepage\" button to exist")
|
||||
mDevice.findObject(UiSelector().textContains("Homepage")).waitForExists(waitingTime)
|
||||
Log.i(TAG, "openHomepageSubMenu: Waited for $waitingTime ms for the \"Homepage\" button to exist")
|
||||
Log.i(TAG, "openHomepageSubMenu: Trying to click the \"Homepage\" button")
|
||||
onView(withText(R.string.preferences_home_2)).click()
|
||||
Log.i(TAG, "openHomepageSubMenu: Clicked the \"Homepage\" button")
|
||||
|
||||
SettingsSubMenuHomepageRobot().interact()
|
||||
return SettingsSubMenuHomepageRobot.Transition()
|
||||
|
@ -291,10 +559,12 @@ class SettingsRobot {
|
|||
fun openAutofillSubMenu(interact: SettingsSubMenuAutofillRobot.() -> Unit): SettingsSubMenuAutofillRobot.Transition {
|
||||
mDevice.findObject(UiSelector().textContains(getStringResource(R.string.preferences_autofill)))
|
||||
.also {
|
||||
Log.i(TAG, "openAutofillSubMenu: Looking for \"Autofill\" settings button")
|
||||
Log.i(TAG, "openAutofillSubMenu: Waiting for $waitingTime ms for the \"Autofill\" button to exist")
|
||||
it.waitForExists(waitingTime)
|
||||
Log.i(TAG, "openAutofillSubMenu: Waited for $waitingTime ms for the \"Autofill\" button to exist")
|
||||
Log.i(TAG, "openAutofillSubMenu: Trying to click the \"Autofill\" button")
|
||||
it.click()
|
||||
Log.i(TAG, "openAutofillSubMenu: Clicked \"Autofill\" settings button")
|
||||
Log.i(TAG, "openAutofillSubMenu: Clicked the \"Autofill\" button")
|
||||
}
|
||||
|
||||
SettingsSubMenuAutofillRobot().interact()
|
||||
|
@ -303,11 +573,12 @@ class SettingsRobot {
|
|||
|
||||
fun openAccessibilitySubMenu(interact: SettingsSubMenuAccessibilityRobot.() -> Unit): SettingsSubMenuAccessibilityRobot.Transition {
|
||||
scrollToElementByText("Accessibility")
|
||||
|
||||
fun accessibilityButton() = onView(withText("Accessibility"))
|
||||
accessibilityButton()
|
||||
.check(matches(isDisplayed()))
|
||||
.click()
|
||||
Log.i(TAG, "openAccessibilitySubMenu: Trying to verify that the \"Accessibility\" button is displayed")
|
||||
onView(withText("Accessibility")).check(matches(isDisplayed()))
|
||||
Log.i(TAG, "openAccessibilitySubMenu: Verified that the \"Accessibility\" button is displayed")
|
||||
Log.i(TAG, "openAccessibilitySubMenu: Trying to click the \"Accessibility\" button")
|
||||
onView(withText("Accessibility")).click()
|
||||
Log.i(TAG, "openAccessibilitySubMenu: Clicked the \"Accessibility\" button")
|
||||
|
||||
SettingsSubMenuAccessibilityRobot().interact()
|
||||
return SettingsSubMenuAccessibilityRobot.Transition()
|
||||
|
@ -317,6 +588,7 @@ class SettingsRobot {
|
|||
localizedText: String = getStringResource(R.string.preferences_language),
|
||||
interact: SettingsSubMenuLanguageRobot.() -> Unit,
|
||||
): SettingsSubMenuLanguageRobot.Transition {
|
||||
Log.i(TAG, "openLanguageSubMenu: Trying to click the $localizedText button")
|
||||
onView(withId(R.id.recycler_view))
|
||||
.perform(
|
||||
RecyclerViewActions.actionOnItem<RecyclerView.ViewHolder>(
|
||||
|
@ -326,6 +598,7 @@ class SettingsRobot {
|
|||
ViewActions.click(),
|
||||
),
|
||||
)
|
||||
Log.i(TAG, "openLanguageSubMenu: Clicked the $localizedText button")
|
||||
|
||||
SettingsSubMenuLanguageRobot().interact()
|
||||
return SettingsSubMenuLanguageRobot.Transition()
|
||||
|
@ -333,8 +606,9 @@ class SettingsRobot {
|
|||
|
||||
fun openSetDefaultBrowserSubMenu(interact: SettingsSubMenuSetDefaultBrowserRobot.() -> Unit): SettingsSubMenuSetDefaultBrowserRobot.Transition {
|
||||
scrollToElementByText("Set as default browser")
|
||||
fun setDefaultBrowserButton() = onView(withText("Set as default browser"))
|
||||
setDefaultBrowserButton().click()
|
||||
Log.i(TAG, "openSetDefaultBrowserSubMenu: Trying to click the \"Set as default browser\" button")
|
||||
onView(withText("Set as default browser")).click()
|
||||
Log.i(TAG, "openSetDefaultBrowserSubMenu: Clicked the \"Set as default browser\" button")
|
||||
|
||||
SettingsSubMenuSetDefaultBrowserRobot().interact()
|
||||
return SettingsSubMenuSetDefaultBrowserRobot.Transition()
|
||||
|
@ -342,9 +616,9 @@ class SettingsRobot {
|
|||
|
||||
fun openEnhancedTrackingProtectionSubMenu(interact: SettingsSubMenuEnhancedTrackingProtectionRobot.() -> Unit): SettingsSubMenuEnhancedTrackingProtectionRobot.Transition {
|
||||
scrollToElementByText("Enhanced Tracking Protection")
|
||||
fun enhancedTrackingProtectionButton() =
|
||||
onView(withText("Enhanced Tracking Protection"))
|
||||
enhancedTrackingProtectionButton().click()
|
||||
Log.i(TAG, "openEnhancedTrackingProtectionSubMenu: Trying to click the \"Enhanced Tracking Protection\" button")
|
||||
onView(withText("Enhanced Tracking Protection")).click()
|
||||
Log.i(TAG, "openEnhancedTrackingProtectionSubMenu: Clicked the \"Enhanced Tracking Protection\" button")
|
||||
|
||||
SettingsSubMenuEnhancedTrackingProtectionRobot().interact()
|
||||
return SettingsSubMenuEnhancedTrackingProtectionRobot.Transition()
|
||||
|
@ -352,16 +626,18 @@ class SettingsRobot {
|
|||
|
||||
fun openLoginsAndPasswordSubMenu(interact: SettingsSubMenuLoginsAndPasswordRobot.() -> Unit): SettingsSubMenuLoginsAndPasswordRobot.Transition {
|
||||
scrollToElementByText("Logins and passwords")
|
||||
fun loginsAndPasswordsButton() = onView(withText("Logins and passwords"))
|
||||
loginsAndPasswordsButton().click()
|
||||
Log.i(TAG, "openLoginsAndPasswordSubMenu: Trying to click the \"Logins and passwords\" button")
|
||||
onView(withText("Logins and passwords")).click()
|
||||
Log.i(TAG, "openLoginsAndPasswordSubMenu: Clicked the \"Logins and passwords\" button")
|
||||
|
||||
SettingsSubMenuLoginsAndPasswordRobot().interact()
|
||||
return SettingsSubMenuLoginsAndPasswordRobot.Transition()
|
||||
}
|
||||
|
||||
fun openTurnOnSyncMenu(interact: SettingsTurnOnSyncRobot.() -> Unit): SettingsTurnOnSyncRobot.Transition {
|
||||
fun turnOnSyncButton() = onView(withText("Sync and save your data"))
|
||||
turnOnSyncButton().click()
|
||||
Log.i(TAG, "openTurnOnSyncMenu: Trying to click the \"Sync and save your data\" button")
|
||||
onView(withText("Sync and save your data")).click()
|
||||
Log.i(TAG, "openTurnOnSyncMenu: Clicked the \"Sync and save your data\" button")
|
||||
|
||||
SettingsTurnOnSyncRobot().interact()
|
||||
return SettingsTurnOnSyncRobot.Transition()
|
||||
|
@ -369,8 +645,9 @@ class SettingsRobot {
|
|||
|
||||
fun openPrivateBrowsingSubMenu(interact: SettingsSubMenuPrivateBrowsingRobot.() -> Unit): SettingsSubMenuPrivateBrowsingRobot.Transition {
|
||||
scrollToElementByText("Private browsing")
|
||||
fun privateBrowsingButton() = mDevice.findObject(textContains("Private browsing"))
|
||||
privateBrowsingButton().click()
|
||||
Log.i(TAG, "openPrivateBrowsingSubMenu: Trying to click the \"Private browsing\" button")
|
||||
mDevice.findObject(textContains("Private browsing")).click()
|
||||
Log.i(TAG, "openPrivateBrowsingSubMenu: Clicked the \"Private browsing\" button")
|
||||
|
||||
SettingsSubMenuPrivateBrowsingRobot().interact()
|
||||
return SettingsSubMenuPrivateBrowsingRobot.Transition()
|
||||
|
@ -378,8 +655,9 @@ class SettingsRobot {
|
|||
|
||||
fun openSettingsSubMenuSitePermissions(interact: SettingsSubMenuSitePermissionsRobot.() -> Unit): SettingsSubMenuSitePermissionsRobot.Transition {
|
||||
scrollToElementByText("Site permissions")
|
||||
fun sitePermissionButton() = mDevice.findObject(textContains("Site permissions"))
|
||||
sitePermissionButton().click()
|
||||
Log.i(TAG, "openSettingsSubMenuSitePermissions: Trying to click the \"Site permissions\" button")
|
||||
mDevice.findObject(textContains("Site permissions")).click()
|
||||
Log.i(TAG, "openSettingsSubMenuSitePermissions: Clicked the \"Site permissions\" button")
|
||||
|
||||
SettingsSubMenuSitePermissionsRobot().interact()
|
||||
return SettingsSubMenuSitePermissionsRobot.Transition()
|
||||
|
@ -387,8 +665,9 @@ class SettingsRobot {
|
|||
|
||||
fun openSettingsSubMenuDeleteBrowsingData(interact: SettingsSubMenuDeleteBrowsingDataRobot.() -> Unit): SettingsSubMenuDeleteBrowsingDataRobot.Transition {
|
||||
scrollToElementByText("Delete browsing data")
|
||||
fun deleteBrowsingDataButton() = mDevice.findObject(textContains("Delete browsing data"))
|
||||
deleteBrowsingDataButton().click()
|
||||
Log.i(TAG, "openSettingsSubMenuDeleteBrowsingData: Trying to click the \"Delete browsing data\" button")
|
||||
mDevice.findObject(textContains("Delete browsing data")).click()
|
||||
Log.i(TAG, "openSettingsSubMenuDeleteBrowsingData: Clicked the \"Delete browsing data\" button")
|
||||
|
||||
SettingsSubMenuDeleteBrowsingDataRobot().interact()
|
||||
return SettingsSubMenuDeleteBrowsingDataRobot.Transition()
|
||||
|
@ -396,8 +675,9 @@ class SettingsRobot {
|
|||
|
||||
fun openSettingsSubMenuDeleteBrowsingDataOnQuit(interact: SettingsSubMenuDeleteBrowsingDataOnQuitRobot.() -> Unit): SettingsSubMenuDeleteBrowsingDataOnQuitRobot.Transition {
|
||||
scrollToElementByText("Delete browsing data on quit")
|
||||
fun deleteBrowsingDataOnQuitButton() = mDevice.findObject(textContains("Delete browsing data on quit"))
|
||||
deleteBrowsingDataOnQuitButton().click()
|
||||
Log.i(TAG, "openSettingsSubMenuDeleteBrowsingDataOnQuit: Trying to click the \"Delete browsing data on quit\" button")
|
||||
mDevice.findObject(textContains("Delete browsing data on quit")).click()
|
||||
Log.i(TAG, "openSettingsSubMenuDeleteBrowsingDataOnQuit: Clicked the \"Delete browsing data on quit\" button")
|
||||
|
||||
SettingsSubMenuDeleteBrowsingDataOnQuitRobot().interact()
|
||||
return SettingsSubMenuDeleteBrowsingDataOnQuitRobot.Transition()
|
||||
|
@ -405,8 +685,9 @@ class SettingsRobot {
|
|||
|
||||
fun openSettingsSubMenuNotifications(interact: SystemSettingsRobot.() -> Unit): SystemSettingsRobot.Transition {
|
||||
scrollToElementByText("Notifications")
|
||||
fun notificationsButton() = mDevice.findObject(textContains("Notifications"))
|
||||
notificationsButton().click()
|
||||
Log.i(TAG, "openSettingsSubMenuNotifications: Trying to click the \"Notifications\" button")
|
||||
mDevice.findObject(textContains("Notifications")).click()
|
||||
Log.i(TAG, "openSettingsSubMenuNotifications: Clicked the \"Notifications\" button")
|
||||
|
||||
SystemSettingsRobot().interact()
|
||||
return SystemSettingsRobot.Transition()
|
||||
|
@ -414,22 +695,27 @@ class SettingsRobot {
|
|||
|
||||
fun openSettingsSubMenuDataCollection(interact: SettingsSubMenuDataCollectionRobot.() -> Unit): SettingsSubMenuDataCollectionRobot.Transition {
|
||||
scrollToElementByText("Data collection")
|
||||
fun dataCollectionButton() = mDevice.findObject(textContains("Data collection"))
|
||||
dataCollectionButton().click()
|
||||
Log.i(TAG, "openSettingsSubMenuDataCollection: Trying to click the \"Data collection\" button")
|
||||
mDevice.findObject(textContains("Data collection")).click()
|
||||
Log.i(TAG, "openSettingsSubMenuDataCollection: Clicked the \"Data collection\" button")
|
||||
|
||||
SettingsSubMenuDataCollectionRobot().interact()
|
||||
return SettingsSubMenuDataCollectionRobot.Transition()
|
||||
}
|
||||
|
||||
fun openAddonsManagerMenu(interact: SettingsSubMenuAddonsManagerRobot.() -> Unit): SettingsSubMenuAddonsManagerRobot.Transition {
|
||||
Log.i(TAG, "openAddonsManagerMenu: Trying to click the \"Add-ons\" button")
|
||||
addonsManagerButton().click()
|
||||
Log.i(TAG, "openAddonsManagerMenu: Clicked the \"Add-ons\" button")
|
||||
|
||||
SettingsSubMenuAddonsManagerRobot().interact()
|
||||
return SettingsSubMenuAddonsManagerRobot.Transition()
|
||||
}
|
||||
|
||||
fun openOpenLinksInAppsMenu(interact: SettingsSubMenuOpenLinksInAppsRobot.() -> Unit): SettingsSubMenuOpenLinksInAppsRobot.Transition {
|
||||
Log.i(TAG, "openOpenLinksInAppsMenu: Trying to click the \"Open links in apps\" button")
|
||||
openLinksInAppsButton().click()
|
||||
Log.i(TAG, "openOpenLinksInAppsMenu: Clicked the \"Open links in apps\" button")
|
||||
|
||||
SettingsSubMenuOpenLinksInAppsRobot().interact()
|
||||
return SettingsSubMenuOpenLinksInAppsRobot.Transition()
|
||||
|
@ -437,7 +723,9 @@ class SettingsRobot {
|
|||
|
||||
fun openHttpsOnlyModeMenu(interact: SettingsSubMenuHttpsOnlyModeRobot.() -> Unit): SettingsSubMenuHttpsOnlyModeRobot.Transition {
|
||||
scrollToElementByText("HTTPS-Only Mode")
|
||||
Log.i(TAG, "openHttpsOnlyModeMenu: Trying to click the \"HTTPS-Only Mode\" button")
|
||||
onView(withText(getStringResource(R.string.preferences_https_only_title))).click()
|
||||
Log.i(TAG, "openHttpsOnlyModeMenu: Clicked the \"HTTPS-Only Mode\" button")
|
||||
mDevice.waitNotNull(
|
||||
Until.findObjects(By.res("$packageName:id/https_only_switch")),
|
||||
waitingTime,
|
||||
|
@ -466,189 +754,15 @@ fun settingsScreen(interact: SettingsRobot.() -> Unit): SettingsRobot.Transition
|
|||
return SettingsRobot.Transition()
|
||||
}
|
||||
|
||||
private fun assertSettingsView() {
|
||||
// verify that we are in the correct library view
|
||||
assertGeneralHeading()
|
||||
assertPrivacyHeading()
|
||||
assertAdvancedHeading()
|
||||
assertAboutHeading()
|
||||
}
|
||||
|
||||
// GENERAL SECTION
|
||||
|
||||
private fun assertSettingsToolbar() =
|
||||
onView(
|
||||
CoreMatchers.allOf(
|
||||
withId(R.id.navigationToolbar),
|
||||
hasDescendant(ViewMatchers.withContentDescription(R.string.action_bar_up_description)),
|
||||
hasDescendant(withText(R.string.settings)),
|
||||
),
|
||||
).check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
|
||||
private fun assertGeneralHeading() {
|
||||
scrollToElementByText("General")
|
||||
onView(withText("General"))
|
||||
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
}
|
||||
|
||||
private fun assertSearchButton() {
|
||||
mDevice.wait(Until.findObject(By.text("Search")), waitingTime)
|
||||
onView(withText(R.string.preferences_search))
|
||||
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
}
|
||||
|
||||
private fun assertHomepageButton() =
|
||||
onView(withText(R.string.preferences_home_2)).check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
|
||||
private fun assertAutofillButton() =
|
||||
onView(withText(R.string.preferences_autofill)).check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
|
||||
private fun assertLanguageButton() {
|
||||
scrollToElementByText(getStringResource(R.string.preferences_language))
|
||||
onView(withText(R.string.preferences_language)).check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
}
|
||||
|
||||
private fun assertCustomizeButton() = onView(withText("Customize"))
|
||||
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
|
||||
private fun assertThemeSelected() = onView(withText("Light"))
|
||||
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
|
||||
private fun assertAccessibilityButton() = onView(withText("Accessibility"))
|
||||
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
|
||||
private fun assertSetAsDefaultBrowserButton() {
|
||||
scrollToElementByText("Set as default browser")
|
||||
onView(withText("Set as default browser"))
|
||||
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
}
|
||||
|
||||
private fun toggleDefaultBrowserSwitch() {
|
||||
scrollToElementByText("Privacy and security")
|
||||
Log.i(TAG, "toggleDefaultBrowserSwitch: Trying to click the \"Set as default browser\" button")
|
||||
onView(withText("Set as default browser")).perform(ViewActions.click())
|
||||
}
|
||||
|
||||
private fun assertAndroidDefaultAppsMenuAppears() {
|
||||
intended(IntentMatchers.hasAction(DEFAULT_APPS_SETTINGS_ACTION))
|
||||
}
|
||||
|
||||
// PRIVACY SECTION
|
||||
private fun assertPrivacyHeading() {
|
||||
scrollToElementByText("Privacy and security")
|
||||
onView(withText("Privacy and security"))
|
||||
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
}
|
||||
|
||||
private fun assertHTTPSOnlyModeButton() {
|
||||
scrollToElementByText(getStringResource(R.string.preferences_https_only_title))
|
||||
onView(
|
||||
withText(R.string.preferences_https_only_title),
|
||||
).check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
}
|
||||
|
||||
private fun assertEnhancedTrackingProtectionButton() {
|
||||
mDevice.wait(Until.findObject(By.text("Privacy and Security")), waitingTime)
|
||||
onView(withId(R.id.recycler_view)).perform(
|
||||
RecyclerViewActions.scrollTo<RecyclerView.ViewHolder>(
|
||||
hasDescendant(withText("Enhanced Tracking Protection")),
|
||||
),
|
||||
).check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
}
|
||||
|
||||
private fun assertLoginsAndPasswordsButton() {
|
||||
scrollToElementByText("Logins and passwords")
|
||||
onView(withText(R.string.preferences_passwords_logins_and_passwords))
|
||||
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
}
|
||||
|
||||
private fun assertPrivateBrowsingButton() {
|
||||
scrollToElementByText("Private browsing")
|
||||
mDevice.wait(Until.findObject(By.text("Private browsing")), waitingTime)
|
||||
onView(withText("Private browsing"))
|
||||
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
}
|
||||
|
||||
private fun assertSitePermissionsButton() {
|
||||
scrollToElementByText("Site permissions")
|
||||
onView(withText("Site permissions"))
|
||||
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
}
|
||||
|
||||
private fun assertDeleteBrowsingDataButton() {
|
||||
scrollToElementByText("Delete browsing data")
|
||||
onView(withText("Delete browsing data"))
|
||||
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
}
|
||||
|
||||
private fun assertDeleteBrowsingDataOnQuitButton() {
|
||||
scrollToElementByText("Delete browsing data on quit")
|
||||
onView(withText("Delete browsing data on quit"))
|
||||
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
}
|
||||
|
||||
private fun assertNotificationsButton() {
|
||||
scrollToElementByText("Notifications")
|
||||
onView(withText("Notifications"))
|
||||
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
}
|
||||
|
||||
private fun assertDataCollectionButton() {
|
||||
scrollToElementByText("Data collection")
|
||||
onView(withText("Data collection"))
|
||||
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
Log.i(TAG, "toggleDefaultBrowserSwitch: Clicked the \"Set as default browser\" button")
|
||||
}
|
||||
|
||||
private fun openLinksInAppsButton() = onView(withText(R.string.preferences_open_links_in_apps))
|
||||
|
||||
private fun assertOpenLinksInAppsButton() {
|
||||
scrollToElementByText("Open links in apps")
|
||||
openLinksInAppsButton()
|
||||
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
Log.i(TAG, "clickOpenLinksInAppsGoToSettingsCFRButton: Verified \"Open links in apps\" setting option")
|
||||
}
|
||||
|
||||
// ADVANCED SECTION
|
||||
private fun assertAdvancedHeading() {
|
||||
onView(withId(R.id.recycler_view)).perform(
|
||||
RecyclerViewActions.scrollTo<RecyclerView.ViewHolder>(
|
||||
hasDescendant(withText("Add-ons")),
|
||||
),
|
||||
)
|
||||
|
||||
onView(withText("Add-ons"))
|
||||
.check(matches(isCompletelyDisplayed()))
|
||||
}
|
||||
|
||||
private fun assertAddonsButton() {
|
||||
onView(withId(R.id.recycler_view)).perform(
|
||||
RecyclerViewActions.scrollTo<RecyclerView.ViewHolder>(
|
||||
hasDescendant(withText("Add-ons")),
|
||||
),
|
||||
)
|
||||
|
||||
addonsManagerButton()
|
||||
.check(matches(isCompletelyDisplayed()))
|
||||
}
|
||||
|
||||
private fun assertRemoteDebuggingButton() {
|
||||
scrollToElementByText("Remote debugging via USB")
|
||||
onView(withText("Remote debugging via USB"))
|
||||
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
}
|
||||
|
||||
private fun assertLeakCanaryButton() {
|
||||
scrollToElementByText("LeakCanary")
|
||||
onView(withText("LeakCanary"))
|
||||
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
}
|
||||
|
||||
// ABOUT SECTION
|
||||
private fun assertAboutHeading(): ViewInteraction {
|
||||
settingsList().scrollToEnd(LISTS_MAXSWIPES)
|
||||
return onView(withText("About"))
|
||||
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
}
|
||||
|
||||
private fun rateOnGooglePlayHeading(): UiObject {
|
||||
val rateOnGooglePlay = mDevice.findObject(UiSelector().text("Rate on Google Play"))
|
||||
settingsList().scrollToEnd(LISTS_MAXSWIPES)
|
||||
|
@ -679,27 +793,10 @@ fun clickRateButtonGooglePlay() {
|
|||
rateOnGooglePlayHeading().click()
|
||||
}
|
||||
|
||||
private fun assertGooglePlayRedirect() {
|
||||
if (isPackageInstalled(GOOGLE_PLAY_SERVICES)) {
|
||||
try {
|
||||
intended(
|
||||
allOf(
|
||||
hasAction(Intent.ACTION_VIEW),
|
||||
hasData(Uri.parse(SupportUtils.RATE_APP_URL)),
|
||||
),
|
||||
)
|
||||
} catch (e: AssertionFailedError) {
|
||||
BrowserRobot().verifyRateOnGooglePlayURL()
|
||||
}
|
||||
} else {
|
||||
BrowserRobot().verifyRateOnGooglePlayURL()
|
||||
}
|
||||
}
|
||||
|
||||
private fun addonsManagerButton() = onView(withText(R.string.preferences_addons))
|
||||
|
||||
private fun goBackButton() =
|
||||
onView(CoreMatchers.allOf(ViewMatchers.withContentDescription("Navigate up")))
|
||||
onView(CoreMatchers.allOf(withContentDescription("Navigate up")))
|
||||
|
||||
private fun settingsList() =
|
||||
UiScrollable(UiSelector().resourceId("$packageName:id/recycler_view"))
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
package org.mozilla.fenix.ui.robots
|
||||
|
||||
import android.util.Log
|
||||
import android.view.KeyEvent
|
||||
import android.view.KeyEvent.ACTION_DOWN
|
||||
import android.view.KeyEvent.KEYCODE_DPAD_LEFT
|
||||
|
@ -28,7 +29,9 @@ import androidx.test.espresso.matcher.ViewMatchers.withText
|
|||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import org.hamcrest.CoreMatchers.allOf
|
||||
import org.hamcrest.Matcher
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.mozilla.fenix.components.Components
|
||||
import org.mozilla.fenix.helpers.Constants.TAG
|
||||
import org.mozilla.fenix.helpers.TestHelper.mDevice
|
||||
import org.mozilla.fenix.helpers.assertIsEnabled
|
||||
import org.mozilla.fenix.helpers.isEnabled
|
||||
|
@ -50,22 +53,68 @@ class SettingsSubMenuAccessibilityRobot {
|
|||
const val TEXT_SIZE = 16f
|
||||
}
|
||||
|
||||
fun verifyAutomaticFontSizingMenuItems() = assertAutomaticFontSizingMenuItems()
|
||||
|
||||
fun clickFontSizingSwitch() = toggleFontSizingSwitch()
|
||||
|
||||
fun verifyEnabledMenuItems() = assertEnabledMenuItems()
|
||||
fun verifyEnabledMenuItems() {
|
||||
Log.i(TAG, "verifyEnabledMenuItems: Trying to verify that the \"Font Size\" title is visible")
|
||||
onView(withText("Font Size")).check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
Log.i(TAG, "verifyEnabledMenuItems: Verified that the \"Font Size\" title is visible")
|
||||
Log.i(TAG, "verifyEnabledMenuItems: Trying to verify that the \"Font Size\" title is enabled")
|
||||
onView(withText("Font Size")).check(matches(isEnabled(true)))
|
||||
Log.i(TAG, "verifyEnabledMenuItems: Verified that the \"Font Size\" title is enabled")
|
||||
Log.i(TAG, "verifyEnabledMenuItems: Trying to verify that the \"Make text on websites larger or smaller\" summary is visible")
|
||||
onView(withText("Make text on websites larger or smaller")).check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
Log.i(TAG, "verifyEnabledMenuItems: Verified that the \"Make text on websites larger or smaller\" summary is visible")
|
||||
Log.i(TAG, "verifyEnabledMenuItems: Trying to verify that the \"Make text on websites larger or smaller\" summary is enabled")
|
||||
onView(withText("Make text on websites larger or smaller")).check(matches(isEnabled(true)))
|
||||
Log.i(TAG, "verifyEnabledMenuItems: Verified that the \"Make text on websites larger or smaller\" summary is enabled")
|
||||
Log.i(TAG, "verifyEnabledMenuItems: Trying to verify the \"This is sample text. It is here to show how text will appear\" sample text")
|
||||
onView(withId(org.mozilla.fenix.R.id.sampleText))
|
||||
.check(matches(withText("This is sample text. It is here to show how text will appear when you increase or decrease the size with this setting.")))
|
||||
Log.i(TAG, "verifyEnabledMenuItems: Verified the \"This is sample text. It is here to show how text will appear\" sample text")
|
||||
Log.i(TAG, "verifyEnabledMenuItems: Trying to verify that the seek bar value is set to 100%")
|
||||
onView(withId(org.mozilla.fenix.R.id.seekbar_value)).check(matches(withText("100%")))
|
||||
Log.i(TAG, "verifyEnabledMenuItems: Verified that the seek bar value is set to 100%")
|
||||
Log.i(TAG, "verifyEnabledMenuItems: Trying to verify that the seek bar is visible")
|
||||
onView(withId(org.mozilla.fenix.R.id.seekbar)).check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
Log.i(TAG, "verifyEnabledMenuItems: Verified that the seek bar is visible")
|
||||
}
|
||||
|
||||
fun verifyMenuItemsAreDisabled() = assertMenuItemsAreDisabled()
|
||||
fun verifyMenuItemsAreDisabled() {
|
||||
Log.i(TAG, "verifyMenuItemsAreDisabled: Trying to verify that the \"Font Size\" title is not enabled")
|
||||
onView(withText("Font Size")).assertIsEnabled(false)
|
||||
Log.i(TAG, "verifyMenuItemsAreDisabled: Verified that the \"Font Size\" title is not enabled")
|
||||
Log.i(TAG, "verifyMenuItemsAreDisabled: Trying to verify that the \"Make text on websites larger or smaller\" summary is not enabled")
|
||||
onView(withText("Make text on websites larger or smaller")).assertIsEnabled(false)
|
||||
Log.i(TAG, "verifyMenuItemsAreDisabled: Verified that the \"Make text on websites larger or smaller\" summary is not enabled")
|
||||
Log.i(TAG, "verifyMenuItemsAreDisabled: Trying to verify that the \"This is sample text. It is here to show how text will appear\" sample text is not enabled")
|
||||
onView(withId(org.mozilla.fenix.R.id.sampleText)).assertIsEnabled(false)
|
||||
Log.i(TAG, "verifyMenuItemsAreDisabled: Verified that the \"This is sample text. It is here to show how text will appear\" sample text is not enabled")
|
||||
Log.i(TAG, "verifyMenuItemsAreDisabled: Trying to verify that the seek bar value is not enabled")
|
||||
onView(withId(org.mozilla.fenix.R.id.seekbar_value)).assertIsEnabled(false)
|
||||
Log.i(TAG, "verifyMenuItemsAreDisabled: Verified that the seek bar value is not enabled")
|
||||
Log.i(TAG, "verifyMenuItemsAreDisabled: Trying to verify that the seek bar is not enabled")
|
||||
onView(withId(org.mozilla.fenix.R.id.seekbar)).assertIsEnabled(false)
|
||||
Log.i(TAG, "verifyMenuItemsAreDisabled: Verified that the seek bar is not enabled")
|
||||
}
|
||||
|
||||
fun changeTextSizeSlider(seekBarPercentage: Int) = adjustTextSizeSlider(seekBarPercentage)
|
||||
|
||||
fun verifyTextSizePercentage(textSize: Int) = assertTextSizePercentage(textSize)
|
||||
fun verifyTextSizePercentage(textSize: Int) {
|
||||
Log.i(TAG, "verifyTextSizePercentage: Trying to verify that the text size percentage is set to: $textSize")
|
||||
onView(withId(org.mozilla.fenix.R.id.sampleText))
|
||||
.check(textSizePercentageEquals(textSize))
|
||||
Log.i(TAG, "verifyTextSizePercentage: Verified that the text size percentage is set to: $textSize")
|
||||
}
|
||||
|
||||
class Transition {
|
||||
fun goBack(interact: SettingsRobot.() -> Unit): SettingsRobot.Transition {
|
||||
Log.i(TAG, "goBack: Waiting for device to be idle")
|
||||
mDevice.waitForIdle()
|
||||
Log.i(TAG, "goBack: Waited for device to be idle")
|
||||
Log.i(TAG, "goBack: Trying to click the navigate up toolbar button")
|
||||
goBackButton().perform(click())
|
||||
Log.i(TAG, "goBack: Clicked the navigate up toolbar button")
|
||||
|
||||
SettingsRobot().interact()
|
||||
return SettingsRobot.Transition()
|
||||
|
@ -73,69 +122,20 @@ class SettingsSubMenuAccessibilityRobot {
|
|||
}
|
||||
}
|
||||
|
||||
private fun assertAutomaticFontSizingMenuItems() {
|
||||
onView(withText("Automatic font sizing"))
|
||||
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
val strFont = "Font size will match your Android settings. Disable to manage font size here."
|
||||
onView(withText(strFont))
|
||||
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
}
|
||||
|
||||
private fun toggleFontSizingSwitch() {
|
||||
Log.i(TAG, "toggleFontSizingSwitch: Trying to click the \"Automatic font sizing\" toggle")
|
||||
// Toggle font size to off
|
||||
onView(withText("Automatic font sizing"))
|
||||
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
.perform(click())
|
||||
}
|
||||
|
||||
private fun assertEnabledMenuItems() {
|
||||
assertFontSize()
|
||||
assertSliderBar()
|
||||
}
|
||||
|
||||
private fun assertFontSize() {
|
||||
val view = onView(withText("Font Size"))
|
||||
view.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
.check(matches(isEnabled(true)))
|
||||
val strFont = "Make text on websites larger or smaller"
|
||||
onView(withText(strFont))
|
||||
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
.check(matches(isEnabled(true)))
|
||||
}
|
||||
|
||||
private fun assertSliderBar() {
|
||||
onView(withId(org.mozilla.fenix.R.id.sampleText))
|
||||
.check(matches(withText("This is sample text. It is here to show how text will appear when you increase or decrease the size with this setting.")))
|
||||
|
||||
onView(withId(org.mozilla.fenix.R.id.seekbar_value))
|
||||
.check(matches(withText("100%")))
|
||||
|
||||
onView(withId(org.mozilla.fenix.R.id.seekbar))
|
||||
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
Log.i(TAG, "toggleFontSizingSwitch: Clicked the \"Automatic font sizing\" toggle")
|
||||
}
|
||||
|
||||
private fun adjustTextSizeSlider(seekBarPercentage: Int) {
|
||||
Log.i(TAG, "adjustTextSizeSlider: Trying to set the seek bar value to: $seekBarPercentage")
|
||||
onView(withId(org.mozilla.fenix.R.id.seekbar))
|
||||
.perform(SeekBarChangeProgressViewAction(seekBarPercentage))
|
||||
}
|
||||
|
||||
private fun assertTextSizePercentage(textSize: Int) {
|
||||
onView(withId(org.mozilla.fenix.R.id.sampleText))
|
||||
.check(textSizePercentageEquals(textSize))
|
||||
}
|
||||
|
||||
private fun assertMenuItemsAreDisabled() {
|
||||
onView(withText("Font Size")).assertIsEnabled(false)
|
||||
|
||||
val strFont = "Make text on websites larger or smaller"
|
||||
|
||||
onView(withText(strFont)).assertIsEnabled(false)
|
||||
|
||||
onView(withId(org.mozilla.fenix.R.id.sampleText)).assertIsEnabled(false)
|
||||
|
||||
onView(withId(org.mozilla.fenix.R.id.seekbar_value)).assertIsEnabled(false)
|
||||
|
||||
onView(withId(org.mozilla.fenix.R.id.seekbar)).assertIsEnabled(false)
|
||||
Log.i(TAG, "adjustTextSizeSlider: Seek bar value was set to: $seekBarPercentage")
|
||||
}
|
||||
|
||||
private fun goBackButton() =
|
||||
|
@ -189,9 +189,11 @@ fun calculateStepSizeFromPercentage(textSizePercentage: Int): Int {
|
|||
return ((textSizePercentage - MIN_VALUE) / STEP_SIZE)
|
||||
}
|
||||
|
||||
fun checkTextSizeOnWebsite(textSizePercentage: Int, components: Components): Boolean {
|
||||
fun checkTextSizeOnWebsite(textSizePercentage: Int, components: Components) {
|
||||
Log.i(TAG, "checkTextSizeOnWebsite: Trying to verify that text size on website is: $textSizePercentage")
|
||||
// Checks the Gecko engine settings for the font size
|
||||
val textSize = calculateStepSizeFromPercentage(textSizePercentage)
|
||||
val newTextScale = ((textSize * STEP_SIZE) + MIN_VALUE).toFloat() / DECIMAL_CONVERSION
|
||||
return components.core.engine.settings.fontSizeFactor == newTextScale
|
||||
assertTrue("$TAG: text size on website was not set to: $textSizePercentage", components.core.engine.settings.fontSizeFactor == newTextScale)
|
||||
Log.i(TAG, "checkTextSizeOnWebsite: Verified that text size on website is: $textSizePercentage")
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
package org.mozilla.fenix.ui.robots
|
||||
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import androidx.test.espresso.Espresso.onView
|
||||
import androidx.test.espresso.assertion.ViewAssertions.matches
|
||||
|
@ -17,6 +18,7 @@ import org.hamcrest.CoreMatchers.allOf
|
|||
import org.mozilla.fenix.HomeActivity
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.helpers.AppAndSystemHelper.registerAndCleanupIdlingResources
|
||||
import org.mozilla.fenix.helpers.Constants.TAG
|
||||
import org.mozilla.fenix.helpers.ViewVisibilityIdlingResource
|
||||
import org.mozilla.fenix.helpers.click
|
||||
|
||||
|
@ -28,8 +30,9 @@ class SettingsSubMenuAddonsManagerAddonDetailedMenuRobot {
|
|||
|
||||
class Transition {
|
||||
fun goBack(interact: SettingsSubMenuAddonsManagerRobot.() -> Unit): SettingsSubMenuAddonsManagerRobot.Transition {
|
||||
fun goBackButton() = onView(allOf(withContentDescription("Navigate up")))
|
||||
goBackButton().click()
|
||||
Log.i(TAG, "goBack: Trying to click the navigate up button")
|
||||
onView(allOf(withContentDescription("Navigate up"))).click()
|
||||
Log.i(TAG, "goBack: Clicked the navigate up button")
|
||||
|
||||
SettingsSubMenuAddonsManagerRobot().interact()
|
||||
return SettingsSubMenuAddonsManagerRobot.Transition()
|
||||
|
@ -42,8 +45,12 @@ class SettingsSubMenuAddonsManagerAddonDetailedMenuRobot {
|
|||
View.VISIBLE,
|
||||
),
|
||||
) {
|
||||
Log.i(TAG, "removeAddon: Trying to verify that the remove add-on button is visible")
|
||||
removeAddonButton().check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
|
||||
Log.i(TAG, "removeAddon: Verified that the remove add-on button is visible")
|
||||
Log.i(TAG, "removeAddon: Trying to click the remove add-on button")
|
||||
removeAddonButton().click()
|
||||
Log.i(TAG, "removeAddon: Clicked the remove add-on button")
|
||||
}
|
||||
|
||||
SettingsSubMenuAddonsManagerRobot().interact()
|
||||
|
|
|
@ -55,12 +55,15 @@ class SettingsSubMenuAddonsManagerRobot {
|
|||
fun verifyAddonsListIsDisplayed(shouldBeDisplayed: Boolean) =
|
||||
assertUIObjectExists(addonsList(), exists = shouldBeDisplayed)
|
||||
|
||||
fun verifyAddonDownloadOverlay() =
|
||||
fun verifyAddonDownloadOverlay() {
|
||||
Log.i(TAG, "verifyAddonDownloadOverlay: Trying to verify that the \"Downloading and verifying add-on\" prompt is displayed")
|
||||
onView(withText(R.string.mozac_add_on_install_progress_caption)).check(matches(isDisplayed()))
|
||||
Log.i(TAG, "verifyAddonDownloadOverlay: Verified that the \"Downloading and verifying add-on\" prompt is displayed")
|
||||
}
|
||||
|
||||
fun verifyAddonPermissionPrompt(addonName: String) {
|
||||
mDevice.waitNotNull(Until.findObject(By.text("Add $addonName?")), waitingTime)
|
||||
|
||||
Log.i(TAG, "verifyAddonPermissionPrompt: Trying to verify that the add-ons permission prompt items are displayed")
|
||||
onView(
|
||||
allOf(
|
||||
withText("Add $addonName?"),
|
||||
|
@ -71,11 +74,14 @@ class SettingsSubMenuAddonsManagerRobot {
|
|||
)
|
||||
.inRoot(isDialog())
|
||||
.check(matches(isDisplayed()))
|
||||
Log.i(TAG, "verifyAddonPermissionPrompt: Verified that the add-ons permission prompt items are displayed")
|
||||
}
|
||||
|
||||
fun clickInstallAddon(addonName: String) {
|
||||
Log.i(TAG, "clickInstallAddon: Looking for $addonName install button")
|
||||
Log.i(TAG, "clickInstallAddon: Waiting for $waitingTime ms for add-ons list to exist")
|
||||
addonsList().waitForExists(waitingTime)
|
||||
Log.i(TAG, "clickInstallAddon: Waited for $waitingTime ms for add-ons list to exist")
|
||||
Log.i(TAG, "clickInstallAddon: Trying to scroll into view the install $addonName button")
|
||||
addonsList().scrollIntoView(
|
||||
mDevice.findObject(
|
||||
UiSelector()
|
||||
|
@ -83,6 +89,8 @@ class SettingsSubMenuAddonsManagerRobot {
|
|||
.childSelector(UiSelector().text(addonName)),
|
||||
),
|
||||
)
|
||||
Log.i(TAG, "clickInstallAddon: Scrolled into view the install $addonName button")
|
||||
Log.i(TAG, "clickInstallAddon: Trying to ensure the full visibility of the the install $addonName button")
|
||||
addonsList().ensureFullyVisible(
|
||||
mDevice.findObject(
|
||||
UiSelector()
|
||||
|
@ -90,22 +98,24 @@ class SettingsSubMenuAddonsManagerRobot {
|
|||
.childSelector(UiSelector().text(addonName)),
|
||||
),
|
||||
)
|
||||
Log.i(TAG, "clickInstallAddon: Found $addonName install button")
|
||||
Log.i(TAG, "clickInstallAddon: Ensured the full visibility of the the install $addonName button")
|
||||
Log.i(TAG, "clickInstallAddon: Trying to click the install $addonName button")
|
||||
installButtonForAddon(addonName).click()
|
||||
Log.i(TAG, "clickInstallAddon: Clicked Install $addonName button")
|
||||
Log.i(TAG, "clickInstallAddon: Clicked the install $addonName button")
|
||||
}
|
||||
|
||||
fun verifyAddonInstallCompleted(addonName: String, activityTestRule: HomeActivityIntentTestRule) {
|
||||
for (i in 1..RETRY_COUNT) {
|
||||
Log.i(TAG, "verifyAddonInstallCompleted: Started try #$i")
|
||||
try {
|
||||
assertUIObjectExists(itemWithText("Okay, Got it"), waitingTime = waitingTimeLong)
|
||||
assertUIObjectExists(itemWithText("OK"), waitingTime = waitingTimeLong)
|
||||
|
||||
break
|
||||
} catch (e: AssertionError) {
|
||||
Log.i(TAG, "verifyAddonInstallCompleted: AssertionError caught, executing fallback methods")
|
||||
if (i == RETRY_COUNT) {
|
||||
throw e
|
||||
} else {
|
||||
Log.i(TAG, "verifyAddonInstallCompleted: $addonName failed to install on try #$i")
|
||||
restartApp(activityTestRule)
|
||||
homeScreen {
|
||||
}.openThreeDotMenu {
|
||||
|
@ -121,96 +131,29 @@ class SettingsSubMenuAddonsManagerRobot {
|
|||
}
|
||||
|
||||
fun verifyAddonInstallCompletedPrompt(addonName: String) {
|
||||
Log.i(TAG, "verifyAddonInstallCompletedPrompt: Trying to verify that completed add-on install prompt items are visible")
|
||||
onView(
|
||||
allOf(
|
||||
withText("Okay, Got it"),
|
||||
withText("OK"),
|
||||
withParent(instanceOf(RelativeLayout::class.java)),
|
||||
hasSibling(withText("$addonName has been added to $appName")),
|
||||
hasSibling(withText("Open it in the menu")),
|
||||
hasSibling(withText("Access $addonName from the $appName menu.")),
|
||||
hasSibling(withText("Allow in private browsing")),
|
||||
),
|
||||
)
|
||||
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
Log.i(TAG, "verifyAddonInstallCompletedPrompt: Verified that completed add-on install prompt items are visible")
|
||||
}
|
||||
|
||||
fun closeAddonInstallCompletePrompt() {
|
||||
onView(withText("Okay, Got it")).click()
|
||||
Log.i(TAG, "closeAddonInstallCompletePrompt: Trying to click the \"OK\" button from the completed add-on install prompt")
|
||||
onView(withText("OK")).click()
|
||||
Log.i(TAG, "closeAddonInstallCompletePrompt: Clicked the \"OK\" button from the completed add-on install prompt")
|
||||
}
|
||||
|
||||
fun verifyAddonIsInstalled(addonName: String) {
|
||||
scrollToElementByText(addonName)
|
||||
assertAddonIsInstalled(addonName)
|
||||
}
|
||||
|
||||
fun verifyEnabledTitleDisplayed() {
|
||||
onView(withText("Enabled"))
|
||||
.check(matches(isCompletelyDisplayed()))
|
||||
}
|
||||
|
||||
fun cancelInstallAddon() = cancelInstall()
|
||||
fun acceptPermissionToInstallAddon() = allowPermissionToInstall()
|
||||
fun verifyAddonsItems() = assertAddonsItems()
|
||||
fun verifyAddonCanBeInstalled(addonName: String) = assertAddonCanBeInstalled(addonName)
|
||||
|
||||
fun selectAllowInPrivateBrowsing() {
|
||||
assertUIObjectExists(itemWithText("Allow in private browsing"), waitingTime = waitingTimeLong)
|
||||
onView(withId(R.id.allow_in_private_browsing)).click()
|
||||
}
|
||||
|
||||
fun installAddon(addonName: String, activityTestRule: HomeActivityIntentTestRule) {
|
||||
homeScreen {
|
||||
}.openThreeDotMenu {
|
||||
}.openAddonsManagerMenu {
|
||||
clickInstallAddon(addonName)
|
||||
verifyAddonPermissionPrompt(addonName)
|
||||
acceptPermissionToInstallAddon()
|
||||
verifyAddonInstallCompleted(addonName, activityTestRule)
|
||||
}
|
||||
}
|
||||
|
||||
class Transition {
|
||||
fun goBack(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition {
|
||||
fun goBackButton() = onView(allOf(withContentDescription("Navigate up")))
|
||||
goBackButton().click()
|
||||
|
||||
HomeScreenRobot().interact()
|
||||
return HomeScreenRobot.Transition()
|
||||
}
|
||||
|
||||
fun openDetailedMenuForAddon(
|
||||
addonName: String,
|
||||
interact: SettingsSubMenuAddonsManagerAddonDetailedMenuRobot.() -> Unit,
|
||||
): SettingsSubMenuAddonsManagerAddonDetailedMenuRobot.Transition {
|
||||
scrollToElementByText(addonName)
|
||||
|
||||
onView(
|
||||
allOf(
|
||||
withId(R.id.add_on_item),
|
||||
hasDescendant(
|
||||
allOf(
|
||||
withId(R.id.add_on_name),
|
||||
withText(addonName),
|
||||
),
|
||||
),
|
||||
),
|
||||
).check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
.perform(click())
|
||||
|
||||
SettingsSubMenuAddonsManagerAddonDetailedMenuRobot().interact()
|
||||
return SettingsSubMenuAddonsManagerAddonDetailedMenuRobot.Transition()
|
||||
}
|
||||
}
|
||||
|
||||
private fun installButtonForAddon(addonName: String) =
|
||||
onView(
|
||||
allOf(
|
||||
withContentDescription(R.string.mozac_feature_addons_install_addon_content_description),
|
||||
isDescendantOfA(withId(R.id.add_on_item)),
|
||||
hasSibling(hasDescendant(withText(addonName))),
|
||||
),
|
||||
)
|
||||
|
||||
private fun assertAddonIsInstalled(addonName: String) {
|
||||
Log.i(TAG, "verifyAddonIsInstalled: Trying to verify that the $addonName add-on was installed")
|
||||
onView(
|
||||
allOf(
|
||||
withId(R.id.add_button),
|
||||
|
@ -218,37 +161,24 @@ class SettingsSubMenuAddonsManagerRobot {
|
|||
hasSibling(hasDescendant(withText(addonName))),
|
||||
),
|
||||
).check(matches(withEffectiveVisibility(Visibility.INVISIBLE)))
|
||||
Log.i(TAG, "verifyAddonIsInstalled: Verified that the $addonName add-on was installed")
|
||||
}
|
||||
|
||||
private fun cancelInstall() {
|
||||
onView(allOf(withId(R.id.deny_button), withText("Cancel")))
|
||||
fun verifyEnabledTitleDisplayed() {
|
||||
Log.i(TAG, "verifyEnabledTitleDisplayed: Trying to verify that the \"Enabled\" heading is displayed")
|
||||
onView(withText("Enabled"))
|
||||
.check(matches(isCompletelyDisplayed()))
|
||||
.perform(click())
|
||||
Log.i(TAG, "verifyEnabledTitleDisplayed: Verified that the \"Enabled\" heading is displayed")
|
||||
}
|
||||
|
||||
private fun allowPermissionToInstall() {
|
||||
mDevice.waitNotNull(Until.findObject(By.text("Add")), waitingTime)
|
||||
|
||||
onView(allOf(withId(R.id.allow_button), withText("Add")))
|
||||
.check(matches(isCompletelyDisplayed()))
|
||||
.perform(click())
|
||||
}
|
||||
|
||||
private fun assertAddonsItems() {
|
||||
assertRecommendedTitleDisplayed()
|
||||
assertAddons()
|
||||
}
|
||||
|
||||
private fun assertRecommendedTitleDisplayed() {
|
||||
fun cancelInstallAddon() = cancelInstall()
|
||||
fun acceptPermissionToInstallAddon() = allowPermissionToInstall()
|
||||
fun verifyAddonsItems() {
|
||||
Log.i(TAG, "verifyAddonsItems: Trying to verify that the \"Recommended\" heading is visible")
|
||||
onView(allOf(withId(R.id.title), withText("Recommended")))
|
||||
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
}
|
||||
|
||||
private fun assertAddons() {
|
||||
assertAddonUblock()
|
||||
}
|
||||
|
||||
private fun assertAddonUblock() {
|
||||
Log.i(TAG, "verifyAddonsItems: Verified that the \"Recommended\" heading is visible")
|
||||
Log.i(TAG, "verifyAddonsItems: Trying to verify that all uBlock Origin items are completely displayed")
|
||||
onView(
|
||||
allOf(
|
||||
isAssignableFrom(RelativeLayout::class.java),
|
||||
|
@ -266,12 +196,12 @@ class SettingsSubMenuAddonsManagerRobot {
|
|||
hasDescendant(withId(R.id.add_button)),
|
||||
),
|
||||
).check(matches(isCompletelyDisplayed()))
|
||||
Log.i(TAG, "verifyAddonsItems: Verified that all uBlock Origin items are completely displayed")
|
||||
}
|
||||
|
||||
private fun assertAddonCanBeInstalled(addonName: String) {
|
||||
fun verifyAddonCanBeInstalled(addonName: String) {
|
||||
scrollToElementByText(addonName)
|
||||
mDevice.waitNotNull(Until.findObject(By.text(addonName)), waitingTime)
|
||||
|
||||
Log.i(TAG, "verifyAddonCanBeInstalled: Trying to verify that the install $addonName button is visible")
|
||||
onView(
|
||||
allOf(
|
||||
withId(R.id.add_button),
|
||||
|
@ -285,6 +215,80 @@ class SettingsSubMenuAddonsManagerRobot {
|
|||
),
|
||||
),
|
||||
).check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
Log.i(TAG, "verifyAddonCanBeInstalled: Verified that the install $addonName button is visible")
|
||||
}
|
||||
|
||||
fun selectAllowInPrivateBrowsing() {
|
||||
assertUIObjectExists(itemWithText("Allow in private browsing"), waitingTime = waitingTimeLong)
|
||||
Log.i(TAG, "selectAllowInPrivateBrowsing: Trying to click the \"Allow in private browsing\" check box")
|
||||
onView(withId(R.id.allow_in_private_browsing)).click()
|
||||
Log.i(TAG, "selectAllowInPrivateBrowsing: Clicked the \"Allow in private browsing\" check box")
|
||||
}
|
||||
|
||||
fun installAddon(addonName: String, activityTestRule: HomeActivityIntentTestRule) {
|
||||
homeScreen {
|
||||
}.openThreeDotMenu {
|
||||
}.openAddonsManagerMenu {
|
||||
clickInstallAddon(addonName)
|
||||
verifyAddonPermissionPrompt(addonName)
|
||||
acceptPermissionToInstallAddon()
|
||||
verifyAddonInstallCompleted(addonName, activityTestRule)
|
||||
}
|
||||
}
|
||||
|
||||
class Transition {
|
||||
fun goBack(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition {
|
||||
Log.i(TAG, "goBack: Trying to click navigate up toolbar button")
|
||||
onView(allOf(withContentDescription("Navigate up"))).click()
|
||||
Log.i(TAG, "goBack: Clicked the navigate up toolbar button")
|
||||
|
||||
HomeScreenRobot().interact()
|
||||
return HomeScreenRobot.Transition()
|
||||
}
|
||||
|
||||
fun openDetailedMenuForAddon(
|
||||
addonName: String,
|
||||
interact: SettingsSubMenuAddonsManagerAddonDetailedMenuRobot.() -> Unit,
|
||||
): SettingsSubMenuAddonsManagerAddonDetailedMenuRobot.Transition {
|
||||
scrollToElementByText(addonName)
|
||||
Log.i(TAG, "openDetailedMenuForAddon: Trying to verify that the $addonName add-on is visible")
|
||||
addonItem(addonName).check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
|
||||
Log.i(TAG, "openDetailedMenuForAddon: Verified that the $addonName add-on is visible")
|
||||
Log.i(TAG, "openDetailedMenuForAddon: Trying to click the $addonName add-on")
|
||||
addonItem(addonName).perform(click())
|
||||
Log.i(TAG, "openDetailedMenuForAddon: Clicked the $addonName add-on")
|
||||
|
||||
SettingsSubMenuAddonsManagerAddonDetailedMenuRobot().interact()
|
||||
return SettingsSubMenuAddonsManagerAddonDetailedMenuRobot.Transition()
|
||||
}
|
||||
}
|
||||
|
||||
private fun installButtonForAddon(addonName: String) =
|
||||
onView(
|
||||
allOf(
|
||||
withContentDescription("Install $addonName"),
|
||||
isDescendantOfA(withId(R.id.add_on_item)),
|
||||
hasSibling(hasDescendant(withText(addonName))),
|
||||
),
|
||||
)
|
||||
|
||||
private fun cancelInstall() {
|
||||
Log.i(TAG, "cancelInstall: Trying to verify that the \"Cancel\" button is completely displayed")
|
||||
onView(allOf(withId(R.id.deny_button), withText("Cancel"))).check(matches(isCompletelyDisplayed()))
|
||||
Log.i(TAG, "cancelInstall: Verified that the \"Cancel\" button is completely displayed")
|
||||
Log.i(TAG, "cancelInstall: Trying to click the \"Cancel\" button")
|
||||
onView(allOf(withId(R.id.deny_button), withText("Cancel"))).perform(click())
|
||||
Log.i(TAG, "cancelInstall: Clicked the \"Cancel\" button")
|
||||
}
|
||||
|
||||
private fun allowPermissionToInstall() {
|
||||
mDevice.waitNotNull(Until.findObject(By.text("Add")), waitingTime)
|
||||
Log.i(TAG, "allowPermissionToInstall: Trying to verify that the \"Add\" button is completely displayed")
|
||||
onView(allOf(withId(R.id.allow_button), withText("Add"))).check(matches(isCompletelyDisplayed()))
|
||||
Log.i(TAG, "allowPermissionToInstall: Verified that the \"Add\" button is completely displayed")
|
||||
Log.i(TAG, "allowPermissionToInstall: Trying to click the \"Add\" button")
|
||||
onView(allOf(withId(R.id.allow_button), withText("Add"))).perform(click())
|
||||
Log.i(TAG, "allowPermissionToInstall: Clicked the \"Add\" button")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -293,5 +297,18 @@ fun addonsMenu(interact: SettingsSubMenuAddonsManagerRobot.() -> Unit): Settings
|
|||
return SettingsSubMenuAddonsManagerRobot.Transition()
|
||||
}
|
||||
|
||||
private fun addonItem(addonName: String) =
|
||||
onView(
|
||||
allOf(
|
||||
withId(R.id.add_on_item),
|
||||
hasDescendant(
|
||||
allOf(
|
||||
withId(R.id.add_on_name),
|
||||
withText(addonName),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
private fun addonsList() =
|
||||
UiScrollable(UiSelector().resourceId("$packageName:id/add_ons_list")).setAsVerticalList()
|
||||
|
|
|
@ -9,7 +9,9 @@ import androidx.test.espresso.Espresso.onView
|
|||
import androidx.test.espresso.assertion.ViewAssertions.matches
|
||||
import androidx.test.espresso.matcher.RootMatchers
|
||||
import androidx.test.espresso.matcher.ViewMatchers.isChecked
|
||||
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
|
||||
import androidx.test.espresso.matcher.ViewMatchers.isNotChecked
|
||||
import androidx.test.espresso.matcher.ViewMatchers.withChild
|
||||
import androidx.test.espresso.matcher.ViewMatchers.withClassName
|
||||
import androidx.test.espresso.matcher.ViewMatchers.withId
|
||||
import androidx.test.espresso.matcher.ViewMatchers.withText
|
||||
|
@ -38,8 +40,16 @@ class SettingsSubMenuAutofillRobot {
|
|||
Log.i(TAG, "verifyAutofillToolbarTitle: Verified \"Autofill\" toolbar title exists")
|
||||
}
|
||||
fun verifyManageAddressesToolbarTitle() {
|
||||
assertUIObjectExists(manageAddressesToolbarTitle)
|
||||
Log.i(TAG, "verifyManageAddressesToolbarTitle: Verified \"Manage addresses\" toolbar title exists")
|
||||
Log.i(TAG, "verifyManageAddressesToolbarTitle: Trying to verify the \"Manage addresses\" toolbar title is displayed")
|
||||
onView(
|
||||
allOf(
|
||||
withId(R.id.navigationToolbar),
|
||||
withChild(
|
||||
withText(R.string.preferences_addresses_manage_addresses),
|
||||
),
|
||||
),
|
||||
).check(matches(isDisplayed()))
|
||||
Log.i(TAG, "verifyManageAddressesToolbarTitle: Verified the \"Manage addresses\" toolbar title is displayed")
|
||||
}
|
||||
|
||||
fun verifyAddressAutofillSection(isAddressAutofillEnabled: Boolean, userHasSavedAddress: Boolean) {
|
||||
|
|
|
@ -23,8 +23,6 @@ import org.hamcrest.CoreMatchers.allOf
|
|||
import org.hamcrest.Matchers
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.helpers.Constants
|
||||
import org.mozilla.fenix.helpers.MatcherHelper.assertUIObjectExists
|
||||
import org.mozilla.fenix.helpers.MatcherHelper.itemContainingText
|
||||
import org.mozilla.fenix.helpers.TestAssetHelper.waitingTimeShort
|
||||
import org.mozilla.fenix.helpers.TestHelper
|
||||
import org.mozilla.fenix.helpers.TestHelper.mDevice
|
||||
|
@ -101,11 +99,6 @@ class SettingsSubMenuHomepageRobot {
|
|||
fun selectWallpaper(wallpaperName: String) =
|
||||
mDevice.findObject(UiSelector().description(wallpaperName)).click()
|
||||
|
||||
fun verifySnackBarText(expectedText: String) =
|
||||
assertUIObjectExists(
|
||||
itemContainingText(expectedText),
|
||||
)
|
||||
|
||||
fun verifySponsoredShortcutsCheckBox(checked: Boolean) = assertSponsoredShortcutsCheckBox(checked)
|
||||
|
||||
class Transition {
|
||||
|
|
|
@ -101,6 +101,9 @@ class SettingsSubMenuSearchRobot {
|
|||
}
|
||||
|
||||
fun verifyDefaultSearchEngineList() {
|
||||
defaultSearchEngineOption("LeOSearch")
|
||||
.check(matches(hasSibling(withId(R.id.engine_icon))))
|
||||
.check(matches(isDisplayed()))
|
||||
defaultSearchEngineOption("LeOSearch")
|
||||
.check(matches(hasSibling(withId(R.id.engine_icon))))
|
||||
.check(matches(isDisplayed()))
|
||||
|
|
|
@ -206,9 +206,6 @@ class TabDrawerRobot {
|
|||
}
|
||||
}
|
||||
|
||||
fun verifySnackBarText(expectedText: String) =
|
||||
assertUIObjectExists(itemContainingText(expectedText))
|
||||
|
||||
fun snackBarButtonClick(expectedText: String) {
|
||||
val snackBarButton =
|
||||
mDevice.findObject(
|
||||
|
|
Before Width: | Height: | Size: 178 KiB After Width: | Height: | Size: 179 KiB |
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 5.1 KiB |
Before Width: | Height: | Size: 7.7 KiB After Width: | Height: | Size: 8.0 KiB |
Before Width: | Height: | Size: 6.7 KiB After Width: | Height: | Size: 6.8 KiB |
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 4.5 KiB |
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 7.5 KiB After Width: | Height: | Size: 7.3 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 9.9 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 33 KiB |
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 178 KiB After Width: | Height: | Size: 179 KiB |
Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 33 KiB |
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 5.1 KiB |
Before Width: | Height: | Size: 7.7 KiB After Width: | Height: | Size: 8.0 KiB |
Before Width: | Height: | Size: 6.7 KiB After Width: | Height: | Size: 6.8 KiB |
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |