Skip to content

Migrate lazycolumnscreen to m3 #69

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,24 +1,30 @@
package snapshot.testing.lazycolumn_previews.compose_screenshot

import android.content.res.Configuration
import android.os.Build
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewFontScale
import androidx.compose.ui.tooling.preview.PreviewLightDark
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.Wallpapers
import com.example.road.to.effective.snapshot.testing.lazycolumnscreen.AppTheme
import com.example.road.to.effective.snapshot.testing.lazycolumnscreen.CoffeeDrinkAppBar
import com.example.road.to.effective.snapshot.testing.lazycolumnscreen.CoffeeDrinkItem
import com.example.road.to.effective.snapshot.testing.lazycolumnscreen.CoffeeDrinkList
import com.example.road.to.effective.snapshot.testing.lazycolumnscreen.R

/**
* Screenshot tests are generated from these Previews.
* A general tolerance value is defined in the gradle plugin
*
* Record: ./gradlew :lazycolumnscreen-previews:compose-screenshot:updateDebugScreenshotTest
* Verify: ./gradlew :lazycolumnscreen-previews:compose-screenshot:validateDebugScreenshotTest
*
* Keep in mind that currently, Compose Preview screenshot testing tool only supports previews
* in the "screenshotTest" source, so previews in the "main" source are ignored
*/
class PreviewsForScreenshotTests {
class CoffeeDrinkItemPreviews {
private val coffeeDrink =
CoffeeDrinkItem(
id = 1L,
Expand Down Expand Up @@ -66,7 +72,7 @@ class PreviewsForScreenshotTests {
}
}

@Preview(apiLevel = 31)
@Preview(apiLevel = 33)
@Composable
fun CoffeeDrinkListApiLevelPreview() {
AppTheme {
Expand All @@ -75,4 +81,62 @@ class PreviewsForScreenshotTests {
)
}
}
}

class AppBarWallpaperPreviews {
// Dynamic Colors are applied from API 31+
@Preview(
apiLevel = 30,
uiMode = Configuration.UI_MODE_NIGHT_YES
)
@Preview(
apiLevel = 30,
uiMode = Configuration.UI_MODE_NIGHT_NO
)
@Preview(
apiLevel = 33,
wallpaper = Wallpapers.BLUE_DOMINATED_EXAMPLE,
uiMode = Configuration.UI_MODE_NIGHT_NO
)
@Preview(
apiLevel = 33,
wallpaper = Wallpapers.BLUE_DOMINATED_EXAMPLE,
uiMode = Configuration.UI_MODE_NIGHT_YES
)
@Preview(
apiLevel = 33,
wallpaper = Wallpapers.RED_DOMINATED_EXAMPLE,
uiMode = Configuration.UI_MODE_NIGHT_NO
)
@Preview(
apiLevel = 33,
wallpaper = Wallpapers.RED_DOMINATED_EXAMPLE,
uiMode = Configuration.UI_MODE_NIGHT_YES
)
@Preview(
apiLevel = 33,
wallpaper = Wallpapers.GREEN_DOMINATED_EXAMPLE,
uiMode = Configuration.UI_MODE_NIGHT_NO
)
@Preview(
apiLevel = 33,
wallpaper = Wallpapers.GREEN_DOMINATED_EXAMPLE,
uiMode = Configuration.UI_MODE_NIGHT_YES
)
@Preview(
apiLevel = 33,
wallpaper = Wallpapers.YELLOW_DOMINATED_EXAMPLE,
uiMode = Configuration.UI_MODE_NIGHT_NO
)
@Preview(
apiLevel = 33,
wallpaper = Wallpapers.YELLOW_DOMINATED_EXAMPLE,
uiMode = Configuration.UI_MODE_NIGHT_YES
)
@Composable
fun PreviewCoffeeDrinkAppBar() {
AppTheme {
CoffeeDrinkAppBar()
}
}
}
5 changes: 4 additions & 1 deletion lazycolumnscreen-previews/roborazzi/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ dependencies {
implementation platform('androidx.compose:compose-bom:2024.05.00')
implementation "androidx.compose.runtime:runtime"
implementation "androidx.compose.foundation:foundation-layout"
implementation "androidx.compose.material:material"
implementation "androidx.compose.material3:material3"
implementation "androidx.compose.material:material-icons-extended"
implementation "androidx.compose.foundation:foundation"
implementation "androidx.compose.animation:animation"
Expand All @@ -81,4 +81,7 @@ dependencies {

testImplementation 'io.github.takahirom.roborazzi:roborazzi-compose:1.26.0'
testImplementation 'com.github.sergio-sastre.ComposablePreviewScanner:android:0.3.0'

// To support Dynamic Colors in Roborazzi tests
testImplementation("com.materialkolor:material-kolor:1.7.0")
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
package snapshot.testing.lazycolumn_previews.roborazzi

import android.content.res.Configuration
import android.os.Build
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewFontScale
import androidx.compose.ui.tooling.preview.PreviewLightDark
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.Wallpapers
import com.example.road.to.effective.snapshot.testing.lazycolumnscreen.AppTheme
import com.example.road.to.effective.snapshot.testing.lazycolumnscreen.CoffeeDrinkAppBar
import com.example.road.to.effective.snapshot.testing.lazycolumnscreen.CoffeeDrinkItem
import com.example.road.to.effective.snapshot.testing.lazycolumnscreen.CoffeeDrinkList
import com.example.road.to.effective.snapshot.testing.lazycolumnscreen.R
Expand Down Expand Up @@ -39,7 +42,6 @@ fun CoffeeDrinkListWithParametersPreview(
}
}


@PreviewFontScale
@PreviewLightDark
@Composable
Expand All @@ -61,7 +63,7 @@ fun CoffeeDrinkListPseudoLocalePreview() {
}
}

@Preview(apiLevel = 31)
@Preview(apiLevel = 33)
@Composable
fun CoffeeDrinkListApiLevelPreview() {
AppTheme {
Expand All @@ -80,4 +82,60 @@ fun CoffeeDrinkListAccessibilityPreview() {
coffeeDrink = coffeeDrink
)
}
}

// Dynamic Colors are applied from API 31+
@Preview(
apiLevel = 30,
uiMode = Configuration.UI_MODE_NIGHT_YES
)
@Preview(
apiLevel = 30,
uiMode = Configuration.UI_MODE_NIGHT_NO
)
@Preview(
apiLevel = 33,
wallpaper = Wallpapers.BLUE_DOMINATED_EXAMPLE,
uiMode = Configuration.UI_MODE_NIGHT_NO
)
@Preview(
apiLevel = 33,
wallpaper = Wallpapers.BLUE_DOMINATED_EXAMPLE,
uiMode = Configuration.UI_MODE_NIGHT_YES
)
@Preview(
apiLevel = 33,
wallpaper = Wallpapers.RED_DOMINATED_EXAMPLE,
uiMode = Configuration.UI_MODE_NIGHT_NO
)
@Preview(
apiLevel = 33,
wallpaper = Wallpapers.RED_DOMINATED_EXAMPLE,
uiMode = Configuration.UI_MODE_NIGHT_YES
)
@Preview(
apiLevel = 33,
wallpaper = Wallpapers.GREEN_DOMINATED_EXAMPLE,
uiMode = Configuration.UI_MODE_NIGHT_NO
)
@Preview(
apiLevel = 33,
wallpaper = Wallpapers.GREEN_DOMINATED_EXAMPLE,
uiMode = Configuration.UI_MODE_NIGHT_YES
)
@Preview(
apiLevel = 33,
wallpaper = Wallpapers.YELLOW_DOMINATED_EXAMPLE,
uiMode = Configuration.UI_MODE_NIGHT_NO
)
@Preview(
apiLevel = 33,
wallpaper = Wallpapers.YELLOW_DOMINATED_EXAMPLE,
uiMode = Configuration.UI_MODE_NIGHT_YES
)
@Composable
fun PreviewCoffeeDrinkAppBar() {
AppTheme {
CoffeeDrinkAppBar()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import sergio.sastre.composable.preview.scanner.android.AndroidComposablePreview
import sergio.sastre.composable.preview.scanner.android.AndroidPreviewInfo
import sergio.sastre.composable.preview.scanner.android.screenshotid.AndroidPreviewScreenshotIdBuilder
import sergio.sastre.composable.preview.scanner.core.preview.ComposablePreview
import snapshot.testing.lazycolumn_previews.roborazzi.utils.RenderPreview
import snapshot.testing.lazycolumn_previews.roborazzi.utils.RobolectricPreviewInfosApplier
import snapshot.testing.lazycolumn_previews.roborazzi.utils.RoborazziConfig
import snapshot.testing.lazycolumn_previews.roborazzi.utils.RoborazziOptionsMapper
Expand Down Expand Up @@ -40,7 +41,9 @@ class RoborazziApiLevelUnder28ComposePreviewTests(
.scanPackageTrees("snapshot.testing.lazycolumn_previews.roborazzi")
.includeAnnotationInfoForAllOf(RoborazziConfig::class.java)
// Native graphics do not work fine on API < 28, and default value is -1
.filterPreviews { previewParams -> previewParams.apiLevel < 28 }
.filterPreviews {
preview -> preview.apiLevel < 28 || preview.apiLevel == 34
}
.getPreviews()
}

Expand All @@ -59,13 +62,13 @@ class RoborazziApiLevelUnder28ComposePreviewTests(
filePath = filePath(AndroidPreviewScreenshotIdBuilder(preview).build()),
roborazziOptions = RoborazziOptionsMapper.createFor(preview)
) {
preview()
RenderPreview(preview)
}
}
}

@RunWith(ParameterizedRobolectricTestRunner::class)
class RoborazziApiLevel31ComposePreviewTests(
class RoborazziApiLevelUnder30ComposePreviewTests(
private val preview: ComposablePreview<AndroidPreviewInfo>,
) {

Expand All @@ -74,7 +77,42 @@ class RoborazziApiLevel31ComposePreviewTests(
AndroidComposablePreviewScanner()
.scanPackageTrees("snapshot.testing.lazycolumn_previews.roborazzi")
.includeAnnotationInfoForAllOf(RoborazziConfig::class.java)
.filterPreviews { previewParams -> previewParams.apiLevel == 31 }
// Native graphics do not work fine on API < 28, and default value is -1
.filterPreviews { preview -> preview.apiLevel == 30 }
.getPreviews()
}

@JvmStatic
@ParameterizedRobolectricTestRunner.Parameters
fun values(): List<ComposablePreview<AndroidPreviewInfo>> = cachedPreviews
}

@GraphicsMode(NATIVE)
@Config(sdk = [30]) // same as filtered previews
@Test
fun snapshot() {
RobolectricPreviewInfosApplier.applyFor(preview)

captureRoboImage(
filePath = filePath(AndroidPreviewScreenshotIdBuilder(preview).build()),
roborazziOptions = RoborazziOptionsMapper.createFor(preview)
) {
RenderPreview(preview)
}
}
}

@RunWith(ParameterizedRobolectricTestRunner::class)
class RoborazziApiLevel33ComposePreviewTests(
private val preview: ComposablePreview<AndroidPreviewInfo>,
) {

companion object {
private val cachedPreviews: List<ComposablePreview<AndroidPreviewInfo>> by lazy {
AndroidComposablePreviewScanner()
.scanPackageTrees("snapshot.testing.lazycolumn_previews.roborazzi")
.includeAnnotationInfoForAllOf(RoborazziConfig::class.java)
.filterPreviews { preview -> preview.apiLevel == 33 }
.getPreviews()
}

Expand All @@ -84,7 +122,7 @@ class RoborazziApiLevel31ComposePreviewTests(
}

@GraphicsMode(NATIVE)
@Config(sdk = [31]) // same as filtered previews
@Config(sdk = [33]) // same as filtered previews
@Test
fun snapshot() {
RobolectricPreviewInfosApplier.applyFor(preview)
Expand All @@ -93,7 +131,7 @@ class RoborazziApiLevel31ComposePreviewTests(
filePath = filePath(AndroidPreviewScreenshotIdBuilder(preview).build()),
roborazziOptions = RoborazziOptionsMapper.createFor(preview)
) {
preview()
RenderPreview(preview)
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package snapshot.testing.lazycolumn_previews.roborazzi.utils

import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Wallpapers
import com.example.road.to.effective.snapshot.testing.lazycolumnscreen.LocalAppTheme
import com.materialkolor.DynamicMaterialTheme
import sergio.sastre.composable.preview.scanner.android.AndroidPreviewInfo
import sergio.sastre.composable.preview.scanner.core.preview.ComposablePreview

@Composable
fun RenderPreview(
previewComposable: ComposablePreview<AndroidPreviewInfo>
) {
val seedColor =
when (previewComposable.previewInfo.wallpaper) {
Wallpapers.RED_DOMINATED_EXAMPLE -> Color.Red
Wallpapers.GREEN_DOMINATED_EXAMPLE -> Color.Green
Wallpapers.YELLOW_DOMINATED_EXAMPLE -> Color.Yellow
Wallpapers.BLUE_DOMINATED_EXAMPLE -> Color.Blue
Wallpapers.NONE -> null
else -> null
}

when (seedColor == null) {
true -> previewComposable()
false ->
CompositionLocalProvider(
LocalAppTheme provides { content -> DynamicMaterialTheme(seedColor) { content() } }
) {
previewComposable()
}
}
}
3 changes: 2 additions & 1 deletion lazycolumnscreen/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,12 @@ dependencies {
implementation "androidx.compose.runtime:runtime"
implementation "androidx.compose.ui:ui"
implementation "androidx.compose.foundation:foundation-layout"
implementation "androidx.compose.material:material"
implementation "androidx.compose.material3:material3"
implementation "androidx.compose.material:material-icons-extended"
implementation "androidx.compose.foundation:foundation"
implementation "androidx.compose.animation:animation"
implementation "androidx.compose.ui:ui-tooling"
implementation "androidx.compose.ui:ui-tooling-preview"
implementation "androidx.compose.runtime:runtime-livedata"

implementation "androidx.navigation:navigation-compose:2.7.7"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import android.view.ViewGroup
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.ui.platform.ComposeView
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.fragment.app.viewModels

class CoffeeDrinksFragment : Fragment() {
Expand Down
Loading