Testing Espresso NestedScrollView - "Runtime Error" scrolls to "look" with identifier:

I need to scroll down my NestedScrollView to test my xml file using Espresso, but I get the error message: "Runtime error" scrolls to "by sight" with id: "

A few other posts that seem to have a similar problem.

I followed these instructions: Android espresso NestedScrollView, how to scroll down

Now I get the specified error and found this message: Scrolling to view has been attempted, but the view is not displayed

I have no add-on in my NestedScrollView - I even tried to remove the padding from alltogether XML for testing purposes, but that didn't matter.

This is my test (for now, it shouldn't do anything, but scroll down):

@Test public void testScrollDownAbilityOfDetailsScrollView(){ goToSpecificItemOnStream(streamItemWithOneImage); onView(withId(R.id.end_of_details)) .perform(ScrollToAction.betterScrollTo()); } 

It uses the specially created Scroll To Action class:

  public final class ScrollToAction implements ViewAction { private static final String TAG = ScrollToAction.class.getSimpleName(); @SuppressWarnings("unchecked") @Override public Matcher<View> getConstraints() { return allOf(withEffectiveVisibility(Visibility.VISIBLE), isDescendantOfA(anyOf( isAssignableFrom(ScrollView.class), isAssignableFrom(HorizontalScrollView.class), isAssignableFrom(NestedScrollView.class)))); } @Override public void perform(UiController uiController, View view) { if (isDisplayingAtLeast(80).matches(view)) { Log.i(TAG, "View is already displayed. Returning."); return; } Rect rect = new Rect(); view.getDrawingRect(rect); if (!view.requestRectangleOnScreen(rect, true /* immediate */)) { Log.w(TAG, "Scrolling to view was requested, but none of the parents scrolled."); } uiController.loopMainThreadUntilIdle(); if (!isDisplayingAtLeast(80).matches(view)) { throw new PerformException.Builder() .withActionDescription(this.getDescription()) .withViewDescription(HumanReadables.describe(view)) .withCause(new RuntimeException( "Scrolling to view was attempted, but the view is not displayed")) .build(); } } public static ViewAction betterScrollTo() { return ViewActions.actionWithAssertions(new ScrollToAction()); } @Override public String getDescription() { return "scroll to"; }} 

A custom ScrollToAction class exists because the regular scrollTo method is tightly bound to ScrollView and HorizontalScrollView, but not to NestedScrollView.

This is the XML file I'm trying to verify:

  <?xml version="1.0" encoding="utf-8"?> <android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/scrollView" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior"> <RelativeLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal"> <FrameLayout android:id="@+id/fl" android:background="#FBFBFB" android:layout_margin="0dp" android:layout_width="match_parent" android:layout_height="350dp"> <android.support.v4.view.ViewPager android:id="@+id/container" android:layout_width="match_parent" android:layout_height="wrap_content" app:layout_behavior="@string/appbar_scrolling_view_behavior" /> <ImageView android:id="@+id/location" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="@dimen/text_margin" android:layout_gravity="left|top" android:background="@null" android:src="@drawable/ic_location_white" android:paddingLeft="-8dp" /> <TextView android:id="@+id/textViewDistance" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toRightOf="@id/location" android:textAppearance="?android:attr/textAppearanceMedium" android:layout_margin="@dimen/text_margin" android:layout_gravity="left|top" android:shadowColor="#262424" android:shadowDx="1" android:shadowDy="1" android:shadowRadius="2" android:textColor="#FBFBFB" android:textSize="22dp" android:singleLine="false" android:paddingLeft="24dp" /> <TextView android:id="@+id/textViewPrice" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceMedium" android:layout_margin="@dimen/text_margin" android:layout_gravity="right|top" android:shadowColor="#262424" android:shadowDx="1" android:shadowDy="1" android:shadowRadius="2" android:textColor="#FBFBFB" android:textSize="22dp"/> <me.relex.circleindicator.CircleIndicator android:id="@+id/indicator" android:layout_width="match_parent" android:layout_height="40dp" android:layout_gravity="bottom" android:shadowColor="#262424" android:shadowDx="1" android:shadowDy="1" android:shadowRadius="1"/> </FrameLayout> <LinearLayout android:layout_below="@id/fl" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:id="@+id/textViewTitle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="left" android:layout_margin="@dimen/text_margin" android:textColor="@color/colorCheckTomBlack" android:textStyle="bold" android:textSize="20dp" /> <TextView android:id="@+id/textViewDescription" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="@dimen/text_margin" android:layout_marginRight="@dimen/text_margin" android:gravity="left" android:textColor="@color/colorCheckTomBlack" android:textSize="18dp" android:layout_weight="0.56" /> <RelativeLayout android:layout_width="match_parent" android:layout_height="65dp" android:paddingTop="30dp"> <ImageButton android:id="@+id/buttonWatchlist" android:src="@drawable/ic_checktom" android:background="@null" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="left" android:layout_marginLeft="55dp" android:layout_marginStart="55dp" android:layout_alignParentTop="true" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" android:onClick="launchWatchlistActivity" android:paddingTop="2dp"/> <ImageButton android:id="@+id/buttonMessage" android:src="@drawable/ic_messages" android:background="@null" android:scaleX="1.2" android:scaleY="1.2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" android:onClick="launchMessageActivity" android:paddingTop="7dp"/> <ImageButton android:id="@+id/buttonShare" android:src="@drawable/ic_share" android:background="@null" android:scaleX="1.5" android:scaleY="1.5" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginRight="54dp" android:layout_marginEnd="54dp" android:layout_alignParentTop="true" android:layout_alignParentRight="true" android:layout_alignParentEnd="true" android:onClick="launchShareActivity"/> </RelativeLayout> <RelativeLayout android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="2dp"> <TextView android:id="@+id/textViewWatchlist" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Watchlist" android:layout_marginLeft="41dp" android:layout_marginStart="41dp" android:layout_alignParentTop="true" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" /> <TextView android:id="@+id/textViewMessage" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Message" android:layout_gravity="center_horizontal" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" /> <TextView android:id="@+id/textViewShare" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Share" android:layout_gravity="center_horizontal" android:layout_alignParentTop="true" android:layout_alignParentRight="true" android:layout_alignParentEnd="true" android:layout_marginRight="52dp" android:layout_marginEnd="52dp" /> </RelativeLayout> <LinearLayout android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="_________________________________________" android:paddingTop="25dp"/> </LinearLayout> <LinearLayout android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center"> <de.hdodenhof.circleimageview.CircleImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/imageView" android:layout_centerHorizontal="true" android:id="@+id/circleView" android:scaleX="0.4" android:scaleY="0.4" android:layout_marginTop="-20dp" android:layout_marginBottom="-60dp" /> </LinearLayout> <LinearLayout android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center"> <LinearLayout android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center"> <TextView android:id="@+id/textViewSellerName" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="18dp"/> </LinearLayout> <LinearLayout android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center"> <TextView android:id="@+id/textViewSellerDestination" android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingBottom="20dp" /> <TextView android:id="@+id/end_of_details" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout> </LinearLayout> </LinearLayout> </RelativeLayout> </android.support.v4.widget.NestedScrollView> 

When the test fails, this is the complete output that I get:

android.support.test.espresso.PerformException: Runtime error 'go to' on view 'with id: com.checktom.checktom: id / end_of_details. at android.support.test.espresso.PerformException $ Builder.build (PerformException.java:83) at android.support.test.espresso.base.DefaultFailureHandler.getUserFriendlyError (DefaultFailureHandler.java:80) at android.support.test.espresso .base.DefaultFailureHandler.handle (DefaultFailureHandler.java:56) in android.support.test.espresso.ViewInteraction.runSynchronouslyOnUiThread (ViewInteraction.java:184) in android.support.test.espresso.ViewInteraction.doPerform (ViewInteraction. ) in the file android.support.test.espresso.ViewInteraction.perform (ViewInteraction.java:87) at com.checktom.checktom.ApplicationTest.testScrollDownAbilityOfDetailsScrollView (ApplicationTest.java:279) in java.lang.reflect.Method.invoke method) in java.lang.reflect.Method.invoke (Method.java{72) at org.junit.runners.model.FrameworkMethod $ 1.runReflectiveCall (FrameworkMethod.java:50) on org.junit.internal.runners.model. ReflectiveCallable.run (ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively (FrameworkMethod.java:47) at org.junit.internal.runners.statements.InvokeMethod.evaluate (InvokeMethod.java:17) at org. junit.internal.runners.statements.RunBefores.evaluate (RunBefores.java:26) at android.support.test.internal.statement.UiThreadStatement.evaluate (UiThreadStatement.java:55) at android.support.test.rule.ActivityTestRule $ ActivityStatement.evaluate (ActivityTestRule.java:270) at org.junit.rules.RunRules.evaluate (RunRules.java:20) at org.junit.runners.ParentRunner.runLeaf (ParentRunner.java:325) at org.junit.runners .BlockJUnit4ClassRunner.runChild (BlockJUnit4ClassRunner.java:78) on org.junit.runners.BlockJUnit4ClassRunner.runChild (BlockJUnit4ClassRunner.java:57) on org.junit.runners.ParentRunner.unner29090 .runners.ParentRunner $ 1.schedule (ParentRunner.java:71) at org.junit.runners.ParentRunner.r unChildren (ParentRunner.java:288) at org.junit.runners.ParentRunner.access $ 000 (ParentRunner.java:58) at org.junit.runners.ParentRunner $ 2.value (ParentRunner.java:268) at org.junit.runners .ParentRunner.run (ParentRunner.java//63) at org.junit.runners.Suite.runChild (Suite.java:128) at org.junit.runners.Suite.runChild (Suite.java:27) at org.junit. runners.ParentRunner $ 3.run (ParentRunner.java:290) on org.junit.runners.ParentRunner $ 1.schedule (ParentRunner.java:71) on org.junit.runners.ParentRunner.runChildren (ParentRunner.java:288) on org .junit.runners.ParentRunner.access $ 000 (ParentRunner.java:58) at org.junit.runners.ParentRunner $ 2.value (ParentRunner.java:268) at org.junit.runners.ParentRunner.run (ParentRunner.java liver63 ) at org.junit.runner.JUnitCore.run (JUnitCore.java:137) at org.junit.runner.JUnitCore.run (JUnitCore.java:115) at android.support.test.internal.runner.TestExecutor.execute (TestExecutor.java:59) on android.support.test.runner.AndroidJUnitRunner.onStart (AndroidJUnitRunner.java:262) at android.app. Instrumentation $ InstrumentationThread.run (Instrumentation.java:1933) Called: java.lang.RuntimeException : scrolling to view has been attempted, but the view is not displayed at com.checktom.checktom.ScrollToAction.perform (ScrollToAction.java:52) at android.support.test.espresso.ViewInteraction $ 1.run (ViewInteraction.java:144) in java .util.concurrent.Executors $ RunnableAdapter.call (Executors.java:422) in java.util.concurrent.FutureTask.run (FutureTask.java:237) on android.os.Handler.handleCallback (Handler.java:739) on android.os.Handler.dispatchMessage (Handler.java:95) on android.os.Looper.loop (Looper.java:145) at android.app.ActivityThread.main (ActivityThread.java:6938) in java.lang.reflect .Method.invoke (comp tween method) in java.lang.reflect.Method.invoke (Method.java{72) at com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run (ZygoteInit.java:1404) at com.android.internal.os. ZygoteInit.main (ZygoteInit.java:1199) Tests completed.

I can say that I am throwing an exception at runtime in my execution method of the ScrollToAction class, but I have yet to find a way to solve it.

In the first post I linked, the new BetterScrollTo method seemed to work like a charm.

+8
source share
3 answers

I have done this:

 onView(withId(R.id.viewToScroll) .perform(nestedScrollTo()) .check(matches(isDisplayed())); 

Where nestedScrollTo() :

 public static ViewAction nestedScrollTo() { return new ViewAction() { @Override public Matcher<View> getConstraints() { return Matchers.allOf( isDescendantOfA(isAssignableFrom(NestedScrollView.class)), withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)); } @Override public String getDescription() { return "View is not NestedScrollView"; } @Override public void perform(UiController uiController, View view) { try { NestedScrollView nestedScrollView = (NestedScrollView) findFirstParentLayoutOfClass(view, NestedScrollView.class); if (nestedScrollView != null) { nestedScrollView.scrollTo(0, view.getTop()); } else { throw new Exception("Unable to find NestedScrollView parent."); } } catch (Exception e) { throw new PerformException.Builder() .withActionDescription(this.getDescription()) .withViewDescription(HumanReadables.describe(view)) .withCause(e) .build(); } uiController.loopMainThreadUntilIdle(); } }; } private static View findFirstParentLayoutOfClass(View view, Class<? extends View> parentClass) { ViewParent parent = new FrameLayout(view.getContext()); ViewParent incrementView = null; int i = 0; while (parent != null && !(parent.getClass() == parentClass)) { if (i == 0) { parent = findParent(view); } else { parent = findParent(incrementView); } incrementView = parent; i++; } return (View) parent; } private static ViewParent findParent(View view) { return view.getParent(); } private static ViewParent findParent(ViewParent view) { return view.getParent(); } 
+8
source

I used this code (inspired by this such answer )

 class MainMenuActivityTest { @Test fun textInputDialog_opens_on_button_clicked() { onView(withId(R.id.text_input_button)) .perform(betterScrollTo()) .perform(click()) } } // scroll-to action that also works with NestedScrollViews class BetterScrollToAction:ViewAction by ScrollToAction() { override fun getConstraints():Matcher<View> { return allOf( withEffectiveVisibility(Visibility.VISIBLE), isDescendantOfA(anyOf( isAssignableFrom(ScrollView::class.java), isAssignableFrom(HorizontalScrollView::class.java), isAssignableFrom(NestedScrollView::class.java)))) } } // convenience method fun betterScrollTo():ViewAction { return ViewActions.actionWithAssertions(BetterScrollToAction()) } 

and now it works


I first used this answer here , but used the following code for my test:

 class MainMenuActivityTest { @Test fun textInputDialog_opens_on_button_clicked() { onView(withId(R.id.text_input_button)) .perform(betterScrollTo()) .perform(click()) } } 

but I got the following exceptions ...

 E/TestRunner: failed: textInputDialog_opens_on_button_clicked(com.github.ericytsang.example.app.android.MainMenuActivityTest) ----- begin exception ----- E/TestRunner: androidx.test.espresso.PerformException: Error performing 'scroll to' on view 'Animations or transitions are enabled on the target device. For more info check: https://developer.android.com/training/testing/espresso/setup#set-up-environment with id: com.github.ericytsang.app.example.android:id/text_input_button'. ............ at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:2196) Caused by: java.lang.RuntimeException: Action will not be performed because the target view does not match one or more of the following constraints: (view has effective visibility=VISIBLE and is descendant of a: (is assignable from class: class android.widget.ScrollView or is assignable from class: class android.widget.HorizontalScrollView or is assignable from class: class android.widget.ListView)) Target view: "AppCompatButton{id=2131296521, res-name=text_input_button, visibility=VISIBLE, width=1008, height=107, has-focus=false, has-focusable=true, has-window-focus=true, is-clickable=true, is-enabled=true, is-focused=false, is-focusable=true, is-layout-requested=false, is-selected=false, layout-p arams=androidx.appcompat.widget.LinearLayoutCompat$LayoutParams@ cec11da, tag=null, root-is-layout-requested=false, has-input-connection=false, x=18.0, y=516.0, text=text input dialog, input-type=0, ime-target=false, has-links=false}" at androidx.test.espresso.ViewInteraction.doPerform(ViewInterac ----- end exception ----- 

 E/TestRunner: failed: textInputDialog_opens_on_button_clicked(com.github.ericytsang.example.app.android.MainMenuActivityTest) ----- begin exception ----- E/TestRunner: androidx.test.espresso.PerformException: Error performing 'scroll to' on view 'with id: com.github.ericytsang.app.example.android:id/text_input_button'. ........ Caused by: java.lang.RuntimeException: Action will not be performed because the target view does not match one or more of the following constraints: (view has effective visibility=VISIBLE and is descendant of a: (is assignable from class: class android.widget.ScrollView or is assignable from class: class android.widget.HorizontalScrollView or is assignable from class: class android.widget.ListView)) Target view: "AppCompatButton{id=2131296521, res-name=text_input_button, visibility=VISIBLE, width=1008, height=107, has-focus=false, has-focusable=true, has-window-focus=true, is-clickable=true, is-enabled=true, is-focused=false, is-focusable=true, is-layout-requested=false, is-selected=false, layout-p arams=androidx.appcompat.widget.LinearLayoutCompat$LayoutParams@ 3e84212, tag=null, root-is-layout-requested=false, has-input-connection=false, x=18.0, y=516.0, text=text input dialog, input-type=0, ime-target=false, has-links=false}" at androidx.test.espresso.ViewInteraction.doPerform(ViewInteraction.java:252) at androidx.test.espresso.ViewInteraction.access$100(ViewInteraction.java:65) at androidx.test.espresso.ViewInteraction$1.call(ViewInteraction.jav ----- end exception ----- 
0
source

You can use the new Espresso test recorder to get the code for nested scrolling - check the Espresso Test Tester

-1
source

All Articles