Saturday, May 12, 2012

AndroidViewClient: Q&A

Q: Hi Diego, thanks for your sharing knowledge.
Now I have a question about how to implement a method like touchByText(self, text)instead of touching the Views by (x,y).


I just want to simply use text instead of android id.
Thank you.


(edited for clarity)

A: This is an interesting question that was posted as a comment to monkeyrunner: interacting with the Views and made me think about the possibility of including this functionality in AndroidViewClient.


After all, one of the most serious limitations of plain monkeyrunner is the need of the screen coordinates in MonkeyDevice.touch(integer x, integer y, integer type).
We have also analyzed here the use of the undocumented EasyMonkeyDevice in monkeyrunner: testing views properties where we described the current shortcomings.


So, fortunately, implementing this feature in AndroidViewClient was not so difficult and it's now available if you download the latest source code. To demonstrate it, we will be using a very simple Activity with 5 ToggleButtons named One, Two, Three, Four and Five.
Then, we will be using a monkeyrunner script using AndroidViewClient to find the buttons and touching them. After the script runs we will be able to see the five buttons in their On state.




The script that will toggle every button on is as follows:

#! /usr/bin/env monkeyrunner
'''
Copyright (C) 2012  Diego Torres Milano
Created on May 5, 2012
  
@author: diego
'''

import sys
import os
import time

# this must be imported before MonkeyRunner and MonkeyDevice,
# otherwise the import fails
try:
    ANDROID_VIEW_CLIENT_HOME = os.environ['ANDROID_VIEW_CLIENT_HOME']
except KeyError:
    print >>sys.stderr, "%s: ERROR: ANDROID_VIEW_CLIENT_HOME not set in environment" % __file__
    sys.exit(1)
sys.path.append(ANDROID_VIEW_CLIENT_HOME + '/src')
from com.dtmilano.android.viewclient import ViewClient

from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice

device = MonkeyRunner.waitForConnection(60, "emulator-5554")
if not device:
   raise Exception('Cannot connect to device')

MonkeyRunner.sleep(5)

vc = ViewClient(device)
vc.dump()

for bt in [ 'One', 'Two', 'Three', 'Four', 'Five' ]:
    b = vc.findViewWithAttribute('text:mText', bt)
    if b:
        (x, y) = b.getXY()
        print >>sys.stderr, "clicking b%s @ (%d,%d) ..." % (bt, x, y)
        b.touch()
    else:
        print >>sys.stderr, "b%s not found" % bt
    time.sleep(7)

print >>sys.stderr, "bye"


Once you run the script you will see how the state of the buttons is gradually changed.
I hope this example helps you getting started with AndroidViewClient.