From d15ce97e36d43badb6b77d4de9ef2e1e2beeb821 Mon Sep 17 00:00:00 2001 From: Chiara Chiappini Date: Mon, 1 Dec 2025 11:43:47 +0000 Subject: [PATCH 1/2] Add snippet for screenshot test --- build.gradle.kts | 1 + gradle/libs.versions.toml | 20 +++++--- wear/build.gradle.kts | 41 ++++++++++++---- .../example/wear/snippets/m3/list/ListTest.kt | 47 +++++++++++++++++++ 4 files changed, 94 insertions(+), 15 deletions(-) create mode 100644 wear/src/test/java/com/example/wear/snippets/m3/list/ListTest.kt diff --git a/build.gradle.kts b/build.gradle.kts index d4ea18313..329e4488f 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -14,6 +14,7 @@ plugins { alias(libs.plugins.android.kotlin.multiplatform.library) apply false alias(libs.plugins.android.lint) apply false alias(libs.plugins.spotless) apply false + alias(libs.plugins.roborazzi) apply false } allprojects { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 40c26140b..3c6c3dacb 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -5,7 +5,7 @@ android-googleid = "1.1.1" androidGradlePlugin = "8.13.0" androidx-activity-compose = "1.11.0" androidx-appcompat = "1.7.0" -androidx-compose-bom = "2025.10.01" +androidx-compose-bom = "2025.11.01" androidx-compose-ui-test = "1.7.0-alpha08" androidx-compose-ui-test-junit4-accessibility = "1.10.0-beta01" androidx-constraintlayout = "2.2.1" @@ -37,8 +37,8 @@ appcompat = "1.7.1" coil = "2.7.0" # @keep compileSdk = "36" -compose-latest = "1.9.4" -composeUiTooling = "1.5.4" +compose-latest = "1.9.5" +composeUiTooling = "1.5.5" coreSplashscreen = "1.2.0" coroutines = "1.10.2" dataStore = "1.1.7" @@ -76,6 +76,8 @@ protoc = "0.9.5" protolayout = "1.3.0" reactive-streams = "1.0.4" recyclerview = "1.4.0" +robolectric = "4.16" +roborazzi = "1.52.0" spotless = "8.0.0" targetSdk = "36" tiles = "1.5.0" @@ -84,9 +86,9 @@ validatorPush = "1.0.0-alpha08" version-catalog-update = "1.0.1" watchfaceComplicationsDataSourceKtx = "1.2.1" wear = "1.3.0" -wearComposeFoundation = "1.5.4" -wearComposeMaterial = "1.5.4" -wearComposeMaterial3 = "1.5.4" +wearComposeFoundation = "1.5.5" +wearComposeMaterial = "1.5.5" +wearComposeMaterial3 = "1.5.5" wearInput = "1.2.0" wearOngoing = "1.1.0" wearToolingPreview = "1.0.0" @@ -209,6 +211,11 @@ hilt-android = { module = "com.google.dagger:hilt-android", version.ref = "hilt" hilt-compiler = { module = "com.google.dagger:hilt-android-compiler", version.ref = "hilt" } horologist-compose-layout = { module = "com.google.android.horologist:horologist-compose-layout", version.ref = "horologist" } horologist-compose-material = { module = "com.google.android.horologist:horologist-compose-material", version.ref = "horologist" } +horologist-roboscreenshots = { module = "com.google.android.horologist:horologist-roboscreenshots", version.ref = "horologist" } +robolectric = { module = "org.robolectric:robolectric", version.ref = "robolectric" } +roborazzi = { group = "io.github.takahirom.roborazzi", name = "roborazzi", version.ref = "roborazzi" } +roborazzi-compose = { group = "io.github.takahirom.roborazzi", name = "roborazzi-compose", version.ref = "roborazzi" } +roborazzi-rule = { group = "io.github.takahirom.roborazzi", name = "roborazzi-junit-rule", version.ref = "roborazzi" } jetbrains-kotlin-stdlib = { module = "org.jetbrains.kotlin:kotlin-stdlib", version.ref = "kotlin" } junit = { module = "junit:junit", version.ref = "junit" } kotlin-coroutines-okhttp = { module = "ru.gildor.coroutines:kotlin-coroutines-okhttp", version.ref = "kotlinCoroutinesOkhttp" } @@ -239,5 +246,6 @@ kotlin-multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref kotlin-parcelize = { id = "org.jetbrains.kotlin.plugin.parcelize", version.ref = "kotlin" } kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" } ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" } +roborazzi = { id = "io.github.takahirom.roborazzi", version.ref = "roborazzi" } spotless = { id = "com.diffplug.spotless", version.ref = "spotless" } version-catalog-update = { id = "nl.littlerobots.version-catalog-update", version.ref = "version-catalog-update" } diff --git a/wear/build.gradle.kts b/wear/build.gradle.kts index 68d64d8dd..23efcf637 100644 --- a/wear/build.gradle.kts +++ b/wear/build.gradle.kts @@ -1,7 +1,10 @@ +import org.gradle.internal.classpath.Instrumented.systemProperty + plugins { alias(libs.plugins.android.application) alias(libs.plugins.kotlin.android) alias(libs.plugins.compose.compiler) + alias(libs.plugins.roborazzi) } android { @@ -30,11 +33,11 @@ android { } } compileOptions { - sourceCompatibility = JavaVersion.VERSION_17 - targetCompatibility = JavaVersion.VERSION_17 + sourceCompatibility = JavaVersion.VERSION_21 + targetCompatibility = JavaVersion.VERSION_21 } kotlin { - jvmToolchain(17) + jvmToolchain(21) } buildFeatures { @@ -47,7 +50,13 @@ android { } } kotlinOptions { - jvmTarget = "17" + jvmTarget = "21" + } + + testOptions { + unitTests { + isIncludeAndroidResources = true + } } } @@ -89,17 +98,31 @@ dependencies { implementation(libs.horologist.compose.material) implementation(libs.androidx.material.icons.core) implementation(libs.androidx.watchface.complications.data.source.ktx) + implementation(libs.androidx.compose.ui.test.manifest) - androidTestImplementation(libs.androidx.compose.ui.test.junit4) - debugImplementation(libs.androidx.compose.ui.tooling) - debugImplementation(libs.androidx.compose.ui.tooling.preview) - debugImplementation(libs.androidx.compose.ui.test.manifest) + // Testing + testImplementation(libs.androidx.compose.ui.test.junit4) testImplementation(libs.junit) + testImplementation(libs.robolectric) + testImplementation(libs.roborazzi) + testImplementation(libs.roborazzi.compose) + testImplementation(libs.roborazzi.rule) + testImplementation(libs.horologist.roboscreenshots) + testImplementation(libs.androidx.test.core) + testImplementation(libs.androidx.test.runner) + testImplementation(libs.androidx.compose.ui.test.manifest) androidTestImplementation(libs.junit) androidTestImplementation(libs.androidx.test.core) androidTestImplementation(libs.androidx.test.runner) androidTestImplementation(libs.androidx.test.espresso.core) + androidTestImplementation(libs.androidx.compose.ui.test.junit4) androidTestImplementation(libs.androidx.compose.ui.test) + androidTestImplementation(libs.androidx.compose.ui.test.manifest) + + debugImplementation(composeBom) debugImplementation(libs.androidx.compose.ui.tooling) -} + debugImplementation(libs.androidx.compose.ui.tooling.preview) + debugImplementation(libs.androidx.compose.ui.test.manifest) + +} \ No newline at end of file diff --git a/wear/src/test/java/com/example/wear/snippets/m3/list/ListTest.kt b/wear/src/test/java/com/example/wear/snippets/m3/list/ListTest.kt new file mode 100644 index 000000000..20b906a25 --- /dev/null +++ b/wear/src/test/java/com/example/wear/snippets/m3/list/ListTest.kt @@ -0,0 +1,47 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.wear.snippets.m3.list + +import com.google.android.horologist.compose.layout.AppScaffold +import com.google.android.horologist.screenshots.rng.WearDevice +import com.google.android.horologist.screenshots.rng.WearScreenshotTest +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.ParameterizedRobolectricTestRunner + +// [START android_wear_screenshot_test] +@RunWith(ParameterizedRobolectricTestRunner::class) +class ComposeListScreenTest( + override val device: WearDevice +) : WearScreenshotTest() { + override val tolerance = 0.02f + + @Test + fun myScreenTest() = + runTest { + AppScaffold{ + ComposeList() + } + } + + companion object { + @JvmStatic + @ParameterizedRobolectricTestRunner.Parameters + fun devices() = WearDevice.entries + } +} +// [END android_wear_screenshot_test] From dd73e46a04aefbb6d5382ba441a3a20147a07b4a Mon Sep 17 00:00:00 2001 From: kul3r4 <820891+kul3r4@users.noreply.github.com> Date: Mon, 1 Dec 2025 15:29:12 +0000 Subject: [PATCH 2/2] Apply Spotless --- .../src/test/java/com/example/wear/snippets/m3/list/ListTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wear/src/test/java/com/example/wear/snippets/m3/list/ListTest.kt b/wear/src/test/java/com/example/wear/snippets/m3/list/ListTest.kt index 20b906a25..03f58b243 100644 --- a/wear/src/test/java/com/example/wear/snippets/m3/list/ListTest.kt +++ b/wear/src/test/java/com/example/wear/snippets/m3/list/ListTest.kt @@ -33,7 +33,7 @@ class ComposeListScreenTest( @Test fun myScreenTest() = runTest { - AppScaffold{ + AppScaffold { ComposeList() } }