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 !!

Summary of Calabash iOS Ruby API – Assertions

Hi guys ! I hope you are well ! Here there are many commands of calabash-ios that are very useful 🙂

Assertions

 

fail(msg="Error. Check log for details.")

check_element_exists(query)
check_element_does_not_exist(query)
check_view_with_mark_exists(expected_mark)

check_element_exists("view marked:'#{expected_mark}'")

 

Touch

 

touch(uiquery, options={})

 

irb(main):037:0> touch("view marked:'switch'")
irb(main):038:0> tap 'switch'
irb(main):040:0> touch("view marked:'First'", :offset => {:x => 50, :y => 0})
irb(main):041:0> touch(nil, :offset => {:x => 50, :y => 0})

 

Keyboard

 

keyboard_enter_char(chr)

irb(main):043:0> keyboard_enter_char "a"
irb(main):076:0> keyboard_enter_char "More"

keyboard_enter_text(text)

irb(main):044:0> keyboard_enter_text "The Quick Brown Fox"

done

Scroll

scroll(uiquery, direction)

irb(main):082:0> scroll "scrollView", :down

 

Tables

 

scroll_to_row(uiquery, number)

irb(main):081:0> scroll_to_row "tableView", 2

scroll_to_cell(options)

{:query => "tableView",
 :row => 0,
 :section => 0,
 :scroll_position => :top,
 :animate => true}
irb(main):003:0> scroll_to_cell(:row => 13, :section => 0)
=> ["; contentOffset: {0, 0}>. Delegate: LPThirdViewController, DataSource: LPThirdViewController"]

:row the row to scroll to
:section the section to scroll to
:scroll_position the position to scroll to :top, :bottom, :middle
:animate animate the scrolling or not

each_cell(options, &block)

{:query => "tableView", #the table view to act on
 :post_scroll => 0.3,  #a pause after each action taken
 :skip_if => nil, #an optional proc to skip some cells
 :animate => true #animate the scrolling?
}
irb(main):008:0> each_cell(:post_scroll=>0) do |row, sec|
irb(main):009:1* puts "Row #{row} in Section #{sec}"
irb(main):010:1> end
Row 0 in Section 0
Row 1 in Section 0
Row 2 in Section 0
Row 3 in Section 0
...
irb(main):001:0> table_labels = []
=> []

irb(main):002:0> each_cell(:animate => false, :post_scroll => 0.1) do |row, sec|
irb(main):003:1*  txt = query("tableViewCell indexPath:#{row},#{sec} label", :text).first
irb(main):004:1>  table_labels << txt irb(main):005:1> end
=> 1

irb(main):006:0> table_labels
=> ["Cell 0", "Cell 1", "Cell 2", "Cell 3", "Cell 4", "Cell 5", "Cell 6", "Cell 7", "Cell 8", "Cell 9", "Cell 10", "Cell 11", "Cell 12", "Cell 13", "Cell 14", "Cell 15", "Cell 16", "Cell 17", "Cell 18", "Cell 19", "Cell 20", "Cell 21", "Cell 22", "Cell 23", "Cell 24", "Cell 25", "Cell 26", "Cell 27", "Cell 28", "Cell 29"]

 

Rotation

rotate(dir)

irb(main):083:0> rotate :left

 

(Event) Playback

playback(recording, options={})

irb(main):103:0> playback "drag_switch_around", :query => "view marked:'switch'", :offset => {:x=>2, :y=>0}

record_begin and record_end

irb(main):104:0> record_begin
=> ""
irb(main):105:0> record_end "move_down"
=> "move_down_ios5_iphone.base64"

 

Location

set_location(options)

:place => "Tower of London"
:latitude => ..., :longitude => ...

 

Backdoor

backdoor(sel, arg)

- (NSString *) calabashBackdoor:(NSString *)aIgnorable;
irb(main):002:0> backdoor("calabashBackdoor:", "")
=> "YES"

 

Screenshot

screenshot(options={:prefix=>nil, :name=>nil})

screenshot({:prefix => "/Users/krukow/tmp", :name=>"my.png"})

screenshot_embed(options={:prefix=>nil, :name=>nil, :label => nil})

screenshot_embed({:prefix => "/Users/krukow/tmp", :name=>"my.png", :label => "Mine"})

 

Misc

 

server_version

irb(main):026:0> server_version
=> {"outcome"=>"SUCCESS", "app_name"=>"LPSimpleExample-cal", "simulator_device"=>"iPhone", "iOS_version"=>"5.1", "app_version"=>"1.0", "system"=>"x86_64", "app_id"=>"com.lesspainful.example.LPSimpleExample-cal", "version"=>"0.9.126", "simulator"=>"iPhone Simulator 358.4, iPhone OS 5.1 (iPhone/9B176)"}

 

client_version

irb(main):027:0> client_version
=> "0.9.127.pre1"

 

calabash_exit

irb(main):028:0> calabash_exit
=> []
irb(main):029:0> server_version
Errno::ECONNREFUSED: Connection refused - connect(2) (http://localhost:37265)

 

escape_quotes(str)

irb(main):007:0> quoted = escape_quotes("Karl's child")
=> "Karl\\'s child"
irb(main):008:0> query("view marked:'#{quoted}'")

 

macro(txt)

macro 'I touch "Second"'

lbl = ".......a long text......"
macro %Q[I use a step with "double" quotes and 'single' and #{lbl}]

 

flash(uiquery)

flash("TableView index:2")

 

Font: https://github.com/calabash/calabash-ios/wiki/03.5-Calabash-iOS-Ruby-API

Summary of Calabash iOS Ruby API – QUERY

Just a summary of useful commands !

Query

query(uiquery, *args)
irb(main):003:0> query("button index:0")
=> [{"class"=>"UIRoundedRectButton", "frame"=>{"y"=>287, "width"=>72, "x"=>100, "height"=>37}, "UIType"=>"UIControl", "description"=>">"}] 
irb(main):005:0> query("button index:0").first.keys
=> ["class", "frame", "UIType", "description"]

irb(main):006:0> query("button index:0").first["frame"]["width"]
=> 72

irb(main):031:0> query("tableView","numberOfSections")
=> [1]
irb(main):033:0> query("tableView","delegate","description")
=> [""]
irb(main):034:0> query("tableView",numberOfRowsInSection:0)
=> [30]
irb(main):035:0> query("tableView","numberOfRowsInSection"=>0)
=> [30]
irb(main):036:0> query("pickerView",:delegate, [{pickerView:nil},{titleForRow:1},{forComponent:0}])
=> ["1,0"]
[pickerView.delegate pickerView:nil titleForRow:1 forComponent:0]

classes(uiquery)

def classes(uiquery,*args)
  query_map(uiquery,:class,*args)
end
irb(main):001:0> classes("view")
=> ["UILayoutContainerView", "UITransitionView", "UIViewControllerWrapperView", "UIView", "UITextField", "UITextFieldRoundedRectBackgroundView", "UIImageView", "UIImageView", "UIImageView", "UITextFieldLabel", "UILabel", "UIRoundedRectButton", "UIButtonLabel", "UISwitch", "_UISwitchInternalView", "UIImageView", "UIView", "UIImageView", "UIImageView", "UIImageView", "UIRoundedRectButton", "UIButtonLabel", "UITabBar", "UITabBarButton", "UITabBarSelectionIndicatorView", "UITabBarSwappableImageView", "UITabBarButtonLabel", "UITabBarButton", "UITabBarSwappableImageView", "UITabBarButtonLabel", "UITabBarButton", "UITabBarSwappableImageView", "UITabBarButtonLabel", "UITabBarButton", "UITabBarSwappableImageView", "UITabBarButtonLabel"]

label(uiquery)

 def label(uiquery)
  query(uiquery, :accessibilityLabel)
end
irb(main):001:0> label("view")
[nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, "Empty list", nil, nil, nil, "Mon", "Dec 17", nil, nil, nil, "Tue", "Dec 18", nil, nil, nil, nil, "Today", nil, nil, nil, "Thu", "Dec 20", nil, nil, nil, nil, nil, "Empty list", nil, nil, "12", "12", nil, nil, "1", "1", nil, nil, "2", "2", nil, nil, "3", "3", nil, nil, nil, nil, nil, "Empty list", nil, nil, "56", "56", nil, nil, "57", "57", nil, nil, "58", "58", nil, nil, nil, nil, nil, "Empty list", nil, nil, "AM", "AM", nil, nil, "PM", "PM", nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, "Name", "First View", "First", "First", nil, "Second", "Second", nil, "other", "switch", nil, nil, nil, nil, nil, nil, "login", "Login", nil, "First", nil, nil, "First", "Second", nil, "Second", "Third", nil, "Third", "Fourth", nil, "Fourth"]

element_does_not_exist(uiquery)

element_exists(uiquery)

view_with_mark_exists(expected_mark)

element_exists("view marked:'#{expected_mark}'")

Waiting

wait_for(options, &block)
{:timeout => 10, #maximum number of seconds to wait
 :retry_frequency => 0.2, #wait this long before retrying the block
 :post_timeout => 0.1, #wait this long after the block returns true
 :timeout_message => "Timed out waiting...", #error message in case options[:timeout] is exceeded
 :screenshot_on_error => true # take a screenshot in case of error
}
irb(main):030:0> wait_for(:timeout => 5) { not query("label text:'Cell 11'").empty? }
irb(main):031:0> wait_for(:timeout => 5) { element_exists("label text:'Cell 20'") }
wait_for(:timeout => 30) do
    res = query("button marked:'Player play icon'", :isSelected)
    res.first == "1"        
end

wait_for_elements_exist(elements_arr, options={})

irb(main):008:0> wait_for_elements_exist( ["label text:'Cell 11'", "tabBarButton marked:'Third'"], :timeout => 2)
wait_for_elements_do_not_exist(elements_arr, options={})
wait_for_none_animating(options={})
wait_poll(opts, &block)
{:until => nil #a predicate which should return true when the condition is satisfied
 :until_exists => nil #a uiquery to function as predicate (i.e. element_exists(opts[:until_exists]))
 :timeout => 10, #maximum number of seconds to wait
 :retry_frequency => 0.2, #wait this long before retrying the block
 :post_timeout => 0.1, #wait this long after the block returns true
 :timeout_message => "Timed out waiting...", #error message in case options[:timeout] is exceeded
 :screenshot_on_error => true # take a screenshot in case of error
}
irb(main):023:0> wait_poll(:until_exists => "label text:'Cell 22'", :timeout => 20) do
irb(main):024:1* scroll("tableView", :down)
irb(main):025:1> end

 

Bye Guys 😀

Font: https://github.com/calabash/calabash-ios/wiki/03.5-Calabash-iOS-Ruby-API

Abstract Methods and Classes

Hello guys,

I will continue with more technical posts today… 🙂

What is ? 

An abstract class is a class that is declared abstract—it may or may not include abstract methods. Abstract classes cannot be instantiated, but they can be subclassed.

An abstract method is a method that is declared without an implementation (without braces, and followed by a semicolon), like this:

abstract void moveTo(double deltaX, double deltaY);

If a class includes abstract methods, then the class itself must be declared abstract, as in:

public abstract class GraphicObject {
   // declare fields
   // declare nonabstract methods
   abstract void draw();
}

When an abstract class is subclassed, the subclass usually provides implementations for all of the abstract methods in its parent class. However, if it does not, then the subclass must also be declared abstract.

An Abstract Class Example

In an object-oriented drawing application, you can draw circles, rectangles, lines, Bezier curves, and many other graphic objects. These objects all have certain states (for example: position, orientation, line color, fill color) and behaviors (for example: moveTo, rotate, resize, draw) in common. Some of these states and behaviors are the same for all graphic objects (for example: position, fill color, and moveTo). Others require different implementations (for example, resize or draw). All GraphicObjects must be able to draw or resize themselves; they just differ in how they do it. This is a perfect situation for an abstract superclass. You can take advantage of the similarities and declare all the graphic objects to inherit from the same abstract parent object (for example, GraphicObject) as shown in the following figure.

Classes Rectangle, Line, Bezier, and Circle Inherit from GraphicObject  

Classes Rectangle, Line, Bezier, and Circle Inherit from GraphicObject

First, you declare an abstract class, GraphicObject, to provide member variables and methods that are wholly shared by all subclasses, such as the current position and the moveTo method. GraphicObject also declares abstract methods for methods, such as draw or resize, that need to be implemented by all subclasses but must be implemented in different ways. The GraphicObject class can look something like this:

abstract class GraphicObject {
    int x, y;
    ...
    void moveTo(int newX, int newY) {
        ...
    }
    abstract void draw();
    abstract void resize();
}

Each nonabstract subclass of GraphicObject, such as Circle and Rectangle, must provide implementations for the draw and resize methods:

class Circle extends GraphicObject {
    void draw() {
        ...
    }
    void resize() {
        ...
    }
}
class Rectangle extends GraphicObject {
    void draw() {
        ...
    }
    void resize() {
        ...
    }
}

Class Members

An abstract class may have static fields and static methods. You can use these static members with a class reference (for example,AbstractClass.staticMethod()) as you would with any other class.

When ?

Abstract Classes is to create templates for future classes and offer the added benefit of letting you define functionality that your child classes can utilize later. You can’t provide an implementation for an Interface.

Why ?

Abstract Classes are a good fit if you want to provide implementation details to your children but don’t want to allow an instance of your class to be directly instantiated (which allows you to partially define a class). If you want to simply define a contract for Objects to follow, then use an Interface.

 
Abstract methods are useful ?

Abstract methods are useful in the same way that defining methods in an Interface is useful. It’s a way for the designer of the Abstract class to say “any child of mine MUST implement this method”.

 

Any question or comment, just write below ! Thank you again ! 

Bye 🙂

 

Font: http://docs.oracle.com/javase/tutorial/java/IandI/abstract.html

http://stackoverflow.com/questions/3344816/when-and-why-to-use-abstract-classes-methods