cashapp / paparazzi

Render your Android screens without a physical device or emulator
https://cashapp.github.io/paparazzi/
Apache License 2.0
2.21k stars 209 forks source link

Popup Content Missing in Paparazzi Rendered Snapshots for Composable Functions #1414

Open hd-bitingbit opened 1 month ago

hd-bitingbit commented 1 month ago

Description When attempting to record a snapshot using Paparazzi for a composable function with a Popup, the content of the Popup disappears in the recorded snapshot.

Steps to Reproduce

  1. Create a composable function that includes a Popup to display information. Sample Code:
    @Composable
    fun TestPopup() {
    MaterialTheme {
        Column(modifier = Modifier.fillMaxSize()) {
            Text(text = "Sample text")
            Popup(alignment = Alignment.BottomCenter) {
                Text(
                    text = "Hello Snapshot!",
                    modifier = Modifier
                        .fillMaxWidth()
                        .heightIn(min = 60.dp),
                    textAlign = TextAlign.Center,
                    color = Color.Black
                )
            }
        }
    }
    }
  2. Attempt to record a snapshot using Paparazzi.

Expected behavior The recorded snapshot should accurately capture the content of the Popup along with the rest of the composable function.

Actual behavior In the recorded snapshot, the Popup is drawn, but the content within it is missing.

Additional information:

Screenshots Preview Screenshot: Screenshot 2024-05-07 at 11 17 07 Recorded Snapshot:

Screenshot 2024-05-07 at 10 38 52
juckrit commented 4 weeks ago

I have this issue too, But in my case it cannot render Dialog Composable.

kevinzheng-ap commented 1 week ago

Hi @geoff-powell, have you made any progress on it? Thanks

geoff-powell commented 1 week ago

Yep, I have a branch with some code that solves this issue. Basically debugged AS Layout Lib and noticed that LL fires multiple render calls to get render the UI. The tracks if the recomposer has pending compositions, and will call a subsequent render per each frame that is rendered.

Still debugging if that is the best solution.