Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to click a view of android program through MonkeyRunner?

I want to use MonkeyRunner to test the compatibility of my android program for a list of devices with different screen resolutions. I need to click a view, but the view is not in the same position for different resolutions. How can I get the position of it or do something else to click it? NEED your help!

like image 210
Yingyi Xu Avatar asked Aug 11 '11 07:08

Yingyi Xu


People also ask

How do I run MonkeyRunner on Android?

Running monkeyrunner You do both by invoking the monkeyrunner command which is found in the tools/ subdirectory of your SDK directory. If you provide a filename as an argument, the monkeyrunner command runs the file's contents as a Python program; otherwise, it starts an interactive session.

What is a monkey tool in Android?

The Monkey is a command-line tool that you can run on any emulator instance or on a device. It sends a pseudo-random stream of user events into the system, which acts as a stress test on the application software you are developing.


3 Answers

I know it's a little late, but you can use hierarchyviewer in android sdk to get the view id.

Then, in your script, use this:

from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice  
from com.android.monkeyrunner.easy import EasyMonkeyDevice, By  

device = MonkeyRunner.waitForConnection()  
easy_device = EasyMonkeyDevice(device)  

# Start your android app

# touch the view by id

easy_device.touch(By.id('view_id'), MonkeyDevice.DOWN_AND_UP)

Later edit: thanks to dtmilano and AndroidViewClient, I was able to do the clicks on views as needed. The link is here: https://github.com/dtmilano/AndroidViewClient

like image 62
Gabriel Porumb Avatar answered Nov 09 '22 10:11

Gabriel Porumb


Unfortunately this is not really possible with MonkeyRunner. One option is to use device.getProperty("display.width"),device.getProperty("display.height") and device.getProperty("display.density") and try to use those to somehow figure out where the view is. Another option would be to use a tool like Sikuli to try to click on the view.

Edit (one year after this answer was initially posted): It is now possible to do what you initially wanted with https://github.com/dtmilano/AndroidViewClient

like image 37
n8schloss Avatar answered Nov 09 '22 10:11

n8schloss


Similar to what someoneHuman said above, I use two functions that convert tap coordinates based on the difference in the resolution of the device I originally wrote the script for and whatever device I am currently using.

First I get the current devices x and y pixel width.

CurrentDeviceX = float(device.getProperty("display.width"))
CurrentDeviceY = float(device.getProperty("display.height"))

Then I define a function for converting x and y coordinates. You can see that the functions below were written for a device that is 1280 x 800.

def transX(x):
''' (number) -> intsvd
TransX takes the x value supplied from the original device
and converts it to match the resolution of whatever device 
is plugged in
'''
OriginalWidth = 1280;
#Get X dimensions of Current Device
XScale = (CurrentDeviceX)/(OriginalWidth)
x = XScale * x
return int(x)


def transY(y):
''' (number) -> int
TransY takes the y value supplied from the original device
and converts it to match the resolution of whatever device 
is plugged in.
'''
OriginalHeight = 800;
#Get Y dimensions of Current Device
YScale = (CurrentDeviceY)/(OriginalHeight)
y = YScale * y
return int(y)

Then I can use these functions when creating tap events in my scripts.

example

device.touch(transX(737), transY(226), 'DOWN_AND_UP')

Please note that this approach is far from perfect, and it will only work if your app utilizes anchoring to adjust UI based on screen size. This is my quick and dirty approach to making scripts that work on multiple devices when UI IDs are unavailable.

like image 28
jpelletier Avatar answered Nov 09 '22 08:11

jpelletier