Importing monkeyrunner into python ViewClient - android

I am interested in making use of the ViewClient extension for MonkeyRunner having run into Broken Pipe issues with pure MonkeyRunner.
I need to still use X/Y coordinates in the device.press(...), device.touch(...), device.drag(...) functions for some of the tests (not a normal android hierarchy) so for this reason I need to import MonkeyRunner into the ViewClient Phyton script - however for the android Apps part of the testing I can use ViewClient proper to search for ID's in the heirarchy. Unless someone knows how to set hardcoded X/Y in ViewClient before calling vc.touch()/vc.drag() etc?
I therefore have the following header to my Python script that attempts to pull in the ViewClient environment and MonkeyRunner path. However running the script always results in the same error:
ImportError: No module named android.monkeyrunner
The part of the script that sets the environment up is structured this way (Environment - Ubuntu 12.04 LTS)
#! /usr/bin/env python
# Import Class Files
import sys
import os
# This must be imported before MonkeyRunner and MonkeyDevice,
# otherwise the import fails.
# PyDev sets PYTHONPATH, use it
try:
for p in os.environ['PYTHONPATH'].split(':'):
if not p in sys.path:
sys.path.append(p)
except:
pass
try:
sys.path.append(os.environ['ANDROID_VIEW_CLIENT_HOME'])
sys.path.append(os.path.join(os.environ['ANDROID_VIEW_CLIENT_HOME'], 'src'))
sys.path.append(os.path.join(os.environ['ANDROID_SDK_ROOT'], 'tools/lib/monkeyrunner.jar'))
sys.path.append(os.path.join(os.environ['ANDROID_SDK_ROOT'], 'tools/lib'))
except:
pass
print sys.path
from com.dtmilano.android.viewclient import ViewClient, View
from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice
So the output of the above looks like this:
mactwixs:~/AndroidViewClient/examples$ ./monkeyscript3.py
['/home/mactwixs/AndroidViewClient/examples', '/home/mactwixs/AndroidViewClient/examples', '/home/mactwixs/AndroidViewClient', '/usr/lib/python2.7', '/usr/lib/python2.7/plat-linux2', '/usr/lib/python2.7/lib-tk', '/usr/lib/python2.7/lib-old', '/usr/lib/python2.7/lib-dynload', '/usr/local/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages/PIL', '/usr/lib/python2.7/dist-packages/gst-0.10', '/usr/lib/python2.7/dist-packages/gtk-2.0', '/usr/lib/python2.7/dist-packages/ubuntu-sso-client', '/usr/lib/python2.7/dist-packages/ubuntuone-client', '/usr/lib/python2.7/dist-packages/ubuntuone-control-panel', '/usr/lib/python2.7/dist-packages/ubuntuone-couch', '/usr/lib/python2.7/dist-packages/ubuntuone-installer', '/usr/lib/python2.7/dist-packages/ubuntuone-storage-protocol', '', '/home/mactwixs/AndroidViewClient', '/home/mactwixs/AndroidViewClient/src', '/home/mactwixs/dev_env/ADT/sdk/tools/lib/monkeyrunner.jar', '/home/mactwixs/dev_env/ADT/sdk/tools/lib']
Traceback (most recent call last):
File "./monkeyscript3.py", line 41, in <module>
from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice
ImportError: No module named android.monkeyrunner
Thanks!
UPDATE:
Interestingly:
mactwixs:~/AndroidViewClient/examples$ python
Python 2.7.3 (default, Sep 26 2013, 20:03:06)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.path_hooks
[<type 'zipimport.zipimporter'>]
>>>
Should there not be <type 'org.python.core.JavaImporter'> too?
UPDATE2:
so the difference is:
mactwixs:~/AndroidViewClient/examples$ python
**Python** 2.7.3 (default, Sep 26 2013, 20:03:06)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>
mactwixs:~/AndroidViewClient/examples$ monkeyrunner
**Jython** 2.5.3 (2.5:c56500f08d34+, Aug 13 2012, 14:54:35)
[Java HotSpot(TM) 64-Bit Server VM (Sun Microsystems Inc.)] on java1.6.0_24
>>>
....so let me try intsalling Jython!
UPDATE3:
Nope. Now it fights with ViewClient so I'm back to square one... and I have found the check-import.py that is supplied with ViewClient. The out of this makes me think something isn't set up quite right as monkeyrunner rather than python is being called for viewclient.py & adbclient.py ...
mactwixs:~/AndroidViewClient/examples$ monkeyrunner check-import.py --debug
sys.path= ['/home/mactwixs/dev_env/ADT/sdk/tools/lib/monkeyrunner.jar', '/home/mactwixs/AndroidViewClient/examples', '/home/mactwixs/dev_env/ADT/sdk/tools/lib/Lib', '/home/mactwixs/dev_env/ADT/sdk/tools/lib/jython-standalone-2.5.3.jar/Lib', '__classpath__', '__pyclasspath__/', '/home/mactwixs/AndroidViewClient/src']
/home/mactwixs/AndroidViewClient/src/com/dtmilano/android/viewclient.py:27: RuntimeWarning:
You should use a 'python' interpreter, not 'monkeyrunner' for this module
warnings.warn(
/home/mactwixs/AndroidViewClient/src/com/dtmilano/android/adb/adbclient.py:26: RuntimeWarning:
You should use a 'python' interpreter, not 'monkeyrunner' for this module
warnings.warn(
OK

I did some experimenting and also looked through the GIT repos and worked out that I can indeed do drag & touch as I needed but without MonkeyRunner and purely in Python - so my problem has gone because I do not have to import Monkey libraries.
import sys
import os
import time
try:
sys.path.append(os.path.join(os.environ['ANDROID_VIEW_CLIENT_HOME'], 'src'))
except:
pass
from com.dtmilano.android.adb import adbclient
import com.dtmilano.android.viewclient as viewclient
device, serialno = viewclient.ViewClient.connectToDeviceOrExit(verbose=True)
device.drag((960,1497),(214,1496),0.15,10)
time.sleep(2)
device.touch(610, 1734, adbclient.DOWN_AND_UP)
time.sleep(2)

Related

Extending LLDB from NDK (Android Studio 3.1.3)

I've found a nice plugin for lldb that allows watching memory regions as images: https://github.com/carlodalmutto/ImageWatchLLDB
As I can see, this plugin was developed for Xcode and not for Android.
However, it is written in Python and therefore should be cross-platform.
I've found a directory c:\Users\username\.lldb\ on my hard drive. Its size is about 1 Gb.
I've created following files: c:\Users\username\.lldbinit, c:\Users\username\lldbinit, c:\Users\username\.lldb\lldbinit, c:\Users\username\.lldb\.lldbinit, c:\Users\username\.lldb\init
All of them have the similar content:
script print "script print Hi from lldb"
echo "echo Hi"
Unfortunately I don't see any output.
I can open LLDB console and issue these commands:
(lldb) script print "script print Hi from lldb"
script print Hi from lldb
(lldb) echo "Hi"
error: 'echo' is not a valid command.
error: Unrecognized command 'echo'.
This means that LLDB understands script print command.
Installation directory for Android Studio contains the subdirectory bin\lldb containing python scripts with pretty printers (file jstring_reader.py, gdb\printing.py, etc)
So, it seems possible to extend LLDB from recent NDK.
The question is: how can I add my custom plugins?
UPDATE. After some hacking I've found that LLDB commands, starting with the "script" string, are actually python commands:
(lldb) script print sys.executable
C:\Android\sdk\lldb\3.1\bin\LLDBFrontend.exe
(lldb) script print sys.version
2.7.10 (default, Feb 24 2016, 14:25:13) [MSC v.1900 64 bit (AMD64)]
(lldb) script print sys.path
['C:/Android/sdk/lldb/3.1/bin', 'C:/Android/Android Studio/bin/lldb/shared/jobject_printers', 'C:/Android/sdk/lldb/3.1/lib/site-packages', 'C:\\Android\\sdk\\lldb\\3.1\\bin\\python27.zip', 'C:\\Android\\sdk\\lldb\\3.1\\DLLs', 'C:\\Android\\sdk\\lldb\\3.1\\lib', 'C:\\Android\\sdk\\lldb\\3.1\\lib\\plat-win', 'C:\\Android\\sdk\\lldb\\3.1\\lib\\lib-tk', 'C:\\Android\\sdk\\lldb\\3.1\\bin', 'C:\\Android\\sdk\\lldb\\3.1', 'C:\\Android\\sdk\\lldb\\3.1\\lib\\site-packages', '.', 'C:\\Android\\Android Studio\\bin\\lldb\\shared\\stl_printers', 'C:\\Android\\sdk\\ndk-bundle\\prebuilt\\windows-x86_64\\share\\pretty-printers\\libstdcxx\\gcc-4.9']
(lldb) script import pip
Traceback (most recent call last):
File "<input>", line 1, in <module>
ImportError: No module named pip
The first idea of installing missing modules with pip has failed.
I update my question: Are there any official guide on writing python plugins for lldb from NDK?
UPDATE 2. Have tried creating Anaconda virtual environment with the same python version and adding it to sys.path. Also failed.
(lldb) script os.environ['PATH']+= r'C:\Anaconda\envs\ndkpy;'
(lldb) script os.environ['PATH']+= r'C:\Anaconda\envs\ndkpy\Library\bin;'
(lldb) script import numpy as np
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "C:\Anaconda\envs\ndkpy\Lib\site-packages\numpy\__init__.py", line 142, in <module>
from . import add_newdocs
File "C:\Anaconda\envs\ndkpy\Lib\site-packages\numpy\add_newdocs.py", line 13, in <module>
from numpy.lib import add_newdoc
File "C:\Anaconda\envs\ndkpy\Lib\site-packages\numpy\lib\__init__.py", line 8, in <module>
from .type_check import *
File "C:\Anaconda\envs\ndkpy\Lib\site-packages\numpy\lib\type_check.py", line 11, in <module>
import numpy.core.numeric as _nx
File "C:\Anaconda\envs\ndkpy\Lib\site-packages\numpy\core\__init__.py", line 26, in <module>
raise ImportError(msg)
ImportError:
Importing the multiarray numpy extension module failed. Most
likely you are trying to import a failed build of numpy.
If you're working with a numpy git repo, try `git clean -xdf` (removes all
files not under version control). Otherwise reinstall numpy.
Original error was: DLL load failed: A dynamic link library (DLL) initialization routine failed.
UPDATE 3. Have found C:\Android\Sdk\lldb\3.1\lib\lib-tk. Tried importing Tkinter, but still no luck:
(lldb) script import Tkinter
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "C:\Android\sdk\lldb\3.1\lib\lib-tk\Tkinter.py", line 39, in <module>
import _tkinter # If this fails your Python may not be configured for Tk
ImportError: No module named _tkinter
Scheme1:
Just run command script import C:\\lldb_plugins\\chisel\\fbchisellldb.py or command script import C:\\lldb_plugins\\LLDB\\lldb_commands\\dslldb.py on your lldb console in Android Studio.
Scheme2:
Create file C:\Users\username\.lldbinit and put the following content to this file:
command script import C:\\lldb_plugins\\chisel\\fbchisellldb.py
command script import C:\\lldb_plugins\\LLDB\\lldb_commands\\dslldb.py
And then, run reload_lldbinit on your lldb console in Android Studio.

How to run a kivy script in the kivy VM?

So I am looking into using Kivy for Android development. Defeating the jedi etc.
But I have hit a roadblock! I installed the Kivy VM image in VirtualBox, but when I try to run the test script:
# /usr/bin/kivy
__version__ = 1.0
from kivy.app import App
from kivy.uix.button import Button
class Hello(App):
def build(self):
btn = Button(text='Hello World')
return btn
Hello().run()
Using:
python main.py
I get:
Traceback (most recent call last):
File "main.py", line 3, in <module>
from kivy.app import App
ImportError: No module named kivy.app
do you have a file named kivy.py in the same folder as main.py?
try
#!/usr/bin/kivy
import kivy
print kivy.__file__
I tried just plain installing kivy as they say to on their website, and it worked.
sudo add-apt-repository ppa:kivy-team/kivy
apt-get install python-kivy

How to touch/press a button/View using AndroidViewClient?

I have an app, for which i wanna run Monkeyrunner (using Android ViewClient)
I am trying to define my view as
Vc = ViewClient(device, serialno)
vc.dump
touchProject = vc.findViewByIdorRaise('id/projectNewGallery')
touchProject.touch()
But I am getting error : ->"com.dtmilano.android.viewclient.ViewNotFoundException: Couldn't find View with ID='id/projectNewGallery' in tree with root=ROOT"
How can i set root ? like this ?
touchProject = vc.findViewByIdorRaise('id/projectNewGallery','id/projectMain')
?
///////////////////////////////////////////////////////////////////////////////////
I am trying to use culebra tool, But I am getting following error.
$ java -jar androidviewclient-2.3.16.jar culebra
ERROR: monkeyrunner was not found and Windows 7 does not support shebang in scripts. Aborting.
I also tried this way (Non-Shebang OS -> Windows 7 )
$ /cygdrive/c/android-sdk/tools/monkeyrunner.bat -plugin /cygdrive/c/Android_Resources_Hassan/MonkeyRunner_KIneMaster/AndroidViewClient-master/AndroidViewClient/bin/androidviewclient-2.3.22.jar culebra myscript.py
Plugin file doesn't exist
Usage: monkeyrunner [options] SCRIPT_FILE
-s MonkeyServer IP Address.
-p MonkeyServer TCP Port.
-v MonkeyServer Logging level (ALL, FINEST, FINER, FINE, CONFIG, INFO, WARNING, SEVERE, OFF)
Ok i was able to run it Windows CMD :
C:\android-sdk\tools>monkeyrunner -plugin C:\Android_Resources_Hassan\MonkeyRunner_KIneMaster\androidviewclient-2.3.24.jar test3_py.py
but I got following error again :
130619 14:41:15.725:S [MainThread] [com.android.monkeyrunner.MonkeyRunnerOptions] Script terminated due to an exception
130619 14:41:15.725:S [MainThread] [com.android.monkeyrunner.MonkeyRunnerOptions]Traceback (most recent call last):
File "C:\android-sdk\tools\test3_py.py", line 71, in <module>
touchProject = vc.findViewByIdOrRaise('id/projectNewGallery')
File "C:\Android_Resources_Hassan\MonkeyRunner_KIneMaster\AndroidViewClient- master\AndroidViewClient\src\com\dtmilano\android\viewclient.py", line 1919, in findViewById
OrRaise raise ViewNotFoundException("ID", viewId, root)
com.dtmilano.android.viewclient.ViewNotFoundException: Couldn't find View with ID='id/projectNewGallery' in tree with root=ROOT
my script file --------------------
#! /usr/bin/env monkeyrunner
'''
Copyright (C) 2012 Diego Torres Milano
Created on Feb 3, 2012
#author: diego
'''
import re
import sys
import os
# 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
# Imports the monkeyrunner modules used by this program
from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice
#starting script
print "start"
# Connects to the current device, returning a MonkeyDevice object
device, serialno = ViewClient.connectToDeviceOrExit()
#device connected
print "connection started"
# sets a variable with the package's internal name
package = 'com.example.app.myApp'
# sets a variable with the name of an Activity in the package
activity = 'com.example.mainapp.MainActivity'
# sets the name of the component to start
runComponent = package + '/' + activity
# Runs the component
device.startActivity(component=runComponent)
#device set to sleep for 4 seconds
print "wait for 4 seconds"
# first screen shot event
MonkeyRunner.sleep(4);
vc = ViewClient(device, serialno)
vc.dump()
root = vc.getRoot()
#touchProject = vc.findViewWithTextOrRaise('', root)
touchProject = vc.findViewByIdOrRaise('projectNewGallery')
touchProject.touch()
# wait for screenshot to save
MonkeyRunner.sleep(2);
# Takes a screenshot
result1 = device.takeSnapshot()
result1.writeToFile('/myPath/shot1.png','png')
# wait for 3 seconds
MonkeyRunner.sleep(3);
is ID same as defined in XML android:id="+id/newProjectGallery" ?
////////////////////// AFTER adding vc.traverse() in code///////////////////
I am getting following error
130620 10:07:43.775:S [MainThread] [com.android.monkeyrunner.MonkeyRunnerOptions] Script terminated due to an exception
130620 10:07:43.775:S [MainThread] [com.android.monkeyrunner.MonkeyRunnerOptions]Traceback (most recent call last):
File "C:\android-sdk\tools\test.py", line 71, in <module>
ViewClient(*ViewClient.connectToDeviceOrExit()).traverse(transform=ViewClient.TRAVERSE_CIT)
File "C:\Android_Resources_Hassan\MonkeyRunner\AndroidViewClient- master\AndroidViewClient\src\com\dtmilano\android\viewclient.py", line 1687, in traverse
print >>stream, "%s%s" % (indent, s)
LookupError: unknown encoding 'ms949'
Moreover I ran dump-simple.py code also. But I am getting again the same error :
130620 10:07:43.775:S [MainThread] [com.android.monkeyrunner.MonkeyRunnerOptions] Script terminated due to an exception
130620 10:07:43.775:S [MainThread] [com.android.monkeyrunner.MonkeyRunnerOptions]Traceback (most recent call last):
File "C:\android-sdk\tools\dump-simple.py", line 30, in <module>
ViewClient(*ViewClient.connectToDeviceOrExit()).traverse(transform=ViewClient.TRAVERSE_CIT)
File "C:\Android_Resources_Hassan\MonkeyRunner\AndroidViewClient- master\AndroidViewClient\src\com\dtmilano\android\viewclient.py", line 1687, in traverse
print >>stream, "%s%s" % (indent, s)
LookupError: unknown encoding 'ms949'
what is causing it ?
Please help me ~
Thanks
I see a couple of errors in your snippet (check this corrected version):
vc = ViewClient(device, serialno)
vc.dump()
touchProject = vc.findViewByIdOrRaise('id/projectNewGallery')
touchProject.touch()
to simplify the process, you can just use culebra to generate the correct script template that you can, later on, adapt to your needs:
When the device screen contains the desired Views:
$ culebra -VC -o myscript.py
edit myscript.py to add the call to the touch() method and run
$ myscript.py
The use of verbose comments (-C) simplifies the identification of Views if IDs are not available.
Update
You were almost there in your first example, I guess the problem should be fixed by my corrected snippet before. The code run, the only problem may be you are expecting IDs that are not there.
Remember, there are no IDs if the back-end is UiAutomator, which is the default back-end for API >= 16.
The java runner expects monkeyrunner to be in the PATH.
It seems /cygdrive/c/Android_Resources_Hassan/MonkeyRunner_KIneMaster/AndroidViewClient-master/AndroidViewClient/bin/androidviewclient-2.3.22.jar does not exist. At least this is what monkeyrunner thinks. Perhaps you should use \ in Windows paths.

Android MonkeyRunner exception

I'm trying to run MonkeyRunner Android test tool from Eclipse (4.2).
I installed Eclipse PyDev plugin, as well as Jython 2.5.1.
My PyDev interpreter is set to Jython / 2.5.
I created a Jython project in Eclipse with a simple jython file:
# Imports the monkeyrunner modules used by this program
from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice
# Connects to the current device, returning a MonkeyDevice object
device = MonkeyRunner.waitForConnection()
Now when I launch it from Eclipse (project > run as JythonProject), I'me getting the following exception:
Traceback (most recent call last):
File "C:\svnrepository\trunk\JythonProject\src\main.py", line 10, in <module>
device = MonkeyRunner.waitForConnection()
at com.android.monkeyrunner.MonkeyRunner.waitForConnection(MonkeyRunner.java:75)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
java.lang.NullPointerException: java.lang.NullPointerException
Any idea what can be wrong?
There is a post of Diego Torres Milano how to configure PyDev to use it with monkeyrunner. I followed his steps and in my case everything works fine.
In brief, at first you need to change your Android installation. You need to rename your monkeyrunner tool to something monkeyrunner-original. Then you need to write in the same folder shell script (name it monkeyrunner) that will invoke monkeyrunner-original in the specific manner.
Script for Linux:
# /bin/bash
if [ "$1" = '-u' ]
then
shift
fi
exec /opt/android-sdk-linux_86/tools/monkeyrunner-original "$#"
Script for Windows:
REM
#echo off if("%1")==("-u") shift "C:\Program Files\Android\android-sdk\tools"/monkeyrunner-original %1 %2 %3 %4 %5 %6 %7 %8
Then in Eclipse, you should define new Python interpreter (not Jython) and point it to the created script.

ImportError: No module named dtmilano

Hi I am new to python development. I am trying to execute the code given at http://dtmilano.blogspot.in/2012/02/monkeyrunner-interacting-with-views.html but when ever i am trying to execute the code i get following error:
Traceback (most recent call last):
File "C:\Users\gur31265\workspace\MonkeyRunnerForSmartRecorder\com\test\Runner.py", line 23, in <module>
from com.dtmilano.android.viewclient import ViewClient
ImportError: No module named dtmilano
I am using eclipse with PyDev and Jython 2.5.3. I had also configured Python 32 on eclipse running on Windows 7 machine. Other Python scripts are running fine but i don't know why code given on dtmilano's blog is causing this error. I had also installed AndroidViewClient and set the ANDROID_VIEW_CLIENT_HOME in system path. Please help.
This took me a bit to work out. Make sure that you append the AndroidViewClient source directory to your path before you import MonkeyRunner.
The following will fail with ImportError: No module named dtmilano:
from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice
sys.path.append('/path/to/android_view_client_home/src')
from com.dtmilano.android.viewclient import ViewClient
However, it will work if you just switch the order:
sys.path.append('/path/to/android_view_client_home/src')
from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice
from com.dtmilano.android.viewclient import ViewClient
It seems that once it imports the com package for MonkeyRunner, it will only look in that package for dtmilano. However, if both com packages are in the path before you import anything, it will know to look in both locations.
You can find a detailed explanation about how to use PYTHONPATH and ANDROID_VIEW_CLIENT_HOME environment variables from Eclipse and PyDev and also from command line at http://dtmilano.blogspot.ca/2012/09/monkeyrunner-importing-from-pythonpath.html.
Briefly:
#!/usr/bin/env monkeyrunner
import re
import sys
import os
import java
# This must be imported before MonkeyRunner and MonkeyDevice,
# otherwise the import fails.
# PyDev sets PYTHONPATH, use it
try:
for p in os.environ['PYTHONPATH'].split(':'):
if not p in sys.path:
sys.path.append(p)
except:
pass
try:
sys.path.append(os.path.join(os.environ['ANDROID_VIEW_CLIENT_HOME'], 'src'))
except:
pass
from com.dtmilano.android.viewclient import ViewClient, View
from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice
Use monkeyrunner located in android SDK to run your code. For example:
to compile a file named help.py use following command:
c:>monkeyrunner help.py
same command will work on linux environment also.

Categories

Resources