Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,15 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
import mozilla.appservices.places.BookmarkRoot
import mozilla.components.browser.state.search.RegionState
import mozilla.components.browser.storage.sync.PlacesBookmarksStorage
import mozilla.components.browser.storage.sync.PlacesHistoryStorage
import mozilla.components.feature.top.sites.TopSite
import mozilla.components.support.locale.LocaleManager.resetToSystemDefault
import mozilla.components.support.locale.LocaleManager.setNewLocale
import org.junit.Assert
import org.junit.Assert.assertEquals
import org.mozilla.fenix.Config
import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.components.PermissionStorage
import org.mozilla.fenix.customtabs.ExternalAppBrowserActivity
Expand Down Expand Up @@ -956,4 +958,19 @@ object AppAndSystemHelper {
Log.i(TAG, "setScreenOrientation: Waited for the compose test rule to be idle.")
Log.i(TAG, "setScreenOrientation: Orientation set to $orientation.")
}

/**
* Whether the default pinned shortcuts are expected on the homepage.
*
* Mirrors the condition in `DefaultPinnedSitesBinding`.
*/
fun isDefaultPinnedShortcutsOnHomepage(): Boolean {
val region = appContext.components.core.store.state.search.region
val expected = region != null && (!Config.channel.isReleased || region != RegionState.Default)
Log.i(
TAG,
"isDefaultPinnedShortcutsOnHomepage: region=$region channel=${Config.channel} expected=$expected",
)
return expected
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ object Constants {
"DuckDuckGo" to "t=fpas",
)

val firstSponsoredShortcutTitle by lazy { getSponsoredShortcutTitle(2) }
val secondSponsoredShortcutTitle by lazy { getSponsoredShortcutTitle(3) }
val firstSponsoredShortcutTitle by lazy { getSponsoredShortcutTitle(1) }
val secondSponsoredShortcutTitle by lazy { getSponsoredShortcutTitle(2) }

// Expected for en-us defaults
val defaultTopSitesList by lazy {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this also be removed, since it's not used in tests anymore?

Expand All @@ -54,6 +54,15 @@ object Constants {
)
}

/**
* The shortcut titles, which are only present when [AppAndSystemHelper.isDefaultPinnedShortcutsOnHomepage] holds.
* Expected for en-us defaults.
*/
val defaultPinnedShortcutTitles by lazy { listOf("Google", "Wikipedia") }

/** The sponsored shortcuts, which are present on every build type. */
val sponsoredShortcutTitles by lazy { listOf(firstSponsoredShortcutTitle, secondSponsoredShortcutTitle) }

// Notes:
// "Ghostery" - not included in the list because of the name discrepancy between the recommended list and the
// install confirmation prompt
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,20 @@ import androidx.compose.ui.test.onNodeWithContentDescription
import androidx.core.graphics.createBitmap
import androidx.core.net.toUri
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.uiautomator.UiSelector
import androidx.test.uiautomator.By
import androidx.test.uiautomator.UiObject2
import java.time.LocalDate
import java.time.LocalTime
import mozilla.components.browser.state.search.SearchEngine
import mozilla.components.browser.state.state.availableSearchEngines
import org.junit.Assert
import org.mozilla.fenix.R
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.helpers.Constants.TAG
import org.mozilla.fenix.helpers.Constants.recommendedAddons
import org.mozilla.fenix.helpers.TestHelper.mDevice
import org.mozilla.fenix.helpers.TestHelper.waitForAppWindowToBeUpdated
import org.mozilla.fenix.home.topsites.TopSitesTestTag
import org.mozilla.fenix.utils.IntentUtils

object DataGenerationHelper {
Expand Down Expand Up @@ -126,24 +129,36 @@ object DataGenerationHelper {
return currentYear + currentMonth + currentDay + currentHour
}

/** Returns sponsored shortcut title based on the index. */
fun getSponsoredShortcutTitle(position: Int): String {
Log.i(
TAG,
"getSponsoredShortcutTitle: Trying to get the title of the sponsored shortcut at position: ${position - 1}",
)
/**
* Returns the title of the [ordinal]th sponsored shortcut, counting only sponsored shortcuts.
*
* The shortcuts are located by their sponsored label rather than by their absolute position in the top sites list,
* because the number of default pinned shortcuts preceding them varies by release channel and region. See
* [sponsoredShortcuts].
*
* @param ordinal One-based index among the sponsored shortcuts only.
*/
fun getSponsoredShortcutTitle(ordinal: Int): String {
Log.i(TAG, "getSponsoredShortcutTitle: Trying to get the title of sponsored shortcut #$ordinal")
val sponsoredShortcut =
mDevice
.findObject(UiSelector().resourceId("top_sites_list.top_site_item").index(position - 1))
.getChild(UiSelector().resourceId("top_sites_list.top_site_item.top_site_title"))
.text
Log.i(
TAG,
"getSponsoredShortcutTitle: The sponsored shortcut at position: ${position - 1} has title: $sponsoredShortcut",
)
sponsoredShortcuts()[ordinal - 1].findObject(By.res(TopSitesTestTag.TOP_SITE_TITLE)).text
Log.i(TAG, "getSponsoredShortcutTitle: Sponsored shortcut #$ordinal has title: $sponsoredShortcut")
return sponsoredShortcut
}

/**
* Returns the top sites that are labelled as sponsored, in the order they appear on the homepage.
*
* Every shortcut lays out a sponsored label, but it only carries text when the shortcut is sponsored, so matching
* on that text distinguishes them.
*/
fun sponsoredShortcuts(): List<UiObject2> {
val sponsoredLabel = getStringResource(R.string.top_sites_sponsored_label)
return mDevice.findObjects(By.res(TopSitesTestTag.TOP_SITE_ITEM_ROOT)).filter {
it.findObject(By.text(sponsoredLabel)) != null
}
}

/** Returns the title of the first matching extension. */
fun getRecommendedExtensionTitle(composeTestRule: ComposeTestRule): String {
var verifiedCount = 0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@ import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.mozilla.fenix.customannotations.SmokeTest
import org.mozilla.fenix.helpers.AppAndSystemHelper.isDefaultPinnedShortcutsOnHomepage
import org.mozilla.fenix.helpers.Constants.RETRY_COUNT
import org.mozilla.fenix.helpers.Constants.TAG
import org.mozilla.fenix.helpers.Constants.defaultTopSitesList
import org.mozilla.fenix.helpers.Constants.defaultPinnedShortcutTitles
import org.mozilla.fenix.helpers.Constants.sponsoredShortcutTitles
import org.mozilla.fenix.helpers.DataGenerationHelper.getSponsoredShortcutTitle
import org.mozilla.fenix.helpers.FenixTestRule
import org.mozilla.fenix.helpers.HomeActivityIntentTestRule
Expand Down Expand Up @@ -71,8 +73,9 @@ class SponsoredShortcutsTest {
fun verifySponsoredShortcutsListTest() {
homeScreen(composeTestRule) {
verifyExistingTopSitesList()
defaultTopSitesList.values.forEach { value ->
verifyExistingTopSitesTabs(value)
sponsoredShortcutTitles.forEach { title -> verifyExistingTopSitesTabs(title) }
if (isDefaultPinnedShortcutsOnHomepage()) {
defaultPinnedShortcutTitles.forEach { title -> verifyExistingTopSitesTabs(title) }
}
verifyAddShortcutButtonExists()
}
Expand All @@ -86,7 +89,9 @@ class SponsoredShortcutsTest {
.goBack {}
.goBack(composeTestRule) {
verifyNotExistingSponsoredTopSitesList()
verifyAddShortcutButtonExists()
if (isDefaultPinnedShortcutsOnHomepage()) {
verifyAddShortcutButtonExists()
}
}
}

Expand All @@ -95,7 +100,7 @@ class SponsoredShortcutsTest {
fun openSponsoredShortcutTest() {
homeScreen(composeTestRule) {
verifyExistingTopSitesList()
sponsoredShortcutTitle = getSponsoredShortcutTitle(2)
sponsoredShortcutTitle = getSponsoredShortcutTitle(1)
}
.openTopSiteTabWithTitle(sponsoredShortcutTitle) {
verifyUrl(sponsoredShortcutTitle)
Expand All @@ -107,7 +112,7 @@ class SponsoredShortcutsTest {
fun openSponsoredShortcutInPrivateTabTest() {
homeScreen(composeTestRule) {
verifyExistingTopSitesList()
sponsoredShortcutTitle = getSponsoredShortcutTitle(2)
sponsoredShortcutTitle = getSponsoredShortcutTitle(1)
}
.openContextMenuOnTopSitesWithTitle(sponsoredShortcutTitle) {}
.openTopSiteInPrivateTab {
Expand All @@ -120,7 +125,7 @@ class SponsoredShortcutsTest {
fun openSponsorsAndYourPrivacyOptionTest() {
homeScreen(composeTestRule) {
verifyExistingTopSitesList()
sponsoredShortcutTitle = getSponsoredShortcutTitle(2)
sponsoredShortcutTitle = getSponsoredShortcutTitle(1)
}
.openContextMenuOnTopSitesWithTitle(sponsoredShortcutTitle) {}
.clickSponsorsAndPrivacyButton {
Expand All @@ -133,7 +138,7 @@ class SponsoredShortcutsTest {
fun openSponsoredShortcutsSettingsOptionTest() {
homeScreen(composeTestRule) {
verifyExistingTopSitesList()
sponsoredShortcutTitle = getSponsoredShortcutTitle(2)
sponsoredShortcutTitle = getSponsoredShortcutTitle(1)
}
.openContextMenuOnTopSitesWithTitle(sponsoredShortcutTitle) {}
.clickSponsoredShortcutsSettingsButton {
Expand All @@ -146,11 +151,11 @@ class SponsoredShortcutsTest {
fun verifySponsoredShortcutsDetailsTest() {
homeScreen(composeTestRule) {
verifyExistingTopSitesList()
sponsoredShortcutTitle = getSponsoredShortcutTitle(2)
sponsoredShortcutTitle2 = getSponsoredShortcutTitle(3)
sponsoredShortcutTitle = getSponsoredShortcutTitle(1)
sponsoredShortcutTitle2 = getSponsoredShortcutTitle(2)

verifySponsoredShortcutDetails(sponsoredShortcutTitle, 2)
verifySponsoredShortcutDetails(sponsoredShortcutTitle2, 3)
verifySponsoredShortcutDetails(sponsoredShortcutTitle, 1)
verifySponsoredShortcutDetails(sponsoredShortcutTitle2, 2)
}
}

Expand All @@ -165,11 +170,11 @@ class SponsoredShortcutsTest {

homeScreen(composeTestRule) {
verifyExistingTopSitesList()
sponsoredShortcutTitle = getSponsoredShortcutTitle(2)
sponsoredShortcutTitle2 = getSponsoredShortcutTitle(3)
sponsoredShortcutTitle = getSponsoredShortcutTitle(1)
sponsoredShortcutTitle2 = getSponsoredShortcutTitle(2)

verifySponsoredShortcutDetails(sponsoredShortcutTitle, 2)
verifySponsoredShortcutDetails(sponsoredShortcutTitle2, 3)
verifySponsoredShortcutDetails(sponsoredShortcutTitle, 1)
verifySponsoredShortcutDetails(sponsoredShortcutTitle2, 2)
}
navigationToolbar(composeTestRule) {}
.enterURLAndEnterToBrowser(firstWebPage.url) {
Expand Down Expand Up @@ -213,7 +218,7 @@ class SponsoredShortcutsTest {
}
.clickAddToShortcutsButton {}
.goToHomescreen {
verifySponsoredShortcutDetails(sponsoredShortcutTitle, 2)
verifySponsoredShortcutDetails(sponsoredShortcutTitle, 1)
verifySponsoredShortcutDoesNotExist(sponsoredShortcutTitle2, 3)
}
}
Expand All @@ -234,11 +239,11 @@ class SponsoredShortcutsTest {
homeScreen(composeTestRule) {
verifyExistingTopSitesList()

sponsoredShortcutTitle = getSponsoredShortcutTitle(2)
sponsoredShortcutTitle2 = getSponsoredShortcutTitle(3)
sponsoredShortcutTitle = getSponsoredShortcutTitle(1)
sponsoredShortcutTitle2 = getSponsoredShortcutTitle(2)

verifySponsoredShortcutDetails(sponsoredShortcutTitle, 2)
verifySponsoredShortcutDetails(sponsoredShortcutTitle2, 3)
verifySponsoredShortcutDetails(sponsoredShortcutTitle, 1)
verifySponsoredShortcutDetails(sponsoredShortcutTitle2, 2)

MockBrowserDataHelper.addPinnedSite(
Pair(pagesList[0].title, pagesList[0].url.toString()),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@ import org.junit.Test
import org.mozilla.fenix.R
import org.mozilla.fenix.customannotations.Converted
import org.mozilla.fenix.customannotations.SmokeTest
import org.mozilla.fenix.helpers.AppAndSystemHelper.isDefaultPinnedShortcutsOnHomepage
import org.mozilla.fenix.helpers.Constants.RETRY_COUNT
import org.mozilla.fenix.helpers.Constants.TAG
import org.mozilla.fenix.helpers.Constants.defaultTopSitesList
import org.mozilla.fenix.helpers.Constants.defaultPinnedShortcutTitles
import org.mozilla.fenix.helpers.Constants.sponsoredShortcutTitles
import org.mozilla.fenix.helpers.DataGenerationHelper.generateRandomString
import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource
import org.mozilla.fenix.helpers.FenixTestRule
Expand Down Expand Up @@ -59,11 +61,7 @@ class TopSitesTest {
homeScreen(composeTestRule) {}
.openThreeDotMenu {}
.clickSettingsButton {}
.goBack(composeTestRule) {
defaultTopSitesList.values.forEach { value ->
verifyExistingTopSitesTabs(value)
}
}
.goBack(composeTestRule) { verifyExistingTopSitesList() }

break
} catch (e: Throwable) {
Expand Down Expand Up @@ -261,8 +259,9 @@ class TopSitesTest {
fun verifyENLocalesDefaultTopSitesListTest() {
homeScreen(composeTestRule) {
verifyExistingTopSitesList()
defaultTopSitesList.values.forEach { value ->
verifyExistingTopSitesTabs(value)
sponsoredShortcutTitles.forEach { title -> verifyExistingTopSitesTabs(title) }
if (isDefaultPinnedShortcutsOnHomepage()) {
defaultPinnedShortcutTitles.forEach { title -> verifyExistingTopSitesTabs(title) }
}
verifyAddShortcutButtonExists()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ import androidx.test.uiautomator.By
import androidx.test.uiautomator.UiObjectNotFoundException
import androidx.test.uiautomator.UiScrollable
import androidx.test.uiautomator.UiSelector
import kotlin.test.assertNotNull
import mozilla.components.browser.menu.R as menuR
import mozilla.components.compose.base.R as composeBaseR
import mozilla.components.compose.browser.toolbar.concept.BrowserToolbarTestTags.ADDRESSBAR_URL_BOX
Expand All @@ -58,6 +59,7 @@ import org.mozilla.fenix.R
import org.mozilla.fenix.helpers.Constants.RETRY_COUNT
import org.mozilla.fenix.helpers.Constants.TAG
import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource
import org.mozilla.fenix.helpers.DataGenerationHelper.sponsoredShortcuts
import org.mozilla.fenix.helpers.MatcherHelper.assertItemIsChecked
import org.mozilla.fenix.helpers.MatcherHelper.assertUIObjectExists
import org.mozilla.fenix.helpers.MatcherHelper.itemContainingText
Expand Down Expand Up @@ -254,18 +256,22 @@ class HomeScreenRobot(private val composeTestRule: ComposeTestRule) {
Log.i(TAG, "verifyAddShortcutButtonExists: Verified that the \"Add shortcut\" button exists")
}

fun verifySponsoredShortcutDetails(sponsoredShortcutTitle: String, position: Int) {
assertUIObjectExists(
itemWithResIdAndIndex(resourceId = "top_sites_list.top_site_item", index = position - 1)
.getChild(UiSelector().resourceId(TOP_SITE_CARD_FAVICON))
)
assertUIObjectExists(
itemWithResIdAndIndex(resourceId = "top_sites_list.top_site_item", index = position - 1)
.getChild(UiSelector().textContains(sponsoredShortcutTitle))
/**
* Asserts the [ordinal]th sponsored shortcut has a favicon and the expected title.
*
* @param sponsoredShortcutTitle The shortcut title which is expected.
* @param ordinal One-based index among the sponsored shortcuts only, matching
* [org.mozilla.fenix.helpers.DataGenerationHelper.getSponsoredShortcutTitle].
*/
fun verifySponsoredShortcutDetails(sponsoredShortcutTitle: String, ordinal: Int) {
val sponsoredShortcut = sponsoredShortcuts()[ordinal - 1]
assertNotNull(
sponsoredShortcut.findObject(By.res(TOP_SITE_CARD_FAVICON)),
"Sponsored shortcut #$ordinal has no favicon",
)
assertUIObjectExists(
itemWithResIdAndIndex(resourceId = "top_sites_list.top_site_item", index = position - 1)
.getChild(UiSelector().textContains(getStringResource(R.string.top_sites_sponsored_label)))
assertNotNull(
sponsoredShortcut.findObject(By.textContains(sponsoredShortcutTitle)),
"Sponsored shortcut #$ordinal is not titled $sponsoredShortcutTitle",
)
}

Expand Down