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

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

Open
MarieT2020 opened this issue Nov 17, 2020 · 29 comments
Open

Comments

@MarieT2020
Copy link

MarieT2020 commented Nov 17, 2020

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)

@vfa-tamhh
Copy link

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

@dnhirsh1
Copy link

any update about that issue?

@Tangjiahui26
Copy link

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

@davidmcraejr
Copy link

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

artem-benda pushed a commit to artem-benda/nd940-todo-list-app that referenced this issue Jul 11, 2021
fix
fixed issues found on project review:
1.	There is no error message when the location permission is denied by the user.
2.	The user can't select a random location on the map.
3.	Device location isn't checked or properly handled right before adding a geofence.
4.	All the users' reminders added earlier stop working after GEOFENCE_EXPIRE_MILLIS.
5.	If the user went to a location with multiple triggering Geofences, only one notification would appear.
6.	No UI tests for Toast messages. (works only for API level < 30, see android/android-test#803)
7.	Predictable errors like data not found are not tested.
@seadowg
Copy link

seadowg commented Oct 29, 2021

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.

@bacarPereira
Copy link

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()))
    }

@rbarbish
Copy link

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?

@davidmcraejr
Copy link

@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...

@arsalan04ahmad
Copy link

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

@AnandaDwiprayoga
Copy link

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

@clarabez
Copy link

clarabez commented Jul 1, 2022

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)))

@arsalan04ahmad
Copy link

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

@TWiStErRob
Copy link
Contributor

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

@arsalan04ahmad
Copy link

@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 :)

@clarabez
Copy link

clarabez commented Jul 5, 2022

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

It is not in my case, same execution time.

@arsalan04ahmad
Copy link

@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

@clarabez
Copy link

clarabez commented Jul 7, 2022

@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.

@arsalan04ahmad
Copy link

arsalan04ahmad commented Jul 7, 2022

@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.

@clarabez
Copy link

clarabez commented Jul 7, 2022

@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.

@arsalan04ahmad
Copy link

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

@clarabez
Copy link

clarabez commented Jul 8, 2022

@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

@Venkat-juju
Copy link

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

@testfacefanpage
Copy link

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
Copy link

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!

@sarimmehdi
Copy link

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

@luongvo
Copy link

luongvo commented Dec 26, 2022

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

omarAhmed22600 added a commit to omarAhmed22600/Location-Reminder that referenced this issue Jan 6, 2023
-Added condition in RemindersActivityTest.kt to run the Toast test only on devices with api less than 30 as in api 30 and later Toasts can't be tested
problem reference: android/android-test#803
djbrown added a commit to djbrown/gnucash-android that referenced this issue Apr 10, 2023
@masud-technope
Copy link

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!

@djbrown
Copy link

djbrown commented Jul 10, 2023

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.

@masud-technope
Copy link

masud-technope commented Jul 10, 2023

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

maugagneur added a commit to maugagneur/vigik that referenced this issue Jul 21, 2023
FIXME: It seems there are some issues with Toast assertion with API 30 and upper -> android/android-test#803
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests