Android GUI crawler - android

Anyone knows a good tool for crawling the GUI of an android app? I found this but couldn't figure out how to run it...

Personally, I don't think it would be too hard to make a simple GUI crawler using MonkeyRunner and AndroidViewClient.
Also, you may want to look into uiautomator and UI Testing
Good is a relative term. I have not used Robotium, but it is mentioned in these circles a lot.
EDIT - Added example based on comment request.
Using MonkeyRunner and AndroidViewClient you can make a heirarchy of views. I think AndroidViewClient has a built-in mechanism to do this, but I wrote my own. This code tries to produce a layout similar to that used by the Linux tree command. The space and line variables are used to setup the "prefix" prepended on each line. Of course, this code uses a depth-first, recursive traversal.
def printViewListDepth(view, depth=0):
space = '|' * int(not depth == 0)
space += (' ' * 2 * (depth-1)) + '|' * int(not depth-1 <= 0)
line = '_' * int(not depth == 0) * 2
text = view.getText()
text = text[:10] + int(len(text) > 10) * '...'
print " [*] %s%s%s %s %s" % (
space, line, view.getUniqueId(),
view.getClass().replace('android.widget.', ''), text)
for ch in view.children:
printViewListDepth(ch, depth+1)
You call printViewListDepth as follows, using a ViewClient returned by AndroidViewClient:
printViewListDepth(viewClient.root)
Note that in the above implementation, the class of View is truncated, by removing "android.widget." and the the text of a View is truncated at 10 characters. You can change these to suit your needs.
Edit Crawling the GUI
With AndroidViewClient you can query whether a View is clickable, someView.isClickable(). If it is clickable, you can invoke a touch event on it, someView.touch(). Assuming most button clicks open a different Activity, you will need to come up with a mechanism of getting back to where you came from to do the recursion.
I imagine that it can be done with some effort, but you may want to start with something as simple as invoking a BACK button press, device.press('KEYCODE_BACK', MonkeyDevice.DOWN_AND_UP). You will probably need to handle application-specific special cases as they arise, but this should get you off to a decent start.

You can take a look at Testdroid App Crawler
This is available in Testdroid Cloud as project type and you can easily run it on 15 free devices.

Related

What is Android Studio shortcut to show function return type, parameter type & names all at the same time?

While I'm typing a function name:
String response;
response.split| // *** '|' denotes the caret position ***
Android Studio shows its declaration and the documentation. I can see return type, parameter names&types and doc all at the same time:
But when I'm inside parentheses, it shows parameters but no return type. (Cmd+P or Ctrl+P)
String response;
response.split(|)
If I press F1 (mac) or Ctrl+Q(win) inside parentheses, sometimes it doens't show anything because there's an error (for not completing the line), but when it shows it shows return type & parameter type but omits parameter names.
Does anyone know the shortcut(and its name) to show the first one - return type, parameter types, and (possibly) documentation all at the same time - while I'm inside parentheses?
Thanks!
I guess this is the one you are looking for, CTRL + space and hover move to any option
CTRL + P
CTRL + Q
CTRL + space
It appears to be out of our control. Based on Intellij IDEA 15.0.4 it's possible but not consistent; at first glance it seems the complete documentation as you desire is given by default for methods which have a single implementation while methods with multiple list them.
This is for List#add (multiple implementations):
And this is for List#get (single implementation):
Another example just to begin to confirm my thoughts, here's Iterator<T>#forEachRemaining (also single implementation):
Perhaps it would be too cluttered to be useful if each were listed.
As you may know, it's possible to jump to a single one in the list by tabbing and pressing enter on the one you want. Then you can use the arrows at the top to go back to see another. Not ideal but better than nothing.

How to use AndroidViewClient findViewWithText() with regex

I have a script to monitor the Notifications screen page.
I can open it via "Culebra" option "UiDevice" -> "Open Notifications".
The notifications error message from some apps have starting characters which are changing, only a constant pattern like "error for" is common but located at different position of the TextView error messages.
Therefore I can't use a regex with the method findViewWithText(regex) as it seems to use a regex match() instead of regex search(). Another solution for my problem is to use traverse() method with my own transform method which can do a regex search() of the view attribute text, but I can't figure out how to pass a parameter like a regex to my own transform method!?
This works for me to touch on a notification with text USB debugging connected:
vc.findViewWithTextOrRaise(re.compile('.*USB.*'), root=vc.findViewByIdOrRaise('id/no_id/3')).touch()
vc.sleep(_s)
notice this is a modified culebra script, that's why findViewWithTextOrRaise() is using the root argument to limit the search to the subtree which may not be needed in all cases, but it's safer to use.
It's worth to mention, that this works too
vc.findViewWithTextOrRaise(re.compile('.*debugging.*'), root=vc.findViewByIdOrRaise('id/no_id/3')).touch()

Calabash android output to HTML gives timeout errors when finding view elements

When running calabash-android and outputting to HTML format, I am getting intermittent exceptions as per the below (typically within the first step of the app). I am using Xamarin and MVVMCross libraries.
Timeout waiting for elements: * marked:'Terms of Use'
(Calabash::Android::WaitHelpers::WaitError)
./features/step_definitions/calabash_steps.rb:4:in `/^User has accepted the Terms of Use$/'
features\registration.feature:8:in `Given User has accepted the Terms of Use'
2
3Given /^User has accepted the Terms of Use$/ do
4 #current_page=page(TermsOfUse).await
5 #current_page.tap_accept_button
6end
7# gem install syntax to get syntax highlighting
The screenshots generated show the UI element is present on the screen, and the same errors never occur when I exclude the html format option and simply write the detail out to the console. Does anybody else have any experience of this?
Most likely the view's text has some formatting information in it.
It's a good practice to use id instead of text for identifying elements. If you have an id, use that:
query("* id:'terms_of_use_id'")
If you don't have an id try to add one.
If that is not possible try to query the whole UI with:
query("*")
Find the element and see what's in it's text property.

MonkeyTalk Android Detect String Containing \n for Button Tap

I am using MonkeyTalk to automate some user test cases for my Android app. Everything is working fine except for when I try and detect a button containing this string:
"Connect\n(Code Required)"
I get this error:
FAILURE: Unable to find Button(Connect\n(Code required))
If I change the button to "Connect" and perform a tap on that value MonkeyTalk has no trouble, but something about the line break must be throwing it off.
After some searching I found this thread that confirmed my suspicious about the line break. There was one suggested fix here, to set the default encoding to UTF-8 (Select the Project > File > Properties > Resources)
However this did not work for me.
I have also tried to find the button using a wildcard like so:
"*(Code Required)"
But this does not seem to be supported either.
Maybe there is an alternative line break character I could use?
Thanks in advance for the help!
Maybe there's a carriage return in there? I know in most text editors a new line actually consists of (carriage return)+(newline).
Also take a look at this:
TextView carriage return not working
Also, depending on how flexible your requirements are, you could use the #N MonkeyId replacement to get the Nth button.
IN javascript you can use below command
app.button("buttonname").tap(x, y);
Use android:contentDesxription="your_component_id" in your view xml file definition or view.setContentDescription("your_component_id"); directly on view in code to make it easy to access in MonkeyTalk.

Trouble with findViewByIdOrRaise in AndroidViewClient

Trying to use MonkeyRunner to perform some testing and want to use AndroidViewClient to work with EditText widgets.
I believe I am using AndroidViewClient correctly (relevant stuff below), findViewByIdOrRaise() is always throwing an error. I've tried every variant of specifying an ID that came to mind.
Here is a snippet from my activity's XML:
<EditText
android:id="#+id/someText"
... >
<requestFocus />
</EditText>
<!-- Yes, that is the actual id of my EditText -->
In my MonkeyRunner script I have the following:
device, serialno = ViewClient.connectToDeviceOrExity(serialNo=myDeviceId)
vc = ViewClient(device=device, serialno=serialno)
device.installPackage(apkPath)
device.startActivity(component='com.app.name/com.app.name.ActivityName')
editTextId = 'id/someText'
try:
someText = vc.findViewByIdOrRaise(editTextId)
someText.touch()
someText.type('Derp derp derp')
except ViewNotFoundException, e:
# The comma above is because Jython 2.5.3 does not support the AS keyword
print ' [*] %s' % (e)
Of course, my code is doing a little more (but not much) than what is shown. I stripped out everything that didn't seem relevant. I will gladly put it all up there, but didn't want to start off with code vomited all up in here.
I've looked at everything I could find on the topic:
AndroidViewClient / AndroidViewClient / examples / email-send.py
monkeyrunner: interacting with the Views
How to enter text in text field using monkeyrunner
How to enter values to a text field using monkeyrunner
Any ideas on what I'm doing wrong?
The latest version of ViewClient gives a unique id to each view in the app. The id format is i/no_id/number. You could use a script called dump.py to see the current views. It is located in the examples folder in ViewClient.

Categories

Resources