If you want to speed up running your Watir tests, one easy way is to use PsExec. With this utility you can start browsers using different users.
To run a Ruby script using PsExec:
psexec.exe -w . -i -d -u <uname> -p <pwd> "myrubyscript.rb"
Wednesday, May 18, 2011
Iframes
For testing pages with iframes, I would suggest using watir-webdriver. It has better support for iframes than Watir.
To access an element in an iframe:
Watir-webdriver driver has some good methods for waiting:
.when_present.set - do something when element is present
.wait_until_present - wait until element is present
.wait_while_present - wait until element disappears
To change focus back to main page from an iframe:
If you are using Google Chrome, you might have problems with text fields. To enter a value in a text field, try:
$ie.frame(:id, 'iframe').text_field(:id, 'mytextfield').set "abcdef"
$ie.frame(:id, 'iframe').text_field(:id, 'mytextfield').set("abcdef")
To access an element in an iframe:
$ie.frame(:id, 'iframe').text_field(:id, 'mytextfield').when_present.set "hello"
Watir-webdriver driver has some good methods for waiting:
.when_present.set - do something when element is present
.wait_until_present - wait until element is present
.wait_while_present - wait until element disappears
To change focus back to main page from an iframe:
$ie.frame(:index, 0).locate
If you are using Google Chrome, you might have problems with text fields. To enter a value in a text field, try:
$ie.frame(:id, 'iframe').text_field(:id, 'mytextfield').set "abcdef"
$ie.frame(:id, 'iframe').text_field(:id, 'mytextfield').set("abcdef")
Friday, May 6, 2011
Some text parsing examples
If a page contains e.g. user information in a format:
an easy way to get the name is:
Another way is to:
Name: John
Gender: Male
...an easy way to get the name is:
$name = $ie.text.slice(Regexp.new('Name: .*?$')).sub("Name: ","")
Another way is to:
$firstarray = $ie.html.split("Name: ")
$secondarray = $firstarray[1].split(/<br>/)
$name = $secondarray[0]
Wednesday, May 4, 2011
UTF-8 characters in input fields
I haven't been able to write utf-8 characters to input fields using Watir. If anybody has, please comment!
For testing UTF-8 characters in input fields, I've created a small PHP script that:
1. Gets the web page.
2. Inserts UTF-8 string to input field value.
3. Displays the page.
Here is an example of the PHP script:
# proxy / url parameters
$proxyName = "proxy.com";
$proxyPort = "8080";
$requestURL = "http://mysite.com"
# create a new cURL resource
$ch = curl_init();
# set URL and other options
curl_setopt($ch, CURLOPT_PROXY, $proxyName);
curl_setopt($ch, CURLOPT_PROXYPORT, $proxyPort);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
curl_setopt($ch, CURLOPT_URL, $requestUrl);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
# pass request
$htmlSource = curl_exec($ch);
# close cURL resource, and free up system resources
curl_close($ch);
# e.g. add / replace input field value with utf-8 string
$htmlSource = ereg_replace($replacethis,$replacewith,$htmlSource);
echo $htmlSource
For testing UTF-8 characters in input fields, I've created a small PHP script that:
1. Gets the web page.
2. Inserts UTF-8 string to input field value.
3. Displays the page.
Here is an example of the PHP script:
# proxy / url parameters
$proxyName = "proxy.com";
$proxyPort = "8080";
$requestURL = "http://mysite.com"
# create a new cURL resource
$ch = curl_init();
# set URL and other options
curl_setopt($ch, CURLOPT_PROXY, $proxyName);
curl_setopt($ch, CURLOPT_PROXYPORT, $proxyPort);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
curl_setopt($ch, CURLOPT_URL, $requestUrl);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
# pass request
$htmlSource = curl_exec($ch);
# close cURL resource, and free up system resources
curl_close($ch);
# e.g. add / replace input field value with utf-8 string
$htmlSource = ereg_replace($replacethis,$replacewith,$htmlSource);
echo $htmlSource
Checking for UTF-8 characters / texts
If you need to check for texts containing UTF-8 characters using Watir. You need to include following lines to your test script:
... and your script file should be UTF-8 encoded without BOM.
require "win32ole"
WIN32OLE.codepage = WIN32OLE::CP_UTF8
... and your script file should be UTF-8 encoded without BOM.
Check for javascript pop-ups
Pop-up handling is not very good in Watir. Here is just one example that checks if a javascript pop-up exist, and if it exists, it closes the browser and pop-up:
# check if javascript pop-up was found
# if pop-up was found, close browser and pop-ups
system("taskkill /T /F /IM iexplore.exe /FI \"USERNAME eq "+$u+"\"")
end
# check if javascript pop-up was found
require 'watir\ie'
require 'watir\contrib\enabled_popup'
$popup = $ie.enabled_popup(1);
require 'watir\contrib\enabled_popup'
$popup = $ie.enabled_popup(1);
# if pop-up was found, close browser and pop-ups
if ($popup)
$u = ENV['USERNAME'] system("taskkill /T /F /IM iexplore.exe /FI \"USERNAME eq "+$u+"\"")
end
How to make sure that all browser windows are closed ...
$u = ENV['USERNAME']
system("taskkill /T /F /IM iexplore.exe /FI \"USERNAME eq "+$u+"\"")
system("taskkill /T /F /IM firefox.exe /FI \"USERNAME eq "+$u+"\"")
system("taskkill /T /F /IM chrome.exe /FI \"USERNAME eq "+$u+"\"")
system("taskkill /T /F /IM firefox.exe /FI \"USERNAME eq "+$u+"\"")
system("taskkill /T /F /IM chrome.exe /FI \"USERNAME eq "+$u+"\"")
Using parameters in regular expressions
Here is an example on how to use parameters in a regular expression:
if not checkintext.match(/(#{checkfortxt})/)
raise "Text '" + checkfortxt + "' not found!"
end
raise "Text '" + checkfortxt + "' not found!"
How to close browser pop-ups
Easiest way to close IE browser pop-ups (not javascript) is to use AutoIt. Here is an example:
autoit = WIN32OLE.new('AutoItX3.Control')
autoit.ControlClick("Windows Internet Explorer",'', 'OK')
autoit.ControlClick("Security Information",'', '&Yes')
autoit.ControlClick("Security Alert",'', '&Yes')
autoit.ControlClick("Security Warning",'', 'Yes')
autoit.ControlClick("Message from webpage",'', 'OK')
autoit = WIN32OLE.new('AutoItX3.Control')
autoit.ControlClick("Windows Internet Explorer",'', 'OK')
autoit.ControlClick("Security Information",'', '&Yes')
autoit.ControlClick("Security Alert",'', '&Yes')
autoit.ControlClick("Security Warning",'', 'Yes')
autoit.ControlClick("Message from webpage",'', 'OK')
Sending HTTP requests and headers
Here is the first example on how to send extra HTTP headers in a HTTP request and then checking the response. In this example Cookie header is sent in a GET request:
require "net/http"
require "net/https"
require "uri"
# HTTP GET without proxy and SSL
res = Net::HTTP.start($host, 80) {|http|
http.get2('/mysite/index.html',{'Cookie' => $cookie})
}
# HTTP GET with proxy, but without SSL
http = Net::HTTP::Proxy($proxyhost, $proxyport).new($host, 80)
res = http.get2('/mysite/index.html',{'Cookie' => $cookie})
# HTTP GET with proxy and SSL
http = Net::HTTP::Proxy($proxyhost, $proxyport).new($host, 443)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
res = http.get2('/mysite/index.html',{'Cookie' => $cookie})
# HTTP response body
$httpresponse = res.body
Here is the second example on how to send HTTP requests and checking the response:
response = sendHttpRequest $myurl,$mypostdata,{'Cookie' => 'xxx'}
puts "Response code:\n" + response[:code].to_s
puts "Response code description:\n" + response[:name].to_s
puts "Response body:\n" + response[:body].to_s
puts "Response headers:\n"+response[:headers].to_s
def sendHttpRequest requrl, postdata=nil, headers=nil
proxyhost = "xxx"
proxyport = "yyy"
url = URI.parse(requrl)
resheaders=""
myurl = "/"
if (not (url.path == nil or url.path == ""))
myurl = url.path
end
if (not (url.query == nil or url.query == ""))
myurl = myurl+"?"+url.query
end
if (not (url.fragment == nil or url.fragment == ""))
myurl = myurl+"#"+url.fragment
end
ht = Net::HTTP.Proxy(proxyhost, proxyport).new(url.host, url.port)
if (requrl.to_s.include? "https")
ht.use_ssl = true
ht.verify_mode = OpenSSL::SSL::VERIFY_NONE
else
ht.use_ssl = false
end
begin
ht.start
rescue
sleep 5
ht.start
end
if (postdata.to_s == "nil" || postdata.to_s == "")
if (headers.to_s == "nil") or (headers.to_s == "")
res,datax = ht.request_get(myurl)
else
res,datax = ht.request_get(myurl,headers)
end
ht.finish
res.each_header() { |key,value| resheaders=resheaders+key+": "+value+"\n" }
return {:name => res.class, :code => res.code, :body => datax, :headers => resheaders}
end
if (headers.to_s == "nil") or (headers.to_s == "")
res,datax = ht.request_post(myurl, postdata)
else
res,datax = ht.request_post(myurl, postdata,headers)
end
ht.finish
res.each_header() { |key,value| resheaders=resheaders+key+": "+value+"\n" }
return {:name => res.class, :code => res.code, :body => datax, :headers => resheaders}
end
require "net/http"
require "net/https"
require "uri"
# HTTP GET without proxy and SSL
res = Net::HTTP.start($host, 80) {|http|
http.get2('/mysite/index.html',{'Cookie' => $cookie})
}
# HTTP GET with proxy, but without SSL
http = Net::HTTP::Proxy($proxyhost, $proxyport).new($host, 80)
res = http.get2('/mysite/index.html',{'Cookie' => $cookie})
# HTTP GET with proxy and SSL
http = Net::HTTP::Proxy($proxyhost, $proxyport).new($host, 443)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
res = http.get2('/mysite/index.html',{'Cookie' => $cookie})
# HTTP response body
$httpresponse = res.body
Here is the second example on how to send HTTP requests and checking the response:
response = sendHttpRequest $myurl,$mypostdata,{'Cookie' => 'xxx'}
puts "Response code:\n" + response[:code].to_s
puts "Response code description:\n" + response[:name].to_s
puts "Response body:\n" + response[:body].to_s
puts "Response headers:\n"+response[:headers].to_s
def sendHttpRequest requrl, postdata=nil, headers=nil
proxyhost = "xxx"
proxyport = "yyy"
url = URI.parse(requrl)
resheaders=""
myurl = "/"
if (not (url.path == nil or url.path == ""))
myurl = url.path
end
if (not (url.query == nil or url.query == ""))
myurl = myurl+"?"+url.query
end
if (not (url.fragment == nil or url.fragment == ""))
myurl = myurl+"#"+url.fragment
end
ht = Net::HTTP.Proxy(proxyhost, proxyport).new(url.host, url.port)
if (requrl.to_s.include? "https")
ht.use_ssl = true
ht.verify_mode = OpenSSL::SSL::VERIFY_NONE
else
ht.use_ssl = false
end
begin
ht.start
rescue
sleep 5
ht.start
end
if (postdata.to_s == "nil" || postdata.to_s == "")
if (headers.to_s == "nil") or (headers.to_s == "")
res,datax = ht.request_get(myurl)
else
res,datax = ht.request_get(myurl,headers)
end
ht.finish
res.each_header() { |key,value| resheaders=resheaders+key+": "+value+"\n" }
return {:name => res.class, :code => res.code, :body => datax, :headers => resheaders}
end
if (headers.to_s == "nil") or (headers.to_s == "")
res,datax = ht.request_post(myurl, postdata)
else
res,datax = ht.request_post(myurl, postdata,headers)
end
ht.finish
res.each_header() { |key,value| resheaders=resheaders+key+": "+value+"\n" }
return {:name => res.class, :code => res.code, :body => datax, :headers => resheaders}
end
Tuesday, May 3, 2011
Screenshots
Watir has some built in functions for taking screenshots, but they are not very good. The best way to take screenshots is by using SnagIt.
Here is an example function for taking screenshots by using SnagIt. This function is also capable of taking screenshots of invisible windows:
def screencapture fname
snagit = WIN32OLE.new('Snagit.ImageCapture')
visibilityState=$ie.getIE.Visible
$ie.getIE.Visible = true
$ie.bring_to_front
$ie.maximize
snagit.Input = 1 #window
snagit.Output = 2 #file
snagit.InputWindowOptions.XPos = 350
# select XPosition for window ID
snagit.InputWindowOptions.YPos = 350
# select YPosition for window ID
snagit.InputWindowOptions.SelectionMethod = 3
# capture window under the X, Y point specified above.
snagit.AutoScrollOptions.StartingPosition = 3
# set scroll to top and left
snagit.OutputImageFile.FileType = 5 #:png
snagit.OutputImageFile.FileNamingMethod = 1 # fixed
tempStoragePath="c:\\screenshot\\"
if (! File::exists?( tempStoragePath ))
tempStoragePath=Dir.pwd+"//screenshot//"
if (! File::exists?( tempStoragePath ))
Dir.mkdir tempStoragePath
end
end
snagit.OutputImageFile.Directory = tempStoragePath
snagit.OutputImageFile.Filename = fname
snagit.AutoScrollOptions.AutoScrollMethod = 0
snagit.Capture
# wait for capture to complete
until snagit.IsCaptureDone do
sleep 0.5
end
$ie.getIE.Visible = visibilityState
end
If you don't have SnagIt installed, then another easy way to take screenshots is by using PHP.
For example, create following PHP file:
<?php
if(!isset($argv[1]))
{
echo "Image not specified!";
exit;
}
else
$image = $argv[1];
$imagefile = "c://".$image.".png";
$im = imagegrabscreen();
imagepng($im, $imagefile);
imagedestroy($im);
?>
... and then, for example, following Ruby function:
def screencapture fname
cmd = 'PHP.exe C:\\screenshot.php ' + fname
puts %x{#{cmd}}
sleep 8
end
Here is an example function for taking screenshots by using SnagIt. This function is also capable of taking screenshots of invisible windows:
def screencapture fname
snagit = WIN32OLE.new('Snagit.ImageCapture')
visibilityState=$ie.getIE.Visible
$ie.getIE.Visible = true
$ie.bring_to_front
$ie.maximize
snagit.Input = 1 #window
snagit.Output = 2 #file
snagit.InputWindowOptions.XPos = 350
# select XPosition for window ID
snagit.InputWindowOptions.YPos = 350
# select YPosition for window ID
snagit.InputWindowOptions.SelectionMethod = 3
# capture window under the X, Y point specified above.
snagit.AutoScrollOptions.StartingPosition = 3
# set scroll to top and left
snagit.OutputImageFile.FileType = 5 #:png
snagit.OutputImageFile.FileNamingMethod = 1 # fixed
tempStoragePath="c:\\screenshot\\"
if (! File::exists?( tempStoragePath ))
tempStoragePath=Dir.pwd+"//screenshot//"
if (! File::exists?( tempStoragePath ))
Dir.mkdir tempStoragePath
end
end
snagit.OutputImageFile.Directory = tempStoragePath
snagit.OutputImageFile.Filename = fname
snagit.AutoScrollOptions.AutoScrollMethod = 0
snagit.Capture
# wait for capture to complete
until snagit.IsCaptureDone do
sleep 0.5
end
$ie.getIE.Visible = visibilityState
end
If you don't have SnagIt installed, then another easy way to take screenshots is by using PHP.
For example, create following PHP file:
<?php
if(!isset($argv[1]))
{
echo "Image not specified!";
exit;
}
else
$image = $argv[1];
$imagefile = "c://".$image.".png";
$im = imagegrabscreen();
imagepng($im, $imagefile);
imagedestroy($im);
?>
... and then, for example, following Ruby function:
def screencapture fname
cmd = 'PHP.exe C:\\screenshot.php ' + fname
puts %x{#{cmd}}
sleep 8
end
Monday, May 2, 2011
Cookies
How to get all cookies for the current domain:
puts $ie.document.cookie
How to get value of a specific cookie:
How to delete all cookies:
require "fileutils"
cookieDir = "C:\\Documents and Settings\\#{ENV['USERNAME']}\\Cookies"
FileUtils.rm_rf cookieDir
NOTE! These examples only work for IE!
Check e.g. from here how to manage cookies in Firefox ...
puts $ie.document.cookie
How to get value of a specific cookie:
$carray = $ie.document.cookie.split(';')
$carray.length.times do |i|
if /MyCookie/.match($carray[i])
$cookieval = $carray[i]
$cvalarray = $cookieval.split('=')
$cookieval = $cvalarray[1]
end
$carray.length.times do |i|
if /MyCookie/.match($carray[i])
$cookieval = $carray[i]
$cvalarray = $cookieval.split('=')
$cookieval = $cvalarray[1]
end
end
puts $cookieval
How to delete all cookies:
require "fileutils"
cookieDir = "C:\\Documents and Settings\\#{ENV['USERNAME']}\\Cookies"
FileUtils.rm_rf cookieDir
NOTE! These examples only work for IE!
Check e.g. from here how to manage cookies in Firefox ...
Subscribe to:
Posts (Atom)