follow me icons

Tuesday, September 28, 2010

Changing User-agent profile in firefox through Selenium Webdriver

Firefox has an add-on called user-agent switcher which is used to switch the browser user agent so that the server thinks the query comes from a mobile devices.

There are times when we need to be able to switch user agent automatically from the cucumber test. This is when we need to test that the apache config can redirect the site correctly to the mobile URL.

We can do this by overriding the default firefox user agent profile to use the required user agent. Firefox has an attribute called general.useragent.override which we can put any user agent profile that we want.

Below is the code on how to do it.

class Capybara::Driver::Selenium
def self.driver
unless @driver
profile = Selenium::WebDriver::Firefox::Profile.new

profile["general.useragent.override"]
= "Mozilla/5.0 (iPhone; U; CPU iPhone" +
" OS 3_0 like Mac OS X; en-us) AppleWebKit/528.18" +
"(KHTML, like Gecko) Version/4.0 Mobile/7A341 Safari/528.16"

@driver = Selenium::WebDriver.for(:firefox, :profile => profile)

at_exit do
@driver.quit
end
end
@driver
end
end



If you want to see all of the availables firefox profile that we can override, you can type the following command on the firefox URL text field "about:config".

Please see below for user agent settings for iPhone, iPad, Nokia, Android:

iPad_UA=Mozilla/5.0 (iPad; U; CPU OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B334b Safari/531.21.10

iPhone_UA=Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_0 like Mac OS X; en-us) AppleWebKit/528.18 (KHTML, like Gecko) Version/4.0 Mobile/7A341 Safari/528.16

N95_UA=Mozilla/5.0 (SymbianOS/9.2; U; Series60/3.1 NokiaN95/10.0.010; Profile/MIDP-2.0 Configuration/CLDC-1.1 ) AppleWebKit/413 (KHTML, like Gecko) Safari/413

LG-G850=LG-G850 V100 UP.Browser/6.2.2 (GUI) MMP/1.0 Profile/MIDP-1.0 Configuration/CLDC-1.0

ANDROD_EMULATOR=Mozilla/5.0 (Linux; U; Android 1.0; en-us; generic) AppleWebKit/525.10+ (KHTML, like Gecko) Version/3.0.4 Mobile Safari/523.12.2

X10_UA="Mozilla/5.0 (Linux; U; Android 1.6; en-gb; SonyEricssonX10i Build/R1FA016) AppleWebKit/528.5+ (KHTML, like Gecko) Version/3.1.2 Mobile Safari/525.20.1"

Monday, September 27, 2010

Adding Screenshot in cucumber html report

Cucumber has provided us a nice way to generate an HTML test report. We can simply run cucumber using the "-f html -out filename" to output the test result into the nicely formatted html report. It would be nice, however, to also automatically embed the failed scenario screenshot into the report as well. This is very useful if you want to run cucumber test in Hudson where you don't monitor how the test run and the log report is sometime not enough to determine whether the error is from the code or from a server error.

In the previous post about screenshot capture using capybara and webdriver, I have put the code on how to capture the screenshot by utilising the "After" hook method in cucumber. This time we will use the after hook as well as the at_exit method.


After do |scenario|

#need to write as a byte instead of IP#puts
if scenario.failed?
name = scenario.name.gsub!(' ', '').gsub!(/[\?\.\&=\-\/\\\(\),\'\"\|]/, '')
File.open("./build/publish/screenshots/#{name}.jpeg", 'wb') do |f|
f.write(Base64.decode64(page.driver.browser.screenshot_as(:base64)))
end
raise "lessthanimg src='screenshots/#{name}.jpeg' /greaterthan"
end
end


Notice that I have to deliberately raise an error in the code so that the img src code is thrown into the html report. Using the usual ruby "puts" will only print it to the console and not the report. I use the scenario.name for the file name and I have to replace the special characters into empty string to create a valid file name.

The other issues that I encountered is that cucumber actually converts "<" and ">" into "&lt" and "&gt". Therefore I have to replace it with "lessthanimg" and "/greaterthan".

That is why I have the "at_exit" code which is to replace the "lessthanimg" and "greaterthan" tags into "<" and ">".


at_exit do
ARGV.each do |a|
if a =~ /\.htm(l)?/
file = File.open(a, 'r')
new_file = ""
while (line = file.gets)
if line.match(/\lessthan/) and line.match(/greaterthan\<\/pre\>/)
new_file = new_file + line.gsub!(/\lessthan/, "<").gsub!(/greaterthan\<\/pre\>/, ">")
else
new_file = new_file + line
end
end
file.close

File.open(a, "w") do |f|
f.write(new_file)
end
end
end
end
I am sure that there should be an easier way to do this. But for now, I can only find this solution. Please feel free to add comments if someone has found an easier and more elegant way for this.

Sunday, September 26, 2010

Firefox Proxy configuration using Selenium Webdriver and Capybara



Quite often we have to run the automation test within the proxy setting. The default browser profile setup that Capybara use is the anonymous profile which does not use proxy setting by default. This will cause problem as the browser will not be able to access the webpage.

To see all of the available configuration in Firefox simply type "about:config" on the firefox address bar. You will then see the following screen:


One solution is to set the browser profile to use a proxy setting. The code can be placed inside the env.rb files to override the anonymous browser profile that Capybara uses.


# Need to override the driver to setup our proxy profile
class Capybara::Driver::Selenium
def self.driver
unless @driver
profile = Selenium::WebDriver::Firefox::Profile.new
profile["network.proxy.type"] = 1
profile["network.proxy.http"] = "proxy setting"
profile["network.proxy.http_port"] = 8080
@driver = Selenium::WebDriver.for(:firefox, :profile => profile)

at_exit do
@driver.quit
end
end
@driver
end
end


If you need to use the Automatic proxy configuration (pac file) URL then you would need to add the following line:

profile["network.proxy.autoconfig_url"]="proxy.pac"


And change the network.proxy.type into 2

profile["network.proxy.type"] = 1



If you need Capybara to use a different browser other than Firefox you can change the webdriver browser's profile. To change the default profile for other browsers you just need to change the @driver to use the browser that you want.

@driver = Selenium::WebDriver.for :ie
or
@driver = Selenium::WebDriver.for :chrome


Please note that webdriver currently only supports Firefox, IE and chrome.


Screenshots capture using capybara and webdriver

Recently, I stumble upon a task on how to automatically capture a screenshot when one of my cucumber scenario fails. I use capybara and webdriver for my automation test.

I found several solutions which include to use a program called scrot in ubuntu and to use another gem http://github.com/mocoso/cucumber-screenshot. However, I run my automation test in both Windows and Ubuntu and therefore I need a way to be able to capture screenshot in both OS.

Webdriver fortunately already has this module implemented in the driver class. Although this only supports firefox browser, it is enough for me as I run the automation in Hudson with firefox and I would want to embed the screenshot in the cucumber html report.

After do |scenario| 
if scenario.failed?
File.open("./screenshots/#{scenario.name}.jpeg",'wb') do |f|
f.write(Base64.decode64(page.driver.browser.screenshot_as(:base64)))
end
end
end

The webdriver class already has the save_screenshot methods, but it does not work in Windows and therefore you need to write the file as byte.

The above code will automatically capture a screenshot whenever the scenario.failed? is true. This is very useful for error reporting because if you run your test in Hudson, you would not be able to see your test running.