From 44d08c294344fea48e99f3355be003e410cf552a Mon Sep 17 00:00:00 2001 From: Adam McNeilly Date: Sun, 4 May 2025 09:37:54 -0400 Subject: [PATCH] Adding base paparazzi test for #232 and workflow for #250. --- .github/workflows/paparazzi_tests.yml | 21 ++++++++ app/build.gradle.kts | 1 + .../test/java/template/BasePaparazziTest.kt | 54 +++++++++++++++++++ buildscripts/setup.gradle | 7 +-- gradle/libs.versions.toml | 2 + 5 files changed, 79 insertions(+), 6 deletions(-) create mode 100644 .github/workflows/paparazzi_tests.yml create mode 100644 app/src/test/java/template/BasePaparazziTest.kt diff --git a/.github/workflows/paparazzi_tests.yml b/.github/workflows/paparazzi_tests.yml new file mode 100644 index 00000000..5777c19f --- /dev/null +++ b/.github/workflows/paparazzi_tests.yml @@ -0,0 +1,21 @@ +name: Paparazzi Tests + +# This will cancel any in progress workflows for the same PR, if +# multiple pushes happen in quick succession. +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +on: pull_request + +jobs: + paparazzi-tests: + runs-on: macos-14 + steps: + - uses: actions/checkout@v4 + + - name: Setup + uses: ./.github/actions/workflow_setup + + - name: Run Tests + run: ./gradlew verifyPaparazziDebug \ No newline at end of file diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 71443145..5df505a7 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -79,6 +79,7 @@ dependencies { annotationProcessor(libs.androidx.room.compiler) + testImplementation(libs.google.testparameterinjector) testImplementation(libs.junit) androidTestImplementation(platform(libs.compose.bom)) diff --git a/app/src/test/java/template/BasePaparazziTest.kt b/app/src/test/java/template/BasePaparazziTest.kt new file mode 100644 index 00000000..a6036986 --- /dev/null +++ b/app/src/test/java/template/BasePaparazziTest.kt @@ -0,0 +1,54 @@ +package template + +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Surface +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import app.cash.paparazzi.Paparazzi +import com.google.testing.junit.testparameterinjector.TestParameter +import com.google.testing.junit.testparameterinjector.TestParameterInjector +import org.junit.Rule +import org.junit.runner.RunWith +import template.theme.TemplateTheme + +/** + * This base class allows us to write Paparazzi tests that validate composable content in both light and dark theme + * using a parameterized test. Just extend this base class and call [snapshot] with your composable content. + */ +@RunWith(TestParameterInjector::class) +abstract class BasePaparazziTest { + @get:Rule + @Suppress("ktlint:standard:backing-property-naming", "VariableNaming") + val _paparazzi = Paparazzi() + + @TestParameter + val useDarkTheme: Boolean = false + + /** + * Validates the supplied [content] in both light and dark theme. + */ + fun snapshot( + screenPaddingDp: Int = 16, + content: @Composable () -> Unit, + ) { + _paparazzi.snapshot { + TemplateTheme { + Surface( + modifier = Modifier + .fillMaxSize(), + ) { + Box( + modifier = Modifier + .fillMaxSize() + .padding(screenPaddingDp.dp), + ) { + content() + } + } + } + } + } +} diff --git a/buildscripts/setup.gradle b/buildscripts/setup.gradle index 084c8a49..df40dc74 100644 --- a/buildscripts/setup.gradle +++ b/buildscripts/setup.gradle @@ -32,7 +32,6 @@ task deleteSetupCode() { delete(setupGradle) if (renameConfig.useRenovateDependencies != true) { - println("Removing renovate dependencies") delete(renovateFile) } } @@ -156,29 +155,25 @@ task keepOrRemoveDependencies { filesWithDependencies.each { fileName -> if (renameConfig.useHiltDependencies != true) { - println("Removing hilt dependencies") removeTextFromFile(fileName, "hilt") removeTextFromFile(fileName, "Hilt") } if (renameConfig.useRoomDependencies != true) { - println("Removing room dependencies") removeTextFromFile(fileName, "room") } if (renameConfig.useRetrofitDependencies != true) { - println("Removing retrofit dependencies") removeTextFromFile(fileName, "retrofit") removeTextFromFile(fileName, "moshi") } if (renameConfig.usePaparazziDependencies != true) { - println("Removing paparazzi dependencies") removeTextFromFile(fileName, "paparazzi") + delete("${rootDir}/.github/workflows/paparazzi_tests.yml") } if (renameConfig.useAndroidXR != true) { - println("Removing xr dependencies") removeTextFromFile(fileName, "xr") } } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index b7522c8c..18398d01 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -24,6 +24,7 @@ paparazzi = "1.3.5" retrofit = "2.11.0" room = "2.7.1" sortDependencies = "0.14" +testParameterInjector = "1.18" xr = "1.0.0-alpha03" xr-material = "1.0.0-alpha06" @@ -50,6 +51,7 @@ compose-ui-test-junit = { group = "androidx.compose.ui", name = "ui-test-junit4" compose-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" } compose-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" } detekt-gradle-plugin = { module = "io.gitlab.arturbosch.detekt:detekt-gradle-plugin", version.ref = "detektGradlePlugin" } +google-testparameterinjector = { module = "com.google.testparameterinjector:test-parameter-injector", version.ref = "testParameterInjector" } gradle = { module = "com.android.tools.build:gradle", version.ref = "agp" } gradle-versions-plugin = { module = "com.github.ben-manes:gradle-versions-plugin", version.ref = "gradleVersionsPlugin" } hilt-android = { module = "com.google.dagger:hilt-android", version.ref = "hilt" }