Script for doing screen captures

Created a screen for doing screen captures, so I can call it while doing other test.  This script uses the time to create an unique file name, so I don’t have to worry about overwriting the same file while running my test.  This script is run by monkeyrunner so I used the full path when calling monkeyrunner and my script (this is a bit bias towards OS X syntax since I am testing on a Mac at the moment)

/Users/me/Android/sdk/tools/monkeyrunner -v ALL  /Users/me/Android/capture_screen.py

-v ALL is for verbose logging

#!/usr/bin/env python
# coding: utf-8

# Screen shot of android

# Needed modules
from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice

import time

# Wait for connection
device = MonkeyRunner.waitForConnection()

# Use the time in seconds to help create an unique file name for the image that is captured

filelocation = "/Users/jmiller/Android/Screen_Shots/"

fileNamePrefix = "scrnCap"

thefile = filelocation + fileNamePrefix + str(int(time.time())) + ".png"

# Snap shot of the screen
result = device.takeSnapshot()

# Write out the results
result.writeToFile(thefile,"png")

Doing it all on a Mac (osx)

Mobile testing at a new company, the catch is I am not on a Mac, I have the commands (adb) work the same as before, but getting the Android SDK stuff to run is a bit different than I am used too (since I configured everything on windows before) at least I shouldn’t have to worry about Windows USB drivers this time around.

I downloaded the latest Android SDK from the Android site and made a point to ignore the eclipse instructions, I am not a developer and I dislike eclipse.  I unzipped the osx and then moved it to a different directory /Users/me/Android/…..  (use what ever works for you)

Now to run things like the SDK or the AVD you can type the command “android sdk” – if the path is setup, the android “tool” is in this directory: /sdk/tools, if your path isn’t setup you can cd to that directory and run the command locally:

  • ./android sdk – to download drivers and such
  • ./android avd – to create new virtual devices

If you set your path (so the system can find the commands) you can run this and other commands easier.

To check what your path is currently set too, you can use the command (you have to run this in a terminal, the linus/osx equivalent to a command prompt:

  • echo $PATH

You can also see what is configured in the paths file, or in the paths.d directory

  • more /etc/paths
  • ls -l /etc/paths.d

Some info about managing paths is here – though it might vary on some older osx installs.

For myself I added a file to paths.d directory for my android stuff (the sudo command will only work if you have those privileges on your mac):

  • sudo sh -c ‘echo “/Users/me/Android/sdk/tools” >> /etc/paths.d/android_paths
  • sudo sh -c ‘echo “/Users/me/Android/sdk/platform-tools” >> /etc/paths.d/android_paths’
    • Note/Reminder “>>” appends to the existing file use “>” to create a new file

Then I ran ls -l /etc/paths.d to verify the file was there:

Me:platform-tools me$ ls -l /etc/paths.d/
total 8
-rw-r–r–  1 root  wheel  75 Dec 1o 11:44 android_paths

To “refresh” your terminal to start working with the new path once you updated it:

  • . /etc/profile

My Phone Sim

I needed a (better) tool to send for sending SMS request via HTTP to a Kannel simulator that display the server response.   One problem was remembering the URL for various test environments, another was remember the SMSC ID does we use for each country or aggregator, much less the short codes.

So I wrote a new phone simulator that could read this stuff from a properties file, and I used python and wxpython.  I am new to both, so it is less than perfect behind the scenes, but it was a nice learning experience and side project to make my life easier.

  • URL – URL to talk to the Kannel Sim
  • Country – Just list the countr
  • SMSC ID – The id for the aggrerator
  • Short code – Phone number we send the SMS request too
  • Phone Number – The phone number (customer) we are testing with
  • SMS Command – What you want to run, things like “help”

I can’t post files here, so I am hosting them on my server

The full program lacks an installer, just unzip and run the phone_sim_ui.exe to see it in action, it is configure for my environment, which doesn’t require a password in QA, it sends up sending something like:

http://<server>/kannelsim/receivesms?receiver_smsc=mqube&sender_phone=5302003201&receiver_phone=88988&request_string=bal

And then querying the server to see Kannel’s response:

http://<server>/kannelsim/query?phone_number=5302003201

Download Links

7 zip gives good compression and is free (also reads zip files), if you don’t have it can be found http://www.7-zip.org/

Kannel – Phone Sim

I haven’t had to test anything new on an Android in a while, so no discoveries yet to post here.  But I did write  a new Phone simulator which is my first crack at writing a program in python with a GUI interface (using WxPython) and talking to the open source Kannel Simulator we use for our SMS services.

When in QA, we can’t send real SMS messages to a phone for testing, so we use a phone simulator to talk to a QA instances of Kannel.  I have found the documentation for Kannel not to be user friendly.  Much less the documentation of the Phone Simulator written 5 years ago internally, in java, so I had to reverse engineer it and do some HTTP processing, I still don’t have an install yet, but I am getting closer.  At least the new phone simulator works and has some of the data fields preloaded which makes it more user friendly.  (Will post phone simulator in a bit)

 

Kannel – Kannel FAQ http://www.kannel.org/faq.shtml

Kannel is an open source project to make a WAP gateway. Kannel also works as a SMS gateway.

SMS for an SMS Gateway it turns SMS messages into http messages (the way we use it) so I needed a Tool to talk to send and receive HTTP request

Backing up the Android

WIP – I think this would be straight forward since one of the “adb” subcommand options is “backup” however it doesn’t seem to be that simple (at least for me).

First the command:

adb backup [-f <file>] [-apk|-noapk] [-shared|-noshared] [-all] [-system|nosystem] [<packages…>]

Note: If a file isn’t specified than it defaults to backup.ab

However apparently the other items aren’t optional it appears, but before I got to specifying the command correctly (if there is a syntax error adb responds by dumping the “help” text to the screen:

adb backup -f C:\Android\huawei_backup.db -all

I was getting the error:  adb: unable to connect for backup

Haven’t found a solution yet

Turning the output from getevent into something something that can be used

My end goal was to to be able to “doodle” on the android screen, with a script.  I can’t do the math to generate the image I want, so I ran the adb shell command “getevent” then using the mouse, I drew on the screen.

However the output isn’t immediately usable, first there was the minor problem of it containing a colon which would throw an error when I tried to run it.  The second and bigger issue, is that the getevent command captures everything in hexadecimal, but the command sendevent, requires everything to be in decimal.  Since monkeyrunner is basically python (the docs say jython, but I haven’t used anything that advance yet), I wrote a python script, that takes an input file containing a bunch of lines that look like this:

/dev/input/event0: 0003 0000 00000073
/dev/input/event0: 0003 0001 000000a8
/dev/input/event0: 0001 014a 00000001
/dev/input/event0: 0000 0000 00000000
/dev/input/event0: 0003 0001 000000a4

And created a new output file with adb shell commands that look like this:

adb shell sendevent /dev/input/event0 3 0 115
adb shell sendevent /dev/input/event0 3 1 168
adb shell sendevent /dev/input/event0 1 330 1
adb shell sendevent /dev/input/event0 0 0 0
adb shell sendevent /dev/input/event0 3 1 164

Which can be run and do the drawing for me on the screen.  This worked, but running a bunch of adb shell commands is really, really slow.  So I tweaked my python script, and instead have to create something like:

#!/bin/sh
echo Running – signature function
sendevent /dev/input/event0 3 0 115
sendevent /dev/input/event0 3 1 168
sendevent /dev/input/event0 1 330 1
sendevent /dev/input/event0 0 0 0
sendevent /dev/input/event0 3 1 164
sendevent /dev/input/event0 0 0 0
……..

This is copied to the device, and run as a local script and runs at an ok speed (not really fast, but much faster than adb shell commands) – the python script prints out instructions with the exact command to run, to copy the file to the device and what to execute it run it.  I will post the python separately, I am new to this code so the code isn’t prefect, but it works and meets my needs.ew

The steps are

  1. Run the app (I did it in the emulator)
  2. Run the command adb shell getevent, om whatever screen you want to doodle/draw on – the output is dumped to the screen
  3. Capture that output when you are done (copy it, usually by right clicking and choosing mark, highlight the area and then hit enter)
    1. Paste the info into notepad, and save it to any file name you want (i.e. captured.dat)
  4. Run the script
    1. hex_to_dec.py captured.dat
      1. catpured.bat is the input data for the script
  5. The script runs pretty fast and kicks out a file captured.scr (the code can be updated to name the file anything)
    1. The script prints out instructions for coping the script to the device and for running the script, that looks something like this

C:\>hex_to_dec.py raw_captured_sig.dat
Processing complete
File created: raw_captured_sig.scr

Copy file to the device
adb push raw_captured_sig.scr /sdcard/raw_captured_sig.scr

Run the script
adb shell sh /sdcard/raw_captured_sig.scr

Python script to convert hexadecimal to decimal for sendevent (hex_to_dec.py)

#!/usr/bin/env python
# coding: utf-8

# From hex_to_dec.py (which I created a while ago)

# Tweaking for Mac
#
# Fixed indenting that wordpress was breaking
#
# You need python installed – more info here:
# Python – http://www.python.org/download/
# The Purpose of this script
#
# Script name: hex_to_dec.py
#
# To turn the getevent output from this:
# /dev/input/event0: 0003 0001 00000092
# to this (something can be run)
# sendevent /dev/input/event0 3 1 92
# Outfile of what to do
# List input file on command line when running
# Open file
# prefix “adb shell sendevent” command to line
# remove colon from input
# convert 3 hexidecimal values to decimal values
# Assemble new complete line
# write out line to new file,
# named the original filename +suffix “bat” – windows batch file ready to run
#

# Importing Stuff
import sys
import fileinput
###################################################################################################
#
# Variables
#

# Command prefix
prefix = "sendevent "

inputline = ""
complete = ""
part1len = 0
part1 = ""
part2 = ""

num1 = 0
num2 = 0
num3 = 0

# File stuff
rawfile = ""
outfile = ""
filename = ""
###################################################################################################
#
# File operations
#

# Grabs the file name from the command line when you run the python script
rawfile = sys.argv[-1]

# Open the input file
# r – Opens a file for reading only. The file pointer is placed at the beginning of the file. This is the default mode.
# w – Opens a file for writing only. Overwrites the file if the file exists. If the file does not exist, creates a new file for writing.
#
fo = open(rawfile, "r")

# Create output file, taking everything in front of the . (kind of windows centric)
filename = rawfile.find(".");
outfile = rawfile[:filename] + ".scr"

# Output file
fw = open(outfile, "w")

# Stuff at the top of the script (first commands to run)
# Puts into bash
fw.write("#!/bin/sh" + "\n")

# User Message
fw.write("echo Running – drawing function " + "\n")

###################################################################################################
#
# Process input string, creating new formatted command
#

for inputline in fo.read().split("\n"):
        # Used for testing/debug
	#print inputline

	# Otherwise let"s process the line
	# Find the location of the colon
	part1len = inputline.find(":");

	# -1 means end of file so quit processing
	if part1len > -1:
		# Only take the first part of the string up to the string
		part1 = inputline[:part1len];

		# Finding the hexidecimal values
		# Splits the string based on spaces, creating an array with 4 strings,
		part2 = inputline.split(" ");

		# we want strings 1,2,3 (since arrays start at 0 (zero))
		# we need to specify the base explicitly (based 16, so hex gets converted to decimal)
		num1 = int(part2[1], 16)
		num2 = int(part2[2], 16)
		num3 = int(part2[3], 16)

		# Put is all together
		complete = prefix + part1 + " " + str(num1) + " " + str(num2) + " " + str(num3)

		# Write out to the file, with a new line feed
		fw.write(complete + "\n")

# For testing
#print complete

# Info for the user
print "Processing complete"
print "File created: ", outfile
print
print "Copy file to the device"
print "adb push " + outfile + " /sdcard/" + outfile
print
print "Run the script"
print "adb shell sh /sdcard/" + outfile
###################################################################################################
#
# File clean up
#

# Close all files
fo.close()
fw.close()

adb shell sendevent, sending touch like events

Oh joy – output in hex but I need decimal

Running my test app in the emulator, to figure out where I was “touching” on the screen, I used the command:

adb shell getevent

Which returns something like:

C:\>adb shell getevent
add device 1: /dev/input/event0
name: “qwerty2”
could not get driver version for /dev/input/mouse0, Not a typewriter
could not get driver version for /dev/input/mice, Not a typewriter
/dev/input/event0: 0003 0000 00000073
/dev/input/event0: 0003 0001 000000a8
/dev/input/event0: 0001 014a 00000001

Which returns everything in hexidecimal, but you can’t send these commands directly back, you had to convert them to decimal, so this

adb shell sendevent /dev/input/event0 0003 0000 00000073
adb shell sendevent /dev/input/event0 0003 0001 000000a8
adb shell sendevent /dev/input/event0 0001 014a 00000001

Becomes this:

adb shell sendevent /dev/input/event0 3 0 115
adb shell sendevent /dev/input/event0 3 1 168
adb shell sendevent /dev/input/event0 1 330 1

However my capture for what I need to doodle on the screen is like 905 lines, that need to the colon removed from “event0:” and have the values converted to decimal to actually work.  Working on a script to take care of this formatting for me.

 

Another great post about this can be found here:  http://softteco.blogspot.com/2011/03/android-writing-events-low-level-touch.html

adb shell sendevent (could not open /dev/input/event0:, No such file or directory)

This is still a work in progress to get monkeyrunner to interact with a screen that people need to basically draw on.

I found this command to get back coordinates of what is being touched on the screen:

adb shell getevent

Which returns something like this

add device 1: /dev/input/event0
name: “qwerty2”
could not get driver version for /dev/input/mouse0, Not a typewriter
could not get driver version for /dev/input/mice, Not a typewriter
/dev/input/event0: 0003 0000 00000073
/dev/input/event0: 0003 0001 000000a8
/dev/input/event0: 0001 014a 00000001
/dev/input/event0: 0000 0000 00000000

….

Trying to send this command back, failed

adb shell sendevent /dev/input/event0: 0003 0000 00000073
adb shell sendevent /dev/input/event0: 0003 0001 000000a8

with this error:

could not open /dev/input/event0:, No such file or directory

After playing around for a bit, I found that the colon was the problem (after event0), removed that the error went away, I don’t see anything on the screen yet, but at least the error is gone.

Correct sytax:

adb shell sendevent /dev/input/event0 0003 0000 00000073
adb shell sendevent /dev/input/event0 0003 0001 000000a8

v

 

Monkeyrunner links & Other automation info

Some links for Monkeyrunner

From the Android site (though it took tweaking to make this work for me)

monkeyrunner | Android Developers – http://developer.android.com/guide/developing/tools/monkeyrunner_concepts.html

 

Additional Documentation from Android

Monkey Device – other program options, like reboot – http://developer.android.com/guide/developing/tools/MonkeyDevice.html
Monkey Image – Pixel and Image stuff –  http://developer.android.com/guide/developing/tools/MonkeyImage.html
Monkey Runner – has some static utility methods. – http://developer.android.com/guide/developing/tools/MonkeyRunner.html

 

Some Other UI Automation Ideas

Android UI Automation Basics – http://goravsingal.hubpages.com/hub/Android-UI-Automation-Basics

 

Python

Python/Jython Downloads – http://www.python.org/download/

Alternatives to Eclipse (which isn’t my favorite beast)

I have been using Notepad++ to write my early learning scripts (though this isn’t an IDE)

Netbeans another IDE

 

Other tools

Robotium – (I felt this needed a lot of developer support in order to me to work with it and I am not a Java person) – http://code.google.com/p/robotium/ – and it integrates with Cucumber but that requires Ruby

 

Paid tools (e.g not free)

TestDroid – http://testdroid.com/