test(deck): Roborazzi Fd screenshot-тесты (360dp) — список досок + доска со стеком (mail/111)

Обвязка build.gradle (плагин roborazzi + testOptions + тест-деп), DeckScreenshotTest рендерит
DeckBoardRow/DeckStackSection на мок-данных bmob-* (метки/срок/чек-пункты/комментарии/исполнитель),
PNG в src/test/screenshots. DeckBoardRow/DeckStackSection private→internal для рендера из теста.
Проверено: recordRoborazziDebug зелёный, detekt green.
This commit is contained in:
b-mob-deck
2026-07-13 09:41:13 +00:00
parent 9efb3595c0
commit 58f11c2991
5 changed files with 116 additions and 2 deletions
+13
View File
@@ -2,6 +2,7 @@ plugins {
id 'com.android.library'
id 'org.jetbrains.kotlin.android'
id 'org.jetbrains.kotlin.plugin.compose'
id 'io.github.takahirom.roborazzi'
}
android {
@@ -21,6 +22,12 @@ android {
kotlinOptions {
jvmTarget = '17'
}
// Roborazzi/Robolectric: рендер Compose deck-экранов в PNG на JVM (Fd-сверка, mail/111).
testOptions {
unitTests {
includeAndroidResources = true
}
}
}
dependencies {
@@ -35,4 +42,10 @@ dependencies {
implementation libs.compose.material3
implementation libs.compose.foundation
implementation libs.lifecycle.viewmodel.compose
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
}
@@ -213,7 +213,7 @@ private fun DeckStackDialogs(
}
@Composable
private fun DeckBoardRow(board: DeckBoard, onClick: () -> Unit) {
internal fun DeckBoardRow(board: DeckBoard, onClick: () -> Unit) {
Row(
modifier = Modifier
.fillMaxWidth()
@@ -245,7 +245,7 @@ private fun DeckBoardRow(board: DeckBoard, onClick: () -> Unit) {
@OptIn(ExperimentalLayoutApi::class)
@Composable
private fun DeckStackSection(
internal fun DeckStackSection(
stack: DeckStack,
canEdit: Boolean,
onCardClick: (DeckCard) -> Unit,
@@ -0,0 +1,101 @@
package ru.forbion.f7cloud.feature.deck
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.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
import ru.forbion.f7cloud.core.designsystem.F7Theme
/**
* Fd-сверка Карточек (Roborazzi, mail/111): рендер экранов в PNG на JVM (360dp, без эмулятора).
* Данные — только мок (`bmob-*`), реальные данные `cloude` не используются.
* Сравнение PNG ↔ веб-эталон (`docs/app-map/reference/deck/`) → пункты Д в `deck.diff.md`.
*/
@RunWith(RobolectricTestRunner::class)
@GraphicsMode(GraphicsMode.Mode.NATIVE)
@Config(sdk = [34], qualifiers = "w360dp-h800dp-xxhdpi")
class DeckScreenshotTest {
@get:Rule
val composeRule = createComposeRule()
private val labels = listOf(
DeckLabel(id = 1, title = "bmob-важное", color = "e74c3c"),
DeckLabel(id = 2, title = "bmob-ревью", color = "3498db"),
)
private val mockStack = DeckStack(
id = 1,
boardId = 1,
title = "В работе",
order = 0,
cards = listOf(
DeckCard(
id = 1,
title = "bmob-карточка со сроком и метками",
done = false,
description = "- [x] шаг 1\n- [ ] шаг 2",
duedate = "2026-07-20T00:00:00+00:00",
order = 0,
stackId = 1,
labels = labels,
assignees = listOf("bmob-user"),
assigneeUids = listOf("bmob-user"),
commentsCount = 3,
),
DeckCard(id = 2, title = "bmob-выполненная", done = true, stackId = 1, order = 1),
),
)
@Test
fun deck_boards_list() {
composeRule.setContent {
F7Theme {
Column(
modifier = Modifier.fillMaxSize().background(Color.White).padding(8.dp),
verticalArrangement = Arrangement.spacedBy(8.dp),
) {
DeckBoardRow(DeckBoard(id = 1, title = "bmob-доска", color = "9b59b6")) {}
DeckBoardRow(DeckBoard(id = 2, title = "bmob-проект", color = "2ecc71")) {}
}
}
}
composeRule.onRoot().captureRoboImage("src/test/screenshots/deck-boards.png")
}
@Test
fun deck_board_with_stack() {
composeRule.setContent {
F7Theme {
Column(
modifier = Modifier.fillMaxSize().background(Color.White).padding(8.dp),
verticalArrangement = Arrangement.spacedBy(12.dp),
) {
DeckStackSection(
stack = mockStack,
canEdit = true,
onCardClick = {},
onToggleDone = {},
onAddCard = {},
onRename = {},
onDelete = {},
)
}
}
}
composeRule.onRoot().captureRoboImage("src/test/screenshots/deck-board.png")
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB