1*21373fa4SWill Schurman // Copyright 2015-present 650 Industries. All rights reserved. 2*21373fa4SWill Schurman package host.exp.exponent.utils 3*21373fa4SWill Schurman 4*21373fa4SWill Schurman import android.graphics.Rect 5*21373fa4SWill Schurman import android.util.Log 6*21373fa4SWill Schurman import android.view.View 7*21373fa4SWill Schurman import androidx.test.espresso.ViewAction 8*21373fa4SWill Schurman import androidx.test.espresso.matcher.ViewMatchers 9*21373fa4SWill Schurman import android.widget.ScrollView 10*21373fa4SWill Schurman import android.widget.HorizontalScrollView 11*21373fa4SWill Schurman import androidx.test.espresso.PerformException 12*21373fa4SWill Schurman import androidx.test.espresso.UiController 13*21373fa4SWill Schurman import androidx.test.espresso.util.HumanReadables 14*21373fa4SWill Schurman import androidx.test.espresso.action.ViewActions 15*21373fa4SWill Schurman import org.hamcrest.Matcher 16*21373fa4SWill Schurman import org.hamcrest.Matchers 17*21373fa4SWill Schurman import java.lang.RuntimeException 18*21373fa4SWill Schurman 19*21373fa4SWill Schurman class ExponentScrollToAction : ViewAction { getConstraintsnull20*21373fa4SWill Schurman override fun getConstraints(): Matcher<View> { 21*21373fa4SWill Schurman return Matchers.allOf( 22*21373fa4SWill Schurman ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE), 23*21373fa4SWill Schurman ViewMatchers.isDescendantOfA( 24*21373fa4SWill Schurman Matchers.anyOf( 25*21373fa4SWill Schurman ViewMatchers.isAssignableFrom(ScrollView::class.java), 26*21373fa4SWill Schurman ViewMatchers.isAssignableFrom( 27*21373fa4SWill Schurman HorizontalScrollView::class.java 28*21373fa4SWill Schurman ), 29*21373fa4SWill Schurman ViewMatchers.withClassName(Matchers.containsString("ScrollView")) 30*21373fa4SWill Schurman ) 31*21373fa4SWill Schurman ) 32*21373fa4SWill Schurman ) 33*21373fa4SWill Schurman } 34*21373fa4SWill Schurman performnull35*21373fa4SWill Schurman override fun perform(uiController: UiController, view: View) { 36*21373fa4SWill Schurman if (ViewMatchers.isDisplayingAtLeast(90).matches(view)) { 37*21373fa4SWill Schurman Log.i(TAG, "View is already displayed. Returning.") 38*21373fa4SWill Schurman return 39*21373fa4SWill Schurman } 40*21373fa4SWill Schurman val rect = Rect() 41*21373fa4SWill Schurman view.getDrawingRect(rect) 42*21373fa4SWill Schurman if (!view.requestRectangleOnScreen(rect, true /* immediate */)) { 43*21373fa4SWill Schurman Log.w(TAG, "Scrolling to view was requested, but none of the parents scrolled.") 44*21373fa4SWill Schurman } 45*21373fa4SWill Schurman uiController.loopMainThreadUntilIdle() 46*21373fa4SWill Schurman if (!ViewMatchers.isDisplayingAtLeast(90).matches(view)) { 47*21373fa4SWill Schurman throw PerformException.Builder() 48*21373fa4SWill Schurman .withActionDescription(this.description) 49*21373fa4SWill Schurman .withViewDescription(HumanReadables.describe(view)) 50*21373fa4SWill Schurman .withCause( 51*21373fa4SWill Schurman RuntimeException( 52*21373fa4SWill Schurman "Scrolling to view was attempted, but the view is not displayed" 53*21373fa4SWill Schurman ) 54*21373fa4SWill Schurman ) 55*21373fa4SWill Schurman .build() 56*21373fa4SWill Schurman } 57*21373fa4SWill Schurman } 58*21373fa4SWill Schurman getDescriptionnull59*21373fa4SWill Schurman override fun getDescription(): String { 60*21373fa4SWill Schurman return "scroll to" 61*21373fa4SWill Schurman } 62*21373fa4SWill Schurman 63*21373fa4SWill Schurman companion object { 64*21373fa4SWill Schurman private val TAG = ExponentScrollToAction::class.java.simpleName exponentScrollTonull65*21373fa4SWill Schurman fun exponentScrollTo(): ViewAction { 66*21373fa4SWill Schurman return ViewActions.actionWithAssertions(ExponentScrollToAction()) 67*21373fa4SWill Schurman } 68*21373fa4SWill Schurman } 69*21373fa4SWill Schurman } 70