Filtering an element using its property in arrays – calabash

Hello again,

More one tip about filtering the element in an array, using some of the properties that you want (text content, position, id, class, html, etc…). In this example, I am finding the array of elements with the specific CSS and after I am returning the element where the property “TextContent” equals a Login.

menu = query("WebView index:0 css:'div li span'").find { |x|
x["textContent"] == "Login" }

Or:

menu = query("WebView index:0 css:'div li span'", :textContent).find { |x| 
x == "Login" }

In this other example, I am returning the element which contains specific text inside of the property “html“.

menu_figure = query("WebView index:0 css:'div li span'").find { |x| 
x["html"].include? ("figure") }

Or:

menu_figure = query("WebView index:0 css:'div li span'", :html).find { |x| 
x.include? ("figure") }

 

If you have any question/suggestion, just let me know.

Thank you guys ! See you next week 🙂

Double_Tap issue -> Calabash-android 0.5.4

Hello folks,

I updated my calabash-android to the new version 0.5.4 and I noticed that my double tap function stopped work on devices.

Seems that now, you need to write query before the element address, like this > double_tap(query(“WebView index:2 css:’xxxxxx'”))

Before I was using double_tap(“WebView index:2 css:’xxxxxx'”) and was working properly.
>> Guys, after I update to calabash-android 0.5.5 I had to remove the query again, and now it is working this way again:

double_tap(query(“WebView index:2 css:’xxxxxx'”))

Just a fast note about this issue that I had.

See you guys 🙂

List of useful commands

1. You can see what is available for instrumentation

adb shell pm list instrumentation

 

2. List packages:

adb shell pm list packages

 

3. To get reports with the run:

calabash-android run mytest.apk –format html –out reports.html

 

4.To see logcat:

adb logcat

 

Fonts:

http://blog.lesspainful.com/2012/03/07/Calabash-Android/

https://github.com/calabash/calabash-android

7 Possible issues and fixes – Calabash android

  • 1. To get rid of warning about ansicolor (windows):

  • open cmd and navigate to the unzipped folder
  • Navigate to x64 (if you have a 64 bit machine) otherwise navigate to x86
  • Execute ‘ansicon.exe -i’ to install and add ansicon to your Windows
  • Run your cucumber test and you should
  • get the colored output result on Windows

 

  • 2. Warning about gem json ~>1.7.7 (Windows):

  • If the above, doesn’t fix it,
    • uninstall Ruby.
    • Install Ruby 1.9.x again
    • Make sure you also install the corresponding Devkit
    • gem install json -v 1.7.7
    • bundle update json

 

  • 3. Jarsigner: unable to sign jar

  • Rename the .apk file to .zip
  • Unpack the .zip file and remove the META-INF folder
  • Zip the folder again and rename it to .apk (zip -r <xxx.apk> *)
  • Sign the apk:
  • Copy your “Calabash” folder having “feature” file.

 

  • 4. No MD5 fingerprint found: (RuntimeError)

  • Paste it into your android workspace having gen, res, src folder. eg., ~/.android
  • Now, Test server will create inside your calabash folder.
  • Navigate to new path and again run apk file.

 

  • 5. If the AndroidManifest.xml is missing:

  • To create AndroidManifest.xml file:  where should this be?
  • calabash-android extract-manifest Downloads\mytest.apk

 

  • 6. If adb device not showing up in “adb devices”:

  • adb kill-server adb start-server adb devices

 

  • 7.Cannot load such file rspec/expectations:

  • Make sure you add the foll. line in your Gemfile
  • gem ‘rspec’

Swipe and Drag – Calabash iOS and Android

Hi guys !!
I am writing examples of swipe and drag on mobile devices with calabash today. Some methods that you can use to test, these drags have the same action as the swipe. (If for some reason the swipe don’t work)
ANDROID:
  def swipe_page_to_left
    performAction('swipe', 'left')
  end

  def swipe_page_to_right
    performAction('swipe', 'right')
  end

  def scroll_to_right
    performAction('drag', 90, 0, 50, 50, 50)
  end

  def scroll_to_left
    performAction('drag', 0, 90, 50, 50, 50)
  end

def scroll_to_up
   performAction('drag', 88, 80, 90, 90, 5)
 end

 def scroll_to_down
    performAction('drag', 70, 10, 80, 0, 3)
 end

IOS
Change to down, left or right:

 swipe(:up)

If you have some question or suggest just write below !
Thank you 🙂

Javascript and CSS – Testing on hybrid apps

Hello everyone 🙂

I am testing a hybrid app these days and I am learning a lot…Ok, but what is a hybrid app ?
Like native apps, run on the device, and are written with web technologies (HTML5, CSS and JavaScript). Hybrid apps run inside a native container, and leverage the device’s browser engine (but not the browser) to render the HTML and process the JavaScript locally. A web-to-native abstraction layer enables access to device capabilities that are not accessible in Mobile Web applications, such as the accelerometer, camera and local storage.

Summarising…. You have to test native elements mixed with web elements… Cool, don’t you think ? HaHa Hard work !

This post have some examples of a query using CSS and an action (click) using Javascript(IOS and Android platform):

Using Javascript to click: (Example)

query("webView index:1", :stringByEvaluatingJavaScriptFromString 'document.getElementsByTagName("iframe")[0].contentWindow.document.getElementByTag("a").click()')

This example, you have to write first the WebView hat contains the HTML and after put that conversor from String to Javascript. Finally, put your code in Javascript 🙂
I don’t know many things about javascript, but you can use the console of the inspector of Chrome or Safari to identify web elements in mobiles (iphone,ipad,tablet).

Examples – CSS:

query("SlidePanelWebView index:2 css:'#articleContainer .currentPanel figure .video-play-button'")

query("SlidePanelWebView index:4 css:'#article_1 .data-copy p strong a'")

element_does_not_exist("WebView css:'.inner a'")

Below the explanation of each part to form a CSS query on Calabash:

query("WebView index:4 css:'#article_1 .data-copy p strong a [style=\'Font:Tahoma\']'")

First: Put the element and the index that contains the element that you want. How you discover this ? You can try each index according with the position where is your element. Like in the end of a page… more chances to be the last index of the element.

Second: Write css:

– Third: Inside each you will choose what properties, class, id or tag you want to use to find the element.

Fourth: When you know the id of the div or the element, you can write here. Put and then the id of the div… If the element that you want was not found until this point, you can use the id of the first div in the hierarchy. Like:

<div id:first>

<div id: second>

<element id: third></element>

</div>

</div>

In this example, you can use the id of the first div instead of the id’s element. And try writing the way to find the element with the tags or classes provided.

Fifth: Class, here you can use the class element. To identify that this is a class you need to put a . before the name of the class… And I used to write only the last name of the class when this has more then one class name. Example:

<div id:first>

<div class: class name second>

</div>

</div>

Sixth: The last thing that you should know it is about the tag name. Like <p>, <a href>, <strong>… When you want to find a tag you just write the tag names separated by space. Like:  div p a , following the example bellow.

<div class: first>

<p>

<a href: third></a>

</p>

</div>

Seventh: When you want to find a property in the middle of the css.You need to put [name of property=value of property] Like when you want to search a specific value for href: [href=https://azevedorafaela.wordpress.com], following the example bellow.

<a href: https://azevedorafaela.wordpress.com></a>

 

More examples of queries calabash with CSS:

query("WebView index:4 css:'#three .scrollable [data-component=buttonBlock] .sectionList li span'")

query("PanelWebView css:'#article .data-copy p strong a'")

query("View index:3 css:'.viewInactive'")

 

If you have any suggestion, questions or comments just write below please !

Bye !!

Query Calabash Android

Hey guys, I will post today some queries to find elements in different ways with calabash-android in console !

 

Basic usage

Using the class of the elements (Button, Label, View, Webview, Tableview, etc…). If you don’t know what is the class, you can use only * to find all the elements on the screen.

 

Results:

 

You can use size, to know the qty of the elements with this class:

 

 

Filtering by class

 

Simple class name

Filtering by class means that we only want to look at certain types of views. This is what we’ve done before when we were searching for Button or TextView:

This is called filtering by simple name. The result shows you that the full class name is android.widget.Button: this is what we call fully qualified class name and the andorid.widgetpart is called package name.

When you query with simple name Calabash only looks at the last bit of the name. This is also case insensitive, so Button, button or bUtTOn is the same in this context.

 

Fully qualified class name

You can also use the fully qualified class name in the query:

Interestingly this gives us two results: the login button and a checkbox. Why is the CheckBox included? In order to understand this you have to understand subclasses.

Let’s look at an example:

There are a lot different buttons in Android like ToggleButton and the Switch. A ToogleButton is just a specific type of Button with some extra functionality and look. A Button is just a simple button with a text in it where the ToggleButton has two states (on and off). So every ToggleButton is a Button but not every Button is a ToggleButton.

The CheckBox is also a subclass of Button – which explains why we get two results. If you use the fully qualified name in the query it will give you the class and all of it’s subclasses. So if there were ToggleButtons and Switches it would also return those.

The main distinction is this:

  • using simple name only looks at the last part of the class and does a simple comparison
  • using the qualified name looks at the class hierarchy and gives back all the class and all of it’s subclasses

 

Filtering by property

Usually there are several buttons, textviews and edit texts on the screen so filtering by class is not enough to identify a single element.

In the query results you get back a set of properties for each view like id, text, class.

Calabash allows you to filter on these properties.

The most used property is the id. On Android every view can have an id, which is an invisible string identifier. The id is not necessarily unique and also not every view has one. Even with these restriction using id is the most reliable way to find views.

 

id property

Let’s try to find the login button by id:

The first part of the query is the class filtering: * means give me all the views. The second part is the property filtering: id:'login_button' means find the view that has the id login_button.

The filtering happens on the result of the first part of the query string. Previously we used "*" so the filtering was applied to all the views. But we could have used different class.

 

text property

Of course id is not the only property that you can filter on. Another commonly used one is the text. This is the label of the view which is visible on the screen:

This will find the view on the screen which has a text Login. Once I found them though I use id instead of text. This results in more stable tests. Labels tend to change more frequently than ids. It also eliminates all the translation and localisation problems.

What if a view doesn’t have an id? Ask the developers to add one. It’s a 5 second task and it will make your life a lot easier.

 

Other properties

Let’s try to find all the disabled buttons:

Notice that while we used single quotes for string parameters we’re not using anything here for false.

The third type of parameter is the integer parameter (numbers). One example is the width parameter:

This gives you all the views that are exactly 200 pixel wide. Notice that we are not using the single quotes to define the value.

You can also combine the filters using multiple criteria. Let’s get all the views which are enabled and the are 50 pixel heigh:

 

How it works

The general syntax for property filtering is the following:

The prop is the name of the property and the value is either a string, a boolean or an integer value.

We’ve already used a couple of properties like id, text, enabled and width. There are a lot more. For starters you can use all the attributes that you see in the query results. But that’s not everything.

Every view object supports a set of methods – you can find all the supported methods on the view’s documentation. For example the View class has an isEnabled() method. When Calabash tries to resolve the property it find the following methods on the view: prop(), getProp() and isProp() in this order.

So for the enabled property it tries to find the enabled(), getEnabled() or isEnabled() methods.

If Calabash does find a method it calls it and compares the return value with the value you specified. If it doesn’t match it gets rid of that view. It also discards the view if it can’t find the appropriate methods.

 

Useful things

In addition to the basic query syntax there are a couple of useful things you can use.

 

marked

The marked keyword is a shorthand for identifying an element by it’s name. It’s a convenience method to filter by id, text or contentDescription properties.

 

index

The result of each query is a standard Ruby array. Because of this you can access the elements directly in it. If you want to get the first view on screen you can do it like this:

The query language also supports the index keyword. The index is very similar than using the array indexing – it gives you the element at a given index:

This is usually used with lists and other collection views. Often you just want to click on the first element on a list.

Be warned though: you should only use index if you really need it. Using index to identify elements in the layout is usually not a good idea – it leads to brittle tests and hard to diagnose problems.

Use ids, text and other identifiers and don’t rely on the ordering of the items!

 

Returning certain properties

Sometimes you’re only interested in certain properties not the full result. Let’s say you want to get all the id’s on the screen:

As you can see a result is an array of strings where only the ids are shown. Isn’t this much nicer?

You can put any property as the second argument of query to get the data you’re interested in. Another example to get all the labels for the enabled views:

query("* enabled:true", :text)

 

Predicate

Calabash supports some filters that are not present in UIScript. Particularly we support filtering by simple NSPredicates. For example searching for a string prefix:

"label {text BEGINSWITH 'Cell 1'}"

which would return the labels with text Cell 1 and Cell 10.

In general you use a NSPredicate by writing a filter: {selector OP val}, where selector is the name of an Objective-C selector to perform on the object, OP is operation, and val is a string or integer value.

Common operations

  • BEGINSWITH, prefix, e.g., "label {text BEGINSWITH 'Cell 1'}"
  • ENDSWITH, suffix, e.g., "label {text ENDSWITH '10'}"
  • LIKE, wildcard searches, e.g., "label {text LIKE 'C*ll'}"
  • CONTAINS, substring, e.g., "label {text CONTAINS 'ell'}"
  • Comparison, <, >, …
  • Case or diacritic insensitive lookups, e.g., "label {text CONTAINS[cd] 'cell'}"

To understand what additional options are available, consult the full syntax for NSPredicate documented by Apple: NSPredicate Syntax

 

Direction

There are four directions descendant, child, parent and sibling. These determines the direction in which search proceeds.

Often, query expressions are a sequence of ClassName expressions. For example:

 "tableViewCell label"

this means “first find all UITableViewCell views, then inside of those, find all the UILabel views”. The key here is the word inside. This is determined by the query direction.

By default the direction is descendant, which intuitively means “search amongst all subviews (or sub-views of sub-views, etc).” But you can change the traversal direction. Here is an advanced example:

label marked:'Tears in Heaven' parent tableViewCell descendant 
tableViewCellReorderControl

This query finds a label ‘Tears in Heaven’, and then proceeds to find the tableViewCell that contains this label (i.e., moving in the parent instead of descendant direction). From the tableViewCell we move down and find the tableViewCellReorderControl.

Valid directions are descendant, parent, child and sibling. Both descendant and childlooks for subviews inside a view. The difference is that descendant keep searching down in the sub-view’s subviews, whereas child only looks down one level. The direction sibling searches for views that are “at the same level” as the present view (this is the same as: first find the immediate parent, then find all subviews except for the view itself).

 

Thank you again !

Bye 🙂

Fonts:

https://github.com/calabash/calabash-ios/wiki/05-Query-syntax

http://krazyrobot.com/2014/04/calabash-using-query/