Skip to content

Commit

Permalink
fix(test): Resolve navigation test case issues caused by altering sta…
Browse files Browse the repository at this point in the history
…rt destination
  • Loading branch information
azrael8576 committed Nov 17, 2023
1 parent f3f2067 commit 07da8c6
Show file tree
Hide file tree
Showing 8 changed files with 84 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,8 @@ class AtAppStateTest {
}

assertThat(state.topLevelDestinations).hasSize(3)
assertThat(state.topLevelDestinations[0].name).ignoringCase().contains("schedule")
assertThat(state.topLevelDestinations[1].name).ignoringCase().contains("home")
assertThat(state.topLevelDestinations[0].name).ignoringCase().contains("home")
assertThat(state.topLevelDestinations[1].name).ignoringCase().contains("schedule")
assertThat(state.topLevelDestinations[2].name).ignoringCase().contains("contact_me")
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ internal open class NavigationRobot(
composeTestRule.waitForIdle()
}

private fun clickNavHome() {
internal fun clickNavHome() {
navHome.performClick()
// 等待任何動畫完成
composeTestRule.waitForIdle()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,11 @@ class NavigationTest {
}

@Test
fun isScheduleScreen_afterLogin() {
fun isHomeScreen_afterLogin() {
welcomeEndToEndRobot(composeTestRule) {
} getStartedClick {
} login {
verifyScheduleTopAppBarDisplayed()
verifyMenuButtonDisplayed()
}
}

Expand All @@ -77,11 +77,11 @@ class NavigationTest {
}

/*
* When pressing back from any top level destination except "Schedule", the app navigates back
* to the "Schedule" destination, no matter which destinations you visited in between.
* When pressing back from any top level destination except "Home", the app navigates back
* to the "Home" destination, no matter which destinations you visited in between.
*/
@Test
fun navigationBar_backFromAnyDestination_returnsToSchedule() {
fun navigationBar_backFromAnyDestination_returnsToHome() {
welcomeEndToEndRobot(composeTestRule) {
} getStartedClick {
} login {
Expand All @@ -91,7 +91,7 @@ class NavigationTest {
// WHEN the user uses the system button/gesture to go back
Espresso.pressBack()
}
verifyScheduleTopAppBarDisplayed()
verifyMenuButtonDisplayed()
}
}

Expand All @@ -106,8 +106,8 @@ class NavigationTest {
navigationRobot(composeTestRule) {
// GIVEN the user navigates to the Contact Me destination
clickNavContactMe()
// and then navigates to the Schedule destination
clickNavSchedule()
// and then navigates to the Home destination
clickNavHome()
// WHEN the user uses the system button/gesture to go back
Espresso.pressBack()
// THEN the app quits
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package com.wei.amazingtalker.ui.robot

import androidx.annotation.StringRes
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.semantics.SemanticsProperties
import androidx.compose.ui.semantics.getOrNull
import androidx.compose.ui.test.SemanticsMatcher
import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.hasContentDescription
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
import androidx.test.ext.junit.rules.ActivityScenarioRule
import com.wei.amazingtalker.MainActivity
import kotlin.properties.ReadOnlyProperty
import com.wei.amazingtalker.feature.home.R as FeatureHomeR

/**
* Screen Robot for End To End Test.
*
* 遵循此模型,找到測試使用者介面元素、檢查其屬性、和透過測試規則執行動作:
* composeTestRule{.finder}{.assertion}{.action}
*
* Testing cheatsheet:
* https://developer.android.com/jetpack/compose/testing-cheatsheet
*/
internal fun homeEndToEndRobot(
composeTestRule: AndroidComposeTestRule<ActivityScenarioRule<MainActivity>, MainActivity>,
func: HomeEndToEndRobot.() -> Unit,
) = HomeEndToEndRobot(composeTestRule).apply(func)

internal open class HomeEndToEndRobot(
private val composeTestRule: AndroidComposeTestRule<ActivityScenarioRule<MainActivity>, MainActivity>,
) {
private fun AndroidComposeTestRule<*, *>.stringResource(@StringRes resId: Int) =
ReadOnlyProperty<Any?, String> { _, _ -> activity.getString(resId) }

private fun withRole(role: Role) = SemanticsMatcher("${SemanticsProperties.Role.name} contains '$role'") {
val roleProperty = it.config.getOrNull(SemanticsProperties.Role) ?: false
roleProperty == role
}

// The strings used for matching in these tests
private val menuDescription by composeTestRule.stringResource(FeatureHomeR.string.menu)

private val menuButton by lazy {
composeTestRule.onNode(
withRole(Role.Button)
.and(hasContentDescription(menuDescription)),
)
}

fun verifyMenuButtonDisplayed() {
menuButton.assertExists().assertIsDisplayed()
}

fun isMenuButtonDisplayed(): Boolean {
return try {
verifyMenuButtonDisplayed()
true
} catch (e: AssertionError) {
false
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,11 @@ internal open class LoginEndToEndRobotRobot(
}
}

infix fun login(func: ScheduleEndToEndRobot.() -> Unit): ScheduleEndToEndRobot {
infix fun login(func: HomeEndToEndRobot.() -> Unit): HomeEndToEndRobot {
loginButton.performClick()
return scheduleEndToEndRobot(composeTestRule) {
return homeEndToEndRobot(composeTestRule) {
// 等待任何動畫完成
composeTestRule.waitUntil(3_000) { isScheduleTopAppBarDisplayed() }
composeTestRule.waitUntil(3_000) { isMenuButtonDisplayed() }
func()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -314,12 +314,14 @@ fun loadImageUsingCoil(resId: Int, isPreview: Boolean): Painter {
private fun MenuButton(
onMenuClick: () -> Unit,
) {
val menu = stringResource(R.string.menu)

IconButton(
onClick = onMenuClick,
modifier = Modifier
.clip(CircleShape)
.background(MaterialTheme.colorScheme.surfaceVariant)
.semantics { contentDescription = "" },
.semantics { contentDescription = menu },
) {
Icon(
imageVector = AtIcons.Menu,
Expand Down
2 changes: 2 additions & 0 deletions feature/home/src/main/res/values-zh-rTW/strings.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- 首頁 -->
<string name="profile_picture">%s 的大頭貼</string>
<string name="menu">選單</string>
</resources>
2 changes: 2 additions & 0 deletions feature/home/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- 首頁 -->
<string name="profile_picture">%s\'s profile picture</string>
<string name="menu">Menu</string>
</resources>

0 comments on commit 07da8c6

Please sign in to comment.