From cc8ffc7693f197bd868202a5cc19ad9eaa576d4c Mon Sep 17 00:00:00 2001 From: ferPrieto Date: Fri, 26 Dec 2025 22:42:52 +0100 Subject: [PATCH 1/2] Added UI tests --- timelineview/build.gradle.kts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/timelineview/build.gradle.kts b/timelineview/build.gradle.kts index 6a23d1d..c20c951 100644 --- a/timelineview/build.gradle.kts +++ b/timelineview/build.gradle.kts @@ -68,6 +68,22 @@ dependencies { // Compose Debug Tools debugImplementation(libs.compose.ui.tooling) debugImplementation(libs.compose.ui.test.manifest) + + // Testing Dependencies + testImplementation("junit:junit:4.13.2") + testImplementation("org.jetbrains.kotlin:kotlin-test") + + // Android Instrumented Testing + androidTestImplementation("androidx.test.ext:junit:1.1.5") + androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1") + androidTestImplementation(platform(libs.compose.bom)) + androidTestImplementation("androidx.compose.ui:ui-test-junit4") + debugImplementation("androidx.compose.ui:ui-test-manifest") + + // Compose Testing + androidTestImplementation("androidx.compose.ui:ui-test") + androidTestImplementation("androidx.test:rules:1.5.0") + androidTestImplementation("androidx.test:runner:1.5.2") } // Force resolution of compatible AndroidX versions From d23e8c828ae58764d7c8c372493dca6800340e2c Mon Sep 17 00:00:00 2001 From: ferPrieto Date: Fri, 26 Dec 2025 22:43:00 +0100 Subject: [PATCH 2/2] Added UI tests --- .../timelineview/ComposeTimelineViewTest.kt | 221 ++++++++++++++++++ 1 file changed, 221 insertions(+) create mode 100644 timelineview/src/androidTest/kotlin/ferprieto/timelineview/ComposeTimelineViewTest.kt diff --git a/timelineview/src/androidTest/kotlin/ferprieto/timelineview/ComposeTimelineViewTest.kt b/timelineview/src/androidTest/kotlin/ferprieto/timelineview/ComposeTimelineViewTest.kt new file mode 100644 index 0000000..e5a7118 --- /dev/null +++ b/timelineview/src/androidTest/kotlin/ferprieto/timelineview/ComposeTimelineViewTest.kt @@ -0,0 +1,221 @@ +package ferprieto.timelineview + +import androidx.compose.ui.test.* +import androidx.compose.ui.test.junit4.createComposeRule +import androidx.compose.ui.unit.dp +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.github.ferprieto.timelineview.R +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith + +/** + * Instrumented tests for ComposeTimelineView composable + * Tests the behavior of the synchronized dual-view timeline component + */ +@RunWith(AndroidJUnit4::class) +class ComposeTimelineViewTest { + + @get:Rule + val composeTestRule = createComposeRule() + + @Test + fun composeTimelineView_isDisplayed() { + // Given + composeTestRule.setContent { + ComposeTimelineView() + } + + // Then + composeTestRule.onNodeWithContentDescription("Past timeline content") + .assertExists() + .assertIsDisplayed() + + composeTestRule.onNodeWithContentDescription("Future timeline content") + .assertExists() + .assertIsDisplayed() + } + + @Test + fun composeTimelineView_withCustomHeight_appliesHeightCorrectly() { + // Given + val customHeight = 200.dp + + composeTestRule.setContent { + ComposeTimelineView(height = customHeight) + } + + // Then + composeTestRule.onNodeWithContentDescription("Past timeline content") + .assertExists() + .assertIsDisplayed() + + composeTestRule.onNodeWithContentDescription("Future timeline content") + .assertExists() + .assertIsDisplayed() + } + + @Test + fun composeTimelineView_withCustomPastContent_usesCorrectDrawable() { + // Given + composeTestRule.setContent { + ComposeTimelineView( + pastContent = R.drawable.soundwave_first_default_1 + ) + } + + // Then + composeTestRule.onNodeWithContentDescription("Past timeline content") + .assertExists() + .assertIsDisplayed() + } + + @Test + fun composeTimelineView_withCustomFutureContent_usesCorrectDrawable() { + // Given + composeTestRule.setContent { + ComposeTimelineView( + futureContent = R.drawable.soundwave_second_default_1 + ) + } + + // Then + composeTestRule.onNodeWithContentDescription("Future timeline content") + .assertExists() + .assertIsDisplayed() + } + + @Test + fun composeTimelineView_withAllCustomParameters_displaysCorrectly() { + // Given + composeTestRule.setContent { + ComposeTimelineView( + height = 150.dp, + pastContent = R.drawable.soundwave_first_default_2, + futureContent = R.drawable.soundwave_second_default_2 + ) + } + + // Then + composeTestRule.onNodeWithContentDescription("Past timeline content") + .assertExists() + .assertIsDisplayed() + + composeTestRule.onNodeWithContentDescription("Future timeline content") + .assertExists() + .assertIsDisplayed() + } + + @Test + fun composeTimelineView_hasBothScrollableAreas() { + // Given + composeTestRule.setContent { + ComposeTimelineView() + } + + // Then + composeTestRule.onNodeWithContentDescription("Past timeline content") + .assertExists() + + composeTestRule.onNodeWithContentDescription("Future timeline content") + .assertExists() + } + + @Test + fun composeTimelineViewAdvanced_withCustomDividerColor_isDisplayed() { + // Given + composeTestRule.setContent { + ComposeTimelineViewAdvanced( + dividerColor = androidx.compose.ui.graphics.Color.Red + ) + } + + // Then + composeTestRule.onNodeWithContentDescription("Past timeline content") + .assertExists() + .assertIsDisplayed() + + composeTestRule.onNodeWithContentDescription("Future timeline content") + .assertExists() + .assertIsDisplayed() + } + + @Test + fun composeTimelineViewAdvanced_withCustomDividerWidth_isDisplayed() { + // Given + composeTestRule.setContent { + ComposeTimelineViewAdvanced( + dividerWidth = 4.dp + ) + } + + // Then + composeTestRule.onNodeWithContentDescription("Past timeline content") + .assertExists() + + composeTestRule.onNodeWithContentDescription("Future timeline content") + .assertExists() + } + + @Test + fun composeTimelineViewAdvanced_withCustomOffsetFraction_isDisplayed() { + // Given + composeTestRule.setContent { + ComposeTimelineViewAdvanced( + offsetFraction = 1f/8f + ) + } + + // Then + composeTestRule.onNodeWithContentDescription("Past timeline content") + .assertExists() + .assertIsDisplayed() + + composeTestRule.onNodeWithContentDescription("Future timeline content") + .assertExists() + .assertIsDisplayed() + } + + @Test + fun composeTimelineViewAdvanced_withAllCustomParameters_displaysCorrectly() { + // Given + composeTestRule.setContent { + ComposeTimelineViewAdvanced( + height = 180.dp, + pastContent = R.drawable.soundwave_first_default_1, + futureContent = R.drawable.soundwave_second_default_1, + offsetFraction = 1f/10f, + dividerWidth = 3.dp, + dividerColor = androidx.compose.ui.graphics.Color.Blue, + paddingExtra = 4.dp + ) + } + + // Then + composeTestRule.onNodeWithContentDescription("Past timeline content") + .assertExists() + .assertIsDisplayed() + + composeTestRule.onNodeWithContentDescription("Future timeline content") + .assertExists() + .assertIsDisplayed() + } + + @Test + fun composeTimelineView_defaultDrawables_areDisplayed() { + // Given + composeTestRule.setContent { + ComposeTimelineView() + } + + // Then + composeTestRule.onNodeWithContentDescription("Past timeline content") + .assertExists() + .assertIsDisplayed() + + composeTestRule.onNodeWithContentDescription("Future timeline content") + .assertExists() + .assertIsDisplayed() + } +} +