Skip to content

Commit

Permalink
refactor: replace hardcoded test tags with C values in `BottomNavig…
Browse files Browse the repository at this point in the history
…ationMenu` screen and tests
  • Loading branch information
charliemangano committed Oct 31, 2024
1 parent a20aaae commit 3a7faa3
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import androidx.compose.ui.test.assertIsSelected
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.performClick
import com.android.periodpals.resources.C
import org.junit.Rule
import org.junit.Test

Expand All @@ -21,12 +22,19 @@ class BottomNavigationMenuTest {
fun bottomNavigationMenu_displaysAllTabs() {
composeTestRule.setContent {
BottomNavigationMenu(
onTabSelect = {}, tabList = LIST_TOP_LEVEL_DESTINATION, selectedItem = "Map")
onTabSelect = {},
tabList = LIST_TOP_LEVEL_DESTINATION,
selectedItem = "Map",
)
}

composeTestRule.onNodeWithTag("bottomNavigationMenu").assertIsDisplayed()
composeTestRule
.onNodeWithTag(C.Tag.BottomNavigationMenu.BOTTOM_NAVIGATION_MENU)
.assertIsDisplayed()
LIST_TOP_LEVEL_DESTINATION.forEach { tab ->
composeTestRule.onNodeWithTag(tab.textId).assertIsDisplayed()
composeTestRule
.onNodeWithTag(C.Tag.BottomNavigationMenu.BOTTOM_NAVIGATION_MENU_ITEM + tab.textId)
.assertIsDisplayed()
}
}

Expand All @@ -40,43 +48,64 @@ class BottomNavigationMenuTest {
BottomNavigationMenu(
onTabSelect = { selectedTab = it.route },
tabList = LIST_TOP_LEVEL_DESTINATION,
selectedItem = selectedTab)
selectedItem = selectedTab,
)
}

// Initially, verify that "MAP" is selected
composeTestRule.onNodeWithTag("Map").assertIsSelected()
composeTestRule
.onNodeWithTag(C.Tag.BottomNavigationMenu.BOTTOM_NAVIGATION_MENU_ITEM + "Map")
.assertIsSelected()

// Perform a click on the "Alert" tab
composeTestRule.onNodeWithTag("Alert").performClick()
composeTestRule
.onNodeWithTag(C.Tag.BottomNavigationMenu.BOTTOM_NAVIGATION_MENU_ITEM + "Alert")
.performClick()

// Now check that the "Alert" tab is selected
composeTestRule.onNodeWithTag("Alert").assertIsSelected()
composeTestRule
.onNodeWithTag(C.Tag.BottomNavigationMenu.BOTTOM_NAVIGATION_MENU_ITEM + "Alert")
.assertIsSelected()

// Optionally, check that the previously selected "Map" tab is no longer selected
composeTestRule.onNodeWithTag("Map").assertIsNotSelected()
composeTestRule
.onNodeWithTag(C.Tag.BottomNavigationMenu.BOTTOM_NAVIGATION_MENU_ITEM + "Map")
.assertIsNotSelected()
}

@Test
fun bottomNavigationMenu_iconAndLabelAreDisplayedCorrectly() {
composeTestRule.setContent {
BottomNavigationMenu(
onTabSelect = {}, tabList = LIST_TOP_LEVEL_DESTINATION, selectedItem = "Profile")
onTabSelect = {},
tabList = LIST_TOP_LEVEL_DESTINATION,
selectedItem = "Profile",
)
}

LIST_TOP_LEVEL_DESTINATION.forEach { tab ->
composeTestRule.onNodeWithTag(tab.textId).assertIsDisplayed()
composeTestRule.onNodeWithTag(tab.textId).assertIsDisplayed()
composeTestRule
.onNodeWithTag(C.Tag.BottomNavigationMenu.BOTTOM_NAVIGATION_MENU_ITEM + tab.textId)
.assertIsDisplayed()
composeTestRule
.onNodeWithTag(C.Tag.BottomNavigationMenu.BOTTOM_NAVIGATION_MENU_ITEM + tab.textId)
.assertIsDisplayed()
}
}

@Test
fun bottomNavigationMenu_initialSelectionIsCorrect() {
composeTestRule.setContent {
BottomNavigationMenu(
onTabSelect = {}, tabList = LIST_TOP_LEVEL_DESTINATION, selectedItem = "Timer")
onTabSelect = {},
tabList = LIST_TOP_LEVEL_DESTINATION,
selectedItem = "Timer",
)
}

composeTestRule.onNodeWithTag("Timer").assertIsSelected()
composeTestRule
.onNodeWithTag(C.Tag.BottomNavigationMenu.BOTTOM_NAVIGATION_MENU_ITEM + "Timer")
.assertIsSelected()
}

@Test
Expand All @@ -87,10 +116,15 @@ class BottomNavigationMenuTest {
BottomNavigationMenu(
onTabSelect = { selectedTab = it.route },
tabList = LIST_TOP_LEVEL_DESTINATION,
selectedItem = selectedTab)
selectedItem = selectedTab,
)
}

composeTestRule.onNodeWithTag("Alert List").performClick()
composeTestRule.onNodeWithTag("Alert List").assertIsSelected()
composeTestRule
.onNodeWithTag(C.Tag.BottomNavigationMenu.BOTTOM_NAVIGATION_MENU_ITEM + "Alert List")
.performClick()
composeTestRule
.onNodeWithTag(C.Tag.BottomNavigationMenu.BOTTOM_NAVIGATION_MENU_ITEM + "Alert List")
.assertIsSelected()
}
}
2 changes: 1 addition & 1 deletion app/src/main/java/com/android/periodpals/resources/C.kt
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ object C {

object BottomNavigationMenu {
const val BOTTOM_NAVIGATION_MENU = "bottomNavigationMenu" // "bottomNavigationMenu"
const val BOTTOM_NAVIGATION_MENU_ITEM = "bottomNavigationMenuItem" // "navigationBarItem"
const val BOTTOM_NAVIGATION_MENU_ITEM = "bottomNavigationMenu" // "navigationBarItem"
}

object TopBar {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,52 +16,42 @@ import androidx.compose.ui.platform.testTag
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.android.periodpals.resources.C

/**
* Displays a bottom navigation menu with selectable tabs.
*
* @param onTabSelect Called when a tab is selected, receiving the selected [TopLevelDestination].
* @param tabList List of [TopLevelDestination] representing the tabs.
* @param selectedItem The route of the currently selected tab.
*
* ### Usage:
* ```
* BottomNavigationMenu(
* onTabSelect = { route -> navigationActions.navigateTo(route) },
* tabList = LIST_TOP_LEVEL_DESTINATION,
* selectedItem = navigationActions.currentRoute()
* )
* ```
*
* ### Testing:
* Verify the bottom navigation menu is displayed with the testTag "bottomNavigationMenu".
*/
@Composable
fun BottomNavigationMenu(
onTabSelect: (TopLevelDestination) -> Unit,
tabList: List<TopLevelDestination>,
selectedItem: String
selectedItem: String,
) {
NavigationBar(
modifier = Modifier.fillMaxWidth().height(60.dp).testTag("bottomNavigationMenu"),
modifier =
Modifier.fillMaxWidth()
.height(60.dp)
.testTag(C.Tag.BottomNavigationMenu.BOTTOM_NAVIGATION_MENU),
containerColor = MaterialTheme.colorScheme.surface,
content = {
tabList.forEach { tab ->
NavigationBarItem(
modifier =
Modifier.clip(RoundedCornerShape(50.dp))
.align(Alignment.CenterVertically)
.testTag(tab.textId),
.testTag(C.Tag.BottomNavigationMenu.BOTTOM_NAVIGATION_MENU_ITEM + tab.textId),
icon = { Icon(tab.icon, contentDescription = null) },
label = {
Text(
text = tab.textId,
style =
MaterialTheme.typography.bodySmall.copy(
fontSize = 10.sp, fontWeight = FontWeight.Normal))
fontSize = 10.sp,
fontWeight = FontWeight.Normal,
),
)
},
selected = tab.route == selectedItem,
onClick = { onTabSelect(tab) })
onClick = { onTabSelect(tab) },
)
}
})
},
)
}

0 comments on commit 3a7faa3

Please sign in to comment.