90
WEB AUTOMATION WITH WATIR Dec 08, 2011

WATIR part2

Embed Size (px)

Citation preview

Page 1: WATIR part2

WEB AUTOMATION WITH WATIRDec 08, 2011

Page 2: WATIR part2

Agenda1. Watir Introduction2. Watir Installation and testing3. Installation testing and troubleshotting4. Ruby/Watir IDE5. A Sample Watir test script6. Running Watir test script7. Locating HTML elements8. Interacting with HTML elements9. Controlling HTML elements10. Watir Unit Test Framework11. Test Implementation with Page Object Pattern12. Watir Recorder13. Others

Page 3: WATIR part2

Watir IntroductionWatir is an open-source Ruby libraries for automating web browsersLocates html objectsInteracts found objectValidate results

Watir supports only Internet Explorer on Windows

Watir-WebDriver supports Chrome, Firefox, Internet Explorer, Opera

Watir uses the power of Ruby programming languages

Page 4: WATIR part2

Watir InstallationInstall Ruby InterpreterInstall RubyGems (package manager)Install WatirInstall Watir-Webdriver

Page 5: WATIR part2

Install Ruby InterpreterOn window

Go to Ruby Installer and choose the most recent version to install (Ruby 1.9.2-p290 or newer)

Follow screen intructions to complete installation

Check that Ruby was installed successfully. In command line>ruby –v ruby 1.9.2p290 (2011-07-09) [i386-mingw32]

Select the following two options• Add Ruby executables to your PATH • Associate .rb and .rbw files with this

Ruby installation

Page 6: WATIR part2

Updating RubyGemsSometimes Ruby installs do not have the latest package of RubyGem

To update your RubyGems>gem update –system (…) RubyGems system software updated

Verify your RubyGems was updated to the current version

>gem –v 1.8.11

Page 7: WATIR part2

Installing WatirIn Command Prompt (new session), type

gem install watir

You should get a response that looks something like this (do not worry if the Watir version number or gems count doesn’t match exactly):

>gem install watir (…) Successfully installed water-2.0.1 13 gems installed

Test the install by driving Internet Explorer

In Command Prompt, type the following: irb require “watir” #truebrowser = Watir::Browser.new #<Watir::IE:0x..f8169d749 url=”about:blank” title=””>

A new IE window should open:

Page 8: WATIR part2

Installing Watir-WebDriverIn Command Prompt

gem install watir-webdriver

You should get a response that looks something like this:

>gem install watir-webdriver (…) Successfully installed watir-webrdiver-0.3.2 6 gems installed

Install ChromeDriver for Chrome browser

Configure security setting in IEFour zones have been set to the

same mode (enabled or disabled).

Page 9: WATIR part2

Installing Watir-WebDriverTest the install by driving Internet Explorer Test the install by driving FirefoxTest the install by driving Chrome

In Command Prompt, type the following: irb require “watir-webdriver” =>#truebrowser = Watir::Browser.new :ie=> #<Watir::Browser:0x4eb80dc url="http://localhost:5555/" title="WebDriver">

Replace :ie with :ff or :chrome to test firefox and chrome respectively

Page 10: WATIR part2

Installation TroubleshottingRefer to http://wiki.mpifix.com/index.php/Installing_Watir_for_Windows#Troubleshooting_Watir-Webdriver

Or copy the whole Ruby folder on a machine has sucessful installation to yours (verified on Windows only)The folder is commonly at C:\Ruby192

Page 11: WATIR part2

Installing Watir on MacThe same steps that happens on Window

Install Ruby interpreter Install/update Ruby Gem

Refer to http://wiki.mpifix.com/index.php/Installing_Watir_for_Mac_OS for further details

Page 12: WATIR part2

Ruby/Watir IDERubyInSteel

Plug in to Visual studio 60-day trial Syntax checking and auto suggestion Also put at \\filevn01\Apps\Utilities\RubyInSteel_VS2010_2.zipNote: RubyInSteel has problem with Ruby 1.9.3 version

RubyMine Standalone 30-day trial Strong syntax checking and auto suggestion Also put at \\filevn01\Apps\Utilities\RubyMine-3.2.4.exe

Others NetBeans TextMate (MAC) Komodo (wins, mac, linux)

Page 13: WATIR part2

Ruby In Steel

Page 14: WATIR part2

RubyMine

Page 15: WATIR part2

Sample Watir test script Google search

require 'watir' # the watir controllerinclude Watir #Declaring Variablestest_site = 'http://www.google.com' #Opening Internet explorer browserie = IE.new #Navigating a web pageie.goto(test_site) #interact with objects in web page by enter a search keyword and click on Search buttonie.text_field(:name, "q").set("pickaxe") # q is the name of the search fieldie.button(:name, "btnG").click # "btnG" is the name of the Search button sleep 4

#evaluating resultsif ie.contains_text("Programming Ruby") puts "Test Passed. Found the test string: 'Programming Ruby'. Actual Results match Expected Results."else puts "Test Failed! Could not find: 'Programming Ruby'"end

Page 16: WATIR part2

Running a Watir test scriptCommand line:

Store watir script into a file and call it from command line

Page 17: WATIR part2

Running a Watir test script-Cont.1RubyInSteel: Point RubyInSteel to Ruby Interpreter

Page 18: WATIR part2

Running a Watir test script-Cont.2RubyInSteel

Just click on Run button to run

Page 19: WATIR part2

Running a Watir test script-Cont.3RubyMine

Just right click on watir file and select “Run…”

Page 20: WATIR part2

End of Day #3• Do you understand items mentioned in this session?• Q&A?

Page 21: WATIR part2

Locating HTML ElementsWatir syntaxGet Element by single artributeGet Element by multiple artributesGet Element by regular expressionGet Element by IndexGet Element by Xpath queryGet Element by nestingTips to locate objects

Page 22: WATIR part2

Locating HTML Elements - Watir syntax

HTML Element Name HTML Example Watir Syntax

TextBox <input type="text" id="one" name="typeinme"> IE.text_field(how, what)

HTMl Button <input type="button" id="one" name="clickme" value="Click Me"> IE.button(how, what)

Image Button <input type="image" src="images/doit.gif"> IE.button(how, what)

Label <label class="ss-q-help" for="entry_0">A text field</label> IE.label(how, what)

DropDownList

<select id="one" name="selectme">

IE.select_list(how, what)

<option></option>

<option>Ruby</option>

<option>Watir</option> <option>CSharp</option>

</select>

CheckBox <input type="checkbox" id="one" name="checkme"> IE.checkbox(how, what) Radio <input type="radio" name="clickme" id="one"> IE.radio(how, what)

Page 23: WATIR part2

Locating HTML Elements-Watir syntax – Cont.1HyperLink

<a href="http://pragmaticprogrammer.com/titles/ruby/" id="one" name="book">Pickaxe</a>

IE.link(how, what)

Form <form id="one" name="loginform" action="login" method="get"> IE.form(how, what) </form>

Frame <frameset cols="*,*">

IE.frame(how, what) <frame src="menu.htm" name="menu">

</frameset>

Span <span class=gbtcb></span> IE.span(how, what)

Div

<div class="ss-form-entry">

IE.div(how, what) <input type="submit" value="Submit" name="submit">

</div>

P <p>This is some text in a paragraph.</p> IE.p(how, what)

Table

<table id="gbmpal">

IE.table(how, what)

<tr> <td class="gbmpala">

<a id="gb_71" onclick="gbar.logger.il(9,{l:'o'})" href="https://accounts.google.com" class="gbml1">Sign out</a>

</td> </tr> </table>

Page 24: WATIR part2

Locating HTML Elements-Watir syntax-Cont.2

Image <img src="planets.gif" width="145" height="126" alt="Planets" usemap="#planetmap" /> IE.img(how, what)

Map

<map name="planetmap">

IE.map(how, what)

<area shape="rect" coords="0,0,82,126" href="sun.htm" alt="Sun" />

<area shape="circle" coords="90,58,3" href="mercur.htm" alt="Mercury" />

</map>

Area <area shape="circle" coords="90,58,3" href="mercur.htm" alt="Mercury" /> IE.label(how, what)

h1-h6

<h1>This is heading 1</h1> IE.h1(how, what) <h2>This is heading 2</h2> IE.h2(how, what) <h3>This is heading 3</h3> … <h4>This is heading 4</h4> <h5>This is heading 5</h5> <h6>This is heading 6</h6>

Page 25: WATIR part2

Locating HTML Elements-Watir syntax - Cont.3

WhereHow’s:

:name:id:index:value:text:title…

What’s:• String value of “how” • /Regular expression/

For example• ie.text_field(:id, “txtUsername”)• ie.text_field(:id, “txtPassword”)• ie.button(:id, “BtnGo”)• ie.select_list(:id, ‘YearDDL’)

Page 26: WATIR part2

Locating HTML Elements - Single artributebrowser.text_field(:id, "entry_0")browser.text_field(:class, "ss-q-short")browser.text_field(:name, "entry.0.single")

Play with this sample page• https://

spreadsheets.google.com/viewform?hl=en&formkey=dDliTk5XU1R4RUMtb2c1WDZxWHNENmc6MQ#gid=0

require "watir-webdriver"include Watirbrowser=Browser.new :chromebrowser.goto "https://spreadsheets.google.com/viewform?hl=en&formkey=dDliTk5XU1R4RUMtb2c1WDZxWHNENmc6MQ#gid=0"browser.text_field(:id, "entry_0").exists?chrome.text_field(:class, "ss-q-short").exists?chrome.text_field(:name, "entry.0.single").exists?

Page 27: WATIR part2

Locating HTML Elements – Multiple artributesbrowser.radio(:name => "entry.8.group", :value => "2")Browser.radio(:name => "entry.8.group", :value => "3")

Play with this sample page• https://

spreadsheets.google.com/viewform?hl=en&formkey=dDliTk5XU1R4RUMtb2c1WDZxWHNENmc6MQ#gid=0

Page 28: WATIR part2

Locating HTML Elements – regular expression

This statement will locate a form on web page which has action link contains “formResponse”

chrome.form(:action, /formResponse/)

Page 29: WATIR part2

Locating HTML Elements – regular expression

This statement will locate a form on web page which has action link contains “formResponse”

chrome.form(:action, /formResponse/)

n$ Matches any string with n at the end of it^n Matches any string with n at the beginning of it/n/ Matches any string that contains string n…

Page 30: WATIR part2

Locating HTML Elements – regular expression-Cont.1

n$ Matches any string with n at the end of it^n Matches any string with n at the beginning of it/n/ Matches any string that contains string n[abc] Match any character between the brackets…

Page 31: WATIR part2

Locating HTML Elements - Indexbrowser.checkbox(:name => "entry.4.group", :index=>0)browser.checkbox(:name => "entry.4.group", :index=>1)browser.checkbox(:name => "entry.4.group", :index=>2)

Play with this sample page• https://

spreadsheets.google.com/viewform?hl=en&formkey=dDliTk5XU1R4RUMtb2c1WDZxWHNENmc6MQ#gid=0

Page 32: WATIR part2

Locating HTML Elements - Xpath

WhenAn element which you can't access using those pre-defined

attributes?There is no API for a particular HTML element?When you want to access some element depeding upon some

other element?When performance is needed

Page 33: WATIR part2

Locating HTML Elements – Xpath-Cont.1

Some Xpath query stringsXpath samples Comment

//div Find all elements of a particular type id(‘bob’) or //*[@id='bob']

Find all elements with a specific ID

//div[@id='bob'] Find an element of a particular type with a specific ID //*[@class='bob'] Find elements with a specific class //div[@class='bob'] Find an element of a particular type with a specific class //div//a Find descendant elements of a particular type //div/a Find direct child elements of a particular type

//div[@class='bob']/.. Find a parent element of an element of a particular type that have an artribute of a specific value

//a[@title] Find elements of a particular type that have a specific attribute

//a[@title='bob'] Find elements of a particular type that have an attribute of a specific value

//a[contains(@title,'bob')] Find elements of a particular type that have an attribute that contains a specific value

//a[starts-with(@title,'bob')] Find elements of a particular type that have an attribute that starts with a specific value

Page 34: WATIR part2

Locating HTML Elements – Xpath-Cont.2

ExampleSuppose you have an HTML "select" element like:

<select foo="bar"> <option value="1"> 1< /option> < /select>

 Now "foo" is not standard attribute but browser will simply ignore it, so you can still get the element by

element = browser.select(:xpath, "//select[@foo='bar']") Suppose you have a "map" like this:

<map name="top_menu_map" id="top_menu_map"> <area shape="rect" coords="18,2,62,17" href="http://abc.com/public/signup.htm" target="_self" alt="engin home"> </area ></map>

 Now there’s no area class in Watir, and you want to access this elementbrowser.element_by_xpath("//area[contains(@href , 'signup.htm')]").click()

Page 35: WATIR part2

Locating HTML Elements – Xpath-Cont.3

ExampleAccessing elements with respect to other elements

<table><tr>

<td> <img src="1.jpg"> <input type="button"> < /td><td> <img src="2.jpg"> <input type="button"> < /td><td> <img src="3.jpg"> <input type="button"> < /td><td> <img src="4.jpg"> <input type="button"> < /td>

< /tr><tr>

<td> <img src="5.jpg"> <input type="button"> < /td><td> <img src="6.jpg"> <input type="button"> < /td><td> <img src="7.jpg"> <input type="button"> < /td><td> <img src="8.jpg"> <input type="button"> < /td>

< /tr>< /table>

Now suppose you want to click on button that has image with src="7.jpg" in front of it. So you have two ways to do it:

 browser.button(:xpath, "//img[@src='7.jpg']/input").click()

Page 36: WATIR part2

Locating HTML Elements – Nesting

You can access an element by going through DOM hierarchyFor example, if you had something like this:

<div id="one"> <div id="two"> <a href="http://watir.com/">click me</a> </div></div>

You could click the link with: browser.div(:id => "one").div(:id => "two").link(:text => "click me").click

 So, there is a browser, then a div, another div and the link we are looking for.

Page 37: WATIR part2

Locating HTML Elements – Nesting – Cont.1

Suppose you have a dropdown list as below

And you want to get all elements in the dropdown [email protected]_list(:id, /dropDownListOdometerUnit/).options.each do |each|

puts each.textend

Page 38: WATIR part2

Locating HTML Elements – Tips

Use irb mode to see whether the element can be gotten, this approach is to avoid any timing issue due to Javascript/Ajax

Use exists methodUse flash method to highlight object on web page screen

E.g.irb(main):064:0> chrome.text_field(:id, "entry_0").exists?=> trueirb(main):065:0> chrome.text_field(:id, "entry_0").flash=> 10

Page 39: WATIR part2

Locating HTML Elements – Tips – Cont.1

Use HTML collections to print all elements of a particular type, you then can easily get the desized elemens from printed propertiesExplicitly specicy HTML elements

@browser.links.each do |link| puts link.hrefend

You can also narrow down the result, just simply fill in further filter condition

@browser.links(:href => /create_vehicle.aspx/).each do |link| puts link.hrefend

Page 40: WATIR part2

Locating HTML Elements – Tips – Cont.2Use browser elements method

Suppose you have the html code as in below screenshot

Your code would beelements = @browser.elements(:class,"ruledRows")elements.each do |element|puts element.textend

The output will be2006 Saturn Ion-2 2.2L2004 Saturn Ion 2.2L, Vin F, Eng Des L61, USA/Canada2001 Dodge Durango 5.9L, Vin Z2007 Ford F-250 Super Duty XL 5.4L, GAS, Vin 5, Eng Cfg V82007 Buick Lucerne CX 3.8L2005 Honda CR-V EX 2.4L

Page 41: WATIR part2

End of Day #4• Do you understand items mentioned in this session?• Q&A?

Page 42: WATIR part2

Interact with HTML ElementsInteract with BrowserInteract with Page elements (HTML elements)

Page 43: WATIR part2

Interact with HTML Elements – Browser Launch browser

browser = Watir::Browser.new :chrome

Navigate to a page URLbrowser = Browser.goto "www.identifix.com"

Launch browser and navigate to a web pagebrowser = Browser.start "www.identifix.com"

Back a page on browserbrowser.back()

Forward a page on browserbrowser.forward()

Refresh browserbrowser.refresh()

Clear browser cookiesbrowser.clear_cookies()

Check if a new window opens with Watir-Webdriverbrowser.windows.size # You can check the number of windows with this method

Page 44: WATIR part2

Interact with HTML Elements – Browser – Cont.1

Attach to a browser window createdUtilize “use” method on browser objectExample:

require "watir-webdriver"include Watirff.goto "www.identifix.com"ff.a(:id, "hlDetailLink").clickff.window(:title, "Featured Fix OF The Week").useff.title #"Featured Fix OF The Week"ff.window(:title, "Direct-Hit").useirb(main):038:0> ff.title #=> "Direct-Hit"

Page 45: WATIR part2

Interact with HTML Elements – Page elementsSetting the text field (or text area) specified name specified

value. ie.text_field(:name,'name').set('value')

Setting the select with to the specified value

ie.select_list(:name,'name').select('value')

Clicking the button with the specified value (label)ie.button(:value,'value').click

Clicking the link matching 'text' ie.link(:text,'text').click

Enabling a [email protected](:name, "name").set

Page 46: WATIR part2

Interact with HTML Elements – Page elements – Cont.1

Accessing elements in a "frame" or "iframe”Note that you can not directly access elemnent in iframe/frame from browser level, the access has to through iframe

This will get the elementff.frame(:name => "ifrmRotation", :id=>"ifrmRotation").area(:target,

"_blank").send_keys :enter

This won’t get the elementff.area(:target, "_blank").send_keys :enter

Page 47: WATIR part2

Interact with HTML Elements – Page elements

Sending keys to interact with elementIn some cases, you need to check actions from user inputs from keyboard, you can also simulate that action in WatirE.g.

@ie.button(:id, 'BtnGo').send_keys :enter

The learn more button in previous example is a typical case, the navigation does not work with click action

Referencehttp://watirwebdriver.com/sending-special-keys/

Page 48: WATIR part2

Interact with HTML Elements – Page elements – Cont.1

Trigger element’s event• Usually in IE, actions like

clicking on hyperlinks, buttons does not trigger the action, in those cases, you will need to trigger element’s events directly from Watir-Webdriver

E.gie.button(:id, "BtnGo").fire_event("onclick")

Page 49: WATIR part2

Controlling your scriptWhy timing control?Sleep statementImplicit waitsExplicit waitsAjax HandlingJavascript handling

Page 50: WATIR part2

Controlling your script - Why timing control?

By design, Watir does not wait for new page to load, except:

when you “use" to an existing windowuse the "click" method"set" or "clear" radio buttons or checkboxeswhen you select an item in a select listwhen you clear a text fieldwhen you "goto" a new pagewhen you "submit" a formwhen you "back", "forward" or "refresh" the browserwhen you "fire_event" on any element

Page 51: WATIR part2

Controlling your script – Why timing control? – Cont.1

This means that you do not have explicitly code for waiting for a browser page to load. However, there are still some circumstances where you will need to wait

New windows (e.g. popup)Objects that depends on Javascript to show upAsynchronous javascript / AJAXSlow things down for troubleshooting reasons

Page 52: WATIR part2

Controlling your script – Sleep statement

An example might be that you're loading the Google home page and for some reason it's taking time to load. So your script could be as below

require 'watir-webdriver'browser = Watir::Browser.start('http://www.google.com')sleep 5 # we need to wait for the page to load, I've chosen 5 seconds which works on my machinebrowser.text_field(:name, 'q').set('ruby poignant')....

Back to sample google search example of the training to see how things work if “sleep 5” statement is removed

Unfortunately the sleep is hardcoded and doesn't work for anyone else who has slower network connection

Page 53: WATIR part2

Controlling your script – Implicit WaitsSpecify a maximum time (in seconds) the script will try to find

an element before timing out. This is done by setting the property of the underlying driverSpecify a maximum time (in seconds) the script will try to find an element before timing out

E.g

require 'watir-webdriver'b = Watir::Browser.newb.driver.manage.timeouts.implicit_wait = 3 #3 seconds

Note: Using implicit waits can make your tests slower and more difficult to understand when they fail

Page 54: WATIR part2

Controlling your script – Explicit WaitsWatir::Wait.until { ... }: where you can wait for a block to be trueobject.when_present.set: where you can do something when it’s presentobject.wait_until_present: where you just wait until something is presentobject.wait_while_present: where you just wait until something

disappears

The default timeout for all these methods is 30 seconds, but your can pass an argument to any of these to increase (or decrease) it as needed.

E.g require 'watir-webdriver'b = Watir::Browser.new :chromeb.goto 'bit.ly/watir-webdriver-demo'b.select_list(:id => 'entry_1').wait_until_presentb.text_field(:id => 'entry_0').when_present.set 'your name'b.button(:name => 'submit').clickb.button(:name => 'submit').wait_while_presentWatir::Wait.until { b.text.include? 'Thank you' }

Page 55: WATIR part2

Controlling your script – Ajax handlingHow?

Ajax handling from Watir is just simply using timing control to wait for result from Ajax event.

The timing control may be a wait loop (while iterate with sleep command) or built-in control functions

=> It’s not recommended to use wait loop

E.g

def wait_until_loaded(timeout = 30) start_time = Time.now until (application_reports_its_loaded == 'true') do sleep 0.1 if Time.now - start_time> timeout raise RuntimeError, "Timed out after #{timeout} seconds" end endend

Or a simpler option

tries = 0until browser.link(:text, /link_to_wait_for/).exists? do sleep 0.5 tries += 1endbrowser.link(:text, /link_to_wait_for/).clickend

Page 56: WATIR part2

Controlling your script – Ajax handling – Cont.1Sample loop control

def wait_until_loaded(timeout = 30) start_time = Time.now until (application_reports_its_loaded == 'true') do sleep 0.1 if Time.now - start_time> timeout raise RuntimeError, "Timed out after #{timeout} seconds" end endEnd

Or a simpler option

tries = 0until browser.link(:text, /link_to_wait_for/).exists? do sleep 0.5 tries += 1endbrowser.link(:text, /link_to_wait_for/).clickend

Page 57: WATIR part2

Controlling your script – Ajax handling – Cont.2

Built-in Methods (explicit methods)Suppose you click on Go button in screenshot aside and expect “the secret word…” is returned

require "watir-webdriver"include Watir@browser = Browser.new :[email protected] ("http://www.degraeve.com/reference/simple-ajax-example.php") @browser.button(:value => "Go").clickWait.until {@browser.div(:id, 'result').text.include? "The secret word"}

Page 58: WATIR part2

Controlling your script – Javascript handling

Same reasons and approaches that applied to Ajax handling

E.gSelect Year, Make, Model and Engine to create a vehicle in DH Create Vehicle page

Wait.until {browser.select(:name, 'YearDDL').when_present.text.include? "Year: Please Select"}browser.select_list(:id, "YearDDL").select “2004”

Page 59: WATIR part2

Watir Unit Test FrameworkInstallationCreate a test instanceCreate a test methodVerify results (assertion statements)Chain test cases in single Unit test classSetup and TeardownA Sample Test::Unit class templateA Sample Watir Test::Unit class Run the test cases in Test::Unit class Run test cases in multiple Test::Unit classes

Page 60: WATIR part2

Watir Unit Test Framework - Installation

Ruby has an xUnit framework called Test::Unit that we can use with Watir. You do not have to install anything, Test::Unit is included in Ruby

• To use Test::Unit in your test scripts, enter the following in your test script require 'test/unit'

Page 61: WATIR part2

Watir Unit Test Framework - Create a test instance

Create your class for your test case that inherites from “Test::Unit::TestCase” class

class myTest < Test::Unit::TestCase # fill in Test Case methods hereend

Page 62: WATIR part2

Watir Unit Test Framework - Create a test method

Test method starts with “test”.Test method that does not start with “test” won’t be called

automatically, but they can be referenced by unit test methods (starts with “test”)

def test_01_search_validbrowser.text_field(:name, "q").set("pickaxe")browser.button(:name, "btnG").clickassert(browser.contains_text("Programming Ruby"),

"Test Passed. Found the test string: 'Programming Ruby'")end

Page 63: WATIR part2

Watir Unit Test Framework - Verify results Watir can support assertions by wrapping Watir methods within an assert

E.g  assert(ie.contains_text("Reached test verification point.") Watir can test for many different states of objects. We can use assertions to check of objects exists, are enabled or disabled, or any other state that the DOM tells the web browser about an object Some assertions that Ruby Unit Test Framework supports• assert (Test::Unit::Assertions)• assert_block (Test::Unit::Assertions)• assert_equal (Test::Unit::Assertions)• assert_no_match (Test::Unit::Assertions)• assert_not_equal (Test::Unit::Assertions)• assert_not_nil (Test::Unit::Assertions)• assert_not_same (Test::Unit::Assertions)• assert_nothing_raised (Test::Unit::Assertions)• assert_nothing_thrown (Test::Unit::Assertions)• assert_raise (Test::Unit::Assertions)• assert_respond_to (Test::Unit::Assertions)

Page 64: WATIR part2

Watir Unit Test Framework - Chain test cases in single Unit test classTest::Unit class allows you to have more than one test method inside

the class

When we run the test script from the command line, Test::Unit uses reflection to go through our test class and execute all the test cases declared in it.

The runner by default executes the test cases alphabetically, so if you

need to chain test cases, prefix letters from the alphabet or numbers after the test prefix to force them to run in order.

 E.g

test_01_your_method_name test_02_your_method_name…

Page 65: WATIR part2

Watir Unit Test Framework - Setup and Teardown

• The method names setup and teardown are reserved for Test::Unit.

• If you would like to use setup and teardown functionality, simply use those as method names for the actions you want executed before and after executing each test case.

def setup # fill in code that will run before every test case hereEnd

def teardown # fill in code that will run after every test case hereend

Page 66: WATIR part2

Watir Unit Test Framework - A Sample Test::Unit class templateA sample Test::Unit class which include things mentioned above would be

as below 

require 'watir-weddriver'require 'test/unit' #includes Ruby's test case functionalityinclude Watir #include Watir namespace class WatirTest < Test::Unit::TestCasedef setup# fill in code that will run before every test case hereend def test_01_your_method_name# fill in method body with Watir code and assertion here end def test_02_your_method_name# fill in method body with Watir code and assertion hereend def teardown# fill in code that will run after every test case hereendend

Page 67: WATIR part2

Watir Unit Test Framework - A Sample Watir Test::Unit class: Google search class WatirTest < Test::Unit::TestCase

def setupif $ie == nil$ie = IE.new$ie.goto("http://google.com")endend

 def test_01_search_valid$ie.text_field(:name, "q").set("pickaxe")$ie.button(:name, "btnG").clickassert($ie.contains_text("Programming Ruby"),

"Test Passed. Found the test string: 'Programming Ruby'")end

def test_02_search_invalid

$ie.text_field(:name, "q").set("csharp")$ie.button(:name, "btnG").clickassert(not($ie.contains_text("Programming Ruby")),

"Test Passed. Did not find string: 'Programming Ruby'")end

end

Page 68: WATIR part2

End of Day #5• Do you understand items mentioned in this session?• Q&A?

Page 69: WATIR part2

Watir Unit Test Framework – Run test cases

• Run single scriptLike running for a watir test script as inntroduced earlier

Syntax>ruby "filepath\filename.rb" argument1 argument2, ... For example

E.g>ruby "C:\Users\trhuynh\Desktop\DirectHit\Main\Tests\Automation\DirectHitPAT\TCs\TC.Login.rb" firefox

Page 70: WATIR part2

Watir Unit Test Framework – Run test cases – Cont.1• Run a specific test method in Unit::TestCase

If Watir is written using Ruby Unit Test Framework, we can only run a particular test method instead of all test methods. In order to do that, specify test method name followed by “--name" directive and your file name

For example>ruby my_test_file.rb --name test_01_your_method_name

Page 71: WATIR part2

Watir Unit Test Framework – Run test cases – Cont.2Using Command-line Arguments

You can access any command-line arguments passed by the shell with the ARGV special variable. ARGV is an Array variable which holds, as strings, each argument passed by the shell.

In your Watir script, you can get each argument by using [] operator (e.g. ARGV[0], ARGV[1]...)

We can make use of this feature to indicate which browser, which test environment the written Watir test scripts to run against

Page 72: WATIR part2

Watir Unit Test Framework – Run test cases – Cont.3Run multiple scripts

Ruby does not support to specify multiple scripts in command line But you can still run multiple scripts by create an additional ruby file which "require" individual

scripts The command-line arguments passed by the shell will be the arguments passing to each

individual scripts specified in additional ruby file

For example, suppose you have two Watir scripts "C:/Users/trhuynh/Desktop/Test/test1.rb" "C:/Users/trhuynh/Desktop/Test/test2.rb"

You then can run these two script by creating an additional file (e.g. testAll.rb) which has content as require "C:/Users/trhuynh/Desktop/Test/test1.rb" require "C:/Users/trhuynh/Desktop/Test/test2.rb"

Now, you can run the test as below >ruby "C:/Users/trhuynh/Desktop/Test/TestAll.rb" firefox

We would utilize this feature to create test suite for PAT in Continuos Integration

Page 73: WATIR part2

Watir Unit Test Framework – Run test cases – Cont.4Run same script with different settings

It’s useful when you want to repeat the same test with various settings like repeating the same test on different browser…

What we need to do is wrap the full path + fike name into system comand

E.gsystem("ruby #{File.dirname(__FILE__)}/Suite.Search.rb \"chrome\" \"www.identifix.com\"")system("ruby #{File.dirname(__FILE__)}/Suite.Search.rb \"firefox\" \"www.identifix.com\"")

Page 74: WATIR part2

Storing element objects and data test with page object frameworkAdvantageAn exampleImplementationTest Execution

Page 75: WATIR part2

Page object framework - advantagePage Objects is a design pattern to model the application under test as objects in your code. Page Objects eliminate duplication by building an abstraction that allows you to write browser tests for maximum functional test maintainability and robustnessPromotes re-use and reduce duplicationMake tests readableMake tests more robustImprove maintainability, particualarly is the application is

rapidly evolving

Page 76: WATIR part2

Page object framework - ExampleConsider this script:

require 'watir-webdriver' # the watir controllerinclude Watir

browser = Watir::Browser.new :chromebrowser.goto "www.identifix.com"

browser.text_field(:id => "txtUsername").set "tester0101"browser.text_field(:id => "txtPassword").set "tester0101"browser.button(:id => "BtnGo").click

assert(Watir::Wait.until { browser.title == " Direct-Hit -- Create A New Vehicle " }

browser.select_list(:id, "YearDDL").select "2004"browser.select_list(:id, "MakeDDL").select "Saturn"browser.select_list(:id, "ModelDDL").select "Ion"browser.select_list(:id, 'OptionsDDL').select "2.2L, Vin F, Eng Des L61, USA/Canada"browser.button(:value,"Select Vehicle").click

assert(Watir::Wait.until { browser.title == "Direct-Hit -- Main Asset Search" }

Page 77: WATIR part2

Page object framework – Example – Cont.1

With page objects, this could be splitted into diferent classes to take the advantage of page object frameworkPages.LoginPages.CreateVehiclePages.VehicleHome

Page 78: WATIR part2

Page object framework – Example – Cont.2Pages.Login.rb

class LoginPage < BrowserContainer def open @browser.goto URL self end

def login_as(user, pass) user_field.set user password_field.set pass go_button.click next_page = CreateVehiclePage.new(@browser) Watir::Wait.until { next_page.loaded? } return next_page end

private def user_field @browser.text_field(:id => "txtUsername") end def password_field @browser.text_field(:id => "txtPassword") end def go_button @browser.button(:id => "BtnGo") endend

Page 79: WATIR part2

Page object framework – Example – Cont.3 Pages.CreateVehicle

class CreateVehiclePage < BrowserContainerdef logged_in?logged_in_element.exists?end def [email protected] == "Direct-Hit -- Create A New Vehicle"end def create_vehicle(year, make, model, engine)@browser.select_list(:id, "YearDDL").select [email protected]_list(:id, "MakeDDL").select [email protected]_list(:id, "ModelDDL").select [email protected]_list(:id, 'OptionsDDL').select engineselect_button.click()#return next_pagenext_page = VehicleHomePage.new(@browser)Watir::Wait.until { next_page.loaded? }return next_pageend

privatedef [email protected](:title => "Logout")enddef [email protected]_list(:id, "YearDDL")enddef [email protected]_list(:id, "MakeDDL")enddef [email protected]_list(:id, "ModelDDL")enddef [email protected](:value,"Select Vehicle")endend

Page 80: WATIR part2

Page object framework – Example – Cont.4Pages.VehicleHome.rb

class VehicleHomePage < BrowserContainerdef logged_in?

logged_in_element.exists?end

def [email protected] == "Direct-Hit -- Main Asset Search"

end

privatedef logged_in_element

@browser.image(:id => "tabHome", :alt => "Home")end

end

Page 81: WATIR part2

Page object framework – Example – Cont.5Parms.Login.rb

class VehicleHomePage < BrowserContainerdef logged_in?

logged_in_element.exists?end

def [email protected] == "Direct-Hit -- Main Asset Search"

end

privatedef logged_in_element

@browser.image(:id => "tabHome", :alt => "Home")end

end

Page 82: WATIR part2

Page object framework – Example – Cont.6Parms.Login.rb

class LoginPageParmsdef self.get_username

return “tester0101"end

def self.get_passwordreturn “tester0101"

endend

Page 83: WATIR part2

Page object framework – Example – Cont.7Site.rb

require "#{File.dirname(__FILE__)}/base_page.rb"require "#{File.dirname(__FILE__)}/login_page.rb"require "#{File.dirname(__FILE__)}/create_vehicle_page.rb"require "#{File.dirname(__FILE__)}/vehicle_home_page.rb"

class Site < BrowserContainer def login_page @login_page = LoginPage.new(@browser) end

def create_vehicle_page @create_vehicle_page = CreateVehiclePage.new(@browser) end def vehicle_home_page @vehicle_home_page = VehicleHomePage.new(@browser) end def close @browser.close endend # Site

Page 84: WATIR part2

Page object framework - Implementation

Create a class file corresponding to each web page of web application• Pages.Login• Pages.CreateVehicle• Pages.VehicleHome

Page 85: WATIR part2

Page object framework – Implementation – Cont.1Define class for each class file

Reference to base class

require "#{File.dirname(__FILE__)}/base_page.rb"

Test methods that users would work on the web page under test; it depends of your test purposes. At least there’re two methods, one to dertermine whether the page is loaded, the other one to dertermine if the page is loaded correctly

def logged_in?logged_in_element.exists?

end

def [email protected] == "Direct-Hit -- Main Asset Search"

end

All object definition should not be exposed to user

privatedef [email protected](:id => "tabHome", :alt => "Home")end

Page 86: WATIR part2

Page object framework – Implementation – Cont.2Add a site classSite represents the web application under test; the site class should contain methods to instantiate all page classes

Add all page class references to site class

require "#{File.dirname(__FILE__)}/base_page.rb"require "#{File.dirname(__FILE__)}/login_page.rb"require "#{File.dirname(__FILE__)}/create_vehicle_page.rb"require "#{File.dirname(__FILE__)}/vehicle_home_page.rb"

Add methods to instantiate each page class

def login_page @login_page = LoginPage.new(@browser) end

def create_vehicle_page @create_vehicle_page = CreateVehiclePage.new(@browser) end def vehicle_home_page @vehicle_home_page = VehicleHomePage.new(@browser) end

Page 87: WATIR part2

Page object framework – Implementation – Cont.3Create further paremeter classesThis is optional; it depends on how much common data your test methods will need to access in each web page. If you feel it’s needed, you may create each paremeter class for each page class

class LoginPageParmsdef self.get_username

return “tester0101"end

def self.get_passwordreturn “tester0101"

endend

Page 88: WATIR part2

Page object framework – Implementation – Cont.4Call page class methods in your test methods in Ruby Test::Unit

framework

def test_01_login@login_page = $site.login_page.open@create_vehicle_page = @login_page.login_as

LoginPageParms.get_username(),\ LoginPageParms.get_password()

assert(@create_vehicle_page.logged_in?, "Test Passed. Login successfully")

end

def test_02_create_vehicle@create_vehicle_page = $site.create_vehicle_page@vehicle_home_page = @create_vehicle_page.create_vehicle "2004",

"Saturn", "Ion", "2.2L, Vin F, Eng Des L61, USA/Canada"assert(@vehicle_home_page.logged_in?, "Created and entered VHP successfully")

end

Page 89: WATIR part2

Page object framework – Test ExecutionSame as running a normal Unit:Test test case, refer to Watir Unit Test

Framework – Run test cases section

Page 90: WATIR part2

End of Day #6• Do you understand items mentioned in this session?• Q&A?