Tuesday, September 04, 2007

Fantastic Community

Hello WATIR World! It has been a long time since I posted to this blog. I have once again been afforded the opportunity to play with WATIR code and improve my development skills. I recently was stuck on refactoring the previous code, so I posted to the WATIR forum.


The community is fantastic and quickly responded with several approaches. I will be honest in that I did not understand some of them, but somehow the responses inspired me to get the code working. Brett asked that I share some snippets of code, so I thought I would post them here.


Before I do that I also need to mention my mistake. When I posted to the forum I really did not include enough information. I was a bit concerned about the proprietary nature of the code, so I only posted a tiny portion of our code. I should have reworked the code and posted the entire script. Please when you post include as much information as possible so these brilliant people can respond appropriately.

Warning there is a lot of code.

Here is an example of what the original code looked like:


# Script is designed to execute Smoke test test cases
#
#
#Initials Date Summary
#CLS 10/04/05 Checked in first draft
#CLS 12/02/05 Clean up/Site Selection code
#List of to do's or ideas for improvement
#

# BEGIN -
#includes:
require 'watir' # the watir controller
require "rexml/document"
require "date"
require '/apps/ruby/lib/ruby/1.8/test/unit'
require '/apps/ruby/lib/ruby/1.8/test/unit/ui/console/testrunner'
require 'watir/testUnitAddons'
require 'watir/WindowHelper'
include REXML
include Watir
puts "## Begin Test - DN Advanced flow"
class SmokeTest < Test::Unit::TestCase
include Watir
def setup
@ie = IE.new
@ie.goto($URL)
end
def startClicker( button , waitTime = 3)
w = WinClicker.new
longName = @ie.dir.gsub("/" , "\\" )
shortName = w.getShortFileName(longName)
c = "start rubyw #{shortName }\\watir\\clickJSDialog.rb #{button } #{ waitTime} "
puts "Starting #{c}"
w.winsystem(c)
w=nil
#assert_same(expected, actual, [message] ) #Expects expected.equal?(actual)
end
def test1
# User enters login information and test validates assertions
assert(@ie.text_field(:id, "Person.username").exists?)
assert(@ie.text_field(:id, "Person.password").exists?)
assert(@ie.link(:id, "loginButton").exists?)
@ie.text_field(:name, "Person.username").set($Username)
@ie.text_field(:name, "Person.password").set($Password)
# User submits login information
@ie.link(:id, "loginButton").click
# User chooses application flow
@ie.image(:src , /ps_header_module_solution_builder_iconUp.gif/).click
# User selects an Account
@ie.selectBox( :name , "NS_Account").select("Basic Training")
# User Sets specific solution name
@ie.text_field(:name, "NS_Title").set("Test1")
# User selects Long Distance Voice check box
@ie.checkBox(:id, "DN").set
assert(@ie.checkbox(:id, "DN").isSet?)
# User selects LD advanced mode
@ie.radio(:id, "advDN_mode").set
assert(@ie.radio(:id, "advDN_mode").isSet?)
# User advances to Solution Status Page
@ie.link(:id, "next").click
# User moves to Site Selection Page
@ie.link(:id, "next").click
# User clears the selection of all sites
@ie.image(:id, "selectAllButton").click
# Selects specific sites
assert( @ie.cell(:id, '001-TX-AUS').exists? )
@ie.cell(:id, '001-TX-AUS').checkbox(:index,1).set
@ie.cell(:id, '002-TX-DAL').checkbox(:index,1).set
# User moves to Sol. Status Page
@ie.link(:id, "next").click
# User deselects technologies
@ie.checkBox(:id, "Frame RelayTECHNOLOGIES").click
# @ie.checkBox(:id, "IVPN CPETECHNOLOGIES").click
@ie.radio(:id, "2_answer").set
# User moves to AME Page
@ie.link(:id, "next").click
# User adds a Local Access
@ie.link(:text, "ADD NEW...").click
@ie.link(:text, "LOCAL ACCESS").click
ie2 = IE.attach(:title, "Local Access")
ie2.selectBox( :name , "loopType").select("Access Link")
ie2.selectBox( :name , "loopSitesAvailable").select("001-TX-AUS")
ie2.selectBox( :name , "loopSitesAvailable").select("002-TX-DAL")
ie2.image(:src , /ps_transferto_button.gif/).click
ie2.image(:src , /ps_save_button.gif/).click
assert(@ie.contains_text('Technology: Access Link - 1.5 Mbps '))
assert( @ie.image(:src , /ps_icon_local_loop.gif/).exists? )
# User adds a port
@ie.link(:text, "ADD NEW...").click
@ie.link(:text, "PORT").click
ie2 = IE.attach(:title, "Port")
ie2.selectBox( :name , "portLoop").select("local access 0")
ie2.selectBox( :name , "portType").select("myport")
ie2.selectBox( :name , "portSitesAvailable").select("001-TX-AUS")
ie2.selectBox( :name , "portSitesAvailable").select("002-TX-DAL")
ie2.image(:src , /ps_transferto_button.gif/).click
ie2.image(:src , /ps_save_button.gif/).click
assert(@ie.contains_text('myPort '))
assert( @ie.image(:src , /ps_icon_local_loop_with_port.gif/).exists? )
# User adds a connection
@ie.link(:text, "ADD NEW...").click
@ie.link(:text, "CONNECTION").click
ie2 = IE.attach(:title, "Connection")
sleep 2
ie2.selectBox( :name , "connPort1").select("port 0")
ie2.selectBox( :name , "connSitesAvailable1").select("001-TX-AUS")
ie2.image(:src , /ps_transferto_button/).click
ie2.selectBox( :name , "connPort2").select("port 0")
ie2.selectBox( :name , "connSitesAvailable2").select("002-TX-DAL")
ie2.link(:url, /connSitesAvailable2/).click
ie2.selectBox( :name , "Bandwidth").select("256.0 kbps")
ie2.selectBox( :name , "connType").select("Standard 256kbps")
ie2.image(:src , /ps_save_button.gif/).click
assert(@ie.contains_text('Standard 256kbps'))
assert( @ie.image(:src , /ps_icon_local_loop_with_port_and_connection.gif/).exists? )
# User moves to Solution Status Page
@ie.link(:id, "next").click
# User moves to Recommedations Page
@ie.link(:id, "next").click
# User moves to Compare Services Page
@ie.link(:id, "next").click
# User moves to General options Page
@ie.link(:id, "next").click
# User moves to Per Site Options Page
@ie.link(:id, "next").click
# User moves to Proposed Solution Page
@ie.link(:id, "next").click
# User saves the solution
@ie.link(:title, "Suspend and save this solution...").click
# # User logouts out of the application
startClicker("OK" , 3) # click the OK button after 3 seconds
sleep 3
@ie.link(:text, "Logout").click
# Closing Browser instance
@ie.close
#
end
end


Here is what the new code looks like:


# Script is designed to execute ATM Smoke test test cases
#
#
#Initials Date Summary
#CLS 10/04/05 Checked in first draft
#CLS 12/02/05 Clean up/Site Selection code
#CLS 08/31/07 Refactored code
#List of to do's or ideas for improvement
#
# BEGIN -
#includes:
require 'watir' # the watir controller
require "rexml/document"
require "date"
require '/apps/ruby/lib/ruby/1.8/test/unit'
require '/apps/ruby/lib/ruby/1.8/test/unit/ui/console/testrunner'
require 'watir/testUnitAddons'
require 'watir/WindowHelper'
require '/SCPTTest/test/Functional/Project1'
include REXML
include Watir
include Project1
include Navigation
puts "## Begin Test - Test1"
puts "## Executes Test cases on SmokeTest Plan"
class Refactor < Test::Unit::TestCase
def test1
@ie = IE.new
@ie.goto("http://localhost:8080/scp/index.jsp")
Login("42","42")
# Prime modes - DN, LD, DIA
# Seconday modes - guidedDIA_mode, advDIA_mode, guidedLD_mode, advLD_mode, guidedDN_mode, advDN_mode
selectAccountModules("Ace Marketing","DNX_ATM_XX","DN","advDN_mode")
selectSites("Dallas Office","Houston Office")
deselectTechnology("Frame RelayTECHNOLOGIES","2_answer")
addAccess("Access Link - 1.5 Mbps","Dallas Office","Houston Office","BOB")
addPort("Port -.536 Mbps:UNI","Dallas Office","Houston Office","BOB")
addConnection("Dallas Office","Houston Office","256.0 kbps","Standard 256kbps","BOB")
quickNavigation()
logout()
end
end

Here are the methods in the module:


# This module provides access to the various data sources used by RPA
# It is designed to make it easier to write RPA functional tests

# Most of the information we need to test RPA is in XML files,
# This module uses REXML to parse the XML.
# REXML is available at http://www.germane-software.com/software/rexml/
require 'watir' # the watir controller
require "rexml/document"
require "date"
require '/apps/ruby/lib/ruby/1.8/test/unit'
require '/apps/ruby/lib/ruby/1.8/test/unit/ui/console/testrunner'
require 'watir/testUnitAddons'
require 'watir/WindowHelper'
require '/projectpath/test/Functional/Project1'
include REXML
include Watir
# This is a module, which can be used Ruby applications and tests.
# To make this module available to your test, add two lines to the file:
# require "Project2"
# include Project2
# There is no need for the test to require or include REXML.
module Project2
require 'watir'
include Watir
# The CatalogData class loads, parses and provides access to the
# PowerSeller catalog XML file, which is how out-of-the-box stores
# product information
class CatalogData
#The constructor for CatalogData takes two strings:
# - scp_dir: the directory where Project2 is installed
# - file: the name of the catalog file, usually 'devCatalogSupplement.xml'
#It creates a REXML Document and assigns it to the instance variable @catalogDoc
def initialize(scp_dir, file)
catalogFile = File.new(scp_dir + "/data/" + file)
@catalogDoc = Document.new catalogFile
end
#Takes a string id, and returns the catalog item with that id, if it
#exists - nil otherwise.
def getItemById(id)
@catalogDoc.elements["catalog/catalogData/item[@id=" + id + "]"]
end
#Returns the string value of the name of the catalog
def getItemName(item)
item.elements["name"].text
end
#Takes a plan element and returns an attribute by Id
def getItemAttributeById(item,id)
item.elements["attributeValue[@attributeId=" + id + "]"]
end
#Takes a plan element and returns the contained price element
def getPlanPriceData(plan)
priceInfo = plan.elements["attributeValue[@attributeId='108']"].cdatas[0].to_s
priceDoc = Document.new priceInfo
end
#Takes a plan and term, and returns a Hash of the pricing info for that plan
#at that term (in months) for the default price sheet
def getTermPrice(plan,term)
priceDoc = getPlanPriceData(plan)
termPriceElement = priceDoc.elements["price/price/dateRange/term[@length=" + term.to_s + "]/discountable"]
termPrice = {"mrc" => termPriceElement.attributes["mrc"].to_f,"nrc" => termPriceElement.attributes["nrc"].to_f }
end
#Takes a string id and returns the string name of that provider
def getProviderById(id)
@catalogDoc.elements["catalog/catalogData/provider[@id=" + id + "]"]
end
end
class Currency
def initialize(float)
@value = float
end
def to_s
currency = @value.to_s
s = sprintf( "%3.2f", currency )
return "$" + s
end
end
# The Table class provides convenience methods for accessing data in
# WATIR tables
class Table
#The constructor for Table takes a WATIR table and
# assigns it to the instance variable @table
def initialize(table)
@table = table
end
#Takes a string and two integers. Returns the contents of
# the table cell at the index of the second integer for the
# row where the string is in the cell at the index of the
# first integer.
# Example: myTable.assoc("findMe",2,4) finds the row of
# the table where the text "findMe" is in the second column,
# and returns the contents of the 4th column
def assoc(text,rowFinder,targetCell)
@table.each { row
if row[rowFinder].to_s.include? text
return row[targetCell].to_s
end
}
return nil
end
def printPretty()
rows = 0
@table.each { row
rows += 1
puts "row " + rows.to_s + ":"
print "\t"
cells = 0
row.each { cell
cells += 1
print "cell " + cells.to_s + ": [" + cell.to_s + "]\t"
}
print "\n"
}
puts "-----------------------------------------------------------------------------------------"
end
end
# This module is intended to provide generic methods for navigation through the PowerSeller application
module Navigation
def startClicker( button , waitTime = 3)
w = WinClicker.new
longName = @ie.dir.gsub("/" , "\\" )
shortName = w.getShortFileName(longName)
c = "start rubyw #{shortName }\\watir\\clickJSDialog.rb #{button } #{ waitTime} "
puts "Starting #{c}"
w.winsystem(c)
w=nil
#assert_same(expected, actual, [message] ) #Expects expected.equal?(actual)
end
#Login for any PowerSeller application
def scpLogin(user,password)
assert(@ie.text_field(:id, "Person.username").exists?)
assert(@ie.text_field(:id, "Person.password").exists?)
# puts "my first variable is " + user
# puts "my second variable is " + password
@ie.text_field(:name, "Person.username").set(user)
@ie.text_field(:name, "Person.password").set(password)
@ie.link(:id, "loginButton").click
end
# Select account and modules
def selectAccountModules(account,solutionName,primemode,secmode)
@ie.image(:src , /ps_header_module_solution_builder_iconUp.gif/).click
@ie.selectBox( :name , "NS_Account").select(account)
@ie.text_field(:name, "NS_Title").set(solutionName)
@ie.checkBox(:id, primemode).set
assert(@ie.checkbox(:id, primemode).isSet?)
@ie.radio(:id, secmode).set
assert(@ie.radio(:id, secmode).isSet?)
@ie.link(:id, "next").click
assert(@ie.contains_text(solutionName))
@ie.link(:id, "next").click
end
#Select sites
def selectSites(site1,site2)
startClicker("OK" , 5)
@ie.image(:id, "selectAllButton").click
assert( @ie.cell(:id, site1).exists? )
@ie.cell(:id, site1).checkbox(:index,1).set
@ie.cell(:id, site2).checkbox(:index,1).set
@ie.link(:id, "next").click
end
def selectFiveSites()
mydata.length
startClicker("OK" , 5)
@ie.image(:id, "selectAllButton").click
assert( @ie.cell(:id, site1).exists? )
@ie.cell(:id, site1).checkbox(:index,1).set
@ie.cell(:id, site2).checkbox(:index,1).set
@ie.cell(:id, site3).checkbox(:index,1).set
@ie.cell(:id, site4).checkbox(:index,1).set
@ie.cell(:id, site5).checkbox(:index,1).set
@ie.link(:id, "next").click
end
def deselectSites(site1,site2)
@ie.link(:id, "back").click
assert(@ie.cell(:id, site1).checkbox(:index,1).isSet?)
assert(@ie.cell(:id, site2).checkbox(:index,1).isSet?)
@ie.cell(:id, site1).checkbox(:index,1).clear
assert_false(@ie.cell(:id, site1).checkbox(:index,1).isSet?)
@ie.cell(:id, site2).checkbox(:index,1).clear
assert_false(@ie.cell(:id, site2).checkbox(:index,1).isSet?)
end
def toggleTermButtons()
assert(@ie.radio(:id, "36ContractTerm").isSet?)
@ie.radio(:id, "12ContractTerm").set
assert(@ie.radio(:id, "12ContractTerm").isSet?)
@ie.radio(:id, "1ContractTerm").set
assert(@ie.radio(:id, "1ContractTerm").isSet?)
assert_false(@ie.radio(:id, "24ContractTerm").isSet?)
@ie.radio(:id, "24ContractTerm").set
assert(@ie.radio(:id, "24ContractTerm").isSet?)
assert_false(@ie.radio(:id, "12ContractTerm").isSet?)
end
# DIA Needs Analysis pages for guided mode
def diaAnalysis()
@ie.link(:id, "next").click
@ie.link(:id, "next").click
end
def diaPreferences(tech1)
# @ie.checkBox(:id, tech1).click
@ie.link(:id, "next").click
end
def deselectTechnology(tech1,premier)
@ie.checkBox(:id, tech1).click
@ie.radio(:id, premier).set
@ie.link(:id, "next").click
end
def selectNVPN(tech1)
@ie.checkBox(:id, tech1).click
@ie.link(:id, "next").click
end
def selectDefaultTechnologies()
@ie.link(:id, "next").click
end
def addAccess(access,site1,site2,assert)
@ie.link(:text, "ADD NEW...").click
sleep 2
@ie.link(:text, "LOCAL ACCESS").click
sleep 2
ie2 = IE.attach(:title, "Local Access")
ie2.selectBox( :name , "loopType").select(access)
ie2.selectBox( :name , "loopSitesAvailable").select(site1)
ie2.selectBox( :name , "loopSitesAvailable").select(site2)
ie2.image(:src , /ps_transferto_button.gif/).click
ie2.image(:src , /ps_save_button.gif/).click
sleep 4
assert(@ie.contains_text(assert))
# assert( @ie.image(:src , /ps_icon_local_loop.gif/).exists? )
end
def addPort(port,site1,site2,assert)
@ie.link(:text, "ADD NEW...").click
sleep 2
@ie.link(:text, "PORT").click
sleep 2
ie2 = IE.attach(:title, "Port")
ie2.selectBox( :name , "portLoop").select("local access 0")
ie2.selectBox( :name , "portType").select(port)
ie2.selectBox( :name , "portSitesAvailable").select(site1)
ie2.selectBox( :name , "portSitesAvailable").select(site2)
ie2.image(:src , /ps_transferto_button.gif/).click
ie2.image(:src , /ps_save_button.gif/).click
sleep 2
assert(@ie.contains_text(assert))
assert( @ie.image(:src , /ps_icon_local_loop_with_port.gif/).exists? )
end
def addServicePlan(domestic,mac,international,site1,site2,assert1,assert2)
@ie.link(:text, "ADD NEW...").click
@ie.link(:text, "SERVICE PLAN").click
ie2 = IE.attach(:title, "Service Plan")
ie2.selectBox( :name , "servicePort").select("port 0")
ie2.selectBox( :name , "domesticServiceType").select(domestic)
ie2.selectBox( :name , "domesticServiceMacLevel").select(mac)
ie2.selectBox( :name , "internationalServiceType").select(international)
ie2.selectBox( :name , "internationalServiceMacLevel").select(">= 0")
ie2.selectBox( :name , "serviceSitesAvailable").select(site1)
ie2.selectBox( :name , "serviceSitesAvailable").select(site2)
ie2.image(:src , /ps_transferto_button.gif/).click
ie2.image(:src , /ps_save_button.gif/).click
assert(@ie.contains_text(assert1))
assert(@ie.contains_text(assert2))
# assert( @ie.image(:src , /ps_icon_local_loop_with_port.gif/).exists? )# User moves to Solution Status Page
end
def addConnection(site1,site2,speed,connection,assert)
@ie.link(:text, "ADD NEW...").click
sleep 2
@ie.link(:text, "CONNECTION").click
sleep 2
ie2 = IE.attach(:title, "Connection")
ie2.selectBox( :name , "connPort1").select("port 0")
ie2.selectBox( :name , "connSitesAvailable1").select(site1)
ie2.image(:src , /ps_transferto_button/).click
ie2.selectBox( :name , "connPort2").select("port 0")
ie2.selectBox( :name , "connSitesAvailable2").select(site2)
ie2.link(:url, /connSitesAvailable2/).click
ie2.selectBox( :name , "Bandwidth").select(speed)
ie2.selectBox( :name , "connType").select(connection)
ie2.image(:src , /ps_save_button.gif/).click
sleep 2
assert(@ie.contains_text(assert))
assert( @ie.image(:src , /ps_icon_local_loop_with_port_and_connection.gif/).exists? )
end
def addProductBundle(bundletype,bundle,site1,site2,assert)
@ie.link(:text, "ADD NEW...").click
@ie.link(:text, "PRODUCT BUNDLE").click
sleep 10
ie2 = IE.attach(:title, "Product Bundle")
assert(ie2.selectBox(:name, "bundleType").exists?)
assert(ie2.selectBox(:name, "bundleType").enabled?)
ie2.selectBox( :name , "bundleType").select(bundletype)
ie2.selectBox( :name , "bundleItem").select(bundle)
ie2.selectBox( :name , "bundleSitesAvailable").select(site1)
ie2.selectBox( :name , "bundleSitesAvailable").select(site2)
ie2.image(:src , /ps_transferto_button.gif/).click
ie2.image(:src , /ps_save_button.gif/).click
sleep 4
assert(@ie.contains_text(assert))
assert( @ie.image(:src , /ps_icon_local_loop_with_port_and_connection.gif/).exists? )
end
def quickNavigation()
@ie.link(:id, "next").click
@ie.link(:id, "next").click
@ie.link(:id, "next").click
@ie.link(:id, "next").click
@ie.link(:id, "next").click
@ie.link(:id, "next").click
@ie.link(:title, "Suspend and save this solution...").click
end
def diaNavigation()
@ie.link(:id, "next").click
@ie.link(:id, "next").click
sleep 2
@ie.checkBox(:id, "sol_0").click
@ie.link(:id, "next").click
@ie.link(:id, "next").click
@ie.link(:id, "next").click
@ie.link(:id, "next").click
@ie.link(:id, "next").click
@ie.link(:title, "Suspend and save this solution...").click
end
def logout()
startClicker("OK" , 3) # click the OK button after 3 seconds
sleep 3
@ie.link(:text, "Logout").click
@ie.close
end
end
end

If you have questions please let me know.

No comments: