diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 85ecd6d..fef0ddb 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -160,6 +160,7 @@ dependencies { implementation(libs.accompanist) + implementation(libs.androidx.glance.testing) implementation(libs.androidx.glance.appwidget) testImplementation(libs.androidx.glance.appwidget.testing) implementation(libs.androidx.glance.material3) diff --git a/app/src/main/java/dev/aungkyawpaing/ccdroidx/feature/widget/DashboardWidget.kt b/app/src/main/java/dev/aungkyawpaing/ccdroidx/feature/widget/DashboardWidget.kt index e2918eb..921431d 100644 --- a/app/src/main/java/dev/aungkyawpaing/ccdroidx/feature/widget/DashboardWidget.kt +++ b/app/src/main/java/dev/aungkyawpaing/ccdroidx/feature/widget/DashboardWidget.kt @@ -36,6 +36,8 @@ import androidx.glance.layout.fillMaxWidth import androidx.glance.layout.height import androidx.glance.layout.padding import androidx.glance.layout.size +import androidx.glance.semantics.semantics +import androidx.glance.semantics.testTag import androidx.glance.text.FontWeight import androidx.glance.text.Text import androidx.glance.text.TextStyle @@ -65,7 +67,7 @@ class DashboardWidget( } @Composable -private fun DashboardWidgetContent(failingProjects: List) { +fun DashboardWidgetContent(failingProjects: List) { val context = LocalContext.current GlanceTheme { @@ -121,6 +123,9 @@ private fun DashboardWidgetContent(failingProjects: List) { ) ) ) + .semantics { + this.testTag = "Project ${project.id} - row" + } ) { Text( text = project.name, diff --git a/app/src/test/java/dev/aungkyawpaing/ccdroidx/feature/widget/DashboardWidgetTest.kt b/app/src/test/java/dev/aungkyawpaing/ccdroidx/feature/widget/DashboardWidgetTest.kt new file mode 100644 index 0000000..179bcd8 --- /dev/null +++ b/app/src/test/java/dev/aungkyawpaing/ccdroidx/feature/widget/DashboardWidgetTest.kt @@ -0,0 +1,65 @@ +package dev.aungkyawpaing.ccdroidx.feature.widget + +import androidx.compose.ui.unit.DpSize +import androidx.compose.ui.unit.dp +import androidx.glance.action.ActionParameters +import androidx.glance.action.actionParametersOf +import androidx.glance.appwidget.testing.unit.assertHasRunCallbackClickAction +import androidx.glance.appwidget.testing.unit.runGlanceAppWidgetUnitTest +import androidx.glance.testing.unit.assertHasStartActivityClickAction +import androidx.glance.testing.unit.hasContentDescription +import androidx.glance.testing.unit.hasTestTag +import androidx.glance.testing.unit.hasText +import androidx.test.core.app.ApplicationProvider +import androidx.test.ext.junit.runners.AndroidJUnit4 +import dev.aungkyawpaing.ccdroidx._testhelper_.ProjectBuilder +import dev.aungkyawpaing.ccdroidx.feature.MainActivity +import org.junit.Test +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4::class) +class DashboardWidgetTest { + + @Test + fun renderWithSomeFailingProjects() = runGlanceAppWidgetUnitTest { + setAppWidgetSize(DpSize(100.dp, 150.dp)) + setContext(ApplicationProvider.getApplicationContext()) + + val failingProjects = listOf( + ProjectBuilder.buildProject(id = 0L, name = "some project 0", webUrl = "some-url-0"), + ProjectBuilder.buildProject(id = 1L, name = "some project 1", webUrl = "some-url-1"), + ) + + provideComposable { + DashboardWidgetContent(failingProjects = failingProjects) + } + + onNode(hasText("2 Red")).assertExists() + onNode(hasText("some project 0")).assertExists() + onNode(hasTestTag("Project 0 - row")).assertHasStartActivityClickAction( + actionParametersOf( + ActionParameters.Key(MainActivity.INTENT_EXTRA_URL) to "some-url-0" + ) + ) + onNode(hasText("some project 1")).assertExists() + onNode(hasTestTag("Project 1 - row")).assertHasStartActivityClickAction( + actionParametersOf( + ActionParameters.Key(MainActivity.INTENT_EXTRA_URL) to "some-url-1" + ) + ) + onNode(hasContentDescription("Sync Project Status")).assertHasRunCallbackClickAction() + } + + @Test + fun renderWithNoFailingProjects() = runGlanceAppWidgetUnitTest { + setAppWidgetSize(DpSize(100.dp, 150.dp)) + setContext(ApplicationProvider.getApplicationContext()) + + provideComposable { + DashboardWidgetContent(failingProjects = emptyList()) + } + + onNode(hasText("All Green")).assertExists() + onNode(hasContentDescription("Sync Project Status")).assertHasRunCallbackClickAction() + } +} \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 4f0437d..0847abe 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -45,6 +45,7 @@ androidx-fragment = { group = "androidx.fragment", name = "fragment-ktx", versio androidx-fragment-testing = { group = "androidx.fragment", name = "fragment-testing", version.ref = "androidx-fragment" } androidx-glance-appwidget = { group = "androidx.glance", name = "glance-appwidget", version.ref = "glance" } androidx-glance-appwidget-testing = { group = "androidx.glance", name = "glance-appwidget-testing", version.ref = "glance" } +androidx-glance-testing = { group = "androidx.glance", name = "glance-testing", version.ref = "glance" } androidx-glance-material3 = { group = "androidx.glance", name = "glance-material3", version.ref = "glance" } androidx-lifecycle-extensions = { group = "androidx.lifecycle", name = "lifecycle-extensions", version = "2.2.0" } androidx-lifecycle-java8 = { group = "androidx.lifecycle", name = "lifecycle-common-java8", version.ref = "androidx-lifecycle" }