diff --git a/.gitattributes b/.gitattributes
index 47f6d98b40..91a089d3fc 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1 +1,2 @@
*.ai binary
+**/src/screenshotTest*/reference/**/*.png filter=lfs diff=lfs merge=lfs -text
diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml
index a9fd7338bb..38079e6552 100644
--- a/.github/workflows/android.yml
+++ b/.github/workflows/android.yml
@@ -20,6 +20,7 @@ jobs:
# gh api repos/actions/checkout/commits/v6 --jq '.sha'
with:
submodules: true
+ lfs: true
- name: set up JDK 17
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5
diff --git a/build.gradle.kts b/build.gradle.kts
index 87b6da70ac..43391554cf 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -112,6 +112,7 @@ gradle.projectsEvaluated {
testTask?.let { dependsOn(it) }
subproject.tasks.findByName("lintDebug")?.let { dependsOn(it) }
+ subproject.tasks.findByName("validateDebugScreenshotTest")?.let { dependsOn(it) }
}
}
diff --git a/core/ui/src/main/java/org/signal/core/ui/compose/SignalPreviews.kt b/core/ui/src/main/java/org/signal/core/ui/compose/SignalPreviews.kt
index 40779b57f8..d78deb51ad 100644
--- a/core/ui/src/main/java/org/signal/core/ui/compose/SignalPreviews.kt
+++ b/core/ui/src/main/java/org/signal/core/ui/compose/SignalPreviews.kt
@@ -126,5 +126,8 @@ annotation class AllNightPreviews
@TabletPreviews
annotation class AllDevicePreviews
+@Preview(name = "rtl", locale = "ar")
+annotation class RtlPreview
+
@Preview(name = "large font", fontScale = 2f)
annotation class LargeFontPreviews
diff --git a/feature/registration/build.gradle.kts b/feature/registration/build.gradle.kts
index c7ef78ec8e..e33afea987 100644
--- a/feature/registration/build.gradle.kts
+++ b/feature/registration/build.gradle.kts
@@ -4,6 +4,7 @@ plugins {
id("com.squareup.wire")
alias(libs.plugins.compose.compiler)
alias(libs.plugins.kotlinx.serialization)
+ alias(testLibs.plugins.compose.screenshot)
}
android {
@@ -23,6 +24,8 @@ android {
isIncludeAndroidResources = true
}
}
+
+ experimentalProperties["android.experimental.enableScreenshotTest"] = true
}
wire {
@@ -87,4 +90,9 @@ dependencies {
androidTestImplementation(testLibs.androidx.test.ext.junit)
androidTestImplementation(libs.androidx.compose.ui.test.junit4)
debugImplementation(libs.androidx.compose.ui.test.manifest)
+
+ // Compose screenshot testing
+ screenshotTestImplementation(testLibs.compose.screenshot.validation.api)
+ screenshotTestImplementation(libs.androidx.compose.ui.tooling.core)
+ screenshotTestImplementation(libs.androidx.compose.ui.tooling.preview)
}
diff --git a/feature/registration/src/screenshotTest/kotlin/org/signal/registration/screens/welcome/WelcomeScreenScreenshotTests.kt b/feature/registration/src/screenshotTest/kotlin/org/signal/registration/screens/welcome/WelcomeScreenScreenshotTests.kt
new file mode 100644
index 0000000000..2d40e6c370
--- /dev/null
+++ b/feature/registration/src/screenshotTest/kotlin/org/signal/registration/screens/welcome/WelcomeScreenScreenshotTests.kt
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2026 Signal Messenger, LLC
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+package org.signal.registration.screens.welcome
+
+import androidx.compose.runtime.Composable
+import com.android.tools.screenshot.PreviewTest
+import org.signal.core.ui.compose.AllDevicePreviews
+import org.signal.core.ui.compose.Previews
+import org.signal.core.ui.compose.RtlPreview
+
+class WelcomeScreenScreenshotTests {
+ @PreviewTest
+ @AllDevicePreviews
+ @RtlPreview
+ @Composable
+ fun WelcomeScreenPhonePreview() {
+ Previews.Preview {
+ WelcomeScreen(onEvent = {})
+ }
+ }
+}
diff --git a/feature/registration/src/screenshotTestDebug/reference/org/signal/registration/screens/welcome/WelcomeScreenScreenshotTests/WelcomeScreenPhonePreview_foldable landscape (day)_41c0d57c_0.png b/feature/registration/src/screenshotTestDebug/reference/org/signal/registration/screens/welcome/WelcomeScreenScreenshotTests/WelcomeScreenPhonePreview_foldable landscape (day)_41c0d57c_0.png
new file mode 100644
index 0000000000..34058c1eeb
--- /dev/null
+++ b/feature/registration/src/screenshotTestDebug/reference/org/signal/registration/screens/welcome/WelcomeScreenScreenshotTests/WelcomeScreenPhonePreview_foldable landscape (day)_41c0d57c_0.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:ca027a262cd5878c40e4abd08f966c0ee6bf8f02eeef787f9832e6b9235a5d37
+size 279488
diff --git a/feature/registration/src/screenshotTestDebug/reference/org/signal/registration/screens/welcome/WelcomeScreenScreenshotTests/WelcomeScreenPhonePreview_foldable landscape (night)_9dae7e43_0.png b/feature/registration/src/screenshotTestDebug/reference/org/signal/registration/screens/welcome/WelcomeScreenScreenshotTests/WelcomeScreenPhonePreview_foldable landscape (night)_9dae7e43_0.png
new file mode 100644
index 0000000000..8b6b518f0a
--- /dev/null
+++ b/feature/registration/src/screenshotTestDebug/reference/org/signal/registration/screens/welcome/WelcomeScreenScreenshotTests/WelcomeScreenPhonePreview_foldable landscape (night)_9dae7e43_0.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:6df52102839dd5fff99d087b01b3f59e4bb7ecf4b7cfc97f28e33075b667ab26
+size 253635
diff --git a/feature/registration/src/screenshotTestDebug/reference/org/signal/registration/screens/welcome/WelcomeScreenScreenshotTests/WelcomeScreenPhonePreview_foldable portrait (day)_bf09cc79_0.png b/feature/registration/src/screenshotTestDebug/reference/org/signal/registration/screens/welcome/WelcomeScreenScreenshotTests/WelcomeScreenPhonePreview_foldable portrait (day)_bf09cc79_0.png
new file mode 100644
index 0000000000..1af71d3e82
--- /dev/null
+++ b/feature/registration/src/screenshotTestDebug/reference/org/signal/registration/screens/welcome/WelcomeScreenScreenshotTests/WelcomeScreenPhonePreview_foldable portrait (day)_bf09cc79_0.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:3af78bd0c9865d3788e824d9075b9d285dc5b721375688a06a5927d1561eff5e
+size 265333
diff --git a/feature/registration/src/screenshotTestDebug/reference/org/signal/registration/screens/welcome/WelcomeScreenScreenshotTests/WelcomeScreenPhonePreview_phone landscape (day)_38357cfa_0.png b/feature/registration/src/screenshotTestDebug/reference/org/signal/registration/screens/welcome/WelcomeScreenScreenshotTests/WelcomeScreenPhonePreview_phone landscape (day)_38357cfa_0.png
new file mode 100644
index 0000000000..b8c342aa8c
--- /dev/null
+++ b/feature/registration/src/screenshotTestDebug/reference/org/signal/registration/screens/welcome/WelcomeScreenScreenshotTests/WelcomeScreenPhonePreview_phone landscape (day)_38357cfa_0.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:df11120f19a776083bf04a1e2c554d15bea2c063442b8f36b54418e4d45c3792
+size 52776
diff --git a/feature/registration/src/screenshotTestDebug/reference/org/signal/registration/screens/welcome/WelcomeScreenScreenshotTests/WelcomeScreenPhonePreview_phone landscape (night)_2eebbf71_0.png b/feature/registration/src/screenshotTestDebug/reference/org/signal/registration/screens/welcome/WelcomeScreenScreenshotTests/WelcomeScreenPhonePreview_phone landscape (night)_2eebbf71_0.png
new file mode 100644
index 0000000000..587f87ff60
--- /dev/null
+++ b/feature/registration/src/screenshotTestDebug/reference/org/signal/registration/screens/welcome/WelcomeScreenScreenshotTests/WelcomeScreenPhonePreview_phone landscape (night)_2eebbf71_0.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:69b8cc1d72e240f18432b18801eaf7a095c4ace4465884b343ce2aa7332984ac
+size 53085
diff --git a/feature/registration/src/screenshotTestDebug/reference/org/signal/registration/screens/welcome/WelcomeScreenScreenshotTests/WelcomeScreenPhonePreview_phone portrait (day)_1526b652_0.png b/feature/registration/src/screenshotTestDebug/reference/org/signal/registration/screens/welcome/WelcomeScreenScreenshotTests/WelcomeScreenPhonePreview_phone portrait (day)_1526b652_0.png
new file mode 100644
index 0000000000..d962ae0eac
--- /dev/null
+++ b/feature/registration/src/screenshotTestDebug/reference/org/signal/registration/screens/welcome/WelcomeScreenScreenshotTests/WelcomeScreenPhonePreview_phone portrait (day)_1526b652_0.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:f28158d9ed0aca0f8d2a8279afd4add681d531d2541f4b013e32f5572c1f88e4
+size 101519
diff --git a/feature/registration/src/screenshotTestDebug/reference/org/signal/registration/screens/welcome/WelcomeScreenScreenshotTests/WelcomeScreenPhonePreview_rtl_5cbb5cfd_0.png b/feature/registration/src/screenshotTestDebug/reference/org/signal/registration/screens/welcome/WelcomeScreenScreenshotTests/WelcomeScreenPhonePreview_rtl_5cbb5cfd_0.png
new file mode 100644
index 0000000000..7f40fa1d49
--- /dev/null
+++ b/feature/registration/src/screenshotTestDebug/reference/org/signal/registration/screens/welcome/WelcomeScreenScreenshotTests/WelcomeScreenPhonePreview_rtl_5cbb5cfd_0.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:b42cffa7e3e731e2496d9504154c479d70d524d3240efcdb62b1f166eb9b0f49
+size 241995
diff --git a/feature/registration/src/screenshotTestDebug/reference/org/signal/registration/screens/welcome/WelcomeScreenScreenshotTests/WelcomeScreenPhonePreview_small foldable landscape (day)_de1bb092_0.png b/feature/registration/src/screenshotTestDebug/reference/org/signal/registration/screens/welcome/WelcomeScreenScreenshotTests/WelcomeScreenPhonePreview_small foldable landscape (day)_de1bb092_0.png
new file mode 100644
index 0000000000..670d6100b0
--- /dev/null
+++ b/feature/registration/src/screenshotTestDebug/reference/org/signal/registration/screens/welcome/WelcomeScreenScreenshotTests/WelcomeScreenPhonePreview_small foldable landscape (day)_de1bb092_0.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:7d6ef9c041521feeb0cda423cbb612f2ecdffe29a4eb97a9310e5c76192f27e6
+size 192932
diff --git a/feature/registration/src/screenshotTestDebug/reference/org/signal/registration/screens/welcome/WelcomeScreenScreenshotTests/WelcomeScreenPhonePreview_small foldable landscape (night)_fe962c61_0.png b/feature/registration/src/screenshotTestDebug/reference/org/signal/registration/screens/welcome/WelcomeScreenScreenshotTests/WelcomeScreenPhonePreview_small foldable landscape (night)_fe962c61_0.png
new file mode 100644
index 0000000000..c3a43d6621
--- /dev/null
+++ b/feature/registration/src/screenshotTestDebug/reference/org/signal/registration/screens/welcome/WelcomeScreenScreenshotTests/WelcomeScreenPhonePreview_small foldable landscape (night)_fe962c61_0.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:a6ba17b3a59fc897a23e55f3a76c4ae9613a6f547919f60c077ee8ea59f8d231
+size 182338
diff --git a/feature/registration/src/screenshotTestDebug/reference/org/signal/registration/screens/welcome/WelcomeScreenScreenshotTests/WelcomeScreenPhonePreview_small foldable portrait (day)_e269713d_0.png b/feature/registration/src/screenshotTestDebug/reference/org/signal/registration/screens/welcome/WelcomeScreenScreenshotTests/WelcomeScreenPhonePreview_small foldable portrait (day)_e269713d_0.png
new file mode 100644
index 0000000000..4fdcc279ab
--- /dev/null
+++ b/feature/registration/src/screenshotTestDebug/reference/org/signal/registration/screens/welcome/WelcomeScreenScreenshotTests/WelcomeScreenPhonePreview_small foldable portrait (day)_e269713d_0.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:c27372e794bcb63f49bf0e89cb495cf29c12d7024db7aeffde0db301f0951432
+size 165171
diff --git a/feature/registration/src/screenshotTestDebug/reference/org/signal/registration/screens/welcome/WelcomeScreenScreenshotTests/WelcomeScreenPhonePreview_tablet landscape (day)_308754cb_0.png b/feature/registration/src/screenshotTestDebug/reference/org/signal/registration/screens/welcome/WelcomeScreenScreenshotTests/WelcomeScreenPhonePreview_tablet landscape (day)_308754cb_0.png
new file mode 100644
index 0000000000..3a168e047b
--- /dev/null
+++ b/feature/registration/src/screenshotTestDebug/reference/org/signal/registration/screens/welcome/WelcomeScreenScreenshotTests/WelcomeScreenPhonePreview_tablet landscape (day)_308754cb_0.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:9b333000ff39c5d726307d9be2691de4657032cbf4a9a5d946afa94ce3001c73
+size 435557
diff --git a/feature/registration/src/screenshotTestDebug/reference/org/signal/registration/screens/welcome/WelcomeScreenScreenshotTests/WelcomeScreenPhonePreview_tablet landscape (night)_d25401fe_0.png b/feature/registration/src/screenshotTestDebug/reference/org/signal/registration/screens/welcome/WelcomeScreenScreenshotTests/WelcomeScreenPhonePreview_tablet landscape (night)_d25401fe_0.png
new file mode 100644
index 0000000000..4e8880f843
--- /dev/null
+++ b/feature/registration/src/screenshotTestDebug/reference/org/signal/registration/screens/welcome/WelcomeScreenScreenshotTests/WelcomeScreenPhonePreview_tablet landscape (night)_d25401fe_0.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:58ab68ce8d815d9f7aa094e0261075759083f67fcd4d40d8a38b519c9ac3ee78
+size 395238
diff --git a/feature/registration/src/screenshotTestDebug/reference/org/signal/registration/screens/welcome/WelcomeScreenScreenshotTests/WelcomeScreenPhonePreview_tablet portrait (day)_ae17fb11_0.png b/feature/registration/src/screenshotTestDebug/reference/org/signal/registration/screens/welcome/WelcomeScreenScreenshotTests/WelcomeScreenPhonePreview_tablet portrait (day)_ae17fb11_0.png
new file mode 100644
index 0000000000..6325fc6ea7
--- /dev/null
+++ b/feature/registration/src/screenshotTestDebug/reference/org/signal/registration/screens/welcome/WelcomeScreenScreenshotTests/WelcomeScreenPhonePreview_tablet portrait (day)_ae17fb11_0.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:34263308f2b19c65983e82c7d775478612529b9174a98c11a23ec3b3e3dbebb6
+size 297926
diff --git a/gradle.properties b/gradle.properties
index 1c485cf149..dc96f55579 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -15,6 +15,7 @@ org.gradle.caching=true
org.gradle.configuration-cache=true
org.gradle.configuration-cache.problems=fail
android.generateSyncIssueWhenLibraryConstraintsAreEnabled=false
+android.experimental.enableScreenshotTest=true
# We never want to use auto-provisioning, as it breaks reproducible builds.
# This should not be a problem, because we never configure a "javaRepositories"
diff --git a/gradle/test-libs.versions.toml b/gradle/test-libs.versions.toml
index e62cf0c1ae..85072f3697 100644
--- a/gradle/test-libs.versions.toml
+++ b/gradle/test-libs.versions.toml
@@ -6,8 +6,13 @@ androidx-test = "1.5.0"
androidx-test-ext-junit = "1.1.5"
robolectric = "4.15.1"
espresso = "3.4.0"
+compose-screenshot = "0.0.1-alpha15"
+
+[plugins]
+compose-screenshot = { id = "com.android.compose.screenshot", version.ref = "compose-screenshot" }
[libraries]
+compose-screenshot-validation-api = { module = "com.android.tools.screenshot:screenshot-validation-api", version.ref = "compose-screenshot" }
junit-junit = "junit:junit:4.13.2"
androidx-test-core = { module = "androidx.test:core", version.ref = "androidx-test" }
androidx-test-core-ktx = { module = "androidx.test:core-ktx", version.ref = "androidx-test" }
diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml
index 7154c4c752..988aeaabfb 100644
--- a/gradle/verification-metadata.xml
+++ b/gradle/verification-metadata.xml
@@ -9985,6 +9985,14 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
@@ -11360,6 +11368,16 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
+
+
@@ -11562,6 +11580,11 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
@@ -11606,6 +11629,19 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -11870,6 +11906,16 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
+
+
@@ -19493,6 +19539,14 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
@@ -19653,6 +19707,11 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
@@ -19741,6 +19800,11 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
@@ -19824,6 +19888,11 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
@@ -20794,6 +20863,11 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
@@ -20874,6 +20948,14 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
@@ -20886,6 +20968,14 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
@@ -20898,6 +20988,22 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+