Retrying add-on installation if it fails.
pull/600/head
sv-ohorvath 2 years ago committed by mergify[bot]
parent c5a247bff1
commit be9fe960fc

@ -19,4 +19,5 @@ object Constants {
const val SPEECH_RECOGNITION = "android.speech.action.RECOGNIZE_SPEECH"
const val LONG_CLICK_DURATION: Long = 5000
const val LISTS_MAXSWIPES: Int = 3
const val RETRY_COUNT = 3
}

@ -9,17 +9,16 @@ import androidx.test.espresso.IdlingRegistry
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.settings
import org.mozilla.fenix.helpers.AndroidAssetDispatcher
import org.mozilla.fenix.helpers.HomeActivityTestRule
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
import org.mozilla.fenix.helpers.RecyclerViewIdlingResource
import org.mozilla.fenix.helpers.RetryTestRule
import org.mozilla.fenix.helpers.TestAssetHelper
import org.mozilla.fenix.helpers.TestAssetHelper.getEnhancedTrackingProtectionAsset
import org.mozilla.fenix.helpers.TestAssetHelper.getGenericAsset
import org.mozilla.fenix.helpers.ViewVisibilityIdlingResource
import org.mozilla.fenix.ui.robots.addonsMenu
import org.mozilla.fenix.ui.robots.homeScreen
@ -35,11 +34,7 @@ class SettingsAddonsTest {
private var addonContainerIdlingResource: ViewVisibilityIdlingResource? = null
@get:Rule
val activityTestRule = HomeActivityTestRule()
@Rule
@JvmField
val retryTestRule = RetryTestRule(3)
val activityTestRule = HomeActivityIntentTestRule()
@Before
fun setUp() {
@ -93,26 +88,28 @@ class SettingsAddonsTest {
)
IdlingRegistry.getInstance().register(addonsListIdlingResource!!)
clickInstallAddon(addonName)
IdlingRegistry.getInstance().unregister(addonsListIdlingResource!!)
verifyAddonPermissionPrompt(addonName)
cancelInstallAddon()
clickInstallAddon(addonName)
acceptPermissionToInstallAddon()
closeAddonInstallCompletePrompt(addonName, activityTestRule)
verifyAddonInstallCompleted(addonName, activityTestRule)
verifyAddonInstallCompletedPrompt(addonName)
closeAddonInstallCompletePrompt()
verifyAddonIsInstalled(addonName)
verifyEnabledTitleDisplayed()
}
}
// Installs an addon, then uninstalls it
@Ignore("Intermittent failures, see: https://github.com/mozilla-mobile/fenix/issues/24843")
@Test
fun verifyAddonsCanBeUninstalled() {
val addonName = "uBlock Origin"
addonsMenu {
installAddon(addonName)
closeAddonInstallCompletePrompt(addonName, activityTestRule)
IdlingRegistry.getInstance().unregister(addonsListIdlingResource!!)
verifyAddonInstallCompleted(addonName, activityTestRule)
closeAddonInstallCompletePrompt()
}.openDetailedMenuForAddon(addonName) {
addonContainerIdlingResource = ViewVisibilityIdlingResource(
activityTestRule.activity.findViewById(R.id.addon_container),
@ -120,6 +117,7 @@ class SettingsAddonsTest {
)
IdlingRegistry.getInstance().register(addonContainerIdlingResource!!)
}.removeAddon {
IdlingRegistry.getInstance().unregister(addonContainerIdlingResource!!)
verifyAddonCanBeInstalled(addonName)
}
}
@ -132,57 +130,38 @@ class SettingsAddonsTest {
activityTestRule.activity.settings().setStrictETP()
val addonName = "uBlock Origin"
val trackingProtectionPage =
TestAssetHelper.getEnhancedTrackingProtectionAsset(mockWebServer)
val trackingProtectionPage = getEnhancedTrackingProtectionAsset(mockWebServer)
addonsMenu {
installAddon(addonName)
closeAddonInstallCompletePrompt(addonName, activityTestRule)
IdlingRegistry.getInstance().unregister(addonsListIdlingResource!!)
verifyAddonInstallCompleted(addonName, activityTestRule)
closeAddonInstallCompletePrompt()
}.goBack {
}.openNavigationToolbar {
}.enterURLAndEnterToBrowser(trackingProtectionPage.url) {
verifyPageContent(trackingProtectionPage.content)
verifyUrl(trackingProtectionPage.url.toString())
}
}
@Ignore("Failing, see: https://github.com/mozilla-mobile/fenix/issues/23749")
@SmokeTest
@Test
fun useAddonsInPrivateModeTest() {
val addonName = "uBlock Origin"
val trackingPage = TestAssetHelper.getEnhancedTrackingProtectionAsset(mockWebServer)
val genericPage = getGenericAsset(mockWebServer, 1)
homeScreen {
}.togglePrivateBrowsingMode()
addonsMenu {
installAddon(addonName)
selectAllowInPrivateBrowsing(activityTestRule)
closeAddonInstallCompletePrompt(addonName, activityTestRule)
IdlingRegistry.getInstance().unregister(addonsListIdlingResource!!)
}.goBack {}
verifyAddonInstallCompleted(addonName, activityTestRule)
selectAllowInPrivateBrowsing()
closeAddonInstallCompletePrompt()
}.goBack {
}.togglePrivateBrowsingMode()
navigationToolbar {
}.enterURLAndEnterToBrowser(trackingPage.url) {
verifyPageContent(trackingPage.content)
}.enterURLAndEnterToBrowser(genericPage.url) {
verifyPageContent(genericPage.content)
}.openThreeDotMenu {
openAddonsSubList()
verifyAddonAvailableInMainMenu(addonName)
}
}
private fun installAddon(addonName: String) {
homeScreen {
}.openThreeDotMenu {
}.openAddonsManagerMenu {
addonsListIdlingResource =
RecyclerViewIdlingResource(
activityTestRule.activity.findViewById(R.id.add_ons_list),
1
)
IdlingRegistry.getInstance().register(addonsListIdlingResource!!)
clickInstallAddon(addonName)
verifyAddonPermissionPrompt(addonName)
acceptPermissionToInstallAddon()
}
}
}

@ -6,9 +6,9 @@
package org.mozilla.fenix.ui.robots
import android.util.Log
import android.widget.RelativeLayout
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.IdlingResourceTimeoutException
import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.matcher.ViewMatchers.Visibility
@ -22,7 +22,6 @@ import androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility
import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.espresso.matcher.ViewMatchers.withParent
import androidx.test.espresso.matcher.ViewMatchers.withText
import androidx.test.rule.ActivityTestRule
import androidx.test.uiautomator.By
import androidx.test.uiautomator.UiSelector
import androidx.test.uiautomator.Until
@ -30,12 +29,15 @@ import org.hamcrest.CoreMatchers.allOf
import org.hamcrest.CoreMatchers.containsString
import org.hamcrest.CoreMatchers.instanceOf
import org.hamcrest.CoreMatchers.not
import org.mozilla.fenix.HomeActivity
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.mozilla.fenix.R
import org.mozilla.fenix.helpers.IdlingResourceHelper.registerAddonInstallingIdlingResource
import org.mozilla.fenix.helpers.IdlingResourceHelper.unregisterAddonInstallingIdlingResource
import org.mozilla.fenix.helpers.Constants.RETRY_COUNT
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime
import org.mozilla.fenix.helpers.TestAssetHelper.waitingTimeLong
import org.mozilla.fenix.helpers.TestHelper.appName
import org.mozilla.fenix.helpers.TestHelper.restartApp
import org.mozilla.fenix.helpers.TestHelper.scrollToElementByText
import org.mozilla.fenix.helpers.click
import org.mozilla.fenix.helpers.ext.waitNotNull
@ -47,23 +49,59 @@ import org.mozilla.fenix.helpers.ext.waitNotNull
class SettingsSubMenuAddonsManagerRobot {
fun verifyAddonPermissionPrompt(addonName: String) = assertAddonPermissionPrompt(addonName)
fun clickInstallAddon(addonName: String) = selectInstallAddon(addonName)
fun closeAddonInstallCompletePrompt(
addonName: String,
activityTestRule: ActivityTestRule<HomeActivity>
) {
try {
assertAddonInstallCompletePrompt(addonName, activityTestRule)
} catch (e: IdlingResourceTimeoutException) {
if (mDevice.findObject(UiSelector().text("Failed to install $addonName")).exists()) {
clickInstallAddon(addonName)
acceptPermissionToInstallAddon()
assertAddonInstallCompletePrompt(addonName, activityTestRule)
fun clickInstallAddon(addonName: String) {
mDevice.waitNotNull(
Until.findObject(By.textContains(addonName)),
waitingTime
)
installButtonForAddon(addonName)
.check(matches(isCompletelyDisplayed()))
.perform(click())
}
fun verifyAddonInstallCompleted(addonName: String, activityTestRule: HomeActivityIntentTestRule) {
for (i in 1..RETRY_COUNT) {
try {
assertFalse(
mDevice.findObject(UiSelector().text("Failed to install $addonName"))
.waitForExists(waitingTime)
)
assertTrue(
mDevice.findObject(UiSelector().text("Okay, Got it"))
.waitForExists(waitingTimeLong)
)
break
} catch (e: AssertionError) {
if (i == RETRY_COUNT) {
throw e
} else {
Log.e("TestLog", "Addon failed to install on try #$i")
restartApp(activityTestRule)
installAddon(addonName)
}
}
}
}
fun verifyAddonInstallCompletedPrompt(addonName: String) {
onView(
allOf(
withText("Okay, Got it"),
withParent(instanceOf(RelativeLayout::class.java)),
hasSibling(withText("$addonName has been added to $appName")),
hasSibling(withText("Open it in the menu")),
hasSibling(withText("Allow in private browsing"))
)
)
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
}
fun closeAddonInstallCompletePrompt() {
onView(withText("Okay, Got it")).click()
}
fun verifyAddonIsInstalled(addonName: String) {
scrollToElementByText(addonName)
assertAddonIsInstalled(addonName)
@ -79,10 +117,23 @@ class SettingsSubMenuAddonsManagerRobot {
fun verifyAddonsItems() = assertAddonsItems()
fun verifyAddonCanBeInstalled(addonName: String) = assertAddonCanBeInstalled(addonName)
fun selectAllowInPrivateBrowsing(activityTestRule: ActivityTestRule<HomeActivity>) {
registerAddonInstallingIdlingResource(activityTestRule)
fun selectAllowInPrivateBrowsing() {
assertTrue(
"Addon install confirmation prompt not displayed",
mDevice.findObject(UiSelector().text("Allow in private browsing"))
.waitForExists(waitingTimeLong)
)
onView(withId(R.id.allow_in_private_browsing)).click()
unregisterAddonInstallingIdlingResource(activityTestRule)
}
fun installAddon(addonName: String) {
homeScreen {
}.openThreeDotMenu {
}.openAddonsManagerMenu {
clickInstallAddon(addonName)
verifyAddonPermissionPrompt(addonName)
acceptPermissionToInstallAddon()
}
}
class Transition {
@ -127,17 +178,6 @@ class SettingsSubMenuAddonsManagerRobot {
)
)
private fun selectInstallAddon(addonName: String) {
mDevice.waitNotNull(
Until.findObject(By.textContains(addonName)),
waitingTime
)
installButtonForAddon(addonName)
.check(matches(isCompletelyDisplayed()))
.perform(click())
}
private fun assertAddonIsEnabled(addonName: String) {
installButtonForAddon(addonName)
.check(matches(not(isCompletelyDisplayed())))
@ -162,27 +202,6 @@ class SettingsSubMenuAddonsManagerRobot {
.check(matches(isCompletelyDisplayed()))
}
private fun assertAddonInstallCompletePrompt(
addonName: String,
activityTestRule: ActivityTestRule<HomeActivity>
) {
registerAddonInstallingIdlingResource(activityTestRule)
onView(
allOf(
withText("Okay, Got it"),
withParent(instanceOf(RelativeLayout::class.java)),
hasSibling(withText("$addonName has been added to $appName")),
hasSibling(withText("Open it in the menu")),
hasSibling(withText("Allow in private browsing"))
)
)
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
.perform(click())
unregisterAddonInstallingIdlingResource(activityTestRule)
}
private fun assertAddonIsInstalled(addonName: String) {
onView(
allOf(

@ -32,7 +32,9 @@ import org.hamcrest.Matchers.not
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.mozilla.fenix.R
import org.mozilla.fenix.helpers.Constants.RETRY_COUNT
import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime
import org.mozilla.fenix.helpers.TestAssetHelper.waitingTimeLong
import org.mozilla.fenix.helpers.TestHelper.packageName
import org.mozilla.fenix.helpers.click
import org.mozilla.fenix.helpers.ext.waitNotNull
@ -121,8 +123,25 @@ class ThreeDotMenuMainRobot {
}
fun verifyAddonAvailableInMainMenu(addonName: String) {
onView(withText(addonName))
.check(matches(isDisplayed()))
for (i in 1..RETRY_COUNT) {
try {
assertTrue(
"Addon not listed in the Add-ons menu",
mDevice.findObject(UiSelector().text(addonName)).waitForExists(waitingTime)
)
break
} catch (e: AssertionError) {
if (i == RETRY_COUNT) {
throw e
} else {
mDevice.pressBack()
browserScreen {
}.openThreeDotMenu {
openAddonsSubList()
}
}
}
}
}
class Transition {
@ -340,6 +359,8 @@ class ThreeDotMenuMainRobot {
fun openAddonsManagerMenu(interact: SettingsSubMenuAddonsManagerRobot.() -> Unit): SettingsSubMenuAddonsManagerRobot.Transition {
clickAddonsManagerButton()
mDevice.findObject(UiSelector().resourceId("$packageName:id/add_ons_list"))
.waitForExists(waitingTimeLong)
SettingsSubMenuAddonsManagerRobot().interact()
return SettingsSubMenuAddonsManagerRobot.Transition()

Loading…
Cancel
Save