1/* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package android.support.design.widget; 18 19import static android.support.design.testutils.FloatingActionButtonActions.hideThenShow; 20import static android.support.design.testutils.FloatingActionButtonActions.setBackgroundTintColor; 21import static android.support.design.testutils.FloatingActionButtonActions.setBackgroundTintList; 22import static android.support.design.testutils.FloatingActionButtonActions.setCompatElevation; 23import static android.support.design.testutils.FloatingActionButtonActions.setImageResource; 24import static android.support.design.testutils.FloatingActionButtonActions.setLayoutGravity; 25import static android.support.design.testutils.FloatingActionButtonActions.setSize; 26import static android.support.design.testutils.FloatingActionButtonActions.showThenHide; 27import static android.support.design.testutils.TestUtilsActions.setClickable; 28import static android.support.design.testutils.TestUtilsActions.setEnabled; 29import static android.support.design.testutils.TestUtilsActions.setSelected; 30import static android.support.design.testutils.TestUtilsMatchers.isPressed; 31import static android.support.design.testutils.TestUtilsMatchers.withFabBackgroundFill; 32import static android.support.design.testutils.TestUtilsMatchers.withFabContentAreaOnMargins; 33import static android.support.design.testutils.TestUtilsMatchers.withFabContentHeight; 34import static android.support.design.widget.DesignViewActions.setVisibility; 35import static android.support.test.espresso.Espresso.onView; 36import static android.support.test.espresso.action.ViewActions.click; 37import static android.support.test.espresso.assertion.ViewAssertions.matches; 38import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; 39import static android.support.test.espresso.matcher.ViewMatchers.withId; 40 41import static org.hamcrest.Matchers.not; 42import static org.mockito.Mockito.mock; 43import static org.mockito.Mockito.times; 44import static org.mockito.Mockito.verify; 45 46import android.app.Activity; 47import android.content.res.ColorStateList; 48import android.graphics.Color; 49import android.graphics.Rect; 50import android.support.design.test.R; 51import android.support.design.testutils.TestUtils; 52import android.support.test.espresso.action.CoordinatesProvider; 53import android.support.test.espresso.action.GeneralSwipeAction; 54import android.support.test.espresso.action.Press; 55import android.support.test.espresso.action.Swipe; 56import android.support.test.filters.LargeTest; 57import android.support.test.filters.MediumTest; 58import android.support.test.filters.SmallTest; 59import android.support.v4.content.ContextCompat; 60import android.view.Gravity; 61import android.view.View; 62 63import org.junit.Test; 64 65public class FloatingActionButtonTest 66 extends BaseInstrumentationTestCase<FloatingActionButtonActivity> { 67 68 public FloatingActionButtonTest() { 69 super(FloatingActionButtonActivity.class); 70 } 71 72 @SmallTest 73 @Test 74 public void testDefaultBackgroundTint() { 75 final int colorAccent = TestUtils.getThemeAttrColor( 76 mActivityTestRule.getActivity(), R.attr.colorAccent); 77 onView(withId(R.id.fab_standard)) 78 .check(matches(withFabBackgroundFill(colorAccent))); 79 } 80 81 @SmallTest 82 @Test 83 public void testSetTintOnDefaultBackgroundTint() { 84 onView(withId(R.id.fab_standard)) 85 .perform(setBackgroundTintColor(Color.GREEN)) 86 .check(matches(withFabBackgroundFill(Color.GREEN))); 87 } 88 89 @SmallTest 90 @Test 91 public void testDeclaredBackgroundTint() { 92 onView(withId(R.id.fab_tint)) 93 .check(matches(withFabBackgroundFill(Color.MAGENTA))); 94 } 95 96 @SmallTest 97 @Test 98 public void testSetTintOnDeclaredBackgroundTint() { 99 onView(withId(R.id.fab_tint)) 100 .perform(setBackgroundTintColor(Color.GREEN)) 101 .check(matches(withFabBackgroundFill(Color.GREEN))); 102 } 103 104 @SmallTest 105 @Test 106 public void testSetStatefulTintAcrossStateChanges() { 107 final Activity activity = mActivityTestRule.getActivity(); 108 109 final ColorStateList tint = ContextCompat.getColorStateList(activity, R.color.fab_tint); 110 final int normal = ContextCompat.getColor(activity, R.color.sand_default); 111 final int notSelected = ContextCompat.getColor(activity, R.color.sand_disabled); 112 113 // First set the background tint list to the ColorStateList 114 onView(withId(R.id.fab_standard)) 115 .perform(setBackgroundTintList(tint)); 116 117 // Assert that the background is tinted correctly across state changes 118 onView(withId(R.id.fab_standard)) 119 .perform(setSelected(true)) 120 .check(matches(withFabBackgroundFill(normal))) 121 .perform(setSelected(false)) 122 .check(matches(withFabBackgroundFill(notSelected))) 123 .perform(setSelected(true)) 124 .check(matches(withFabBackgroundFill(normal))); 125 } 126 127 @SmallTest 128 @Test 129 public void testDeclaredStatefulTintAcrossStateChanges() { 130 final Activity activity = mActivityTestRule.getActivity(); 131 final int normal = ContextCompat.getColor(activity, R.color.sand_default); 132 final int disabled = ContextCompat.getColor(activity, R.color.sand_disabled); 133 134 // Assert that the background is tinted correctly across state changes 135 onView(withId(R.id.fab_state_tint)) 136 .perform(setSelected(true)) 137 .check(matches(withFabBackgroundFill(normal))) 138 .perform(setSelected(false)) 139 .check(matches(withFabBackgroundFill(disabled))); 140 } 141 142 @SmallTest 143 @Test 144 public void setVectorDrawableSrc() { 145 onView(withId(R.id.fab_standard)) 146 .perform(setImageResource(R.drawable.vector_icon)); 147 } 148 149 @SmallTest 150 @Test 151 public void testSetMiniSize() { 152 final int miniSize = mActivityTestRule.getActivity().getResources() 153 .getDimensionPixelSize(R.dimen.fab_mini_height); 154 155 onView(withId(R.id.fab_standard)) 156 .perform(setSize(FloatingActionButton.SIZE_MINI)) 157 .check(matches(withFabContentHeight(miniSize))); 158 } 159 160 @SmallTest 161 @Test 162 public void testSetSizeToggle() { 163 final int miniSize = mActivityTestRule.getActivity().getResources() 164 .getDimensionPixelSize(R.dimen.fab_mini_height); 165 final int normalSize = mActivityTestRule.getActivity().getResources() 166 .getDimensionPixelSize(R.dimen.fab_normal_height); 167 168 onView(withId(R.id.fab_standard)) 169 .perform(setSize(FloatingActionButton.SIZE_MINI)) 170 .check(matches(withFabContentHeight(miniSize))); 171 172 onView(withId(R.id.fab_standard)) 173 .perform(setSize(FloatingActionButton.SIZE_NORMAL)) 174 .check(matches(withFabContentHeight(normalSize))); 175 } 176 177 @SmallTest 178 @Test 179 public void testOffset() { 180 onView(withId(R.id.fab_standard)) 181 .perform(setLayoutGravity(Gravity.LEFT | Gravity.TOP)) 182 .check(matches(withFabContentAreaOnMargins(Gravity.LEFT | Gravity.TOP))); 183 184 onView(withId(R.id.fab_standard)) 185 .perform(setLayoutGravity(Gravity.RIGHT | Gravity.BOTTOM)) 186 .check(matches(withFabContentAreaOnMargins(Gravity.RIGHT | Gravity.BOTTOM))); 187 } 188 189 @SmallTest 190 @Test 191 public void testHideShow() { 192 onView(withId(R.id.fab_standard)) 193 .perform(setVisibility(View.VISIBLE)) 194 .perform(hideThenShow(FloatingActionButtonImpl.SHOW_HIDE_ANIM_DURATION)) 195 .check(matches(isDisplayed())); 196 } 197 198 @MediumTest 199 @Test 200 public void testShowHide() { 201 onView(withId(R.id.fab_standard)) 202 .perform(setVisibility(View.GONE)) 203 .perform(showThenHide(FloatingActionButtonImpl.SHOW_HIDE_ANIM_DURATION)) 204 .check(matches(not(isDisplayed()))); 205 } 206 207 @LargeTest 208 @Test 209 public void testClickableTouchAndDragOffView() { 210 onView(withId(R.id.fab_standard)) 211 .perform(setClickable(true)) 212 .perform(new GeneralSwipeAction( 213 Swipe.SLOW, 214 new CoordinatesProvider() { 215 @Override 216 public float[] calculateCoordinates(View view) { 217 // Create coordinators that in the center of the FAB's content area 218 final FloatingActionButton fab = (FloatingActionButton) view; 219 220 final int[] xy = new int[2]; 221 fab.getLocationOnScreen(xy); 222 final Rect rect = new Rect(); 223 fab.getContentRect(rect); 224 225 return new float[] { 226 xy[0] + rect.centerX(), 227 xy[1] + rect.centerY() 228 }; 229 } 230 }, 231 new CoordinatesProvider() { 232 @Override 233 public float[] calculateCoordinates(View view) { 234 // Create coordinators that in the center horizontally, but well 235 // below the view vertically (by 50% of the height) 236 final int[] xy = new int[2]; 237 view.getLocationOnScreen(xy); 238 239 return new float[]{ 240 xy[0] + (view.getWidth() / 2f), 241 xy[1] + (view.getHeight() * 1.5f) 242 }; 243 } 244 }, 245 Press.FINGER)) 246 .check(matches(not(isPressed()))); 247 } 248 249 @MediumTest 250 @Test 251 public void testOnClickListener() { 252 final View.OnClickListener listener = mock(View.OnClickListener.class); 253 final View view = mActivityTestRule.getActivity().findViewById(R.id.fab_standard); 254 view.setOnClickListener(listener); 255 256 // Click on the fab 257 onView(withId(R.id.fab_standard)).perform(click()); 258 259 // And verify that the listener was invoked once 260 verify(listener, times(1)).onClick(view); 261 } 262 263 @SmallTest 264 @Test 265 public void testSetCompatElevation() { 266 onView(withId(R.id.fab_standard)) 267 .perform(setEnabled(false)) 268 .perform(setCompatElevation(0)); 269 270 onView(withId(R.id.fab_standard)) 271 .perform(setEnabled(true)) 272 .perform(setCompatElevation(8)); 273 } 274} 275