Monday, October 1, 2012

JavaScript Dialogs with Web Drivers


JavaScript dialogs are fairly common in web applications.Watir and Watir-Webdriver have different methods for dealing with JS dialogs.

Webdriver has an Alerts API, and Watir-Webdriver has an alerts helper which makes use of that, with a few different methods in it to deal with various styles of javascript popups.Below are the commands to tackle different dialogs using web drivers


JavaScript Alerts
# Check if alert is shown
browser.alert.exists?

# Get text of alert
browser.alert.text

# Close alert
browser.alert.ok
browser.alert.close

JavaScript Confirms
# Accept confirm
browser.alert.ok

# Cancel confirm
browser.alert.close

JavaScript Prompt
# Enter text to prompt
browser.alert.set "Prompt answer"

# Accept prompt
browser.alert.ok

# Cancel prompt
browser.alert.close

If you are not on web drivers then you can use traditional .click and no_wait variants to get rid of them.

Tuesday, September 11, 2012

Grid Continued...


WatirGrid is Distributed

Built with standard DRb packages. Completely written in Ruby using core libraries.Lets you control Watir objects remotely with transmission passed by reference.

The standard Ruby library ships with a package known as DRb, it means Distributed Ruby. DRb is an incredibly easy package to learn and use. It has the benefits of being written completely in Ruby and using core libraries. It also offers advantages such as automatic selection of object transmission (either pass by value or pass by reference), reasonable speed, and the ability to run on any operating system that runs Ruby. 

WatirGrid is Parallel

WatirGrid uses Threads to execute Watir test cases in parallel (sort of). Threads execute on remote Watir objects, offloading any processing overheads

threads = []
  grid.browsers.each_with_index do |browser, index|
    threads << Thread.new do
      ...
    end
  end
threads.each {|thread| thread.join}


Key Terminology

Controllers implements a repository of tuples (tuple space) that can be accessed concurrently. The controller hosts the ring server which advertises these tuples across a grid network. Typically you will host one controller on a central machine.

Providers make remote Watir objects available to the tuple space hosted by the ring server. Typically you will host one or many providers on your grid network, for example, each PC may become a single provider of a Watir tuple in the form of an Internet Explorer, Firefox or Safari browser object.

Example:

require 'watirgrid'
require 'pp'
# Start a Controller

controller = Controller.new
controller.start
# Start a Provider
provider = Provider.new(:browser_type => 'safari')
provider.start
grid = Watir::Grid.new
grid.start(:take_all => true)
pp grid.browsers.first
# Take the first browser on the grid and execute some Watir
browser = grid.browsers.first[:object].new_browser
browser.goto "http://google.com"
browser.close


Thursday, September 6, 2012

WatirGrid

WatirGrid allows for distributed testing across a grid network using Watir.WatirGrid allows a local client to control remote Watir objects in parallel, hosted by providers on a grid network, via a central controller.

The controller implements a repository of tuples (tuple space) that can be accessed concurrently. The controller also hosts a ring server which advertises these tuples across a grid network making it loosely coupled.
Typically you will host one controller on a central machine. You will normally connect to this controller via a contoller_uri. You can also find this controller by its ring server, using a UDP broadcast for the ring server port.
The providers make remote Watir objects available to the tuple space hosted by the controller. Typically you will host one or many providers on your grid network, for example, each PC may become a single provider of a Watir tuple in the form of an Internet Explorer, Firefox, Safari or WebDriver browser object.

WatirGrid IS

  • A lightweight, pure Ruby implementation of distributed computing using DRb and Rinda.
  • A simple way to control remote Watir objects in parallel.
  • Cross platform friendly and works on Windows, OSX or Linux.
  • Open source, you’re already looking in the right place if you want the source code.
  • WebDriver friendly, thanks to the wire protocol, WatirGrid happily runs with WebDriver implementations such as watir-webdriver and selenium-webdriver.

    More Coming soon...

Wednesday, September 5, 2012

Dealing With Browser Certificates


IE:

The watir documentation has a workaround for this:

my_browser.link(:id, "overridelink").click

Another solution for this is to use autoit to tab into the 'continue to website', saves having to add to website all the time

    autoit=WIN32OLE.new('AutoItX3.Control')
    i=1
    while i < 11 
        autoit.Send("{Tab}")
        i+=1
    end

    autoit.Send("{Enter}")

Firefox:

The Firefox driver properly handles untrusted certificates by default.

If you have a trusted certificate, but there is some other certificate error such as a hostname mismatch (eg. using a production certificate in test), you should do the following:

profile = Selenium::WebDriver::Firefox::Profile.new
profile.assume_untrusted_certificate_issuer = false
b = Watir::Browser.new :firefox, :profile => profile
The reason this is needed is explained here.

Chrome:

It is easy to ignore invalid Browser certificates in Google Chrome by passing a command line switch:

Watir::Browser.new :chrome, :switches => ['--ignore-certificate-errors']

Thursday, March 29, 2012

Headless gem


The headless gem is a ruby wrapper for Xvfb, the virtual frame buffer.Virtual frame buffers are used to run graphical software on a “headless”, i.e. display-less, server.Headless gem makes it possible to create and release frame buffers straight from Ruby code. 

This gem makes it easy to run graphical applications (such as real web browsers) on a headless Linux machine. 

Command to install this gem:

gem install headless

An Example:

require 'watir-webdriver'
require 'headless'
headless = Headless.new
headless.start
b = Watir::Browser.start 'www.google.com'
puts b.title
b.close
headless.destroy

Finally, running WebDriver headless tests requires you to run a Selenium Server, which is additional overhead for your tests.


But why headless?


Whilst running automated browser tests in a headless form can speed things up, the main reason,  people wanting headless watir-web driver support is so that tests can be run on headless Linux machines, for example, a Jenkins Server.

Stop loading browser page

Sometimes the page is loading too slow, and we get a timeout error from watir-webdriver. Like in the below case:

require 'watir-webdriver'
browser = Watir::Browser.new :chrome
begin
  browser.goto("any url for a slow site")
 # Raise Timeout exception in 60 sec
rescue
  browser.send_keys(:escape) # => Raise another Timeout exception
end

Browser just refuses to respond to any othere commands before it finished loading the page. AS in this case the escape command is never executed until page loading is done.

This can be solved in below way:

require 'watir-webdriver'

client = Selenium::WebDriver::Remote::Http::Default.new
client.timeout = 60 
@browser = Watir::Browser.new :chrome, :http_client => client

begin
  @browser.goto mySite
rescue => e
  puts "Browser timed out: #{e}"
end

next_command

I hope this helps...

Monday, January 9, 2012

Adding Html tags to Watir libraries

Html tags to be verified in html page are maintained in non_control_elements.rb file in watir libraries under location Ruby location\lib\ruby\gems\1.9.1\gems\watir-2.0.4\lib.

If you have the framework for tags verification and some tags are not identified signifies that it is not there in non_control_elements. Here is the easy way to do it, just add below code to the end of this file

class LEGEND < NonControlElement
    TAG = 'LEGEND'
  end
  class TH < NonControlElement
    TAG = 'TH'
  end
  class BR < NonControlElement
    TAG = 'BR'
  end

With watir version 2.0.4 this has slightly changed and you need to do below:

%w[Pre P Div Span Map Area Li Ul H1 H2 H3 H4 H5 H6
     Dl Dt LEGEND TH TD Dd Strong Em Del Font Meta Ol].each do |elem|
    module_eval %Q{
      class #{elem} < NonControlElement; end
    }

This is it and you should be good to verify them in your framework. Hope it helps.

Thursday, December 8, 2011

Watir-WebDriver


WebDriver is a common browser automation tool that uses what ever is the most appropriate mechanism to control a browser, but with a common API. WebDriver supports not only real browsers (IE, Chrome & Firefox) but also headless ones (using HtmlUnit). It’s basically a nice Watir (ruby) implementation on WebDriver, so it gives you four browsers (three real, one headless) using one neat API, out of the box.

Running Watir-WebDriver

There are essentially two components you need: the Watir-WebDriver ruby gem, and the remote WebDriver server. The remote WebDriver server is only needed if you want to run your tests in headless mode without a real browser (or want to use Opera).

The Watir-WebDriver ruby gem

It’s a simple matter of opening a command prompt and typing:

gem install watir-webdriver (windows)

The remote WebDriver Server

This is the slightly tricky part. This is so that WebDriver can run headless without a real browser, and isn’t needed for real browser support (bar Opera). The quickest easiest way to get up and running is to download this java jar file, open a command prompt where you have saved it, and run:

java -jar selenium-server-standalone-2.0b1.jar

Example:

require 'rubygems'
require 'watir-webdriver'
b = Watir::Browser.new :chrome
b.goto 'www.google.com'
b.text_field(:name => 'q').set 'watir'
b.button(:name => 'btnK').click
b.div(:id => 'center_col').wait_until_present
puts "Displaying page: '#{b.title}' with results: '#{b.div(:id => "center_col").text}'"
b.close

The only difference for Firefox:

b = Watir::Browser.new :firefox

The only difference for IE:

b = Watir::Browser.new :ie

Watir 2.0.4


Watir 2.0.4 has been released. This version has the following changes:

* IE#execute_script escapes multi-line JavaScript scripts
* allow css and xpath locators for element collection methods, fixes
* Zero based Indexing

Install it with:
gem install watir

Tuesday, November 15, 2011

SSL error with Ruby 1.9

For some sites, whenever you try to open/load a https url it gives a certificate verification failed error.Below is the error detail


C:/Ruby192/lib/ruby/1.9.1/net/http.rb:678:in `connect': SSL_connect returned=1 e
rrno=0 state=SSLv3 read server certificate B: certificate verify failed (OpenSSL
::SSL::SSLError)

Ruby 1.9 installation doesn’t find the certification authority certificates (CA Certs) used to verify the authenticity of secured web servers.Basically ruby can't find any root certificates to trust and hence it throws this error.



The solution is to install the certificate and tell your http object to use it in below 2 steps:

   1. sudo port install curl-ca-bundle

   2. https.ca_file = '/opt/local/share/curl/curl-ca-bundle.crt'


or add the following, just next to http.use_ssl:

http.verify_mode = OpenSSL::SSL::VERIFY_NONE

Friday, September 30, 2011

WATIR 2.0


Watir 2.0 got released recently. Here are some features in the newest version:


1. No FireWatir:
There won’t be any new releases of FireWatir due to the fact that JSSH extension, which is used to control Firefox by FireWatir, is not available for Firefox versions 4 and newer.


2. Zero based indexing:
Watir has used one based indexing so far but with 2.0 it is using Zero based indexing. If you are using Watir 1.x and you’d like to access first div element on the page, you’d write code like this:


browser.div(:index => 1)
In Watir 2.0 and newer, you have to write code like this instead:


browser.div(:index => 0)


3. Multiple locators:
All elements support multiple locators for searching. 
e.g. browser.span(:name => "something", :class => "else")


4. Default locator:
In other words – if no other locators are specified, then :index => 0 will be used as a default. for e.g.
browser.span(:class => "something").div(:index => 1).span(:class => "else")  //1.x
browser.span(:class => "something").div.span(:class => "else") //2.0


5. Aliased methods
In Watir 2.0 you can use #tr, #trs, #td, #tds, #a, #as, #img and #imgs instead of instead of browser.row, browser.td or browser.cell.

Friday, September 23, 2011

Connecting to MySQL database

Here is one way to connect to MySQL database using ruby. This can be easily enhanced further to interact with the db like reading and writing records.


require "mysql"

   begin
     # connect to the MySQL server
     dbh = Mysql.real_connect("localhost", "testuser", "testpass", "test")
     # get server version string and display it
     puts "Server version: " + dbh.get_server_info
   rescue Mysql::Error => e
     puts "Error code: #{e.errno}"
     puts "Error message: #{e.error}"
     puts "Error SQLSTATE: #{e.sqlstate}" if e.respond_to?("sqlstate")
   ensure
     # disconnect from server
     dbh.close if dbh
   end
Let me know if you need any specific.

Tuesday, August 30, 2011

Failed to create WIN32OLE object from AutoItX3.Control


This is a  problem of registering the dll file, and hence it create an object of AutoIt. To register the autoit dll from command prompt, use following command


1.regsvr32 C:\ruby192\lib\ruby\gems\1.9.1\gems\watir-1.8.1\lib\watir\AutoItX3.dll


Although it does call the register code before creating an object, the 
error was in creating an autoit object.


2.You can also try adding line to top of the file


require 'win32ole'


Some more drag drop methods

With reference to my earlier posts on drag and drop, here are few more methods. You will need to have WindowsInput module,posted in earlier posts, along with below.

def drag_drop_on(target, src_offset=0, dst_offset=0)

     assert_target target
     drop_x = target.left_edge_absolute + dst_offset
     drop_y = target.top_edge_absolute + dst_offset
      drag_to(drop_x, drop_y, src_offset)
end

def drag_drop(target, src_offset=1, dst_offset=1)
            drag_x = left_edge_absolute + src_offset
    drag_y = top_edge_absolute + src_offset
           drop_x = target.left_edge_absolute + dst_offset
           drop_y = target.top_edge_absolute + dst_offset
           WindowsInput.move_mouse(drag_x, drag_y)
           WindowsInput.left_down
           WindowsInput.move_mouse(drop_x, drop_y)
          WindowsInput.left_up
end

def drag_drop_distance(distance_x, distance_y, src_offset=0, dst_offset=0)
   drag_x, drag_y = source_x_y(src_offset)
   drop_x = drag_x + distance_x + dst_offset
   drop_y = drag_y + distance_y + dst_offset
   drag_to(drop_x, drop_y, src_offset)
end

def drag_drop_at(drop_x, drop_y, src_offset=0)
   drag_to(drop_x, drop_y, src_offset)
end

def drag_drop_below(target, src_offset=0, dst_offset=0)
   assert_target target
   drop_x = target.left_edge_absolute + dst_offset
   drop_y = target.bottom_edge_absolute + 2 + dst_offset
   drag_to(drop_x, drop_y, src_offset)
end

def drag_drop_above(target, src_offset=0, dst_offset=0)
   assert_target target
   drop_x = target.left_edge_absolute + dst_offset
   drop_y = target.top_edge_absolute - 2 + dst_offset
   drag_to(drop_x, drop_y, src_offset)
end

def drag_to(drop_x, drop_y, src_offset)
   drag_x, drag_y = source_x_y(src_offset)
   WindowsInput.move_mouse(drag_x, drag_y)
   WindowsInput.left_down
   WindowsInput.move_mouse(drop_x, drop_y)
   WindowsInput.left_up
end

Thursday, August 25, 2011

Working with PDF files


In our project, we needed to read check the contents of a 'PDF report'  that comes embedded in a 'IE' window.The process is a little complicated and not so straightforward.


First you will need to download pdftk. Download these files and extract the files only in the C:\windows\system32 folder. http://www.accesspdf.com/article.php/20041130153545577 


Secondly you will need to download and isntall xpdf : http://pdf-toolkit.rubyforge.org/ . Extract those files into the C:\windows\system32 folder.Then you will need the PDF::TOOLKIT gem. This can be found here http://rubyforge.org/projects/pdf-toolkit/ 


Basically this will convert the pdf to a textfile and you can do what 
you like with it. In the following example I have just read a file on
my c:\ and displayed it using the 'puts' command.



require 'rubygems'
require 'pdf/toolkit' 

my_pdf = PDF::Toolkit.open("c:\\file.pdf")
text = my_pdf.to_text.read
puts text



I hope this helps

Thursday, October 28, 2010

Finding HTML Elements in Watir

TextBox:
   
IE.text_field(how, what)

Button:

IE.button(how, what)

DropDownList:

IE.select_list(how, what)

CheckBox:   

IE.checkbox(how, what)

RadioButton:   

IE.radio(how, what)

HyperLink:   

IE.link(how, what)

Form:   

IE.form(how, what)

Frame:   

IE.frame(how, what)

And many, many more (div, label, image, etc…)…

Test Unit

Test::Unit is a library of Ruby (just like Watir)

It is not technically part of Watir…however it is used regularly to structure tests.

To use Test::Unit in your scripts you ‘require’ it just as you do watir

require ‘test/unit’
require ‘watir’

Test::Unit is a way to organize your code into “tests”

Test::Unit has built in methods called “assertions” that help your tests with validation.

assert(browser.link(:text, “Click Here”).exists?)

The above statement will return a TRUE or FALSE indicating a pass or fail in your test.

Below is the basic code structure of a class in Test unit

require 'test/unit’

    class TC_MyTest < Test::Unit::TestCase
    include Watir

    def setup        #optional
    end            #optional
    def teardown      #optional
    end             #optional

        def test_pass
            assert(something.exists?)
        end
    end 


Watir Recorders

Watir is not a record/playback tool. However, there are several recorders “out there”

WatirMaker:

 It is a utility for Watir test developers which will record actions in a browser. It comes in two flavors: the C# version, and the Ruby version

Watir WebRecorder:

WebRecorder is an action recorder for web applications. A version that creates Watir scripts was released in February 2006. A handy tool to help learn Watir.Free, but not open source

Webmetrics RIA Script Recorder:

The script recorder is a tool to help generate a working watir script that can be used with the Webmetrics Rich Internet Application Monitoring. Webmetrics RIA Monitoring utilizes the open source technology Watir to do performance monitoring.

Tuesday, September 21, 2010

Exception handling in Ruby

The Ruby Exception Handling mechanism includes:

1. rescue and final clauses - for handling unwanted errors and
exit gracefully.

2. raise - for deliberately creating and raising exceptions in
code.

3. catch and throw clause - for continuing execution at some
point up the function call stack


I have been mainly using rescue in my code and have managed to handle most of the exceptions.

Example

i=0
while i<=10
  begin
    if i ==0
      1/0
    end
    raise "random exception"
   rescue ZeroDivisionError
    i+=1
  end
end

Rescuing Exceptions Inside Methods

def  foo_method
  puts "Hi"  raise
  puts "Bye"
rescue
  puts "Rescuing exceptions"

Adding support for html elements in WATIR

Any HTML element or tag can be to WATIR framework by updating non_control_elements.rb in watir framework.

1. Go to C:\ruby\lib\ruby\gems\1.8\gems\watir-1.6.5\lib\watir
2. Open non_control_elements.rb and add tags which are not there in the list and you wish to validate

class Ul < NonControlElement
    TAG = 'UL'
  end
  class H1 < NonControlElement
    TAG = 'H1'
  end
  class H2 < NonControlElement
    TAG = 'H2'
  end
class LEGEND < NonControlElement
    TAG = 'LEGEND'
  end
  class TH < NonControlElement
    TAG = 'TH'
  end

This can be then used to validate any text/links/listboxes etc on the html page.