takahirom / roborazzi

Make JVM Android integration test visible 🤖📸
https://takahirom.github.io/roborazzi/
Apache License 2.0
709 stars 34 forks source link

Dialogs and Full screen capture issue #512

Open mattinger opened 3 hours ago

mattinger commented 3 hours ago

So i'm having some issues with capturing dialog snapshots when using the material3 theme.

I'm rendering a simple AlertDialog with an explicit container color of Color.White. However, when i capture either the screen or dialog contents, it's giving me an entirely different container color. You'll notice that the dialog container is some other color (that's not white). However, if i then set the composition local LocalTonalElevationEnabled to false, everything renders properly with the only difference being the tonal elevation enabled or not. The one on the left is the default setting, the one on the right is with me explicitly setting LocalTonalEvenvationEnabled to false.

I would chalk this up to a material 3 issue, however when i run either of these in a device (or emulator) they both look correct:

It seems like something in the capture mechanism isn't playing well with the tonal elevation.

@GraphicsMode(GraphicsMode.Mode.NATIVE)
@RunWith(AndroidJUnit4::class)
@Config(qualifiers = "w360dp-h1000dp")
class SnapshotIssue {
    @get:Rule
    val roborazziRule = RoborazziRule(
        options = RoborazziRule.Options(
            roborazziOptions = RoborazziOptions(
                compareOptions = RoborazziOptions.CompareOptions(
                    changeThreshold = 0.001F
                )
            )
        )
    )

    @Composable
    fun DialogContent() {
        AlertDialog(
            title = { Text("title") },
            text = { Text("body") },
            containerColor = Color.White,
            onDismissRequest = { },
            confirmButton = {
                TextButton(
                    onClick = { },
                ) {
                    Text("CANCEL")
                }
            },
            dismissButton = {
                TextButton(
                    onClick = { },
                ) {
                    Text("OK")
                }
            }
        )
    }

    @Composable
    fun WithMaterial3Theme(content: @Composable () -> Unit) {

        MaterialTheme(
            colorScheme = lightColorScheme(
                surface = Color.White,
                onSurface = Color.Black
            )
        ) {
            content()
        }
    }

    @OptIn(ExperimentalTestApi::class)
    @Test
    fun withTonalElevationDefault() {
        runComposeUiTest {
            setContent {
                WithMaterial3Theme {
                    DialogContent()
                }
            }

            onNode(isDialog()).captureRoboImage()
            captureScreenRoboImage()
        }
    }

    @OptIn(ExperimentalTestApi::class)
    @Test
    fun withTonalElevationDisabled() {
        runComposeUiTest {
            setContent {
                WithMaterial3Theme {
                    CompositionLocalProvider(LocalTonalElevationEnabled provides true) {
                        DialogContent()
                    }
                }
            }

            onNode(isDialog()).captureRoboImage()
            captureScreenRoboImage()
        }
    }
}
mattinger commented 2 hours ago

As a side note, we generally don't want tonal elevation, so our current solution is going to be to turn this off at the root theme level anyway, but I figured i should report this behavior in case it causes others issues.