1bfd48d0521963754e04e407499ee9e278fe06c0fChris Banes/* 2bfd48d0521963754e04e407499ee9e278fe06c0fChris Banes * Copyright (C) 2016 The Android Open Source Project 3bfd48d0521963754e04e407499ee9e278fe06c0fChris Banes * 4bfd48d0521963754e04e407499ee9e278fe06c0fChris Banes * Licensed under the Apache License, Version 2.0 (the "License"); 5bfd48d0521963754e04e407499ee9e278fe06c0fChris Banes * you may not use this file except in compliance with the License. 6bfd48d0521963754e04e407499ee9e278fe06c0fChris Banes * You may obtain a copy of the License at 7bfd48d0521963754e04e407499ee9e278fe06c0fChris Banes * 8bfd48d0521963754e04e407499ee9e278fe06c0fChris Banes * http://www.apache.org/licenses/LICENSE-2.0 9bfd48d0521963754e04e407499ee9e278fe06c0fChris Banes * 10bfd48d0521963754e04e407499ee9e278fe06c0fChris Banes * Unless required by applicable law or agreed to in writing, software 11bfd48d0521963754e04e407499ee9e278fe06c0fChris Banes * distributed under the License is distributed on an "AS IS" BASIS, 12bfd48d0521963754e04e407499ee9e278fe06c0fChris Banes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13bfd48d0521963754e04e407499ee9e278fe06c0fChris Banes * See the License for the specific language governing permissions and 14bfd48d0521963754e04e407499ee9e278fe06c0fChris Banes * limitations under the License. 15bfd48d0521963754e04e407499ee9e278fe06c0fChris Banes */ 16bfd48d0521963754e04e407499ee9e278fe06c0fChris Banes 17bfd48d0521963754e04e407499ee9e278fe06c0fChris Banespackage android.support.design.widget; 18bfd48d0521963754e04e407499ee9e278fe06c0fChris Banes 19754cb29c50f09a83251dd4bb633ba445b2411adbAurimas Liutikasimport static android.support.design.testutils.TestUtilsActions.setLayoutDirection; 20754cb29c50f09a83251dd4bb633ba445b2411adbAurimas Liutikasimport static android.support.test.espresso.Espresso.onView; 21754cb29c50f09a83251dd4bb633ba445b2411adbAurimas Liutikasimport static android.support.test.espresso.action.ViewActions.click; 22754cb29c50f09a83251dd4bb633ba445b2411adbAurimas Liutikasimport static android.support.test.espresso.action.ViewActions.swipeLeft; 23754cb29c50f09a83251dd4bb633ba445b2411adbAurimas Liutikasimport static android.support.test.espresso.action.ViewActions.swipeRight; 248c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikovimport static android.support.test.espresso.assertion.ViewAssertions.matches; 25754cb29c50f09a83251dd4bb633ba445b2411adbAurimas Liutikasimport static android.support.test.espresso.matcher.ViewMatchers.isAssignableFrom; 26754cb29c50f09a83251dd4bb633ba445b2411adbAurimas Liutikasimport static android.support.test.espresso.matcher.ViewMatchers.isCompletelyDisplayed; 27754cb29c50f09a83251dd4bb633ba445b2411adbAurimas Liutikasimport static android.support.test.espresso.matcher.ViewMatchers.isDescendantOfA; 28754cb29c50f09a83251dd4bb633ba445b2411adbAurimas Liutikasimport static android.support.test.espresso.matcher.ViewMatchers.withId; 29754cb29c50f09a83251dd4bb633ba445b2411adbAurimas Liutikasimport static android.support.test.espresso.matcher.ViewMatchers.withText; 30754cb29c50f09a83251dd4bb633ba445b2411adbAurimas Liutikas 31754cb29c50f09a83251dd4bb633ba445b2411adbAurimas Liutikasimport static org.hamcrest.core.AllOf.allOf; 328c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikovimport static org.junit.Assert.assertFalse; 338c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikovimport static org.junit.Assert.assertTrue; 34754cb29c50f09a83251dd4bb633ba445b2411adbAurimas Liutikasimport static org.mockito.Matchers.any; 35754cb29c50f09a83251dd4bb633ba445b2411adbAurimas Liutikasimport static org.mockito.Mockito.mock; 368c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikovimport static org.mockito.Mockito.never; 37ca9c74379e9fb2b38965253836a2ab0e36990c45Kirill Grouchnikovimport static org.mockito.Mockito.spy; 38754cb29c50f09a83251dd4bb633ba445b2411adbAurimas Liutikasimport static org.mockito.Mockito.times; 39754cb29c50f09a83251dd4bb633ba445b2411adbAurimas Liutikasimport static org.mockito.Mockito.verify; 40754cb29c50f09a83251dd4bb633ba445b2411adbAurimas Liutikasimport static org.mockito.Mockito.verifyNoMoreInteractions; 41754cb29c50f09a83251dd4bb633ba445b2411adbAurimas Liutikas 42c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikovimport android.content.res.Resources; 43c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikovimport android.support.annotation.Nullable; 44c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikovimport android.support.annotation.StringRes; 45bfd48d0521963754e04e407499ee9e278fe06c0fChris Banesimport android.support.design.test.R; 463a8340d4a090bc8ab7ad3a774fb6d999e7384301Kirill Grouchnikovimport android.support.design.testutils.SnackbarUtils; 47bfd48d0521963754e04e407499ee9e278fe06c0fChris Banesimport android.support.test.espresso.ViewAction; 48bfd48d0521963754e04e407499ee9e278fe06c0fChris Banesimport android.support.test.espresso.ViewInteraction; 49e855c308ce795c6ac382b94670c264fc368ba882Chris Banesimport android.support.test.espresso.action.CoordinatesProvider; 50e855c308ce795c6ac382b94670c264fc368ba882Chris Banesimport android.support.test.espresso.action.GeneralSwipeAction; 51e855c308ce795c6ac382b94670c264fc368ba882Chris Banesimport android.support.test.espresso.action.Press; 52e855c308ce795c6ac382b94670c264fc368ba882Chris Banesimport android.support.test.espresso.action.Swipe; 53e6cf359406cd7baaa0659b54c1b7d8ac45db122aAurimas Liutikasimport android.support.test.filters.LargeTest; 54754cb29c50f09a83251dd4bb633ba445b2411adbAurimas Liutikasimport android.support.test.filters.MediumTest; 55c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikovimport android.support.v4.view.ViewCompat; 56c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikovimport android.text.TextUtils; 57bfd48d0521963754e04e407499ee9e278fe06c0fChris Banesimport android.view.View; 58754cb29c50f09a83251dd4bb633ba445b2411adbAurimas Liutikas 597b7e3bfd940aa1b41497ac4c6710a97b54c3e551Kirill Grouchnikovimport org.junit.Before; 60ee3e8053ef6b55e31fa0be004061318ec394eb64Kirill Grouchnikovimport org.junit.Test; 61bfd48d0521963754e04e407499ee9e278fe06c0fChris Banes 624bb57b2c7c5e8fa607119bd5089535d5862cb979Aurimas Liutikas@MediumTest 637b7e3bfd940aa1b41497ac4c6710a97b54c3e551Kirill Grouchnikovpublic class SnackbarTest extends BaseInstrumentationTestCase<SnackbarActivity> { 64bfd48d0521963754e04e407499ee9e278fe06c0fChris Banes private static final String MESSAGE_TEXT = "Test Message"; 65c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov private static final @StringRes int MESSAGE_ID = R.string.snackbar_text; 66bfd48d0521963754e04e407499ee9e278fe06c0fChris Banes private static final String ACTION_TEXT = "Action"; 67c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov private static final @StringRes int ACTION_ID = R.string.snackbar_action; 68bfd48d0521963754e04e407499ee9e278fe06c0fChris Banes 697b7e3bfd940aa1b41497ac4c6710a97b54c3e551Kirill Grouchnikov private CoordinatorLayout mCoordinatorLayout; 707b7e3bfd940aa1b41497ac4c6710a97b54c3e551Kirill Grouchnikov 71b6b4a30c2832e00e4d471665471748f0cb8143bcChris Banes private interface DismissAction { 72c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov void dismiss(Snackbar snackbar); 73c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov } 74c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov 757b7e3bfd940aa1b41497ac4c6710a97b54c3e551Kirill Grouchnikov public SnackbarTest() { 767b7e3bfd940aa1b41497ac4c6710a97b54c3e551Kirill Grouchnikov super(SnackbarActivity.class); 777b7e3bfd940aa1b41497ac4c6710a97b54c3e551Kirill Grouchnikov } 787b7e3bfd940aa1b41497ac4c6710a97b54c3e551Kirill Grouchnikov 797b7e3bfd940aa1b41497ac4c6710a97b54c3e551Kirill Grouchnikov @Before 807b7e3bfd940aa1b41497ac4c6710a97b54c3e551Kirill Grouchnikov public void setup() { 817b7e3bfd940aa1b41497ac4c6710a97b54c3e551Kirill Grouchnikov mCoordinatorLayout = 827b7e3bfd940aa1b41497ac4c6710a97b54c3e551Kirill Grouchnikov (CoordinatorLayout) mActivityTestRule.getActivity().findViewById(R.id.col); 837b7e3bfd940aa1b41497ac4c6710a97b54c3e551Kirill Grouchnikov } 847b7e3bfd940aa1b41497ac4c6710a97b54c3e551Kirill Grouchnikov 85c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov private void verifySnackbarContent(final Snackbar snackbar, final String expectedMessage, 868c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov final String expectedAction) throws Throwable { 873a8340d4a090bc8ab7ad3a774fb6d999e7384301Kirill Grouchnikov // Show the snackbar 888da7b24b08afba7ec155a371117df018bcc25eefKirill Grouchnikov SnackbarUtils.showTransientBottomBarAndWaitUntilFullyShown(snackbar); 89c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov 90c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov // Verify that we're showing the message 91c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov withText(expectedMessage).matches(allOf( 92c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov isDescendantOfA(isAssignableFrom(Snackbar.SnackbarLayout.class)), 93c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov isCompletelyDisplayed())); 94c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov 95c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov // If the action is not empty, verify that we're showing it 96c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov if (!TextUtils.isEmpty(expectedAction)) { 97c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov withText(expectedAction).matches(allOf( 98c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov isDescendantOfA(isAssignableFrom(Snackbar.SnackbarLayout.class)), 99c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov isCompletelyDisplayed())); 100c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov } 101c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov 102c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov // Dismiss the snackbar 1038da7b24b08afba7ec155a371117df018bcc25eefKirill Grouchnikov SnackbarUtils.dismissTransientBottomBarAndWaitUntilFullyDismissed(snackbar); 104c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov } 105c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov 106e6cf359406cd7baaa0659b54c1b7d8ac45db122aAurimas Liutikas @LargeTest 107c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov @Test 1088c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov public void testBasicContent() throws Throwable { 109c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov // Verify different combinations of snackbar content (message and action) and duration 110c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov 111c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov final Resources res = mActivityTestRule.getActivity().getResources(); 112c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov final String resolvedMessage = res.getString(MESSAGE_ID); 113c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov final String resolvedAction = res.getString(ACTION_ID); 114c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov 115c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov // String message and no action 116c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov verifySnackbarContent( 117c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov Snackbar.make(mCoordinatorLayout, MESSAGE_TEXT, Snackbar.LENGTH_SHORT), 118c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov MESSAGE_TEXT, null); 119c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov 120c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov // Resource message and no action 121c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov verifySnackbarContent( 122c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov Snackbar.make(mCoordinatorLayout, MESSAGE_ID, Snackbar.LENGTH_LONG), 123c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov resolvedMessage, null); 124c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov 125c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov // String message and string action 126c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov verifySnackbarContent( 127c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov Snackbar.make(mCoordinatorLayout, MESSAGE_TEXT, Snackbar.LENGTH_INDEFINITE) 128c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov .setAction(ACTION_TEXT, mock(View.OnClickListener.class)), 129c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov MESSAGE_TEXT, ACTION_TEXT); 130c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov 131c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov // String message and resource action 132c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov verifySnackbarContent( 133c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov Snackbar.make(mCoordinatorLayout, MESSAGE_TEXT, Snackbar.LENGTH_SHORT) 134c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov .setAction(ACTION_ID, mock(View.OnClickListener.class)), 135c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov MESSAGE_TEXT, resolvedAction); 136c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov 137c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov // Resource message and resource action 138c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov verifySnackbarContent( 139c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov Snackbar.make(mCoordinatorLayout, MESSAGE_ID, Snackbar.LENGTH_LONG) 140c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov .setAction(ACTION_ID, mock(View.OnClickListener.class)), 141c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov resolvedMessage, resolvedAction); 142c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov } 143c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov 144c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov private void verifyDismissCallback(final ViewInteraction interaction, 145c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov final @Nullable ViewAction action, final @Nullable DismissAction dismissAction, 14642e7d6fafcde7bfe261dd7d8d75ee53ca0cd6790Aurimas Liutikas final int length, @Snackbar.Callback.DismissEvent final int expectedEvent) 14742e7d6fafcde7bfe261dd7d8d75ee53ca0cd6790Aurimas Liutikas throws Throwable { 148ca9c74379e9fb2b38965253836a2ab0e36990c45Kirill Grouchnikov final BaseTransientBottomBar.BaseCallback mockCallback = 149ca9c74379e9fb2b38965253836a2ab0e36990c45Kirill Grouchnikov mock(BaseTransientBottomBar.BaseCallback.class); 1507b7e3bfd940aa1b41497ac4c6710a97b54c3e551Kirill Grouchnikov final Snackbar snackbar = Snackbar.make(mCoordinatorLayout, MESSAGE_TEXT, length) 1517b7e3bfd940aa1b41497ac4c6710a97b54c3e551Kirill Grouchnikov .setAction(ACTION_TEXT, mock(View.OnClickListener.class)) 1528c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov .addCallback(mockCallback); 1537b7e3bfd940aa1b41497ac4c6710a97b54c3e551Kirill Grouchnikov 1548c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov // Show the snackbar 1558c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov SnackbarUtils.showTransientBottomBarAndWaitUntilFullyShown(snackbar); 1568c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov // Verify that our onShown has been called 1578c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov verify(mockCallback, times(1)).onShown(snackbar); 1588c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov // and that the snackbar is either shown or queued to be shown 1598c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov assertTrue(snackbar.isShownOrQueued()); 1608c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov // and also check that we have the intended message / action displayed somewhere in 1618c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov // our hierarchy 1628c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov onView(withText(MESSAGE_TEXT)).check(matches(isCompletelyDisplayed())); 1638c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov onView(withText(ACTION_TEXT)).check(matches(isCompletelyDisplayed())); 1643a8340d4a090bc8ab7ad3a774fb6d999e7384301Kirill Grouchnikov 1653a8340d4a090bc8ab7ad3a774fb6d999e7384301Kirill Grouchnikov // Now perform the UI interaction 1668c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov SnackbarUtils.performActionAndWaitUntilFullyDismissed(snackbar, 1678c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov new SnackbarUtils.TransientBottomBarAction() { 1688c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov @Override 1698c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov public void perform() throws Throwable { 1708c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov if (action != null) { 1718c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov interaction.perform(action); 1728c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov } else if (dismissAction != null) { 1738c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov mActivityTestRule.runOnUiThread(new Runnable() { 1748c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov @Override 1758c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov public void run() { 1768c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov dismissAction.dismiss(snackbar); 1778c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov } 1788c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov }); 1798c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov } 1808c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov } 1818c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov }); 1828c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov 1838c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov // Verify that our onDismissed has been called 1847b7e3bfd940aa1b41497ac4c6710a97b54c3e551Kirill Grouchnikov verify(mockCallback, times(1)).onDismissed(snackbar, expectedEvent); 1857b7e3bfd940aa1b41497ac4c6710a97b54c3e551Kirill Grouchnikov verifyNoMoreInteractions(mockCallback); 1868c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov // and that the snackbar is neither shown nor queued to be shown 1878c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov assertFalse(snackbar.isShownOrQueued()); 188bfd48d0521963754e04e407499ee9e278fe06c0fChris Banes } 189bfd48d0521963754e04e407499ee9e278fe06c0fChris Banes 190bfd48d0521963754e04e407499ee9e278fe06c0fChris Banes @Test 19142e7d6fafcde7bfe261dd7d8d75ee53ca0cd6790Aurimas Liutikas public void testDismissViaActionClick() throws Throwable { 1927b7e3bfd940aa1b41497ac4c6710a97b54c3e551Kirill Grouchnikov verifyDismissCallback( 193bfd48d0521963754e04e407499ee9e278fe06c0fChris Banes onView(withId(R.id.snackbar_action)), 194c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov click(), 195c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov null, 196bfd48d0521963754e04e407499ee9e278fe06c0fChris Banes Snackbar.LENGTH_LONG, 197bfd48d0521963754e04e407499ee9e278fe06c0fChris Banes Snackbar.Callback.DISMISS_EVENT_ACTION); 198bfd48d0521963754e04e407499ee9e278fe06c0fChris Banes } 199bfd48d0521963754e04e407499ee9e278fe06c0fChris Banes 200bfd48d0521963754e04e407499ee9e278fe06c0fChris Banes @Test 20142e7d6fafcde7bfe261dd7d8d75ee53ca0cd6790Aurimas Liutikas public void testDismissViaSwipe() throws Throwable { 2027b7e3bfd940aa1b41497ac4c6710a97b54c3e551Kirill Grouchnikov verifyDismissCallback( 203bfd48d0521963754e04e407499ee9e278fe06c0fChris Banes onView(isAssignableFrom(Snackbar.SnackbarLayout.class)), 204c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov swipeRight(), 205c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov null, 206bfd48d0521963754e04e407499ee9e278fe06c0fChris Banes Snackbar.LENGTH_LONG, 207bfd48d0521963754e04e407499ee9e278fe06c0fChris Banes Snackbar.Callback.DISMISS_EVENT_SWIPE); 208bfd48d0521963754e04e407499ee9e278fe06c0fChris Banes } 209bfd48d0521963754e04e407499ee9e278fe06c0fChris Banes 210bfd48d0521963754e04e407499ee9e278fe06c0fChris Banes @Test 21142e7d6fafcde7bfe261dd7d8d75ee53ca0cd6790Aurimas Liutikas public void testDismissViaSwipeRtl() throws Throwable { 212c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov onView(withId(R.id.col)).perform(setLayoutDirection(ViewCompat.LAYOUT_DIRECTION_RTL)); 213c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov if (ViewCompat.getLayoutDirection(mCoordinatorLayout) == ViewCompat.LAYOUT_DIRECTION_RTL) { 214c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov // On devices that support RTL layout, the start-to-end dismiss swipe is done 215c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov // with swipeLeft() action 216c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov verifyDismissCallback( 217c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov onView(isAssignableFrom(Snackbar.SnackbarLayout.class)), 218c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov swipeLeft(), 219c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov null, 220c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov Snackbar.LENGTH_LONG, 221c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov Snackbar.Callback.DISMISS_EVENT_SWIPE); 222c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov } 223c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov } 224c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov 225c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov @Test 22642e7d6fafcde7bfe261dd7d8d75ee53ca0cd6790Aurimas Liutikas public void testDismissViaApi() throws Throwable { 227c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov verifyDismissCallback( 228c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov onView(isAssignableFrom(Snackbar.SnackbarLayout.class)), 229c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov null, 230c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov new DismissAction() { 231c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov @Override 232c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov public void dismiss(Snackbar snackbar) { 233c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov snackbar.dismiss(); 234c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov } 235c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov }, 236c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov Snackbar.LENGTH_LONG, 237c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov Snackbar.Callback.DISMISS_EVENT_MANUAL); 238c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov } 239c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov 240e6cf359406cd7baaa0659b54c1b7d8ac45db122aAurimas Liutikas @LargeTest 241c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov @Test 24242e7d6fafcde7bfe261dd7d8d75ee53ca0cd6790Aurimas Liutikas public void testDismissViaTimeout() throws Throwable { 243c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov verifyDismissCallback( 244c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov onView(isAssignableFrom(Snackbar.SnackbarLayout.class)), 245c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov null, 246c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov null, 247c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov Snackbar.LENGTH_LONG, 248c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov Snackbar.Callback.DISMISS_EVENT_TIMEOUT); 249c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov } 250c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov 251e6cf359406cd7baaa0659b54c1b7d8ac45db122aAurimas Liutikas @LargeTest 252c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov @Test 253e855c308ce795c6ac382b94670c264fc368ba882Chris Banes public void testSwipeUpDismissesViaTimeout() throws Throwable { 254e855c308ce795c6ac382b94670c264fc368ba882Chris Banes verifyDismissCallback( 255e855c308ce795c6ac382b94670c264fc368ba882Chris Banes onView(isAssignableFrom(Snackbar.SnackbarLayout.class)), 256e855c308ce795c6ac382b94670c264fc368ba882Chris Banes // This is a swipe up, from the middle center of the view, to above the view 257e855c308ce795c6ac382b94670c264fc368ba882Chris Banes // (outside the bounds) 258e855c308ce795c6ac382b94670c264fc368ba882Chris Banes new GeneralSwipeAction( 259e855c308ce795c6ac382b94670c264fc368ba882Chris Banes Swipe.SLOW, 260e855c308ce795c6ac382b94670c264fc368ba882Chris Banes new CoordinatesProvider() { 261e855c308ce795c6ac382b94670c264fc368ba882Chris Banes @Override 262e855c308ce795c6ac382b94670c264fc368ba882Chris Banes public float[] calculateCoordinates(View view) { 263e855c308ce795c6ac382b94670c264fc368ba882Chris Banes final int[] loc = new int[2]; 264e855c308ce795c6ac382b94670c264fc368ba882Chris Banes view.getLocationOnScreen(loc); 265e855c308ce795c6ac382b94670c264fc368ba882Chris Banes return new float[]{ 266e855c308ce795c6ac382b94670c264fc368ba882Chris Banes loc[0] + view.getWidth() / 2, 267e855c308ce795c6ac382b94670c264fc368ba882Chris Banes loc[1] + view.getHeight() / 2}; 268e855c308ce795c6ac382b94670c264fc368ba882Chris Banes } 269e855c308ce795c6ac382b94670c264fc368ba882Chris Banes }, 270e855c308ce795c6ac382b94670c264fc368ba882Chris Banes new CoordinatesProvider() { 271e855c308ce795c6ac382b94670c264fc368ba882Chris Banes @Override 272e855c308ce795c6ac382b94670c264fc368ba882Chris Banes public float[] calculateCoordinates(View view) { 273e855c308ce795c6ac382b94670c264fc368ba882Chris Banes final int[] loc = new int[2]; 274e855c308ce795c6ac382b94670c264fc368ba882Chris Banes view.getLocationOnScreen(loc); 275e855c308ce795c6ac382b94670c264fc368ba882Chris Banes return new float[]{ 276e855c308ce795c6ac382b94670c264fc368ba882Chris Banes loc[0] + view.getWidth() / 2, 277e855c308ce795c6ac382b94670c264fc368ba882Chris Banes loc[1] - view.getHeight()}; 278e855c308ce795c6ac382b94670c264fc368ba882Chris Banes } 279e855c308ce795c6ac382b94670c264fc368ba882Chris Banes }, 280e855c308ce795c6ac382b94670c264fc368ba882Chris Banes Press.FINGER 281e855c308ce795c6ac382b94670c264fc368ba882Chris Banes ), 282e855c308ce795c6ac382b94670c264fc368ba882Chris Banes null, 283e855c308ce795c6ac382b94670c264fc368ba882Chris Banes Snackbar.LENGTH_SHORT, 284e855c308ce795c6ac382b94670c264fc368ba882Chris Banes Snackbar.Callback.DISMISS_EVENT_TIMEOUT); 285e855c308ce795c6ac382b94670c264fc368ba882Chris Banes } 286e855c308ce795c6ac382b94670c264fc368ba882Chris Banes 287e855c308ce795c6ac382b94670c264fc368ba882Chris Banes @Test 28842e7d6fafcde7bfe261dd7d8d75ee53ca0cd6790Aurimas Liutikas public void testDismissViaAnotherSnackbar() throws Throwable { 289c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov final Snackbar anotherSnackbar = 290c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov Snackbar.make(mCoordinatorLayout, "A different message", Snackbar.LENGTH_SHORT); 291c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov 292c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov // Our dismiss action is to show another snackbar (and verify that the original snackbar 293c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov // is now dismissed with CONSECUTIVE event) 294c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov verifyDismissCallback( 295c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov onView(isAssignableFrom(Snackbar.SnackbarLayout.class)), 296c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov null, 297c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov new DismissAction() { 298c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov @Override 299c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov public void dismiss(Snackbar snackbar) { 300c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov anotherSnackbar.show(); 301c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov } 302c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov }, 303c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov Snackbar.LENGTH_LONG, 304c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov Snackbar.Callback.DISMISS_EVENT_CONSECUTIVE); 305c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov 306c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov // And dismiss the second snackbar to get back to clean state 3078da7b24b08afba7ec155a371117df018bcc25eefKirill Grouchnikov SnackbarUtils.dismissTransientBottomBarAndWaitUntilFullyDismissed(anotherSnackbar); 308c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov } 309c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov 310c554016bf7e7e057479cf005770dd5e127500329Kirill Grouchnikov @Test 311bfd48d0521963754e04e407499ee9e278fe06c0fChris Banes public void testActionClickListener() { 3127b7e3bfd940aa1b41497ac4c6710a97b54c3e551Kirill Grouchnikov final View.OnClickListener mockClickListener = mock(View.OnClickListener.class); 3137b7e3bfd940aa1b41497ac4c6710a97b54c3e551Kirill Grouchnikov final Snackbar snackbar = 3147b7e3bfd940aa1b41497ac4c6710a97b54c3e551Kirill Grouchnikov Snackbar.make(mCoordinatorLayout, MESSAGE_TEXT, Snackbar.LENGTH_SHORT) 3157b7e3bfd940aa1b41497ac4c6710a97b54c3e551Kirill Grouchnikov .setAction(ACTION_TEXT, mockClickListener); 316bfd48d0521963754e04e407499ee9e278fe06c0fChris Banes 3173a8340d4a090bc8ab7ad3a774fb6d999e7384301Kirill Grouchnikov // Show the snackbar 3188da7b24b08afba7ec155a371117df018bcc25eefKirill Grouchnikov SnackbarUtils.showTransientBottomBarAndWaitUntilFullyShown(snackbar); 3193a8340d4a090bc8ab7ad3a774fb6d999e7384301Kirill Grouchnikov // perform the action click 3203a8340d4a090bc8ab7ad3a774fb6d999e7384301Kirill Grouchnikov onView(withId(R.id.snackbar_action)).perform(click()); 3213a8340d4a090bc8ab7ad3a774fb6d999e7384301Kirill Grouchnikov // and verify that our click listener has been called 3227b7e3bfd940aa1b41497ac4c6710a97b54c3e551Kirill Grouchnikov verify(mockClickListener, times(1)).onClick(any(View.class)); 323bfd48d0521963754e04e407499ee9e278fe06c0fChris Banes } 3248c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov 3258c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov @Test 3268c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov public void testSetCallback() throws Throwable { 3278c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov final Snackbar snackbar = 3288c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov Snackbar.make(mCoordinatorLayout, MESSAGE_TEXT, Snackbar.LENGTH_INDEFINITE) 3298c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov .setAction(ACTION_TEXT, mock(View.OnClickListener.class)); 330ca9c74379e9fb2b38965253836a2ab0e36990c45Kirill Grouchnikov final Snackbar.Callback mockCallback = spy(new Snackbar.Callback()); 3318c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov snackbar.setCallback(mockCallback); 3328c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov 3338c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov SnackbarUtils.showTransientBottomBarAndWaitUntilFullyShown(snackbar); 3348c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov verify(mockCallback, times(1)).onShown(snackbar); 3358c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov 3368c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov SnackbarUtils.dismissTransientBottomBarAndWaitUntilFullyDismissed(snackbar); 3378c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov verify(mockCallback, times(1)).onDismissed(snackbar, 3388c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov BaseTransientBottomBar.BaseCallback.DISMISS_EVENT_MANUAL); 3398c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov } 3408c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov 3418c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov @Test 3428c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov public void testSingleCallback() throws Throwable { 3438c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov final Snackbar snackbar = 3448c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov Snackbar.make(mCoordinatorLayout, MESSAGE_TEXT, Snackbar.LENGTH_INDEFINITE) 3458c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov .setAction(ACTION_TEXT, mock(View.OnClickListener.class)); 3468c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov final BaseTransientBottomBar.BaseCallback mockCallback1 = 3478c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov mock(BaseTransientBottomBar.BaseCallback.class); 3488c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov final BaseTransientBottomBar.BaseCallback mockCallback2 = 3498c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov mock(BaseTransientBottomBar.BaseCallback.class); 3508c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov snackbar.addCallback(mockCallback1); 3518c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov 3528c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov SnackbarUtils.showTransientBottomBarAndWaitUntilFullyShown(snackbar); 3538c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov verify(mockCallback1, times(1)).onShown(snackbar); 3548c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov verify(mockCallback2, never()).onShown(snackbar); 3558c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov 3568c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov SnackbarUtils.dismissTransientBottomBarAndWaitUntilFullyDismissed(snackbar); 3578c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov verify(mockCallback1, times(1)).onDismissed(snackbar, 3588c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov BaseTransientBottomBar.BaseCallback.DISMISS_EVENT_MANUAL); 3598c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov verify(mockCallback2, never()).onDismissed(snackbar, 3608c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov BaseTransientBottomBar.BaseCallback.DISMISS_EVENT_MANUAL); 3618c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov } 3628c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov 3638c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov @Test 3648c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov public void testMultipleCallbacks() throws Throwable { 3658c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov final Snackbar snackbar = 3668c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov Snackbar.make(mCoordinatorLayout, MESSAGE_TEXT, Snackbar.LENGTH_INDEFINITE) 3678c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov .setAction(ACTION_TEXT, mock(View.OnClickListener.class)); 3688c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov final BaseTransientBottomBar.BaseCallback mockCallback1 = 3698c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov mock(BaseTransientBottomBar.BaseCallback.class); 3708c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov final BaseTransientBottomBar.BaseCallback mockCallback2 = 3718c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov mock(BaseTransientBottomBar.BaseCallback.class); 3728c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov snackbar.addCallback(mockCallback1); 3738c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov snackbar.addCallback(mockCallback2); 3748c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov 3758c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov SnackbarUtils.showTransientBottomBarAndWaitUntilFullyShown(snackbar); 3768c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov verify(mockCallback1, times(1)).onShown(snackbar); 3778c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov verify(mockCallback2, times(1)).onShown(snackbar); 3788c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov 3798c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov SnackbarUtils.dismissTransientBottomBarAndWaitUntilFullyDismissed(snackbar); 3808c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov verify(mockCallback1, times(1)).onDismissed(snackbar, 3818c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov BaseTransientBottomBar.BaseCallback.DISMISS_EVENT_MANUAL); 3828c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov verify(mockCallback2, times(1)).onDismissed(snackbar, 3838c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov BaseTransientBottomBar.BaseCallback.DISMISS_EVENT_MANUAL); 3848c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov } 3858c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov 3868c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov @Test 3878c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov public void testMultipleCallbacksWithRemoval() throws Throwable { 3888c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov final Snackbar snackbar = 3898c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov Snackbar.make(mCoordinatorLayout, MESSAGE_TEXT, Snackbar.LENGTH_INDEFINITE) 3908c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov .setAction(ACTION_TEXT, mock(View.OnClickListener.class)); 3918c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov final BaseTransientBottomBar.BaseCallback mockCallback1 = 3928c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov mock(BaseTransientBottomBar.BaseCallback.class); 3938c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov final BaseTransientBottomBar.BaseCallback mockCallback2 = 3948c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov mock(BaseTransientBottomBar.BaseCallback.class); 3958c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov snackbar.addCallback(mockCallback1); 3968c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov snackbar.addCallback(mockCallback2); 3978c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov 3988c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov SnackbarUtils.showTransientBottomBarAndWaitUntilFullyShown(snackbar); 3998c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov verify(mockCallback1, times(1)).onShown(snackbar); 4008c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov verify(mockCallback2, times(1)).onShown(snackbar); 4018c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov 4028c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov snackbar.removeCallback(mockCallback2); 4038c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov 4048c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov SnackbarUtils.dismissTransientBottomBarAndWaitUntilFullyDismissed(snackbar); 4058c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov verify(mockCallback1, times(1)).onDismissed(snackbar, 4068c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov BaseTransientBottomBar.BaseCallback.DISMISS_EVENT_MANUAL); 4078c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov verify(mockCallback2, never()).onDismissed(snackbar, 4088c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov BaseTransientBottomBar.BaseCallback.DISMISS_EVENT_MANUAL); 4098c153ac8980737c4292ae1c019c69471607b3859Kirill Grouchnikov } 410bfd48d0521963754e04e407499ee9e278fe06c0fChris Banes} 411