diff --git a/core/testing/src/main/java/io/github/droidkaigi/confsched/testing/MiniRobots.kt b/core/testing/src/main/java/io/github/droidkaigi/confsched/testing/MiniRobots.kt index 15b92e88d..483692792 100644 --- a/core/testing/src/main/java/io/github/droidkaigi/confsched/testing/MiniRobots.kt +++ b/core/testing/src/main/java/io/github/droidkaigi/confsched/testing/MiniRobots.kt @@ -9,6 +9,7 @@ import io.github.droidkaigi.confsched.data.sessions.FakeSessionsApiClient import io.github.droidkaigi.confsched.data.sessions.SessionsApiClient import io.github.droidkaigi.confsched.testing.coroutines.runTestWithLogging import kotlinx.coroutines.test.TestDispatcher +import org.robolectric.RuntimeEnvironment import org.robolectric.shadows.ShadowLooper import javax.inject.Inject import kotlin.time.Duration.Companion.seconds @@ -95,6 +96,16 @@ class DefaultWaitRobot @Inject constructor( } } +interface FontScaleRobot { + fun setFontScale(fontScale: Float) +} + +class DefaultFontScaleRobot @Inject constructor() : FontScaleRobot { + override fun setFontScale(fontScale: Float) { + RuntimeEnvironment.setFontScale(fontScale) + } +} + interface TimetableServerRobot { enum class ServerStatus { Operational, diff --git a/core/testing/src/main/java/io/github/droidkaigi/confsched/testing/RobolectricDescribeSpecParameterBuilder.kt b/core/testing/src/main/java/io/github/droidkaigi/confsched/testing/RobolectricDescribeSpecParameterBuilder.kt index 27465fcb0..ce45cc71f 100644 --- a/core/testing/src/main/java/io/github/droidkaigi/confsched/testing/RobolectricDescribeSpecParameterBuilder.kt +++ b/core/testing/src/main/java/io/github/droidkaigi/confsched/testing/RobolectricDescribeSpecParameterBuilder.kt @@ -7,7 +7,7 @@ inline fun describeTests(block: TestCaseTreeBuilder.() -> Unit): return generateTestCases(root) } -fun DescribedTestCase.execute(robot: T) { +suspend fun DescribedTestCase.execute(robot: T) { for ((index, step) in steps.withIndex()) { println("Executing step: $index ($description)") when (step) { @@ -26,8 +26,8 @@ fun DescribedTestCase.execute(robot: T) { sealed class TestNode { data class Describe(val description: String, val children: List>) : TestNode() - data class Run(val action: T.() -> Unit) : TestNode() - data class Check(val description: String, val action: T.() -> Unit) : TestNode() + data class Run(val action: suspend T.() -> Unit) : TestNode() + data class Check(val description: String, val action: suspend T.() -> Unit) : TestNode() } data class DescribedTestCase( @@ -59,11 +59,11 @@ class TestCaseTreeBuilder { children.add(TestNode.Describe(description, builder.children)) } - fun run(action: T.() -> Unit) { + fun run(action: suspend T.() -> Unit) { children.add(TestNode.Run { action() }) } - fun check(description: String, action: T.() -> Unit) { + fun check(description: String, action: suspend T.() -> Unit) { children.add(TestNode.Check(description) { action() }) } diff --git a/core/testing/src/main/java/io/github/droidkaigi/confsched/testing/robot/TimetableItemDetailScreenRobot.kt b/core/testing/src/main/java/io/github/droidkaigi/confsched/testing/robot/TimetableItemDetailScreenRobot.kt index eb2aca09a..700066e7d 100644 --- a/core/testing/src/main/java/io/github/droidkaigi/confsched/testing/robot/TimetableItemDetailScreenRobot.kt +++ b/core/testing/src/main/java/io/github/droidkaigi/confsched/testing/robot/TimetableItemDetailScreenRobot.kt @@ -15,13 +15,21 @@ import io.github.droidkaigi.confsched.designsystem.theme.KaigiTheme import io.github.droidkaigi.confsched.sessions.TimetableItemDetailBookmarkIconTestTag import io.github.droidkaigi.confsched.sessions.TimetableItemDetailScreen import io.github.droidkaigi.confsched.sessions.timetableItemDetailScreenRoute +import io.github.droidkaigi.confsched.testing.DefaultFontScaleRobot import io.github.droidkaigi.confsched.testing.DefaultScreenRobot +import io.github.droidkaigi.confsched.testing.DefaultTimetableServerRobot +import io.github.droidkaigi.confsched.testing.FontScaleRobot import io.github.droidkaigi.confsched.testing.ScreenRobot +import io.github.droidkaigi.confsched.testing.TimetableServerRobot import javax.inject.Inject class TimetableItemDetailScreenRobot @Inject constructor( private val screenRobot: DefaultScreenRobot, -) : ScreenRobot by screenRobot { + private val timetableServerRobot: DefaultTimetableServerRobot, + private val fontScaleRobot: DefaultFontScaleRobot, +) : ScreenRobot by screenRobot, + TimetableServerRobot by timetableServerRobot, + FontScaleRobot by fontScaleRobot { suspend fun setupScreenContent() { val firstSessionId = SessionsAllResponse.Companion.fake().sessions.first().id diff --git a/feature/sessions/src/androidUnitTest/kotlin/io/github/droidkaigi/confsched/sessions/TimetableItemDetailScreenTest.kt b/feature/sessions/src/androidUnitTest/kotlin/io/github/droidkaigi/confsched/sessions/TimetableItemDetailScreenTest.kt index 63720a346..adb25c285 100644 --- a/feature/sessions/src/androidUnitTest/kotlin/io/github/droidkaigi/confsched/sessions/TimetableItemDetailScreenTest.kt +++ b/feature/sessions/src/androidUnitTest/kotlin/io/github/droidkaigi/confsched/sessions/TimetableItemDetailScreenTest.kt @@ -1,21 +1,24 @@ package io.github.droidkaigi.confsched.sessions import android.os.Bundle -import androidx.test.ext.junit.runners.AndroidJUnit4 import dagger.hilt.android.testing.BindValue import dagger.hilt.android.testing.HiltAndroidTest +import io.github.droidkaigi.confsched.testing.DescribedTestCase import io.github.droidkaigi.confsched.testing.RobotTestRule +import io.github.droidkaigi.confsched.testing.TimetableServerRobot.ServerStatus +import io.github.droidkaigi.confsched.testing.describeTests +import io.github.droidkaigi.confsched.testing.execute import io.github.droidkaigi.confsched.testing.robot.TimetableItemDetailScreenRobot import io.github.droidkaigi.confsched.testing.runRobot import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith -import org.robolectric.annotation.Config +import org.robolectric.ParameterizedRobolectricTestRunner import javax.inject.Inject -@RunWith(AndroidJUnit4::class) +@RunWith(ParameterizedRobolectricTestRunner::class) @HiltAndroidTest -class TimetableItemDetailScreenTest { +class TimetableItemDetailScreenTest(private val testCase: DescribedTestCase) { @get:Rule @BindValue val robotTestRule: RobotTestRule = RobotTestRule( @@ -34,67 +37,87 @@ class TimetableItemDetailScreenTest { @Test fun checkLaunchShot() { runRobot(timetableItemDetailScreenRobot) { - setupScreenContent() - checkScreenCapture() + testCase.execute(timetableItemDetailScreenRobot) } } - @Test - fun checkLaunchAccessibilityShot() { - runRobot(timetableItemDetailScreenRobot) { - setupScreenContent() - checkAccessibilityCapture() - } - } - - @Test - fun checkBookmarkToggleShot() { - runRobot(timetableItemDetailScreenRobot) { - setupScreenContent() - clickBookmarkButton() - checkScreenCapture() - } - } - - @Test - fun checkScrollShot() { - runRobot(timetableItemDetailScreenRobot) { - setupScreenContent() - scroll() - checkScreenCapture() - scroll() - checkScreenCapture() - scroll() - checkScreenCapture() - scroll() - checkScreenCapture() - } - } - - @Test - @Config(fontScale = 0.5f) - fun checkSmallFontScaleShot() { - runRobot(timetableItemDetailScreenRobot) { - setupScreenContent() - checkScreenCapture() - } - } - - @Test - @Config(fontScale = 1.5f) - fun checkLargeFontScaleShot() { - runRobot(timetableItemDetailScreenRobot) { - setupScreenContent() - checkScreenCapture() - } - } - - @Test - @Config(fontScale = 2.0f) - fun checkHugeFontScaleShot() { - runRobot(timetableItemDetailScreenRobot) { - setupScreenContent() - checkScreenCapture() + companion object { + @JvmStatic + @ParameterizedRobolectricTestRunner.Parameters(name = "{0}") + fun testCases(): List> { + return describeTests { + describe("when server is operational") { + run { + setupTimetableServer(ServerStatus.Operational) + } + describe("when launch") { + run { + setupScreenContent() + } + check("should show session detail title") { + // FIXME: Add check for session detail title + captureScreenWithChecks() + } + check("check accessibility") { + checkAccessibilityCapture() + } + describe("click bookmark button") { + run { + clickBookmarkButton() + } + check("should show bookmarked session") { + // FIXME: Add check for bookmarked session + captureScreenWithChecks() + } + describe("click bookmark button again") { + run { + clickBookmarkButton() + } + check("should show unbookmarked session") { + // FIXME: Add check for unbookmarked session + captureScreenWithChecks() + } + } + } + describe("scroll") { + run { + scroll() + } + check("should show scrolled session detail") { + // FIXME: Add check for scrolled session detail + captureScreenWithChecks() + } + } + } + describe("when font scale is small") { + run { + setFontScale(0.5f) + setupScreenContent() + } + check("should show session detail with small font scale") { + captureScreenWithChecks() + } + } + describe("when font scale is large") { + run { + setFontScale(1.5f) + setupScreenContent() + } + check("should show session detail with large font scale") { + captureScreenWithChecks() + } + } + describe("when font scale is huge") { + run { + setFontScale(2.0f) + setupScreenContent() + } + check("should show session detail with huge font scale") { + captureScreenWithChecks() + } + } + } + } } } }