I believe I've found the bug.
If you look at
https://android.googlesource.com/platform/frameworks/testing/+/jb-mr0-release%5E1/uiautomator/library/src/com/android/uiautomator/core/UiScrollable.java you'll get this public boolean scrollIntoView(UiSelector selector) method.
That method calls has the code:
if(!scrollForward()) {
return false;
}
And if you put debugging statements into that, you'll see it fails to scroll forwards the first time. Simply changing the if statement to the below works.
if(!scrollForward() && x!=0) {
Obviously this is rather a nasty hack, and I'm unsure why it's needed.
In more detail, I have these print statements in my overridden methods. Note I'm simply commenting out the return statement in the if statement above to show it failing.
@Override
public boolean scrollIntoView(UiSelector selector) throws UiObjectNotFoundException {
// if we happen to be on top of the text we want then return here
System.out.println("My max search swipes are: ");
System.out.println(getMaxSearchSwipes());
if (exists(getSelector().childSelector(selector))) {
return (true);
} else {
System.out.println("It doesn't exist on this page");
// we will need to reset the search from the beginning to start search
scrollToBeginning(getMaxSearchSwipes());
System.out.println("I appear to have swiped to the beginning.");
if (exists(getSelector().childSelector(selector))) {
return (true);
}
for (int x = 0; x < getMaxSearchSwipes(); x++) {
System.out.println("I'm going forward a page: " + x);
if(!scrollForward()) {
System.out.println("Couldn't scroll forwards?");
//return false;
}
if(exists(getSelector().childSelector(selector))) {
return true;
}
}
}
return false;
}
@Override
public boolean scrollForward(int steps) throws UiObjectNotFoundException {
System.out.println("I'm scrolling forwards by these steps: " + steps);
return super.scrollForward(steps);
}And if I start search for an app (that doesn't exist) in the Apps method I get this output. Notice the
Couldn't scroll forwards? at the end are normal, since I'm trying to scroll to a page that doesn't exist. However, the first 'Couldn't scroll forwards?' is incorrect -- it's on the first page and therefore should be able to scroll forwards. (in fact, from observations it does indeed seem to be scrolling the page)My max search swipes are:
20
It doesn't exist on this page
I appear to have swiped to the beginning.
I'm going forward a page: 0
I'm scrolling forwards by these steps: 55
Couldn't scroll forwards?
I'm going forward a page: 1
I'm scrolling forwards by these steps: 55
I'm going forward a page: 2
I'm scrolling forwards by these steps: 55
I'm going forward a page: 3
I'm scrolling forwards by these steps: 55
I'm going forward a page: 4
I'm scrolling forwards by these steps: 55
I'm going forward a page: 5
I'm scrolling forwards by these steps: 55
I'm going forward a page: 6
I'm scrolling forwards by these steps: 55
I'm going forward a page: 7
I'm scrolling forwards by these steps: 55
I'm going forward a page: 8
I'm scrolling forwards by these steps: 55
I'm going forward a page: 9
I'm scrolling forwards by these steps: 55
I'm going forward a page: 10
I'm scrolling forwards by these steps: 55
I'm going forward a page: 11
I'm scrolling forwards by these steps: 55
I'm going forward a page: 12
I'm scrolling forwards by these steps: 55
Couldn't scroll forwards?
I'm going forward a page: 13
I'm scrolling forwards by these steps: 55
Couldn't scroll forwards?
I'm going forward a page: 14
I'm scrolling forwards by these steps: 55
Couldn't scroll forwards?
I'm going forward a page: 15
I'm scrolling forwards by these steps: 55
Couldn't scroll forwards?
I'm going forward a page: 16
I'm scrolling forwards by these steps: 55
Couldn't scroll forwards?
I'm going forward a page: 17
I'm scrolling forwards by these steps: 55
Couldn't scroll forwards?
I'm going forward a page: 18
I'm scrolling forwards by these steps: 55
Couldn't scroll forwards?
I'm going forward a page: 19
I'm scrolling forwards by these steps: 55
Couldn't scroll forwards?
It appears the public boolean scrollForward(int steps) methods is erroneously saying it can't scroll forwards on the first attempt, whereas I believe it is doing from my observations.
Here's the source to my example program:
getUiDevice().pressHome();
UiObject allAppsButton = new UiObject(new UiSelector().description("Apps"));
allAppsButton.clickAndWaitForNewWindow();
UiObject appsTab = new UiObject(new UiSelector().text("Apps"));
appsTab.click();
UiScrollable appsView = new UiScrollable(new UiSelector().scrollable(true));
appsView.setMaxSearchSwipes(20);
appsView.setAsHorizontalList();
UiObject settingsApp = appsView.getChildByText(
new UiSelector().className(android.widget.TextView.class.getName()),
"xxSettings", // Intentionally failing here for the above demonstration.
true);
settingsApp.clickAndWaitForNewWindow();