android-test icon indicating copy to clipboard operation
android-test copied to clipboard

Toast message assertions not working with android 11 and target sdk 30

Open MarieT2020 opened this issue 3 years ago • 29 comments

Description

On the app I am testing there are a number of toast messages that I check to make sure toasts are displayed with correct text. My espresso tests started to fail when using Android 11 and SDK30.

Steps to Reproduce

I have a simple check where I try to check the text appears on screen for a toast. onView(withText(R.string.toast_text)).inRoot( withDecorView(not(activityRule.activity.window.decorView))) .check(matches(isDisplayed()))

I have also tried with a Custom toast matcher without any luck

fun onToast(
        text: Int,
       @IntRange(from = 1) maximumRetries: Int = MAX_RETRIES
 ): ViewInteraction = onView(withText(text)).inRoot(ToastMatcher(maximumRetries))

class ToastMatcher(private val maximumRetries: Int) : TypeSafeMatcher<Root>() {

private var currentFailures: Int = 0

override fun describeTo(description: Description?) {
    description?.appendText("no toast found after")
}

override fun matchesSafely(item: Root?): Boolean {
    val type: Int? = item?.windowLayoutParams?.get()?.type

    if(TYPE_TOAST == type || TYPE_APPLICATION_OVERLAY == type) {
        val windowToken = item.decorView.windowToken
        val appToken = item.decorView.applicationWindowToken

        if(windowToken == appToken) {
            return true
        }
    }

    return ++currentFailures >= maximumRetries
}
}

onToast(R.string.toast_text) .check(matches(isDisplayed()))

Expected Results

Tests pass. This works as expected when using OS lower than android 11. It also works as expected when using android 11 and sdk 29. I also tried updating the version of androidx and espresso to the latest version 3.3.0 and 1.3.0 but this did not make any difference.

Actual Results

Result when using withDecorView androidx.test.espresso.NoMatchingRootException: Matcher 'with decor view not <DecorView@5ae48a6[TestActivity]>' did not match any of the following roots: [Root{application-window-token=android.view.ViewRootImpl$W@1337585, window-token=android.view.ViewRootImpl$W@1337585, has-window-focus=true, layout-params-type=1, layout-params-string={(0,0)(fillxfill) sim={state=hidden} ty=BASE_APPLICATION wanim=0x10302fe fl=LAYOUT_IN_SCREEN LAYOUT_INSET_DECOR SPLIT_TOUCH HARDWARE_ACCELERATED DRAWS_SYSTEM_BAR_BACKGROUNDS pfl=FORCE_DRAW_STATUS_BAR_BACKGROUND FIT_INSETS_CONTROLLED fitSides=}, decor-view-string=DecorView{id=-1, visibility=VISIBLE, width=1080, height=2160, has-focus=false, has-focusable=true, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, layout-params={(0,0)(fillxfill) sim={state=hidden} ty=BASE_APPLICATION wanim=0x10302fe fl=LAYOUT_IN_SCREEN LAYOUT_INSET_DECOR SPLIT_TOUCH HARDWARE_ACCELERATED DRAWS_SYSTEM_BAR_BACKGROUNDS pfl=FORCE_DRAW_STATUS_BAR_BACKGROUND FIT_INSETS_CONTROLLED fitSides=}, tag=null, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, child-count=3}}] at dalvik.system.VMStack.getThreadStackTrace(Native Method) at java.lang.Thread.getStackTrace(Thread.java:1736) at androidx.test.espresso.base.DefaultFailureHandler.getUserFriendlyError(DefaultFailureHandler.java:96) at androidx.test.espresso.base.DefaultFailureHandler.handle(DefaultFailureHandler.java:59) at androidx.test.espresso.ViewInteraction.waitForAndHandleInteractionResults(ViewInteraction.java:322) at androidx.test.espresso.ViewInteraction.check(ViewInteraction.java:306)

Result when using ToastMatcher androidx.test.espresso.NoMatchingViewException: No views in hierarchy found matching: with string from resource id: <2131755255>[toast_text] value: Toast Text. If the target view is not part of the view hierarchy, you may need to use Espresso.onData to load it from one of the following AdapterViews:com.squareup.timessquare.CalendarPickerView{1af12d7 VFED.VC.. ........ 0,0-1080,1657 #7f09010e app:id/calendarPv} View Hierarchy: +>DecorView{id=-1, visibility=VISIBLE, width=1080, height=2160, has-focus=false, has-focusable=true, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, layout-params={(0,0)(fillxfill) ty=BASE_APPLICATION wanim=0x10302fe fl=LAYOUT_IN_SCREEN LAYOUT_INSET_DECOR SPLIT_TOUCH HARDWARE_ACCELERATED DRAWS_SYSTEM_BAR_BACKGROUNDS pfl=FORCE_DRAW_STATUS_BAR_BACKGROUND FIT_INSETS_CONTROLLED fitSides=}, tag=null, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, child-count=3} |

AndroidX Test and Android OS Versions

AndroidX Test: 1.2.0 Espresso: 3.2.0 Android OS: Android 11 (API 30)

MarieT2020 avatar Nov 17 '20 10:11 MarieT2020

Get the same this issue. If I use target lower api 30, It will work fine. Has Anyone fixed it?

vfa-tamhh avatar Mar 18 '21 10:03 vfa-tamhh

any update about that issue?

dnhirsh1 avatar May 31 '21 09:05 dnhirsh1

Any updates on this issue? I am still getting the same errors. Any workarounds? Thanks!

Tangjiahui26 avatar Jun 09 '21 18:06 Tangjiahui26

We are also trying to figure this out if anyone has came up with a solution.

davidmcraejr avatar Jun 16 '21 14:06 davidmcraejr

Also experiencing this. We're most likely going to pull out an interface for showing toasts that can be replaced with a recording fake in tests for assertions, but it'd be good to get guidance around if this is something that Espresso will support again in future.

seadowg avatar Oct 29 '21 13:10 seadowg

Get the same this issue. When I run the test using ToastMaster or DecorView the test takes a long time to run no matter if it is API 30 or 29 and in the end it fails.

    @Test
    @UiThreadTest
    fun showToastMessage_message_should_be_displayed() {
        val messageExpected = appContext.getString(R.string.toastMessage)
        appContext.showToastMessage(messageExpected))
        onView(withText(messageExpected)).inRoot(ToastMatcher())
            .check(matches(isDisplayed()))
    }
    @Test
    @UiThreadTest
    fun showToastMessage_message_should_be_displayed() {
        val messageExpected = appContext.getString(R.string.toastMessage)
        appContext.showToastMessage(messageExpected))
        onView(withText(messageExpected))
            .inRoot(withDecorView(not(decorView)))
            .check(matches(isDisplayed()))
    }

bacarPereira avatar Feb 10 '22 16:02 bacarPereira

So after looking at every link and StackOverflow it looks like there is no way to check for a toast if targetSdk is 30 as of May 2022?

rbarbish avatar May 20 '22 18:05 rbarbish

@rbarbish I ended up just adding a version check in the test and only running that test on sdks less than 30, not optimal but until a solution is found its what we can do...

davidmcraejr avatar May 20 '22 18:05 davidmcraejr

I am also not able to find any solution to this issue. If any solution Found pls share:)

arsalan04ahmad avatar May 30 '22 05:05 arsalan04ahmad

I face this issue too, when I run my android test in android 7 it works fine, but when I try in my android 11 it fails

AnandaDwiprayoga avatar Jun 06 '22 15:06 AnandaDwiprayoga

This is also happening to me, so I resolved it replacing inRoot by this solution with UIAutomator and assertTrue:

import androidx.test.platform.app.InstrumentationRegistry
import junit.framework.Assert.assertTrue
import androidx.test.uiautomator.By
import androidx.test.uiautomator.UiDevice

val device: UiDevice
        get() = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())

assertTrue(device.hasObject(By.text(toastMessageDuplicated)))

clarabez avatar Jul 01 '22 01:07 clarabez

@clarabez Won't the ui automator take time initializing?

arsalan04ahmad avatar Jul 05 '22 11:07 arsalan04ahmad

Maybe, but you're not having Toasts in all of your tests hopefully, right? 😅

TWiStErRob avatar Jul 05 '22 11:07 TWiStErRob

@TWiStErRob Yes I have used Toast as less as possible because of the testing issue. But there are some cases that can only be verified using toast . I am stuck in that :)

arsalan04ahmad avatar Jul 05 '22 12:07 arsalan04ahmad

@clarabez Won't the ui automator take time initializing?

It is not in my case, same execution time.

clarabez avatar Jul 05 '22 12:07 clarabez

@clarabez Still my test cases are failing can you pls elaborate

val device: UiDevice
        get() = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())

This get() is giving syntax error, can you pls share the complete Toast matcher code . It would be really helpful

arsalan04ahmad avatar Jul 07 '22 09:07 arsalan04ahmad

@clarabez Still my test cases are failing can you pls elaborate

val device: UiDevice
        get() = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())

This get() is giving syntax error, can you pls share the complete Toast matcher code . It would be really helpful

Sure! The project that I am working with this solution is open in my GitHub here. Feel free to check it! :) Let me know if it works for you.

clarabez avatar Jul 07 '22 11:07 clarabez

@clarabez I cannot open your project. Its showing page not found. I assume that its in your android testing repository. Can you pls specify the package and the class to look at.

arsalan04ahmad avatar Jul 07 '22 11:07 arsalan04ahmad

@clarabez I cannot open your project. Its showing page not found. I assume that its in your android testing repository. Can you pls specify the package and the class to look at.

Ops, sorry, it was private. Now it is public. Link here.

clarabez avatar Jul 07 '22 12:07 clarabez

@clarabez It didn't work for me in Android 12 , the assertion always Fails :\

arsalan04ahmad avatar Jul 07 '22 12:07 arsalan04ahmad

@clarabez It didn't work for me in Android 12 , the assertion always Fails :\

oh, sad to hear that! :( let us know if you find any valid solution for Android 12

clarabez avatar Jul 08 '22 12:07 clarabez

@clarabez what you are testing in your project is a Snackbar ... not a toast.. this solution don't work for toast

Venkat-juju avatar Jul 21 '22 05:07 Venkat-juju

Hello everyone, does anyone have updates for this topic ? So until now we can not test Toast is displayed from Android 11 with Espresso ? Please share if you have some updates about that. Thank you all.

testfacefanpage avatar Oct 21 '22 08:10 testfacefanpage

Hi @ralf-at-android

When I write the test to verify Toast is displayed like this:

Espresso.onView(withText("Toast message here")).inRoot(withDecorView(not(decorView))).check(matches(isDisplayed()))

It work fine in Android lower Android 11. But from Android 11 I have an exception like this:

androidx.test.espresso.NoMarchingRootException: Matcher 'with decor view not <DecorView@17028cf[MyActivity]>' did not match any of the following roots: [Root{application-window-token=android.view.ViewRootImpl$W@3daab3f, window-token=android.view.ViewRootImpl$W@3daab3f, has-window-focus=true, layout-params-type=1, layout-params-string={(0,0)(fillxfill) ty=BASE_APPLICATION wanim=0x10302fe

Thank you for your idea about that!

testfacefanpage avatar Oct 22 '22 05:10 testfacefanpage

So, we are unable to test toasts now? Is there a reason for that? Security issues?

sarimmehdi avatar Dec 10 '22 16:12 sarimmehdi

+1 can't test with a ToastMatcher on API 30 https://stackoverflow.com/questions/28390574/checking-toast-message-in-android-espresso

luongvo avatar Dec 26 '22 05:12 luongvo

I am testing with API 33, Android 13, does not work. Does anybody have any updates on this problem? It looks like Toast is a red flag for Espresso-based testing. It was such a cool UI!

masud-technope avatar Jul 10 '23 01:07 masud-technope

I am testing with API 33, Android 13, does not work. Does anybody have any updates on this problem? It looks like Toast is a red flag for Espresso-based testing. It was such a cool UI!

We switched from Toast to SnackBar, might bei an option for you too.

djbrown avatar Jul 10 '23 06:07 djbrown

Thanks a ton, @djbrown :) I was spending days with the Toast. Now SnackBar worked like a charm!

masud-technope avatar Jul 10 '23 15:07 masud-technope