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