Closed MikaReesu closed 1 year ago
@mikareesu this is an interesting question, because based on the FragmentScenario source code, the problem is that when you use launchFragmentInContainer<T: Fragment>
, it internally uses an EmptyFragmentActivity
rather than your MainActivity
.
The EmptyFragmentActivity has support for a custom theme, but no other means of customization.
Based on FragmentScenario source code, this cannot be customized when using FragmentScenario.
So even though you have Navigator.install()
and a BackstackHost
installed in MainActivity
, it appears that the Activity in EmptyFragmentActivity
has no idea how to do that. There seems to also be no way to access this class from the outside and make any necessary customizations. Makes me wonder what FragmentScenario
is even doing, then.
Personally, when I was using Espresso, I was using getInstrumentation().runOnMainSync()
directly instead of androidx.test
.
However, it appears that ActivityScenario.onActivity
does exactly that: https://github.com/android/android-test/blob/5d69602b7f5950e8c62027e7eeb7f613e5f3b015/core/java/androidx/test/core/app/ActivityScenario.java#L802
Which means that instead of using launchFragmentInContainer
, you can theoretically use activityScenario.onActivity { activity -> Navigator.getBackstack(activity).setHistory(History.of(YourFragmentKey()), StateChange.REPLACE) }
in order to get the fragment showing, and you don't need launchFragmentInContainer
as that starts using EmptyFragmentActivity
instead of your MainActivity
.
Hope that helps.
Thank you very much for this answer. It was indeed spot on.
To give the exact code to achieve that, because I just tried it and it's working wonderfully.
You need the Activity Rule :
@Rule @JvmField val activityRule = ActivityScenarioRule(MainActivity::class.java)
And the test to access to the Fragment :
`@Test fun testFragmentIsVisible() {
activityRule.run {
scenario.onActivity {
activity -> Navigator.getBackstack(activity).setHistory(History.of(YourFragmentKey()), StateChange.REPLACE)
}
}
// your action to modify the view or whatever you wanna do.
}`
You said, "when I was using espresso", does it mean that you use something else now?
Thank you for your help!
You said, "when I was using espresso", does it mean that you use something else now?
Mistake in wording tbh. Espresso is still the best way to automate UI tests when using Views.
Thank you for your help!
Glad it works 😄
Hello, I am new to using espresso with Kotlin.
I'm using simple stack since a lot of time and since have a sometime I started to implement espresso.
Maybe it is my misunderstanding since it is new to me to use espresso.
`@RunWith(AndroidJUnit4::class) class FragmentTest {
}
I created an activityRule to have the MainActivity running from start and after I wanted to start one of my fragment.
I get this error directly :
java.lang.NullPointerException: Attempt to invoke virtual method 'com.zhuinden.simplestack.Backstack com.zhuinden.simplestack.navigator.BackstackHost.getBackstack()' on a null object reference
I would like to know how I could set up the Backstack properly in the test itself or the @Before.
The Backstack is setup this way in my MainActivity :
Navigator.configure() .setStateChanger(SimpleStateChanger(this)) .setGlobalServices(app.globalServices) .setScopedServices(DefaultServiceProvider()) .setShouldPersistContainerChild(false) .install(this, findViewById(R.id.container), History.of(SplashScreen()))
Espresso is new to me, so tell me if what I was doing is totally wrong and if you could give me a guidance on this it will be very helpful.
Thank you very much!