[XDA-University] Ravi H Basawa:
3. What all methods present in viewclient?​

- Some of the most used methods I have listed below -

'TRAVERSE_CIT', 'TRAVERSE_CITB', 'TRAVERSE_CITC', 'TRAVERSE_CITCD', 'TRAVERSE_CITCDS', 'TRAVERSE_CITG', 'TRAVERSE_CITPS', 'TRAVERSE_CITUI', 'TRAVERSE_S', '_ViewClient__findViewWithAttributeInTree', '_ViewClient__findViewWithAttributeInTreeOrRaise', '_ViewClient__findViewWithAttributeInTreeThatMatches', '_ViewClient__findViewsWithAttributeInTree', '_ViewClient__getFocusedWindowPosition', '_ViewClient__hammingDistance', '_ViewClient__levenshteinDistance', '_ViewClient__mapSerialNo', '_ViewClient__obtainAdbPath', '_ViewClient__obtainDeviceSerialNumber', '_ViewClient__parseTree', '_ViewClient__parseTreeFromUiAutomatorDump', '_ViewClient__pickleable', '_ViewClient__splitAttrs', '_ViewClient__traverse', '__del__', '__doc__', '__init__', '__module__', 'assertServiceResponse', 'connectToDeviceOrExit', 'distance', 'distanceTo', 'dump', 'excerpt', 'findViewById', 'findViewByIdOrRaise', 'findViewByTag', 'findViewByTagOrRaise', 'findViewWithAttribute', 'findViewWithAttributeOrRaise', 'findViewWithAttributeThatMatches', 'findViewWithContentDescription', 'findViewWithContentDescriptionOrRaise', 'findViewWithText', 'findViewWithTextOrRaise', 'findViewsContainingPoint', 'findViewsWithAttribute', 'getRoot', 'getSdkVersion', 'getViewIds', 'getViewsById', 'hammingDistance', 'imageDirectory', 'installPackage', 'isKeyboardShown', 'levenshteinDistance', 'list', 'longTouch', 'serviceResponse', 'setAlarm', 'setText', 'setViews', 'setViewsFromUiAutomatorDump', 'sleep', 'swipe', 'touch', 'traverse', 'traverseShowClassIdAndText', 'traverseShowClassIdTextAndBounds', 'traverseShowClassIdTextAndCenter', 'traverseShowClassIdTextAndContentDescription', 'traverseShowClassIdTextAndTag', 'traverseShowClassIdTextAndUniqueId', 'traverseShowClassIdTextContentDescriptionAndScreenshot', 'traverseShowClassIdTextPositionAndSize', 'traverseTakeScreenshot', 'writeImageToFile', 'writeViewImageToFileInDir'

4. How to import and use android viewclient?​

- Once you have installed android viewclient next step is to use this in our new project. Below is the code snippit for importing android view client -

'''
Created on Dec 19, 2015
@author: ravi h basawa
'''
from com.dtmilano.android.viewclient import ViewClient
device, serialno = ViewClient.connectToDeviceOrExit()
vc = ViewClient(device=device, serialno=serialno)

5. How do I automate android native/3rd party apps using android ViewClient?​

Pre-conditions in your device:

1. Enable USB debugging.

2. Enable stay awake option.

Pre-conditions in PC:

1. android sdk should be present.

2. connect your testing device. (double check with cmd "adb devices")

3. python env. variables are all set.

4. Create a new folder named "Automation" on your desktop.

5. Inside it create a new text file and paste the below given code and save it as Settings.py (or whatever you want to give)

Lets start-- It is very easy to automate android apps using android ViewClient. Let me teach you a simple code which will open settings application.

NOTE: This program I have written using my Nexus device running Android latest version 6.0; So the below program may give you errors. Please edit the code accordingly.

'''
Created on Dec 19, 2015
@author: ravi h basawa
'''
from com.dtmilano.android.viewclient import ViewClient
device, serialno = ViewClient.connectToDeviceOrExit()
vc = ViewClient(device=device, serialno=serialno)

print "################## Settings application test ####################"
device.startActivity('com.android.settings/.Settings')
print 'TEST : PASS'

Once you write the above code, let us save it as Settings.py And then we will try to open it using IDLE software which will come pre-bundled with python as shown below:

* To execute our newly written code we gonna press F5.

Explanation on above code --

The first line of code is to import dtmilano's ViewClient method.

the second line is used to define the devices which you have connected, In my case as I have connected only one device I will not provide serialno,

Going further I will show you as how to connect to two devices and make them communicate.

6. How to take screen shots using viewclient?​

- Now we will take our code to the next level, We gonna open settings app, and then we are going to click on About phone option. and also we'll take screen shot of the device to check as what is inside About phone.

NOTE: Create a folder named "Screenshots" at your current working directory(That is in our case folder named Automation) or else you will get Error saying no folder named "Screenshots" is present.

'''
Created on Dec 19, 2015
@author: ravi h basawa
'''
import re
import sys
import time
import os

from PIL import Image

from com.dtmilano.android.viewclient import ViewClient
device, serialno = ViewClient.connectToDeviceOrExit()
vc = ViewClient(device=device, serialno=serialno)

print "################## Settings application test ####################"
device.startActivity('com.android.settings/.Settings')
print 'SUCCESFULLY OPENED SETTINGS APP'
vc.dump() ## this is used to refresh the screen.

## below is the for loop used to swipe screen five times. the input swipe command takes 4 args that is X1,Y1,X2,Y2 which can be found using "Pointer location" option present in developer settings.

for i in range(5):
device.shell('input swipe 651 1307 677 680')
vc.dump()
vc.findViewWithText("About phone").touch()##this line will click on About phone option.
print 'About phone option found and clicked'
vc.dump()
time.sleep(2)
device.takeSnapshot(reconnect=True).save(os.getcwd()+'\\Screenshots\\'+'OS_version.png') #this line will take screenshot of the device and store it in the folder named Screenshots.
print 'Screenshot taken'
print 'TEST : PASS'

Now when you execute the above code you will see the result as below -

Now let us write a code to check the current android version displayed under settings app is proper or not.

'''
Created on Dec 19, 2015
@author: ravi h basawa
'''

import re
import sys
import time
import os

from PIL import Image

from com.dtmilano.android.viewclient import ViewClient
device, serialno = ViewClient.connectToDeviceOrExit()
vc = ViewClient(device=device, serialno=serialno)

print "################## Android OS VERSION TEST ####################"
device.startActivity('com.android.settings/.Settings')
print 'Settings app opened'
vc.dump()
for i in range(5):
device.shell('input swipe 651 1307 677 680')
vc.dump()
vc.findViewWithText("About phone").touch()
vc.dump()
print 'About phone option clicked'
device.shell('input swipe 651 1307 677 680')
vc.dump()
version = vc.findViewWithText('Android version')
if version:
vnum = vc.findViewWithText('6.0')
if vnum:
print 'Android OS version is 6.0'
vc.dump()
time.sleep(2)
device.takeSnapshot(reconnect=True).save(os.getcwd()+'\\Screenshots\\'+'OS_version.png') #this line will take screenshot of the device and store it in the folder named Screenshots.
print 'Screenshot taken'
print 'TEST : PASS'
device.press('KEYCODE_HOME')
else:
print 'Incorrect OS version'
print 'TEST : FAIL'
else:
print 'Android version string not found'
print 'TEST : FAIL'
device.press('KEYCODE_HOME')

In the above code you might be wondring as what does vc.dump() stands for, It is actually refreshes the screen and it makes easier to find required data on the screen. Without vc.dump() method there is 100% guarenty that our script gonna fail.

OK, Now we will wrtie a script which has Python functions in it.

Before this let us learn as what is 'def' in Pyhton is all about:

As we all know that we define functions to provide the required functionality. Below are some rules to define a function in Python.

[*] Function blocks begin with the keyword def followed by the function name and parentheses ( ( ) ).

[*] Any input parameters or arguments should be placed within these parentheses. You can also define parameters inside these parentheses.

[*] function names can be started with a _ or a small letter.

[*] The code block within every function starts with a colon (:) and is indented.

Now I will write a simple code to show you as how def works.

'''
Created on Dec 19, 2015
@author: ravi h basawa
'''
def test():
print 'Hi I am inside a function'
test()

As you can see from the above code, there is a single tab given after the fucntion test():, these are called as indents. Once you start using IDLE for python script writing you will get to know more on these indents.

Just for testing purpose try to write your own functions using IDLE; Once you type as " def test(): " and hit ENTER without the qouats you will see a single tab occured. This is how Pyhton works. There are no curly brases in it. But only Indents. If you can handle these indents you are good to go.

And one more thing I forgot to explain you guys, That is you can Indent a region by using the shortcut ctrl+] and Dedent using the shortcut ctrl+[

For now let us write the same code; But this time we will use 'def' in it.

'''
Created on Dec 19, 2015
@author: ravi h basawa
'''

import re
import sys
import time
import os

from PIL import Image

from com.dtmilano.android.viewclient import ViewClient
device, serialno = ViewClient.connectToDeviceOrExit()
vc = ViewClient(device=device, serialno=serialno)

def os_test():
print "################## Android OS VERSION TEST ####################"
device.startActivity('com.android.settings/.Settings')
print 'Settings app opened'
vc.dump()
for i in range(5):
device.shell('input swipe 651 1307 677 680')
vc.dump()
vc.findViewWithText("About phone").touch()
vc.dump()
print 'About phone option clicked'
device.shell('input swipe 651 1307 677 680')
vc.dump()
version = vc.findViewWithText('Android version')
if version:
vnum = vc.findViewWithText('6.0')
if vnum:
print 'Android OS version is 6.0'
vc.dump()
time.sleep(2)
device.takeSnapshot(reconnect=True).save(os.getcwd()+'\\Screenshots\\'+'OS_version.png') #this line will take screenshot of the device and store it in the folder named Screenshots.
print 'Screenshot taken'
print 'TEST : PASS'
device.press('KEYCODE_HOME')
else:
print 'Incorrect OS version'
print 'TEST : FAIL'
else:
print 'Android version string not found'
print 'TEST : FAIL'
device.press('KEYCODE_HOME')
os_test()

Output of the above code will be as below:

============= RESTART: C:\Users\ravi\Desktop\testing\Settings.py =============

################## Android OS VERSION TEST ####################

Settings app opened

About phone option clicked

Android OS version is 6.0

Screenshot taken

TEST : PASS

>>>