Skip to content
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

Composables with NavHost are not rendered correctly #635

Open
magdamagda opened this issue Nov 21, 2022 · 6 comments
Open

Composables with NavHost are not rendered correctly #635

magdamagda opened this issue Nov 21, 2022 · 6 comments
Labels
bug Something isn't working

Comments

@magdamagda
Copy link

Description
When calling paparazzi.snapshot(...) for composable that has NavHost inside test fails with error NavHost requires a ViewModelStoreOwner to be provided via LocalViewModelStoreOwner. After mocking ViewModelStoreOwner test runs successfully, snapshot is generated but NavHost is empty.

Steps to Reproduce
I try to take screenshot for following composable:

paparazzi.snapshot("test") {
            NavHost(
                    navController = navController,
                    startDestination = "route"
                ) {
                    composable("route") {
                        Text(text = "Test")
                    }
                }
}

As a result I get an error:
NavHost requires a ViewModelStoreOwner to be provided via LocalViewModelStoreOwner

When I try to mock missing ViewModelStoreOwner like that:

paparazzi.snapshot("test") {
            mockkStatic(ViewTreeViewModelStoreOwner::class)
            every {ViewTreeViewModelStoreOwner.get(any())} returns ViewModelStoreOwner { ViewModelStore() }
            val navController = rememberNavController()
            NavHost(
                navController = navController,
                startDestination = "route"
            ) {
                composable("route") {
                    Text(text = "Test")
                }
            }
}

Rendered screenshot is empty.

Expected behavior
I would expect screenshot to have "Test" label displayed.

Additional information:

  • Paparazzi Version: 1.1.0-sdk33-alpha02
  • Compile SDK: 33
  • Gradle Version: 7.5.1
  • Android Gradle Plugin Version: 7.2.2
@magdamagda magdamagda added the bug Something isn't working label Nov 21, 2022
@alexvanyo
Copy link
Contributor

In the second example (where a ViewModelStore is available), this likely an issue with the navigation component in the same vein as #513. The initial route is not immediately displayed, so similarly a NavHost won't display the start destination in a @Preview.

A NavHost would likely need to support being used in a @Preview before it would be able to be rendered by Paparazzi, unless there is support added for async effects.

@nuhkoca
Copy link

nuhkoca commented Dec 25, 2022

@alexvanyo I use animateContentSize or other animate*AsStates and am facing this issue, too. My tests are empty even if I wrap those into @Preview it still doesn't work. Any idea?

@JakeWharton
Copy link
Collaborator

Is your example a real-world one or contrived? I do not think you should place your entire navigational infrastructure into the composable under test. You should be placing individual screens.

Also please, please, please do not use mocking to solve these types of problems. Compose has a hierarchical service loader that you can use to insert services that are required by children. For ViewModelStoreOwner you can use https://developer.android.com/reference/kotlin/androidx/lifecycle/viewmodel/compose/LocalViewModelStoreOwner like this:

CompositionLocal(LocalViewModelStoreOwner provides yourFake) {
  RegularComposeStuff()
}

@magdamagda
Copy link
Author

What if screen has top app bar, bottom bar and navigation between them? Then only option to test whole screen is to put composable with navigation under test.
I think similar issue is with snackbars scaffoldState.snackbarHostState.showSnackbar() runs asynchronously and snackbars are not rendered.

@magdamagda
Copy link
Author

Is there any chance it will be fixed on paparazzi site? Or should we wait for support for async effect in @Preview?

@alexvanyo
Copy link
Contributor

For the NavHost in particular, 2.6.0-alpha06 includes a change that allows @Previews to show the start destination, which means this is likely to work in Paparazzi now as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants