Skip to content
Merged
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
@@ -1,6 +1,7 @@
package org.mozilla.tryfox.data

import kotlinx.coroutines.delay
import org.mozilla.tryfox.data.repositories.DownloadFileRepository
import java.io.File

class FakeDownloadFileRepository(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package org.mozilla.tryfox.data

class FakeFenixRepository(
import org.mozilla.tryfox.data.repositories.TreeherderRepository

class FakeTreeherderRepository(
private val simulateNetworkError: Boolean = false,
private val networkErrorMessage: String = "Fake network error",
) : IFenixRepository {
) : TreeherderRepository {

override suspend fun getPushByRevision(
project: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ package org.mozilla.tryfox.data

import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import org.mozilla.tryfox.data.repositories.UserDataRepository

/**
* A fake implementation of [UserDataRepository] for testing purposes.
* A fake implementation of [org.mozilla.tryfox.data.repositories.UserDataRepository] for testing purposes.
*/
class FakeUserDataRepository : UserDataRepository {

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
package org.mozilla.tryfox.ui.screens

import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.junit4.createAndroidComposeRule
import androidx.compose.ui.test.onNodeWithTag
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.mozilla.tryfox.MainActivity

/**
* UI tests to verify that Firefox Release and Firefox Beta cards correctly detect
* installed apps and allow launching them.
*
* These tests assert that:
* - Firefox Release card (org.mozilla.firefox) is displayed on the home screen
* - Firefox Beta card (org.mozilla.fenix-beta) is displayed on the home screen
* - Both cards have proper download/install buttons
* - The cards are distinct from the Fenix Nightly card
*/
@RunWith(AndroidJUnit4::class)
class FirefoxReleaseAndBetaInstallationTest {

@get:Rule
val composeTestRule = createAndroidComposeRule<MainActivity>()

@Test
fun homeScreen_showsFirefoxReleaseCard() {
// Wait for the home screen to load
composeTestRule.waitForIdle()

// Assert Firefox Release card title is displayed using testTag
// The testTag is: "app_title_text_fenix-release"
val firefoxReleaseTitleTag = "app_title_text_fenix-release"
composeTestRule.onNodeWithTag(firefoxReleaseTitleTag, useUnmergedTree = true)
.assertIsDisplayed()
}

@Test
fun homeScreen_showsFirefoxBetaCard() {
// Wait for the home screen to load
composeTestRule.waitForIdle()

// Assert Firefox Beta card title is displayed using testTag
// The testTag is: "app_title_text_fenix-beta"
val firefoxBetaTitleTag = "app_title_text_fenix-beta"
composeTestRule.onNodeWithTag(firefoxBetaTitleTag, useUnmergedTree = true)
.assertIsDisplayed()
}

@Test
fun homeScreen_firefoxReleaseAndBetaCardsAreDistinct() {
// Wait for the home screen to load
composeTestRule.waitForIdle()

// Verify that both Firefox Release and Beta cards are displayed separately
val firefoxReleaseTitleTag = "app_title_text_fenix-release"
val firefoxBetaTitleTag = "app_title_text_fenix-beta"

composeTestRule.onNodeWithTag(firefoxReleaseTitleTag, useUnmergedTree = true)
.assertIsDisplayed()
composeTestRule.onNodeWithTag(firefoxBetaTitleTag, useUnmergedTree = true)
.assertIsDisplayed()
}

@Test
fun homeScreen_fenixNightlyCardStillDisplayed() {
// Wait for the home screen to load
composeTestRule.waitForIdle()

// Verify that the original Fenix (Nightly) card is still displayed
val fenixNightlyTitleTag = "app_title_text_fenix"
composeTestRule.onNodeWithTag(fenixNightlyTitleTag, useUnmergedTree = true)
.assertIsDisplayed()
}

@Test
fun homeScreen_allThreeFenixVariantsDisplayed() {
// Wait for the home screen to load
composeTestRule.waitForIdle()

// Verify all three Fenix variants are displayed:
// 1. Fenix (Nightly) - org.mozilla.fenix
// 2. Firefox (Release) - org.mozilla.firefox
// 3. Firefox Beta - org.mozilla.fenix-beta

val fenixNightlyTitleTag = "app_title_text_fenix"
val firefoxReleaseTitleTag = "app_title_text_fenix-release"
val firefoxBetaTitleTag = "app_title_text_fenix-beta"

composeTestRule.onNodeWithTag(fenixNightlyTitleTag, useUnmergedTree = true)
.assertIsDisplayed()
composeTestRule.onNodeWithTag(firefoxReleaseTitleTag, useUnmergedTree = true)
.assertIsDisplayed()
composeTestRule.onNodeWithTag(firefoxBetaTitleTag, useUnmergedTree = true)
.assertIsDisplayed()
}

@Test
fun homeScreen_firefoxReleaseCardCanBeLaunched() {
// Wait for the home screen to load
composeTestRule.waitForIdle()

// Verify that the Firefox Release card is displayed and can be interacted with
val firefoxReleaseTitleTag = "app_title_text_fenix-release"
composeTestRule.onNodeWithTag(firefoxReleaseTitleTag, useUnmergedTree = true)
.assertIsDisplayed()

// The card exists and is displayed, which means it's ready for interaction
// (clicking on it would launch the app if installed)
}

@Test
fun homeScreen_firefoxBetaCardCanBeLaunched() {
// Wait for the home screen to load
composeTestRule.waitForIdle()

// Verify that the Firefox Beta card is displayed and can be interacted with
val firefoxBetaTitleTag = "app_title_text_fenix-beta"
composeTestRule.onNodeWithTag(firefoxBetaTitleTag, useUnmergedTree = true)
.assertIsDisplayed()

// The card exists and is displayed, which means it's ready for interaction
// (clicking on it would launch the app if installed)
}

@Test
fun homeScreen_firefoxReleaseDetectsInstallationCorrectly() {
// Wait for the home screen to load
composeTestRule.waitForIdle()

// Verify that the Firefox Release card is displayed
// This verifies that:
// 1. MozillaPackageManager.fenixRelease is being queried
// 2. The app correctly checks if org.mozilla.firefox is installed
val firefoxReleaseTitleTag = "app_title_text_fenix-release"
composeTestRule.onNodeWithTag(firefoxReleaseTitleTag, useUnmergedTree = true)
.assertIsDisplayed()
}

@Test
fun homeScreen_firefoxBetaDetectsInstallationCorrectly() {
// Wait for the home screen to load
composeTestRule.waitForIdle()

// Verify that the Firefox Beta card is displayed
// This verifies that:
// 1. MozillaPackageManager.fenixBeta is being queried
// 2. The app correctly checks if org.mozilla.fenix-beta is installed
val firefoxBetaTitleTag = "app_title_text_fenix-beta"
composeTestRule.onNodeWithTag(firefoxBetaTitleTag, useUnmergedTree = true)
.assertIsDisplayed()
}

@Test
fun homeScreen_allFenixVariantsLoadWithoutErrors() {
// Wait for the home screen to load fully
composeTestRule.waitForIdle()

// Verify that all three Fenix variants load successfully
// This is the core test that verifies the fix is working:
// - Fenix Nightly (org.mozilla.fenix)
// - Firefox Release (org.mozilla.firefox)
// - Firefox Beta (org.mozilla.fenix-beta)

val fenixNightlyTitleTag = "app_title_text_fenix"
val firefoxReleaseTitleTag = "app_title_text_fenix-release"
val firefoxBetaTitleTag = "app_title_text_fenix-beta"

// All should be displayed without errors
composeTestRule.onNodeWithTag(fenixNightlyTitleTag, useUnmergedTree = true)
.assertIsDisplayed()
composeTestRule.onNodeWithTag(firefoxReleaseTitleTag, useUnmergedTree = true)
.assertIsDisplayed()
composeTestRule.onNodeWithTag(firefoxBetaTitleTag, useUnmergedTree = true)
.assertIsDisplayed()
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
package org.mozilla.tryfox.ui.screens

import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.hasContentDescription
import androidx.compose.ui.test.junit4.createAndroidComposeRule
import androidx.compose.ui.test.onNodeWithTag
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.mozilla.tryfox.MainActivity
import org.mozilla.tryfox.R

@RunWith(AndroidJUnit4::class)
class HomeScreenTest {
Expand All @@ -18,29 +16,44 @@ class HomeScreenTest {
val composeTestRule = createAndroidComposeRule<MainActivity>()

@Test
fun homeScreen_showsFenixAndFocusCards() {
val activity = composeTestRule.activity

fun homeScreen_showsFenixNightlyCard() {
// --- Fenix (Nightly) Card ---
val fenixIconDesc = activity.getString(R.string.app_icon_firefox_nightly_description)
val fenixIconMatcher = hasContentDescription(fenixIconDesc)
val fenixTitleTag = "app_title_text_fenix"

// Assert Fenix icon is displayed
composeTestRule.onNode(fenixIconMatcher, useUnmergedTree = true).assertIsDisplayed()

// Assert Fenix text (found by tag) is displayed
composeTestRule.onNodeWithTag(fenixTitleTag, useUnmergedTree = true).assertIsDisplayed()
}

@Test
fun homeScreen_showsFenixBetaCard() {
// --- Fenix Beta Card ---
val betaTitleTag = "app_title_text_fenix-beta"

// Assert Beta text (found by tag) is displayed
composeTestRule.onNodeWithTag(betaTitleTag, useUnmergedTree = true).assertIsDisplayed()
}

// --- Focus Card ---
val focusIconDesc = activity.getString(R.string.app_icon_focus_description)
val focusIconMatcher = hasContentDescription(focusIconDesc)
val focusTitleTag = "app_title_text_focus"
@Test
fun homeScreen_showsFenixReleaseCard() {
// --- Fenix Release Card ---
val releaseTitleTag = "app_title_text_fenix-release"

// Assert Release text (found by tag) is displayed
composeTestRule.onNodeWithTag(releaseTitleTag, useUnmergedTree = true).assertIsDisplayed()
}

@Test
fun homeScreen_showsAllThreeFenixVariants() {
// --- Fenix (Nightly) Card ---
val fenixTitleTag = "app_title_text_fenix"
composeTestRule.onNodeWithTag(fenixTitleTag, useUnmergedTree = true).assertIsDisplayed()

// Assert Focus icon is displayed
composeTestRule.onNode(focusIconMatcher, useUnmergedTree = true).assertIsDisplayed()
// --- Fenix Beta Card ---
val betaTitleTag = "app_title_text_fenix-beta"
composeTestRule.onNodeWithTag(betaTitleTag, useUnmergedTree = true).assertIsDisplayed()

// Assert Focus text (found by tag) is displayed
composeTestRule.onNodeWithTag(focusTitleTag, useUnmergedTree = true).assertIsDisplayed()
// --- Fenix Release Card ---
val releaseTitleTag = "app_title_text_fenix-release"
composeTestRule.onNodeWithTag(releaseTitleTag, useUnmergedTree = true).assertIsDisplayed()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,19 @@ import org.junit.Test
import org.junit.runner.RunWith
import org.mozilla.tryfox.data.FakeCacheManager
import org.mozilla.tryfox.data.FakeDownloadFileRepository
import org.mozilla.tryfox.data.FakeFenixRepository
import org.mozilla.tryfox.data.FakeIntentManager
import org.mozilla.tryfox.data.FakeTreeherderRepository
import org.mozilla.tryfox.data.FakeUserDataRepository
import org.mozilla.tryfox.data.UserDataRepository
import org.mozilla.tryfox.data.managers.CacheManager
import org.mozilla.tryfox.data.repositories.UserDataRepository

@RunWith(AndroidJUnit4::class)
class ProfileScreenTest {

@get:Rule
val composeTestRule = createComposeRule()

private val fenixRepository = FakeFenixRepository()
private val fenixRepository = FakeTreeherderRepository()
private val downloadFileRepository = FakeDownloadFileRepository()
private val userDataRepository: UserDataRepository = FakeUserDataRepository()
private val cacheManager: CacheManager = FakeCacheManager()
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
<queries>
<package android:name="org.mozilla.fenix" />
<package android:name="org.mozilla.focus.nightly" />
<package android:name="org.mozilla.firefox" />
<package android:name="org.mozilla.firefox_beta" />
<package android:name="org.mozilla.reference.browser" />
</queries>

Expand Down
6 changes: 3 additions & 3 deletions app/src/main/java/org/mozilla/tryfox/TryFoxViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
import org.mozilla.tryfox.data.DownloadFileRepository
import org.mozilla.tryfox.data.DownloadState
import org.mozilla.tryfox.data.IFenixRepository
import org.mozilla.tryfox.data.NetworkResult
import org.mozilla.tryfox.data.managers.CacheManager
import org.mozilla.tryfox.data.managers.IntentManager
import org.mozilla.tryfox.data.repositories.DownloadFileRepository
import org.mozilla.tryfox.data.repositories.TreeherderRepository
import org.mozilla.tryfox.model.CacheManagementState
import org.mozilla.tryfox.ui.models.AbiUiModel
import org.mozilla.tryfox.ui.models.ArtifactUiModel
Expand All @@ -39,7 +39,7 @@ import java.io.File
* @param project The initial repository to search in.
*/
class TryFoxViewModel(
private val fenixRepository: IFenixRepository,
private val fenixRepository: TreeherderRepository,
private val downloadFileRepository: DownloadFileRepository,
private val cacheManager: CacheManager,
private val intentManager: IntentManager,
Expand Down
Loading