Solo autoscroll issue solution

Robotium Solo – is very cool abstraction layer with pretty nice implementation, but as usual it can’t fits everybody’s needs, for example:
You need to find some text on the screen and click it, using solo it looks like:
/*Solo search methods have a comment: ‘Will automatically scroll when needed’
this logic is causing a lot of problems when scrolling down procedure is stuck in the end of the list and looping in dead cycle or raising an exception, or assertation false
*/
if(solo.searchText(“some text”)) {
solo.clickOnText(“some text”);
} else {
Log.e(“###”,”some text was not found”);
}

Here 2 methods are doing autoscroll – searchText and clickOnText, so if text will be modified or gone after search, but before click, clickOnText will cause dead loop scrolling the view down (if scrolling is available). It is not good approach for search & click logic and completely breaking Stress testing of the application, we have found better and more safe way by extending Solo with custom search methods:

// second param – is flag if method needs to click on the found text
if(!solo.safeSearchForShownText(“some text”, true))
Log.e(“###”,”some text was not found”);

/* safeSearchForShownText implementation, you can extend Solo class with these useful methods:
*/
public boolean safeSearchForShownText(String text) {
return safeSearchForShownText(text, false);
}

boolean safeSearchForShownText(String text, boolean click) {

if(text == null || text.length() == 0) {
Log.i(TAG, “Passed text is null or empty”);
return false;
}

ArrayList allViews = this.getViews();

if(allViews == null || allViews.size() == 0) {
Log.i(TAG, “Passed text is null or empty”);
return false;
}

for (View v: allViews) {
String viewText = “”;
// checking text in Buttons, CheckBoxes, TextViews
if(v instanceof TextView && v.isShown()) {
TextView tvView = (TextView) v;
viewText = tvView.getText().toString();
} else if (v instanceof Button
&& v.isShown()) {
Button btnView = (Button) v;
viewText = btnView.getText().toString();
} else if (v instanceof CheckBox
&& v.isShown()) {
CheckBox chbView = (CheckBox) v;
viewText = chbView.getText().toString();
} else {
continue;
}

if(viewText.length() == 0) continue;
// You are welcome to use Regex approach, it will be better than indexOf
if(viewText.indexOf(text) != -1) {
Log.i(TAG, “text found: ” + viewText);

if(click) {
int[] xy = new int[2];
v.getLocationOnScreen(xy);
Log.i(TAG, “X:Y = ” + xy[0] + “:” + xy[1]);
Log.i(TAG, “click: ” + viewText);
this.clickOnScreen(xy[0], xy[1]);
this.sleep(2000);
}

return true;
}
}

return false;
}

Extending Solo by this way you will never stuck in the dead cycle or your test will be never unexpectedly interrupted.

You are welcome to modify this source code as you like using your own ideology and programming paradigms 🙂

Happy coding! (:

Best regards,
Yahor