Skip to content

Commit

Permalink
Merge pull request DroidKaigi#502 from Corvus400/enhancement/staff_sc…
Browse files Browse the repository at this point in the history
…reen_test_enhancement

♻️ Enhanced StaffScreen testing.
  • Loading branch information
takahirom authored Aug 18, 2024
2 parents fc553d1 + 2752a21 commit 4055cb0
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 38 deletions.
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
package io.github.droidkaigi.confsched.testing.robot

import androidx.compose.ui.test.assertContentDescriptionEquals
import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.assertTextEquals
import androidx.compose.ui.test.hasTestTag
import androidx.compose.ui.test.onChildren
import androidx.compose.ui.test.onFirst
import androidx.compose.ui.test.hasText
import androidx.compose.ui.test.performScrollToIndex
import io.github.droidkaigi.confsched.designsystem.theme.KaigiTheme
import io.github.droidkaigi.confsched.model.Staff
import io.github.droidkaigi.confsched.model.fakes
import io.github.droidkaigi.confsched.staff.StaffItemTestTagPrefix
import io.github.droidkaigi.confsched.staff.StaffScreen
import io.github.droidkaigi.confsched.staff.StaffScreenLazyColumnTestTag
import io.github.droidkaigi.confsched.staff.component.StaffItemImageTestTag
import io.github.droidkaigi.confsched.staff.component.StaffItemUserNameTextTestTag
import io.github.droidkaigi.confsched.testing.utils.assertCountAtLeast
import io.github.droidkaigi.confsched.testing.utils.hasTestTag
import javax.inject.Inject

class StaffScreenRobot @Inject constructor(
Expand All @@ -26,20 +35,81 @@ class StaffScreenRobot @Inject constructor(
waitUntilIdle()
}

fun checkExistsStaffItem() {
fun scrollToIndex10() {
composeTestRule
.onNode(hasTestTag(StaffScreenLazyColumnTestTag))
.onChildren()
.onFirst()
.assertExists()
.assertIsDisplayed()
.performScrollToIndex(10)
}

fun checkDoesNotExistsStaffItem() {
fun checkShowFirstAndSecondStaffs() {
checkRangeStaffItemsDisplayed(
fromTo = 0..2,
)
}

private fun checkRangeStaffItemsDisplayed(
fromTo: IntRange,
) {
val staffList = Staff.fakes().subList(fromTo.first, fromTo.last)
staffList.forEach { staff ->
composeTestRule
.onNode(hasTestTag(StaffItemTestTagPrefix.plus(staff.id)))
.assertExists()
.assertIsDisplayed()

composeTestRule
.onNode(
matcher = hasTestTag(StaffItemImageTestTag.plus(staff.username)),
useUnmergedTree = true,
)
.assertExists()
.assertIsDisplayed()
.assertContentDescriptionEquals(staff.username)

composeTestRule
.onNode(
matcher = hasTestTag(StaffItemUserNameTextTestTag.plus(staff.username)),
useUnmergedTree = true,
)
.assertExists()
.assertIsDisplayed()
.assertTextEquals(staff.username)
}
}

fun checkStaffItemsDisplayed() {
// Check there are two staffs
composeTestRule
.onNode(hasTestTag(StaffScreenLazyColumnTestTag))
.onChildren()
.onFirst()
.onAllNodes(hasTestTag(StaffItemTestTagPrefix, substring = true))
.assertCountAtLeast(2)
}

fun checkDoesNotFirstStaffItemDisplayed() {
val staff = Staff.fakes().first()
composeTestRule
.onNode(hasTestTag(StaffItemTestTagPrefix.plus(staff.id)))
.assertDoesNotExist()

composeTestRule
.onNode(
matcher = hasTestTag(StaffItemImageTestTag.plus(staff.username)),
useUnmergedTree = true,
)
.assertDoesNotExist()

composeTestRule
.onNode(
matcher = hasTestTag(StaffItemUserNameTextTestTag.plus(staff.username)),
useUnmergedTree = true,
)
.assertDoesNotExist()
}

fun checkErrorSnackbarDisplayed() {
composeTestRule
.onNode(
hasText("Fake IO Exception"),
useUnmergedTree = true,
).assertIsDisplayed()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ import io.github.droidkaigi.confsched.testing.DescribedBehavior
import io.github.droidkaigi.confsched.testing.describeBehaviors
import io.github.droidkaigi.confsched.testing.execute
import io.github.droidkaigi.confsched.testing.robot.StaffScreenRobot
import io.github.droidkaigi.confsched.testing.robot.StaffServerRobot.ServerStatus.Error
import io.github.droidkaigi.confsched.testing.robot.StaffServerRobot.ServerStatus.Operational
import io.github.droidkaigi.confsched.testing.robot.StaffServerRobot
import io.github.droidkaigi.confsched.testing.robot.runRobot
import io.github.droidkaigi.confsched.testing.rules.RobotTestRule
import org.junit.Rule
Expand Down Expand Up @@ -41,36 +40,46 @@ class StaffScreenTest(
return describeBehaviors<StaffScreenRobot>(name = "StaffScreen") {
describe("when server is operational") {
run {
setupStaffServer(Operational)
setupStaffServer(StaffServerRobot.ServerStatus.Operational)
}
describe("when launch") {
run {
setupScreenContent()
}
itShould("show staff screen") {
captureScreenWithChecks(
checks = {
checkExistsStaffItem()
},
)
itShould("show first and second staffs") {
captureScreenWithChecks {
checkShowFirstAndSecondStaffs()
}
}
}
}

describe("when server is down") {
run {
setupStaffServer(Error)
describe("when scroll to index 10") {
run {
scrollToIndex10()
}
itShould("show staffs") {
captureScreenWithChecks {
checkStaffItemsDisplayed()
}
}
}
}
describe("when launch") {

describe("when server is down") {
run {
setupScreenContent()
setupStaffServer(StaffServerRobot.ServerStatus.Error)
}
itShould("show snackbar") {
captureScreenWithChecks(
checks = {
checkDoesNotExistsStaffItem()
},
)
describe("when launch") {
run {
setupScreenContent()
}
itShould("does not show staff and show snackbar") {
captureScreenWithChecks(
checks = {
checkDoesNotFirstStaffItemDisplayed()
checkErrorSnackbarDisplayed()
},
)
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import org.jetbrains.compose.ui.tooling.preview.Preview
const val staffScreenRoute = "staff"
const val StaffScreenTestTag = "StaffScreenTestTag"
const val StaffScreenLazyColumnTestTag = "StaffScreenLazyColumnTestTag"
const val StaffItemTestTagPrefix = "StaffItemTestTag:"

fun NavGraphBuilder.staffScreens(
onNavigationIconClick: () -> Unit,
Expand Down Expand Up @@ -121,21 +122,23 @@ fun StaffScreen(
modifier = Modifier
.fillMaxSize()
.padding(top = padding.calculateTopPadding())
.testTag(StaffScreenLazyColumnTestTag)
.let {
if (scrollBehavior != null) {
it.nestedScroll(scrollBehavior.nestedScrollConnection)
} else {
it
}
},
}
.testTag(StaffScreenLazyColumnTestTag),
contentPadding = PaddingValues(bottom = padding.calculateBottomPadding()),
) {
items(uiState.staff) { staff ->
StaffItem(
staff = staff,
onStaffItemClick = onStaffItemClick,
modifier = Modifier.fillMaxWidth(),
modifier = Modifier
.fillMaxWidth()
.testTag(StaffItemTestTagPrefix.plus(staff.id)),
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.vector.rememberVectorPainter
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import io.github.droidkaigi.confsched.designsystem.theme.KaigiTheme
Expand All @@ -29,6 +30,9 @@ import org.jetbrains.compose.ui.tooling.preview.Preview

private val staffIconShape = CircleShape

const val StaffItemImageTestTag = "StaffItemImageTestTag:"
const val StaffItemUserNameTextTestTag = "StaffItemUserNameTextTestTag:"

@Composable
fun StaffItem(
staff: Staff,
Expand All @@ -48,21 +52,23 @@ fun StaffItem(
painter = previewOverride(previewPainter = { rememberVectorPainter(image = Icons.Default.Person) }) {
rememberAsyncImagePainter(staff.iconUrl)
},
contentDescription = null,
contentDescription = staff.username,
modifier = Modifier
.size(52.dp)
.clip(staffIconShape)
.border(
width = 1.dp,
color = MaterialTheme.colorScheme.outline,
shape = staffIconShape,
),
)
.testTag(StaffItemImageTestTag.plus(staff.username)),
)
Text(
text = staff.username,
style = MaterialTheme.typography.bodyLarge,
maxLines = 2,
overflow = TextOverflow.Ellipsis,
modifier = Modifier.testTag(StaffItemUserNameTextTestTag.plus(staff.username)),
)
}
}
Expand Down

0 comments on commit 4055cb0

Please sign in to comment.