I also meet getChildByText only scrolling once, and I am trying to trace it. I believe that the main reason may be from the system.
When you call getChildByText , its stream:
getChildByText -> scrollIntoView -> scrollForward -> scrollSwipe
In scrollSwipe system launches a cleanup command, wait for it to find all AccessibilityEvent and the AccessibilityEvent.TYPE_VIEW_SCROLLED filter on the current screen. This step will force UiScrollable to scroll again or check it at the end.
But the error is here, the system cannot return to the right of AccessibilityEvent .
public boolean scrollSwipe(final int downX, final int downY, final int upX, final int upY, final int steps) { Runnable command = new Runnable() { @Override public void run() { swipe(downX, downY, upX, upY, steps); } };
I think the best way is to override the code and determine the appropriate MaxSearchSwipes , and if the element exceeds this size, make the test unsuccessful.
public class UiScrollableFix extends UiScrollable { public UiScrollableFix(UiSelector container) { super(container); } @Override public boolean scrollIntoView(UiSelector selector) throws UiObjectNotFoundException { Tracer.trace(selector); // if we happen to be on top of the text we want then return here UiSelector childSelector = getSelector().childSelector(selector); if (exists(childSelector)) { return (true); } else { // we will need to reset the search from the beginning to start search scrollToBeginning(getMaxSearchSwipes()); if (exists(childSelector)) { return (true); } for (int x = 0; x < getMaxSearchSwipes(); x++) { Log.e("test", "x=" + x); boolean scrolled = scrollForward(); if (exists(childSelector)) { return true; } //For avoiding the scroll fail. // if (!scrolled && x!=0) { // return false; // } } } return false; } }
source share