mirror of
https://github.com/Novaloop-AG/element-x-android.git
synced 2026-10-31 08:15:02 +00:00
Remove Roborazzi, use Paparazzi for Compound (#7735)
* Remove Roborazzi, use Paparazzi for Compound The new screenshots will be recorded with the rest of the Paparazzi ones. Note the names changed, since Paparazzi enforces a `$packagename.$testname.$name.$extension` format * Set a max width value for color previews * Merge the `verifyPaparazziDebug` CI steps * Update screenshots --------- Co-authored-by: ElementBot <android@element.io>
This commit is contained in:
committed by
GitHub
parent
95d734efc9
commit
c4529b87b4
@@ -57,12 +57,6 @@ echo "Deleting previous screenshots"
|
||||
echo "Record screenshots"
|
||||
./gradlew recordPaparazziDebug --stacktrace $GRADLE_ARGS
|
||||
|
||||
echo "Deleting previous screenshots"
|
||||
./gradlew removeOldScreenshots --stacktrace --warn $GRADLE_ARGS
|
||||
|
||||
echo "Record screenshots (Compound)"
|
||||
./gradlew :libraries:compound:recordRoborazziDebug --stacktrace -PpreDexEnable=false --max-workers 4 --warn $GRADLE_ARGS
|
||||
|
||||
echo "Committing changes"
|
||||
git config http.sslVerify false
|
||||
|
||||
|
||||
@@ -76,10 +76,7 @@ jobs:
|
||||
run: ./gradlew :app:testGplayDebugUnitTest testDebugUnitTest -x :tests:konsist:testDebugUnitTest $CI_GRADLE_ARG_PROPERTIES
|
||||
|
||||
- name: ⚙️ Run screenshot tests
|
||||
run: ./gradlew :tests:uitests:verifyPaparazziDebug $CI_GRADLE_ARG_PROPERTIES
|
||||
|
||||
- name: ⚙️ Run Compound screenshot tests
|
||||
run: ./gradlew :libraries:compound:verifyRoborazziDebug $CI_GRADLE_ARG_PROPERTIES
|
||||
run: ./gradlew verifyPaparazziDebug $CI_GRADLE_ARG_PROPERTIES
|
||||
|
||||
- name: ⚙️ Generate kover coverage report
|
||||
run: ./gradlew :koverXmlReportMerged :koverHtmlReportMerged :koverVerifyAll -x testDebugUnitTest $CI_GRADLE_ARG_PROPERTIES
|
||||
@@ -103,7 +100,6 @@ jobs:
|
||||
name: tests-and-screenshot-tests-results
|
||||
path: |
|
||||
**/build/paparazzi/failures/
|
||||
**/build/roborazzi/failures/
|
||||
**/build/reports/tests/*UnitTest/
|
||||
|
||||
- name: 🚫 Modify summary on error
|
||||
|
||||
+4
-23
@@ -18,7 +18,6 @@ plugins {
|
||||
alias(libs.plugins.compose.compiler) apply false
|
||||
alias(libs.plugins.ksp) apply false
|
||||
alias(libs.plugins.dependencycheck) apply false
|
||||
alias(libs.plugins.roborazzi) apply false
|
||||
alias(libs.plugins.dependencyanalysis)
|
||||
alias(libs.plugins.detekt)
|
||||
alias(libs.plugins.ktlint)
|
||||
@@ -153,7 +152,6 @@ allprojects {
|
||||
maxParallelForks = (Runtime.getRuntime().availableProcessors() / 2).coerceAtLeast(1)
|
||||
|
||||
val isScreenshotTest = project.gradle.startParameter.taskNames.any { it.contains("paparazzi", ignoreCase = true) }
|
||||
val isRoborazziTest = project.gradle.startParameter.taskNames.any { it.contains("roborazzi", ignoreCase = true) }
|
||||
if (isScreenshotTest) {
|
||||
// Paparazzi tests benefit from parallelisation, so we can use half the available cores to run them in parallel.
|
||||
maxParallelForks = (Runtime.getRuntime().availableProcessors() / 2).coerceAtLeast(1)
|
||||
@@ -178,12 +176,10 @@ allprojects {
|
||||
// Disable screenshot tests by default
|
||||
exclude("ui/*.class")
|
||||
exclude("translations/*.class")
|
||||
if (isRoborazziTest.not()) {
|
||||
// Roborazzi screenshot tests (:libraries:compound) live in a `screenshot` package, which
|
||||
// the two patterns above do not match, so they used to run on every plain unit test run.
|
||||
// They are verified by the dedicated `verifyRoborazziDebug` task instead.
|
||||
exclude("**/screenshot/**")
|
||||
}
|
||||
// The Compound screenshot tests (:libraries:compound) live in a `screenshot` package, which
|
||||
// the two patterns above do not match, so they would otherwise run on every plain unit test run.
|
||||
// They are verified by the dedicated `verifyPaparazziDebug` task instead.
|
||||
exclude("**/screenshot/**")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -230,21 +226,6 @@ subprojects {
|
||||
tasks.findByName("recordPaparazziRelease")?.dependsOn(removeOldScreenshotsTask)
|
||||
}
|
||||
|
||||
// Make sure to delete old snapshot before recording new ones
|
||||
subprojects {
|
||||
val screenshotsDir = File("${project.projectDir}/screenshots")
|
||||
val removeOldScreenshotsTask = tasks.register("removeOldScreenshots") {
|
||||
onlyIf { screenshotsDir.exists() }
|
||||
doFirst {
|
||||
println("Delete previous screenshots located at $screenshotsDir\n")
|
||||
screenshotsDir.deleteRecursively()
|
||||
}
|
||||
}
|
||||
tasks.findByName("recordRoborazzi")?.dependsOn(removeOldScreenshotsTask)
|
||||
tasks.findByName("recordRoborazziDebug")?.dependsOn(removeOldScreenshotsTask)
|
||||
tasks.findByName("recordRoborazziRelease")?.dependsOn(removeOldScreenshotsTask)
|
||||
}
|
||||
|
||||
subprojects {
|
||||
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile>().configureEach {
|
||||
compilerOptions {
|
||||
|
||||
@@ -59,10 +59,6 @@ ksp.allow.all.target.configuration=false
|
||||
# Used to prevent detekt from reusing invalid cached rules
|
||||
detekt.use.worker.api=true
|
||||
|
||||
# Let test include roborazzi verification
|
||||
# https://github.com/takahirom/roborazzi?tab=readme-ov-file#roborazzitest
|
||||
roborazzi.test.verify=true
|
||||
|
||||
# Needed after enabling proguard on AGP 8.13.1
|
||||
android.r8.gradual.support=true
|
||||
|
||||
|
||||
@@ -32,7 +32,6 @@ accompanist = "0.37.3"
|
||||
|
||||
# Test
|
||||
test_core = "1.7.0"
|
||||
roborazzi = "1.74.0"
|
||||
|
||||
# Jetbrain
|
||||
datetime = "0.8.0"
|
||||
@@ -247,11 +246,6 @@ google_autoservice_annotations = { module = "com.google.auto.service:auto-servic
|
||||
# Miscellaneous
|
||||
androidx-test-ext-junit = { group = "androidx.test.ext", name = "junit", version.ref = "androidx-test-ext-junit" }
|
||||
|
||||
# Test
|
||||
test_roborazzi = { module = "io.github.takahirom.roborazzi:roborazzi", version.ref = "roborazzi" }
|
||||
test_roborazzi_compose = { module = "io.github.takahirom.roborazzi:roborazzi-compose", version.ref = "roborazzi" }
|
||||
test_roborazzi_junit = { module = "io.github.takahirom.roborazzi:roborazzi-junit-rule", version.ref = "roborazzi" }
|
||||
|
||||
[bundles]
|
||||
|
||||
[plugins]
|
||||
@@ -269,7 +263,6 @@ dependencygraph = "com.savvasdalkitsis.module-dependency-graph:0.12"
|
||||
dependencycheck = "org.owasp.dependencycheck:13.0.0"
|
||||
dependencyanalysis = { id = "com.autonomousapps.dependency-analysis", version.ref = "dependencyAnalysis" }
|
||||
paparazzi = "app.cash.paparazzi:2.0.0-alpha05"
|
||||
roborazzi = { id = "io.github.takahirom.roborazzi", version.ref = "roborazzi" }
|
||||
sqldelight = { id = "app.cash.sqldelight", version.ref = "sqldelight" }
|
||||
firebaseAppDistribution = { id = "com.google.firebase.appdistribution", version.ref = "firebaseAppDistribution" }
|
||||
sonarqube = "org.sonarqube:7.5.0.8588"
|
||||
|
||||
@@ -10,7 +10,7 @@ import extension.testCommonDependencies
|
||||
|
||||
plugins {
|
||||
id("io.element.android-compose-library")
|
||||
alias(libs.plugins.roborazzi)
|
||||
alias(libs.plugins.paparazzi)
|
||||
}
|
||||
|
||||
android {
|
||||
@@ -21,9 +21,30 @@ android {
|
||||
}
|
||||
}
|
||||
|
||||
// Paparazzi's layoutlib runtime conflicts with Robolectric, so during Paparazzi record/verify runs
|
||||
// only execute the screenshot tests (which use Paparazzi) and leave the Robolectric-based unit tests
|
||||
// out. On plain unit test runs the screenshot package is excluded in the root build.gradle.kts.
|
||||
tasks.withType(Test::class).configureEach {
|
||||
val isScreenshotTest = gradle.startParameter.taskNames.any { it.contains("paparazzi", ignoreCase = true) }
|
||||
if (isScreenshotTest) {
|
||||
include("**/screenshot/**")
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
testCommonDependencies(libs)
|
||||
testImplementation(libs.test.roborazzi)
|
||||
testImplementation(libs.test.roborazzi.compose)
|
||||
testImplementation(libs.test.roborazzi.junit)
|
||||
|
||||
// Paparazzi 1.3.2 workaround (see https://github.com/cashapp/paparazzi/blob/master/CHANGELOG.md#132---2024-01-13)
|
||||
constraints.add("testImplementation", "com.google.guava:guava") {
|
||||
attributes {
|
||||
attribute(
|
||||
TargetJvmEnvironment.TARGET_JVM_ENVIRONMENT_ATTRIBUTE,
|
||||
objects.named(TargetJvmEnvironment::class.java, TargetJvmEnvironment.STANDARD_JVM)
|
||||
)
|
||||
}
|
||||
because(
|
||||
"LayoutLib and sdk-common depend on Guava's -jre published variant." +
|
||||
"See https://github.com/cashapp/paparazzi/issues/906."
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+5
-4
@@ -11,6 +11,7 @@ package io.element.android.compound.previews
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
@@ -27,7 +28,7 @@ import kotlinx.collections.immutable.persistentMapOf
|
||||
@Preview(heightDp = 2000)
|
||||
@Composable
|
||||
internal fun CompoundSemanticColorsLight() = ElementTheme {
|
||||
Surface {
|
||||
Surface(Modifier.width(300.dp)) {
|
||||
Column(
|
||||
modifier = Modifier.padding(16.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(10.dp)
|
||||
@@ -48,7 +49,7 @@ internal fun CompoundSemanticColorsLight() = ElementTheme {
|
||||
internal fun CompoundSemanticColorsLightHc() = ElementTheme(
|
||||
compoundDark = compoundColorsHcDark,
|
||||
) {
|
||||
Surface {
|
||||
Surface(Modifier.width(300.dp)) {
|
||||
Column(
|
||||
modifier = Modifier.padding(16.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(10.dp)
|
||||
@@ -67,7 +68,7 @@ internal fun CompoundSemanticColorsLightHc() = ElementTheme(
|
||||
@Preview(heightDp = 2000)
|
||||
@Composable
|
||||
internal fun CompoundSemanticColorsDark() = ElementTheme(theme = Theme.Dark) {
|
||||
Surface {
|
||||
Surface(Modifier.width(300.dp)) {
|
||||
Column(
|
||||
modifier = Modifier.padding(16.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(10.dp)
|
||||
@@ -89,7 +90,7 @@ internal fun CompoundSemanticColorsDarkHc() = ElementTheme(
|
||||
theme = Theme.Dark,
|
||||
compoundDark = compoundColorsHcDark,
|
||||
) {
|
||||
Surface {
|
||||
Surface(Modifier.width(300.dp)) {
|
||||
Column(
|
||||
modifier = Modifier.padding(16.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(10.dp)
|
||||
|
||||
+8
-10
@@ -8,24 +8,22 @@
|
||||
|
||||
package io.element.android.compound.screenshot
|
||||
|
||||
import com.github.takahirom.roborazzi.captureRoboImage
|
||||
import io.element.android.compound.screenshot.utils.screenshotFile
|
||||
import io.element.android.compound.screenshot.utils.createPaparazziRule
|
||||
import io.element.android.compound.theme.AvatarColorsPreviewDark
|
||||
import io.element.android.compound.theme.AvatarColorsPreviewLight
|
||||
import io.element.android.tests.testutils.robolectric.RobolectricTest
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.robolectric.annotation.Config
|
||||
import org.robolectric.annotation.GraphicsMode
|
||||
|
||||
@GraphicsMode(GraphicsMode.Mode.NATIVE)
|
||||
class AvatarColorsTest : RobolectricTest() {
|
||||
class AvatarColorsTest {
|
||||
@get:Rule
|
||||
val paparazzi = createPaparazziRule()
|
||||
|
||||
@Test
|
||||
@Config(sdk = [35], qualifiers = "xxhdpi")
|
||||
fun screenshots() {
|
||||
captureRoboImage(file = screenshotFile("Avatar Colors - Light.png")) {
|
||||
paparazzi.snapshot(name = "Avatar Colors - Light") {
|
||||
AvatarColorsPreviewLight()
|
||||
}
|
||||
captureRoboImage(file = screenshotFile("Avatar Colors - Dark.png")) {
|
||||
paparazzi.snapshot(name = "Avatar Colors - Dark") {
|
||||
AvatarColorsPreviewDark()
|
||||
}
|
||||
}
|
||||
|
||||
+11
-13
@@ -11,36 +11,34 @@ package io.element.android.compound.screenshot
|
||||
import androidx.compose.foundation.layout.ColumnScope
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.runtime.Composable
|
||||
import com.github.takahirom.roborazzi.captureRoboImage
|
||||
import io.element.android.compound.previews.IconsCompoundPreviewDark
|
||||
import io.element.android.compound.previews.IconsCompoundPreviewLight
|
||||
import io.element.android.compound.previews.IconsCompoundPreviewRtl
|
||||
import io.element.android.compound.previews.IconsPreview
|
||||
import io.element.android.compound.screenshot.utils.screenshotFile
|
||||
import io.element.android.compound.screenshot.utils.createPaparazziRule
|
||||
import io.element.android.compound.theme.ElementTheme
|
||||
import io.element.android.compound.theme.Theme
|
||||
import io.element.android.compound.tokens.generated.CompoundIcons
|
||||
import io.element.android.tests.testutils.robolectric.RobolectricTest
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.robolectric.annotation.Config
|
||||
import org.robolectric.annotation.GraphicsMode
|
||||
|
||||
@GraphicsMode(GraphicsMode.Mode.NATIVE)
|
||||
class CompoundIconTest : RobolectricTest() {
|
||||
class CompoundIconTest {
|
||||
@get:Rule
|
||||
val paparazzi = createPaparazziRule()
|
||||
|
||||
@Test
|
||||
@Config(sdk = [35], qualifiers = "w1024dp-h2048dp")
|
||||
fun screenshots() {
|
||||
captureRoboImage(file = screenshotFile("Compound Icons - Light.png")) {
|
||||
paparazzi.snapshot(name = "Compound Icons - Light") {
|
||||
IconsCompoundPreviewLight()
|
||||
}
|
||||
captureRoboImage(file = screenshotFile("Compound Icons - Rtl.png")) {
|
||||
paparazzi.snapshot(name = "Compound Icons - Rtl") {
|
||||
IconsCompoundPreviewRtl()
|
||||
}
|
||||
captureRoboImage(file = screenshotFile("Compound Icons - Dark.png")) {
|
||||
paparazzi.snapshot(name = "Compound Icons - Dark") {
|
||||
IconsCompoundPreviewDark()
|
||||
}
|
||||
captureRoboImage(file = screenshotFile("Compound Vector Icons - Light.png")) {
|
||||
paparazzi.snapshot(name = "Compound Vector Icons - Light") {
|
||||
val content: List<@Composable ColumnScope.() -> Unit> = CompoundIcons.all.map {
|
||||
@Composable { Icon(imageVector = it, contentDescription = null) }
|
||||
}
|
||||
@@ -51,7 +49,7 @@ class CompoundIconTest : RobolectricTest() {
|
||||
)
|
||||
}
|
||||
}
|
||||
captureRoboImage(file = screenshotFile("Compound Vector Icons - Dark.png")) {
|
||||
paparazzi.snapshot(name = "Compound Vector Icons - Dark") {
|
||||
val content: List<@Composable ColumnScope.() -> Unit> = CompoundIcons.all.map {
|
||||
@Composable { Icon(imageVector = it, contentDescription = null) }
|
||||
}
|
||||
|
||||
+7
-9
@@ -8,20 +8,18 @@
|
||||
|
||||
package io.element.android.compound.screenshot
|
||||
|
||||
import com.github.takahirom.roborazzi.captureRoboImage
|
||||
import io.element.android.compound.previews.CompoundTypographyPreview
|
||||
import io.element.android.compound.screenshot.utils.screenshotFile
|
||||
import io.element.android.tests.testutils.robolectric.RobolectricTest
|
||||
import io.element.android.compound.screenshot.utils.createPaparazziRule
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.robolectric.annotation.Config
|
||||
import org.robolectric.annotation.GraphicsMode
|
||||
|
||||
@GraphicsMode(GraphicsMode.Mode.NATIVE)
|
||||
class CompoundTypographyTest : RobolectricTest() {
|
||||
class CompoundTypographyTest {
|
||||
@get:Rule
|
||||
val paparazzi = createPaparazziRule()
|
||||
|
||||
@Test
|
||||
@Config(sdk = [35], qualifiers = "h2048dp-xxhdpi")
|
||||
fun screenshots() {
|
||||
captureRoboImage(file = screenshotFile("Compound Typography.png")) {
|
||||
paparazzi.snapshot(name = "Compound Typography") {
|
||||
CompoundTypographyPreview()
|
||||
}
|
||||
}
|
||||
|
||||
+8
-9
@@ -18,22 +18,21 @@ import androidx.compose.material3.Text
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.github.takahirom.roborazzi.captureRoboImage
|
||||
import io.element.android.compound.colors.SemanticColorsLightDark
|
||||
import io.element.android.compound.screenshot.utils.screenshotFile
|
||||
import io.element.android.compound.screenshot.utils.createPaparazziRule
|
||||
import io.element.android.compound.theme.ElementTheme
|
||||
import io.element.android.compound.theme.ForcedDarkElementTheme
|
||||
import io.element.android.tests.testutils.robolectric.RobolectricTest
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.robolectric.annotation.Config
|
||||
import org.robolectric.annotation.GraphicsMode
|
||||
|
||||
@GraphicsMode(GraphicsMode.Mode.NATIVE)
|
||||
class ForcedDarkElementThemeTest : RobolectricTest() {
|
||||
class ForcedDarkElementThemeTest {
|
||||
// The preview uses `fillMaxSize` to fill the inner Surface, so it needs a bounded frame.
|
||||
@get:Rule
|
||||
val paparazzi = createPaparazziRule(widthDp = 420, heightDp = 640)
|
||||
|
||||
@Test
|
||||
@Config(sdk = [35], qualifiers = "xxhdpi")
|
||||
fun screenshots() {
|
||||
captureRoboImage(file = screenshotFile("ForcedDarkElementTheme.png")) {
|
||||
paparazzi.snapshot(name = "ForcedDarkElementTheme") {
|
||||
ElementTheme {
|
||||
Surface {
|
||||
Column(
|
||||
|
||||
+9
-10
@@ -12,32 +12,31 @@ import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.github.takahirom.roborazzi.captureRoboImage
|
||||
import io.element.android.compound.previews.ColorPreview
|
||||
import io.element.android.compound.screenshot.utils.screenshotFile
|
||||
import io.element.android.compound.screenshot.utils.createPaparazziRule
|
||||
import io.element.android.compound.theme.ElementTheme
|
||||
import io.element.android.compound.theme.LinkColor
|
||||
import io.element.android.compound.theme.SnackBarLabelColorDark
|
||||
import io.element.android.compound.theme.SnackBarLabelColorLight
|
||||
import io.element.android.tests.testutils.robolectric.RobolectricTest
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.robolectric.annotation.Config
|
||||
import org.robolectric.annotation.GraphicsMode
|
||||
|
||||
@GraphicsMode(GraphicsMode.Mode.NATIVE)
|
||||
class LegacyColorsTest : RobolectricTest() {
|
||||
class LegacyColorsTest {
|
||||
@get:Rule
|
||||
val paparazzi = createPaparazziRule()
|
||||
|
||||
@Test
|
||||
@Config(sdk = [35], qualifiers = "xxhdpi")
|
||||
fun screenshots() {
|
||||
captureRoboImage(file = screenshotFile("Legacy Colors.png")) {
|
||||
paparazzi.snapshot(name = "Legacy Colors") {
|
||||
ElementTheme {
|
||||
Surface {
|
||||
Surface(Modifier.width(300.dp)) {
|
||||
Column(modifier = Modifier.padding(16.dp)) {
|
||||
Text(text = "Legacy Colors")
|
||||
Spacer(modifier = Modifier.height(10.dp))
|
||||
|
||||
+15
-16
@@ -12,32 +12,31 @@ import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.github.takahirom.roborazzi.captureRoboImage
|
||||
import io.element.android.compound.screenshot.utils.screenshotFile
|
||||
import io.element.android.compound.screenshot.utils.createPaparazziRule
|
||||
import io.element.android.compound.theme.ColorsSchemeDarkHcPreview
|
||||
import io.element.android.compound.theme.ColorsSchemeDarkPreview
|
||||
import io.element.android.compound.theme.ColorsSchemeLightHcPreview
|
||||
import io.element.android.compound.theme.ColorsSchemeLightPreview
|
||||
import io.element.android.compound.theme.ElementTheme
|
||||
import io.element.android.tests.testutils.robolectric.RobolectricTest
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.robolectric.annotation.Config
|
||||
import org.robolectric.annotation.GraphicsMode
|
||||
|
||||
@GraphicsMode(GraphicsMode.Mode.NATIVE)
|
||||
class MaterialColorSchemeTest : RobolectricTest() {
|
||||
class MaterialColorSchemeTest {
|
||||
@get:Rule
|
||||
val paparazzi = createPaparazziRule()
|
||||
|
||||
@Test
|
||||
@Config(sdk = [35], qualifiers = "h2048dp-xhdpi")
|
||||
fun screenshots() {
|
||||
captureRoboImage(file = screenshotFile("Material3 Colors - Light.png")) {
|
||||
paparazzi.snapshot(name = "Material3 Colors - Light") {
|
||||
ElementTheme {
|
||||
Surface {
|
||||
Surface(Modifier.width(300.dp)) {
|
||||
Column(modifier = Modifier.padding(16.dp)) {
|
||||
Text(
|
||||
text = "M3 Light colors",
|
||||
@@ -49,9 +48,9 @@ class MaterialColorSchemeTest : RobolectricTest() {
|
||||
}
|
||||
}
|
||||
}
|
||||
captureRoboImage(file = screenshotFile("Material3 Colors - Light HC.png")) {
|
||||
paparazzi.snapshot(name = "Material3 Colors - Light HC") {
|
||||
ElementTheme {
|
||||
Surface {
|
||||
Surface(Modifier.width(300.dp)) {
|
||||
Column(modifier = Modifier.padding(16.dp)) {
|
||||
Text(
|
||||
text = "M3 Light HC colors",
|
||||
@@ -63,9 +62,9 @@ class MaterialColorSchemeTest : RobolectricTest() {
|
||||
}
|
||||
}
|
||||
}
|
||||
captureRoboImage(file = screenshotFile("Material3 Colors - Dark.png")) {
|
||||
paparazzi.snapshot(name = "Material3 Colors - Dark") {
|
||||
ElementTheme {
|
||||
Surface {
|
||||
Surface(Modifier.width(300.dp)) {
|
||||
Column(modifier = Modifier.padding(16.dp)) {
|
||||
Text(
|
||||
text = "M3 Dark colors",
|
||||
@@ -77,9 +76,9 @@ class MaterialColorSchemeTest : RobolectricTest() {
|
||||
}
|
||||
}
|
||||
}
|
||||
captureRoboImage(file = screenshotFile("Material3 Colors - Dark HC.png")) {
|
||||
paparazzi.snapshot(name = "Material3 Colors - Dark HC") {
|
||||
ElementTheme {
|
||||
Surface {
|
||||
Surface(Modifier.width(300.dp)) {
|
||||
Column(modifier = Modifier.padding(16.dp)) {
|
||||
Text(
|
||||
text = "M3 Dark HC colors",
|
||||
|
||||
+8
-9
@@ -8,20 +8,19 @@
|
||||
|
||||
package io.element.android.compound.screenshot
|
||||
|
||||
import com.github.takahirom.roborazzi.captureRoboImage
|
||||
import io.element.android.compound.screenshot.utils.screenshotFile
|
||||
import io.element.android.compound.screenshot.utils.createPaparazziRule
|
||||
import io.element.android.compound.theme.MaterialTextPreview
|
||||
import io.element.android.tests.testutils.robolectric.RobolectricTest
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.robolectric.annotation.Config
|
||||
import org.robolectric.annotation.GraphicsMode
|
||||
|
||||
@GraphicsMode(GraphicsMode.Mode.NATIVE)
|
||||
class MaterialTextTest : RobolectricTest() {
|
||||
class MaterialTextTest {
|
||||
// MaterialTextPreview relies on `weight`/`fillMaxSize`, so it needs a bounded frame to lay out.
|
||||
@get:Rule
|
||||
val paparazzi = createPaparazziRule(widthDp = 420, heightDp = 1200)
|
||||
|
||||
@Test
|
||||
@Config(sdk = [35], qualifiers = "w480dp-h1200dp-xxhdpi")
|
||||
fun screenshots() {
|
||||
captureRoboImage(file = screenshotFile("MaterialText Colors.png")) {
|
||||
paparazzi.snapshot(name = "MaterialText Colors") {
|
||||
MaterialTextPreview()
|
||||
}
|
||||
}
|
||||
|
||||
+7
-9
@@ -8,20 +8,18 @@
|
||||
|
||||
package io.element.android.compound.screenshot
|
||||
|
||||
import com.github.takahirom.roborazzi.captureRoboImage
|
||||
import io.element.android.compound.previews.TypographyPreview
|
||||
import io.element.android.compound.screenshot.utils.screenshotFile
|
||||
import io.element.android.tests.testutils.robolectric.RobolectricTest
|
||||
import io.element.android.compound.screenshot.utils.createPaparazziRule
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.robolectric.annotation.Config
|
||||
import org.robolectric.annotation.GraphicsMode
|
||||
|
||||
@GraphicsMode(GraphicsMode.Mode.NATIVE)
|
||||
class MaterialTypographyTest : RobolectricTest() {
|
||||
class MaterialTypographyTest {
|
||||
@get:Rule
|
||||
val paparazzi = createPaparazziRule()
|
||||
|
||||
@Test
|
||||
@Config(sdk = [35], qualifiers = "h2048dp-xxhdpi")
|
||||
fun screenshots() {
|
||||
captureRoboImage(file = screenshotFile("Material Typography.png")) {
|
||||
paparazzi.snapshot(name = "Material Typography") {
|
||||
TypographyPreview()
|
||||
}
|
||||
}
|
||||
|
||||
+8
-10
@@ -19,22 +19,20 @@ import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.github.takahirom.roborazzi.captureRoboImage
|
||||
import io.element.android.compound.previews.ColorsSchemePreview
|
||||
import io.element.android.compound.screenshot.utils.screenshotFile
|
||||
import io.element.android.compound.screenshot.utils.createPaparazziRule
|
||||
import io.element.android.compound.theme.ElementTheme
|
||||
import io.element.android.compound.theme.Theme
|
||||
import io.element.android.tests.testutils.robolectric.RobolectricTest
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.robolectric.annotation.Config
|
||||
import org.robolectric.annotation.GraphicsMode
|
||||
|
||||
@GraphicsMode(GraphicsMode.Mode.NATIVE)
|
||||
class MaterialYouThemeTest : RobolectricTest() {
|
||||
class MaterialYouThemeTest {
|
||||
@get:Rule
|
||||
val paparazzi = createPaparazziRule()
|
||||
|
||||
@Test
|
||||
@Config(sdk = [35], qualifiers = "h2048dp-xhdpi")
|
||||
fun screenshots() {
|
||||
captureRoboImage(file = screenshotFile("MaterialYou Theme - Light.png")) {
|
||||
paparazzi.snapshot(name = "MaterialYou Theme - Light") {
|
||||
ElementTheme(dynamicColor = true) {
|
||||
Surface {
|
||||
Column(
|
||||
@@ -49,7 +47,7 @@ class MaterialYouThemeTest : RobolectricTest() {
|
||||
}
|
||||
}
|
||||
}
|
||||
captureRoboImage(file = screenshotFile("MaterialYou Theme - Dark.png")) {
|
||||
paparazzi.snapshot(name = "MaterialYou Theme - Dark") {
|
||||
ElementTheme(dynamicColor = true, theme = Theme.Dark) {
|
||||
Surface {
|
||||
Column(
|
||||
|
||||
+10
-12
@@ -8,35 +8,33 @@
|
||||
|
||||
package io.element.android.compound.screenshot
|
||||
|
||||
import com.github.takahirom.roborazzi.captureRoboImage
|
||||
import io.element.android.compound.previews.CompoundSemanticColorsDark
|
||||
import io.element.android.compound.previews.CompoundSemanticColorsDarkHc
|
||||
import io.element.android.compound.previews.CompoundSemanticColorsLight
|
||||
import io.element.android.compound.previews.CompoundSemanticColorsLightHc
|
||||
import io.element.android.compound.screenshot.utils.screenshotFile
|
||||
import io.element.android.tests.testutils.robolectric.RobolectricTest
|
||||
import io.element.android.compound.screenshot.utils.createPaparazziRule
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.robolectric.annotation.Config
|
||||
import org.robolectric.annotation.GraphicsMode
|
||||
|
||||
@GraphicsMode(GraphicsMode.Mode.NATIVE)
|
||||
class SemanticColorsTest : RobolectricTest() {
|
||||
@Config(sdk = [35], qualifiers = "h2000dp-xhdpi")
|
||||
class SemanticColorsTest {
|
||||
@get:Rule
|
||||
val paparazzi = createPaparazziRule()
|
||||
|
||||
@Test
|
||||
fun screenshots() {
|
||||
captureRoboImage(file = screenshotFile("Compound Semantic Colors - Light.png")) {
|
||||
paparazzi.snapshot(name = "Compound Semantic Colors - Light") {
|
||||
CompoundSemanticColorsLight()
|
||||
}
|
||||
|
||||
captureRoboImage(file = screenshotFile("Compound Semantic Colors - Light HC.png")) {
|
||||
paparazzi.snapshot(name = "Compound Semantic Colors - Light HC") {
|
||||
CompoundSemanticColorsLightHc()
|
||||
}
|
||||
|
||||
captureRoboImage(file = screenshotFile("Compound Semantic Colors - Dark.png")) {
|
||||
paparazzi.snapshot(name = "Compound Semantic Colors - Dark") {
|
||||
CompoundSemanticColorsDark()
|
||||
}
|
||||
|
||||
captureRoboImage(file = screenshotFile("Compound Semantic Colors - Dark HC.png")) {
|
||||
paparazzi.snapshot(name = "Compound Semantic Colors - Dark HC") {
|
||||
CompoundSemanticColorsDarkHc()
|
||||
}
|
||||
}
|
||||
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2023-2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.compound.screenshot.utils
|
||||
|
||||
import app.cash.paparazzi.DeviceConfig
|
||||
import app.cash.paparazzi.Paparazzi
|
||||
import com.android.ide.common.rendering.api.SessionParams.RenderingMode
|
||||
import com.android.resources.Density
|
||||
|
||||
// Screenshots are captured at xxhdpi so the icon grids stay sharp. This is the density scale factor
|
||||
// (480dpi / 160dpi), used to convert the dp bounds below into the pixel values [DeviceConfig] expects.
|
||||
private const val DENSITY_SCALE = 2
|
||||
|
||||
// Upper bounds for self-sizing screenshots, in dp. Large enough to fit the tallest and widest
|
||||
// Compound preview; `RenderingMode.SHRINK` then crops each image down to its actual content.
|
||||
private const val MAX_WIDTH_DP = 2048
|
||||
private const val MAX_HEIGHT_DP = 4800
|
||||
|
||||
/**
|
||||
* Creates a [Paparazzi] rule for the Compound screenshot tests.
|
||||
*
|
||||
* By default each screenshot sizes itself to its content ([RenderingMode.SHRINK]) instead of being
|
||||
* rendered at a fixed device frame size, and the [DeviceConfig] only acts as an upper bound.
|
||||
*
|
||||
* Pass [widthDp] and [heightDp] for previews that rely on `fillMaxSize`/`weight` and therefore need
|
||||
* a bounded frame to lay out correctly: they are then rendered at that fixed size instead.
|
||||
*
|
||||
* [useDeviceResolution] is enabled so screenshots are captured at full device resolution. Without
|
||||
* it, Paparazzi downscales every image to a 1000px max dimension, which makes large previews (such
|
||||
* as the icon grids) look pixelated.
|
||||
*/
|
||||
fun createPaparazziRule(
|
||||
widthDp: Int? = null,
|
||||
heightDp: Int? = null,
|
||||
): Paparazzi {
|
||||
val selfSizing = widthDp == null || heightDp == null
|
||||
return Paparazzi(
|
||||
deviceConfig = DeviceConfig(
|
||||
screenWidth = (widthDp ?: MAX_WIDTH_DP) * DENSITY_SCALE,
|
||||
screenHeight = (heightDp ?: MAX_HEIGHT_DP) * DENSITY_SCALE,
|
||||
xdpi = 480,
|
||||
ydpi = 480,
|
||||
density = Density.XXHIGH,
|
||||
softButtons = false,
|
||||
),
|
||||
renderingMode = if (selfSizing) RenderingMode.SHRINK else RenderingMode.NORMAL,
|
||||
supportsRtl = true,
|
||||
useDeviceResolution = true,
|
||||
maxPercentDifference = 0.01,
|
||||
)
|
||||
}
|
||||
-19
@@ -1,19 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2023-2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.compound.screenshot.utils
|
||||
|
||||
import java.io.File
|
||||
|
||||
/**
|
||||
* Returns a [File] object for a screenshot with the given [filename].
|
||||
* This is to ensure we have a consistent location for all screenshots.
|
||||
*/
|
||||
fun screenshotFile(filename: String): File {
|
||||
return File("screenshots", filename)
|
||||
}
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Reference in New Issue
Block a user