Originally reported on Rubyforge:
http://rubyforge.org/tracker/index.php?func=detail&aid=1666&group_id=104&atid=490
> I may not use this directly, but its gien me som eideas for a new
> method in watir - generate_template Which would do sort of what you
> have for each page maybe something like
> this:
>
> Ie.goto('google.com')
> Ie.generate_template
>
> this would then print something like:
> # Objects
> # ie.text_field(:name, 'q').?????
> # ie.button(:value , 'Search').???
> # ie.button(:value , 'Im Feeling Lucky').???
>
> # Links
> # ie.link(:text, "web").???
> # etc
>
> You could then navigate through your site normally collecting
> templates as you go, and then fill in the bits you need later
>
This script is from John LLoyd Jones
Sorry it took so long. The script below is a pretty rough hack, but it does the job. We have some pretty complex pages,
and this really save lots of typing. It contains some assumptions that may not apply in
general: 1) all input fields have ids (true for me because the custom JSP tags force it ) 2) ids here are structured
(e.g.
customer.address.street) and mostly, the last bit is the interesting part. Anyway, the basic recursive descent stuff
can be recycled even if you change the details.
#-------------------------------------------------------------------------------------------------------------#
#
# Generate WATIR script
# #------------------------------------------------------------------------------------------------------------#
#includes:
require 'ftools'
require 'watir' # the watir controller
include Watir
class generate_test
#variables:
def initialize
@testSite = '
http://localhost:7001/app/' # Change this as required
if ARGV[0]
@testLink = ARGV[0]
else
$stderr.print "Please give a URL to process\n"
exit 1
end
name = @testLink.scan(/[\w\-\d:\\]+(?=\.do|\.html)/).to_s
@scriptname = name + ".rb"
puts "script name is #{@scriptname}"
@hashString = ""
@testString = ""
@formString = ""
@script = File.new(@scriptname, File::CREAT | File::TRUNC | File::RDWR);
$stderr.print "Writing script to #{@scriptname}\n"
@script.print "# Automatically generated WATIR script from url \"" + @testLink +
"\"\n"
end
def printScriptStart
header = <<EOH
#-------------------------------------------------------------------------------------------------------------#
#
# Simple WATIR autogenerated script
# Purpose: <NB! DOCUMENT THE PURPOSE NB!>
# * entering text into fields
# * clicking buttons
# * checking to see if a page contains text.
# Test will <DOCUMENT THIS SCRIPT>
# #------------------------------------------------------------------------------------------------------------#
#includes:
require 'watir' # the watir controller
include Watir
#variables:
testSite = "@{testSite}" # Change this if required
testURL = "#{@testLink}" # from the page name
EOH
@script.print header
end
def printPartTwo()
@script.print " puts \"Step 2: enter test data\"\n"
@script.print @testString
end
def printTestData
@script.print " # create test data \n"
@script.print " testData = {\n"
@script.print @hashString
@script.print " }\n\n"
end
def printPartOne
text = <<EOF
#open the IE browser
$ie = IE.new
puts "## Beginning of test"
puts " "
puts "Step 1: go to the test site: " + testSite
$ie.goto(testSite)
puts " Action: entered " + testSite + "in the address bar."
a = $ie.pageContainsText("One moment...")
# wait for the meta refresh
sleep 3
# Wait for the search page to come up
20.times {
sleep 1
a = $ie.pageContainsText("Customer #")
break if a
}
# Choose Add from the menu side bar
$ie.link(:url, testURL).click
EOF
@script.print text
end
def printPartThree()
submit = if @formString.length > 0 then @formString else " # $ie.button(:value,
\"Submit\").click" end
text = <<EOF
puts "Step 3: click the 'Save' button"
#{submit} # NB MODIFY THIS AS REQUIRED
puts " Action: clicked the Save button."
a = $ie.pageContainsText("Sample Text") # NB! YOU MUST MODIFY THIS TO MATCH YOUR RESULT PAGE
if a
puts " Test succeded\\n"
exit 0
else
puts " Test failed\\n"
exit 1
end
EOF
@script.print text
end
## addField add a has entry to testData and the appropraite code to set
## the field value for
def addField( node )
nodename = node.invoke("nodeName")
if nodename == 'INPUT' || nodename == 'SELECT' || nodename == 'TEXTAREA'
type = case nodename
when 'INPUT' then node.invoke("type")
else nodename.downcase
end
id = node.invoke("id")
tokens = id.to_s.split("\.") # NB May not be valid for most people
name = tokens[tokens.size-1] # modify this if it doesn't make sense for you
className = node.invoke("className")
puts "#{nodename} type=\"#{type}\" id=\"#{id}\"
class=\"#{className}\""
expr = case type
when "text" then " $ie.textField(:id,
\"#{id}\").set(testData['#{name}'])\n"
when "select" then " $ie.selectBox(:id,
\"#{id}\").select(testData['#{name}'])\n"
when "checkbox" then " if testData['#{name}'] ==
\"checked\"\n $ie.checkBox(:id, \"#{id}\").set\n else\n
$ie.checkBox(:id, \"#{id}\").clear\n end\n"
when "radio" then " $ie.checkBox(:id, \"#{id}\").set\n"
when "button" then " # $ie.button(:id, \"#{id}\").click\n"
when "hidden" then " # $ie.textField(:id,
\"#{id}\").set(testData['#{name}']) #hidden Field\n"
else "" # "# input id=#{id[0]} has type #{type}\n"
end
@hashString += "'#{name}' => \"\",\n" if name
@testString += expr
elsif nodename == "FORM"
id = node.invoke("id")
@formString = " $ie.form(:id, \"#{id}\").submit"
end
end
def parseChildren (elm)
children = elm.invoke("childNodes")
n = 0
while n < children.length
node = children[ n.to_s ]
parseChildren( node )
addField( node )
n = n + 1
end
end
def main
#open the IE browser
$ie = IE.new
puts "## Beginning of test"
puts " "
puts "Step 1: go to the test site: " + @testSite
$ie.goto(@testSite)
puts " Action: entered " + @testSite + "in the address bar."
a = $ie.pageContainsText("One moment...")
# wait for the meta refresh
sleep 3
# Wait for the search page to come up
a = $ie.pageContainsText("Customer #")
puts " Action: clicking on link " + @testLink
$ie.link(:url, @testLink).click
sleep 3
# a = $ie.pageContainsText("Date:")
puts " Action: parsing the page..."
body = $ie.getDocument().body
parseChildren (body)
printScriptStart
printTestData
printPartOne
printPartTwo
printPartThree
puts " Action: done."
end
end
if $0 == __FILE__
t = generate_test.new
t.main
end