トラッキング コード

3/01/2015

How to check Toast window, on android test-kit Espresso

If we read the following public document, we can check other window.
Using inRoot to target non-default windows

onView(withText("South China Sea"))
  .inRoot(withDecorView(not(is(getActivity().getWindow().getDecorView()))))
  .perform(click());

But, I think this is not cool.

We can create a custom matcher.
Toast window has the WindowManager.LayoutParams.TYPE_TOAST.

The followinf code is sample.
    /**
     * Matcher that is Toast window.
     */
    public static Matcher<Root> isToast() {
        return new TypeSafeMatcher<Root>() {

            @Override
            public void describeTo(Description description) {
                description.appendText("is toast");
            }

            @Override
            public boolean matchesSafely(Root root) {
                int type = root.getWindowLayoutParams().get().type;
                if ((type == WindowManager.LayoutParams.TYPE_TOAST)) {
                    IBinder windowToken = root.getDecorView().getWindowToken();
                    IBinder appToken = root.getDecorView().getApplicationWindowToken();
                    if (windowToken == appToken) {
                        // windowToken == appToken means this window isn't contained by any other windows.
                        // if it was a window for an activity, it would have TYPE_BASE_APPLICATION.
                        return true;
                    }
                }
                return false;
            }
        };
    }

12 comments:

  1. Hi, thanks for the post!, really good. One question, why do you think the first approach is not cool?

    ReplyDelete
  2. the first approach is not checked "TYPE_TOAST". it mean that window type is not checked.
    we should create a custom matcher,

    ReplyDelete
  3. Interesting approach to read..Thank you for sharingAndroid Training

    ReplyDelete
  4. I am getting this android.support.test.espresso.NoMatchingRootException: Matcher 'is toast' did not match any of the following roots:
    What should I do?

    ReplyDelete
    Replies
    1. If you are using kotlin, this would resolve it

      onView(withText(R.string.invalid_phone_number)).inRoot(ToastMatcher().apply {
      matches(isDisplayed())
      }

      Delete
    2. Using this way the assertion will always pass, even if there is no toast.

      Delete
    3. This comment has been removed by the author.

      Delete
  5. Toasts have a period of visibility and during testing it could happen that the assert explained is run when the toast has already dissapeared, depending on android's device. How do you manage these situations?

    ReplyDelete
  6. In this particular article, you will see a summary, satisfy browse this post. kaffebryggare

    ReplyDelete
  7. can you write matcher class in kotlin

    ReplyDelete