Documente Academic
Documente Profesional
Documente Cultură
Agenda
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13.
Watir Introduction Watir Installation and testing Installation testing and troubleshotting Ruby/Watir IDE A Sample Watir test script Running Watir test script Locating HTML elements Interacting with HTML elements Controlling HTML elements Watir Unit Test Framework Test Implementation with Page Object Pattern Watir Recorder Others
Watir Introduction
Watir is an open-source Ruby libraries for
Windows Watir-WebDriver supports Chrome, Firefox, Internet Explorer, Opera Watir uses the power of Ruby programming languages
Watir Installation
Install Ruby Interpreter Install RubyGems (package manager) Install Watir
Install Watir-Webdriver
Select the following two options Add Ruby executables to your PATH Associate .rb and .rbw files with this Ruby installation
Updating RubyGems
Sometimes Ruby installs do not have the
current version
>gem v 1.8.11
Installing Watir
In 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 doesnt match exactly):
>gem install watir () Successfully installed water-2.0.1 13 gems installed
Installing Watir-WebDriver
In Command Prompt
gem install watir-webdriver
Installing Watir-WebDriver
Test the install by driving Internet Explorer
Replace :ie with :ff or :chrome to test firefox and chrome respectively
Installation Troubleshotting
Refer 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
Ruby/Watir IDE
RubyInSteel
Plug in to Visual studio 60-day trial Syntax checking and auto suggestion Also put at \\filevn01\Apps\Utilities\RubyInSteel_VS2010_2.zip
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)
Ruby In Steel
RubyMine
#Declaring Variables test_site = 'http://www.google.com' #Opening Internet explorer browser ie = IE.new #Navigating a web page ie.goto(test_site) #interact with objects in web page by enter a search keyword and click on Search button ie.text_field(:name, "q").set("pickaxe") # q is the name of the search field ie.button(:name, "btnG").click # "btnG" is the name of the Search button sleep 4 #evaluating results if 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
End of Day #3
Do you understand items mentioned in this session?
Q&A?
HTML Example
<input type="text" id="one" name="typeinme"> <input type="button" id="one" name="clickme" value="Click Me"> <input type="image" src="images/doit.gif"> <label class="ss-q-help" for="entry_0">A text field</label>
Watir Syntax IE.text_field(how, what) IE.button(how, what) IE.button(how, what) IE.label(how, what)
DropDownList
IE.select_list(how, what)
CheckBox Radio
IE.link(how, what)
IE.form(how, what)
<input type="submit" value="Submit" name="submit"> </div> <p>This is some text in a paragraph.</p> <table id="gbmpal"> <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>
Table
IE.table(how, what)
IE.img(how, what)
Map
<area shape="circle" coords="90,58,3" href="mercur.htm" alt="Mercury" /> </map>
IE.map(how, what)
Area
<area shape="circle" coords="90,58,3" href="mercur.htm" alt="Mercury" /> <h1>This is heading 1</h1> <h2>This is heading 2</h2> <h3>This is heading 3</h3> <h4>This is heading 4</h4> <h5>This is heading 5</h5> <h6>This is heading 6</h6>
h1-h6
For example ie.text_field(:id, txtUsername) ie.text_field(:id, txtPassword) ie.button(:id, BtnGo) ie.select_list(:id, YearDDL)
n$ ^n /n/
Matches any string with n at the end of it Matches any string with n at the beginning of it Matches any string that contains string n
^n
/n/ [abc]
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']")
Now theres no area class in Watir, and you want to access this element
browser.element_by_xpath("//area[contains(@href , 'signup.htm')]").click()
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()
hierarchy
For example, if you had something like this:
So, there is a browser, then a div, another div and the link we are looking for.
E.g.
irb(main):064:0> chrome.text_field(:id, "entry_0").exists? => true irb(main):065:0> chrome.text_field(:id, "entry_0").flash => 10
you then can easily get the desized elemens from printed properties
Explicitly specicy HTML elements
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.href end
The output will be 2006 Saturn Ion-2 2.2L 2004 Saturn Ion 2.2L, Vin F, Eng Des L61, USA 2001 Dodge Durango 5.9L, Vin Z 2007 Ford F-250 Super Duty XL 5.4L, GAS, Vin 2007 Buick Lucerne CX 3.8L 2005 Honda CR-V EX 2.4L
End of Day #4
Do you understand items mentioned in this session?
Q&A?
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 checkbox @browser.checkbox(:name, "name").set
"frame" or "iframe
Note that you can not directly access elemnent in iframe/frame from browser level, the access has to through iframe
This wont get the element ff.area(:target, "_blank").send_keys :enter This will get the element ff.frame(:name => "ifrmRotation", :id=>"ifrmRotation").area(:target, "_blank").send_keys :enter
The learn more button in previous example is a typical case, the navigation does not work with click action Reference http://watirwebdriver.com/sending-special-keys/
Sleep statement
Implicit waits Explicit waits
Ajax Handling
Javascript handling
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 machine browser.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
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.new b.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
present object.wait_until_present: where you just wait until something is present object.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 :chrome b.goto 'bit.ly/watir-webdriver-demo' b.select_list(:id => 'entry_1').wait_until_present b.text_field(:id => 'entry_0').when_present.set 'your name' b.button(:name => 'submit').click b.button(:name => 'submit').wait_while_present Watir::Wait.until { b.text.include? 'Thank you' }
for result from Ajax event. The timing control may be a wait loop (while iterate with sleep command) or built-in control functions
Or a simpler option
tries = 0 until browser.link(:text, /link_to_wait_for/).exists? do sleep 0.5 tries += 1 end browser.link(:text, /link_to_wait_for/).click end
(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 :chrome @browser.goto ("http://www.degraeve.com/reference/simple-ajax-example.php") @browser.button(:value => "Go").click Wait.until {@browser.div(:id, 'result').text.include? "The secret word"}
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'
Test method that does not start with test wont be called
automatically, but they can be referenced by unit test methods (starts with test)
def test_01_search_valid browser.text_field(:name, "q").set("pickaxe") browser.button(:name, "btnG").click assert(browser.contains_text("Programming Ruby"), "Test Passed. Found the test string: 'Programming Ruby'") end
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)
Watir Unit Test Framework - Chain test cases in single Unit test class
Test::Unit class allows you to have more than one test method
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
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 here End def teardown # fill in code that will run after every test case here end
would be as below
require 'watir-weddriver' require 'test/unit' include Watir #includes Ruby's test case functionality #include Watir namespace
class WatirTest < Test::Unit::TestCase def setup # fill in code that will run before every test case here end 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 here end def teardown # fill in code that will run after every test case here end end
Watir Unit Test Framework - A Sample Watir Test::Unit class: Google search
class WatirTest < Test::Unit::TestCase def setup if $ie == nil $ie = IE.new $ie.goto("http://google.com") end end def test_01_search_valid $ie.text_field(:name, "q").set("pickaxe") $ie.button(:name, "btnG").click assert($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").click assert(not($ie.contains_text("Programming Ruby")), "Test Passed. Did not find string: 'Programming Ruby'") end end
End of Day #5
Do you understand items mentioned in this session?
Q&A?
E.g
>ruby "C:\Users\trhuynh\Desktop\DirectHit\Main\Tests\Automation\DirectHitPAT\ TCs\TC.Login.rb" firefox
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
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
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.g
system("ruby #{File.dirname(__FILE__)}/Suite.Search.rb \"chrome\" \"www.identifix.com\"") system("ruby #{File.dirname(__FILE__)}/Suite.Search.rb \"firefox\" \"www.identifix.com\"")
Storing element objects and data test with page object framework
Advantage
An example
Implementation Test Execution
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 robustness
Promotes re-use and reduce duplication Make tests readable Make tests more robust Improve maintainability, particualarly is the application is
rapidly evolving
be splitted into diferent classes to take the advantage of page object framework
Pages.Login Pages.CreateVehicle Pages.VehicleHome
end
def create_vehicle(year, make, model, engine) @browser.select_list(:id, "YearDDL").select year @browser.select_list(:id, "MakeDDL").select make @browser.select_list(:id, "ModelDDL").select model @browser.select_list(:id, 'OptionsDDL').select engine select_button.click() #return next_page next_page = VehicleHomePage.new(@browser) Watir::Wait.until { next_page.loaded? } return next_page end private def logged_in_element @browser.link(:title => "Logout") end def year_select @browser.select_list(:id, "YearDDL") end def make_select @browser.select_list(:id, "MakeDDL") end def model_select @browser.select_list(:id, "ModelDDL") end def select_button @browser.button(:value,"Select Vehicle") end end
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 end end # Site
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 therere 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 loaded? @browser.title == "Direct-Hit -- Main Asset Search" end
private def logged_in_element @browser.image(:id => "tabHome", :alt => "Home") end
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
end
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
End of Day #6
Do you understand items mentioned in this session?
Q&A?