test(designsystem): Roborazzi screenshot-каркас — рендер Compose в PNG на JVM (Fd-сверка без эмулятора)
Пилот: F7PrimaryButton/F7SecondaryButton рендерятся в PNG (390dp xxhdpi) через Robolectric+Roborazzi, recordRoborazziDebug зелёный. Основа автономного Fd-прохода: экран → PNG → сравнение с веб-мобильной forbion. Роли добавляют тесты на свои экраны.
This commit is contained in:
@@ -7,6 +7,7 @@ plugins {
|
|||||||
id 'org.jetbrains.kotlin.plugin.serialization' version '2.3.0' apply false
|
id 'org.jetbrains.kotlin.plugin.serialization' version '2.3.0' apply false
|
||||||
id 'org.jetbrains.kotlin.plugin.parcelize' version '2.3.0' apply false
|
id 'org.jetbrains.kotlin.plugin.parcelize' version '2.3.0' apply false
|
||||||
id 'com.google.devtools.ksp' version '2.3.4' apply false
|
id 'com.google.devtools.ksp' version '2.3.4' apply false
|
||||||
|
id 'io.github.takahirom.roborazzi' version '1.42.0' apply false
|
||||||
id 'com.google.gms.google-services' version '4.4.2' apply false
|
id 'com.google.gms.google-services' version '4.4.2' apply false
|
||||||
id 'io.gitlab.arturbosch.detekt' version '1.23.8' apply false
|
id 'io.gitlab.arturbosch.detekt' version '1.23.8' apply false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ plugins {
|
|||||||
id 'com.android.library'
|
id 'com.android.library'
|
||||||
id 'org.jetbrains.kotlin.android'
|
id 'org.jetbrains.kotlin.android'
|
||||||
id 'org.jetbrains.kotlin.plugin.compose'
|
id 'org.jetbrains.kotlin.plugin.compose'
|
||||||
|
id 'io.github.takahirom.roborazzi'
|
||||||
}
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
@@ -22,6 +23,12 @@ android {
|
|||||||
kotlinOptions {
|
kotlinOptions {
|
||||||
jvmTarget = '17'
|
jvmTarget = '17'
|
||||||
}
|
}
|
||||||
|
// Roborazzi/Robolectric: рендер Compose в PNG на JVM (Fd-сверка без эмулятора).
|
||||||
|
testOptions {
|
||||||
|
unitTests {
|
||||||
|
includeAndroidResources = true
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
@@ -32,4 +39,14 @@ dependencies {
|
|||||||
implementation libs.compose.material3
|
implementation libs.compose.material3
|
||||||
implementation libs.coil.compose
|
implementation libs.coil.compose
|
||||||
implementation libs.coil.svg
|
implementation libs.coil.svg
|
||||||
|
|
||||||
|
// Screenshot-тесты (JVM)
|
||||||
|
testImplementation composeBom
|
||||||
|
testImplementation libs.junit
|
||||||
|
testImplementation libs.robolectric
|
||||||
|
testImplementation libs.roborazzi
|
||||||
|
testImplementation libs.roborazzi.compose
|
||||||
|
testImplementation libs.roborazzi.junit.rule
|
||||||
|
testImplementation libs.compose.ui.test.junit4
|
||||||
|
debugImplementation libs.compose.ui.test.manifest
|
||||||
}
|
}
|
||||||
|
|||||||
+50
@@ -0,0 +1,50 @@
|
|||||||
|
package ru.forbion.f7cloud.core.designsystem
|
||||||
|
|
||||||
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.test.junit4.createComposeRule
|
||||||
|
import androidx.compose.ui.test.onRoot
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.github.takahirom.roborazzi.captureRoboImage
|
||||||
|
import org.junit.Rule
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
import org.robolectric.RobolectricTestRunner
|
||||||
|
import org.robolectric.annotation.Config
|
||||||
|
import org.robolectric.annotation.GraphicsMode
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Пилот Roborazzi: рендер Compose designsystem в PNG на JVM (без эмулятора).
|
||||||
|
* Каркас Fd-сверки: экран → PNG → сравнение с веб-мобильной forbion.
|
||||||
|
*/
|
||||||
|
@RunWith(RobolectricTestRunner::class)
|
||||||
|
@GraphicsMode(GraphicsMode.Mode.NATIVE)
|
||||||
|
@Config(sdk = [34], qualifiers = "w390dp-h844dp-xxhdpi")
|
||||||
|
class ScreenshotProofTest {
|
||||||
|
|
||||||
|
@get:Rule
|
||||||
|
val composeRule = createComposeRule()
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun designsystem_primary_button() {
|
||||||
|
composeRule.setContent {
|
||||||
|
F7Theme {
|
||||||
|
Column(
|
||||||
|
modifier = Modifier.fillMaxSize().background(Color.White).padding(16.dp),
|
||||||
|
verticalArrangement = Arrangement.spacedBy(12.dp),
|
||||||
|
) {
|
||||||
|
Text("F7 design proof — Roborazzi")
|
||||||
|
F7PrimaryButton(text = "Сохранить", onClick = {})
|
||||||
|
F7SecondaryButton(text = "Отмена", onClick = {})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
composeRule.onRoot().captureRoboImage("src/test/screenshots/proof-primary-button.png")
|
||||||
|
}
|
||||||
|
}
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 95 KiB |
@@ -8,6 +8,8 @@ coreKtx = "1.15.0" # был дрейф 1.13.1 / 1.15.0
|
|||||||
lifecycle = "2.8.7" # был дрейф 2.8.1 / 2.8.7
|
lifecycle = "2.8.7" # был дрейф 2.8.1 / 2.8.7
|
||||||
coil = "2.7.0" # был дрейф 2.6.0 / 2.7.0
|
coil = "2.7.0" # был дрейф 2.6.0 / 2.7.0
|
||||||
media3 = "1.4.1" # нативный медиа-слой (видео/аудио) — ExoPlayer
|
media3 = "1.4.1" # нативный медиа-слой (видео/аудио) — ExoPlayer
|
||||||
|
roborazzi = "1.42.0" # screenshot-тесты Compose на JVM (Fd-сверка без эмулятора)
|
||||||
|
robolectric = "4.14.1"
|
||||||
coroutines = "1.10.1" # был дрейф 1.8.1 / 1.10.1
|
coroutines = "1.10.1" # был дрейф 1.8.1 / 1.10.1
|
||||||
navigationCompose = "2.8.9"
|
navigationCompose = "2.8.9"
|
||||||
room = "2.7.2"
|
room = "2.7.2"
|
||||||
@@ -42,6 +44,13 @@ coil-svg = { group = "io.coil-kt", name = "coil-svg", version.ref = "coil" }
|
|||||||
coil-gif = { group = "io.coil-kt", name = "coil-gif", version.ref = "coil" }
|
coil-gif = { group = "io.coil-kt", name = "coil-gif", version.ref = "coil" }
|
||||||
media3-exoplayer = { group = "androidx.media3", name = "media3-exoplayer", version.ref = "media3" }
|
media3-exoplayer = { group = "androidx.media3", name = "media3-exoplayer", version.ref = "media3" }
|
||||||
media3-ui = { group = "androidx.media3", name = "media3-ui", version.ref = "media3" }
|
media3-ui = { group = "androidx.media3", name = "media3-ui", version.ref = "media3" }
|
||||||
|
|
||||||
|
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-junit-rule = { group = "io.github.takahirom.roborazzi", name = "roborazzi-junit-rule", version.ref = "roborazzi" }
|
||||||
|
robolectric = { group = "org.robolectric", name = "robolectric", version.ref = "robolectric" }
|
||||||
|
compose-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" }
|
||||||
|
compose-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" }
|
||||||
coroutines-android = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-android", version.ref = "coroutines" }
|
coroutines-android = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-android", version.ref = "coroutines" }
|
||||||
coroutines-play-services = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-play-services", version.ref = "coroutines" }
|
coroutines-play-services = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-play-services", version.ref = "coroutines" }
|
||||||
okhttp = { group = "com.squareup.okhttp3", name = "okhttp", version.ref = "okhttp" }
|
okhttp = { group = "com.squareup.okhttp3", name = "okhttp", version.ref = "okhttp" }
|
||||||
|
|||||||
Reference in New Issue
Block a user