
Watir WebDriver as a test automation tool
A recent article about WebDriver reminded me a little about the complex we use to automate testing Web applications.
So, the tests are based on the RSpec + Watir WebDriver bundle (for Rails applications, it would be more appropriate to look towards Capybara). With the support of Bundler and local WebDrivers, an easy installation is performed on the tester's workplace (install Ruby 1.9, Rubygems, Bundler, and run
Due to the ci_reporter gem, integration with Jenkins CI is carried out, and due to the parallel_tests gem and Selenium Grid, parallelization of tests is performed (today parallel tests are not used in production yet).
Here is a test example:
The sites under test and the testing method are defined in the settings.
By setting the environment variables WATIR_ENV and WATIR_BROWSER, we define the testing environment for a particular test run.
All customization is performed by two files. .rspec: spec_helper.rb:
So, the tests are based on the RSpec + Watir WebDriver bundle (for Rails applications, it would be more appropriate to look towards Capybara). With the support of Bundler and local WebDrivers, an easy installation is performed on the tester's workplace (install Ruby 1.9, Rubygems, Bundler, and run
bundle install
). Gemfile source:source :rubygems
gem "watir-webdriver", "~>0.6.1"
gem "rspec-core", "~> 2.0"
gem "rspec-expectations", "~> 2.0"
gem "rr", "~> 1.0"
gem "ci_reporter", "~> 1.7"
Due to the ci_reporter gem, integration with Jenkins CI is carried out, and due to the parallel_tests gem and Selenium Grid, parallelization of tests is performed (today parallel tests are not used in production yet).
Here is a test example:
describe "FirstSite" do
before(:all) do
site! "first"
end
# returns true on success; otherwise false.
def login_as(data)
browser.rel_goto "/"
browser.title.should include 'example.com'
browser.text_field(:id => 'login').set data[:login]
browser.text_field(:id => 'password').set data[:password]
submit_button = browser.button(:id => 'submit')
submit_button.click
browser.url =~ %r{/welcome$}
end
def logout
browser.rel_goto "/"
browser.button(:id => 'logout').click
end
describe :login do
auth = fixture :auth
describe :successful do
after(:each) do
logout
end
auth.keys.select { |key| key.kind_of?(Symbol) }.each do |key|
next if key == :wrong
it "Logging in as #{key} should be OK" do
login_as(auth[key]).should be_true
end
end
end
describe :wrong do
it "Logging in with wrong credentials should fail" do
login_as(auth[:wrong]).should_not be_true
end
end
end
end
The sites under test and the testing method are defined in the settings.
---
production:
sites:
first: "http://staging.example.com"
webdriver:
hub: "http://192.168.13.6:8888/wd/hub"
test:
sites:
first: "http://staging.example.com"
webdriver:
hub: "http://192.168.13.6:8888/wd/hub"
development:
sites:
first: "localhost:5678"
webdriver:
local: true
By setting the environment variables WATIR_ENV and WATIR_BROWSER, we define the testing environment for a particular test run.
All customization is performed by two files. .rspec: spec_helper.rb:
--format nested
--color
--require ./spec_helper.rb
require "rubygems"
require "bundler/setup"
require "yaml"
require "watir-webdriver"
require "rspec/core"
$LOAD_PATH << File.join(File.dirname(__FILE__), 'lib') # для различных библиотек.
module RegruHelpers
include Selenium
def site!(site)
RSpec.configuration.site = RSpec.configuration.sites[site]
end
def fixture(name)
RegruHelpers.symbolized YAML.load_file(
File.join(File.dirname(__FILE__), 'fixtures', "#{name}.yml")
)
end
def screenshot!(text = '')
directory = File.join(File.dirname(__FILE__), 'spec', 'screenshots')
file_name = "#{example.metadata.full_description}-#{text}.png"
file_path =File.join(directory, file_name)
browser.screenshot.save file_path
end
def save_html!(text = '')
directory = File.join(File.dirname(__FILE__), 'spec', 'html')
file_name = "#{example.metadata.full_description}-#{text}.html"
file_path =File.join(directory, file_name)
File.open(file_path, "w") do |f|
f.print browser.html
end
end
Watir::Browser.class_eval do
def rel_goto url
goto "#{RSpec.configuration.site}#{url}"
end
end
def browser
RSpec.configuration.browser ||= begin
local = RSpec.configuration.watir_settings[:webdriver][:local]
if local
Watir::Browser.new(RSpec.configuration.browser_type)
else
capabilities = WebDriver::Remote::Capabilities.send(
RSpec.configuration.browser_type,
:javascript_enabled => true
)
Watir::Browser.new(
:remote,
:url => RSpec.configuration.watir_settings[:webdriver][:hub],
:desired_capabilities => capabilities
)
end
end
end
end
RSpec.configure do |config|
config.mock_with :rr
config.add_setting :watir_settings
config.add_setting :browser_type
config.add_setting :sites
config.add_setting :site
config.add_setting :browser
config.include RegruHelpers
config.extend RegruHelpers
environment = ENV['WATIR_ENV'] || 'test'
browser_type = (ENV['WATIR_BROWSER'] || 'chrome').to_sym
watir_settings = RegruHelpers.symbolized YAML.load_file(File.join(File.dirname(__FILE__), 'settings.yml'))[environment]
RSpec.configuration.watir_settings = watir_settings
RSpec.configuration.sites = watir_settings[:sites]
RSpec.configuration.site = watir_settings[:sites]['first']
RSpec.configuration.browser_type = browser_type
config.after(:suite) do
unless RSpec.configuration.browser.nil?
RSpec.configuration.browser.close
RSpec.configuration.browser = nil
end
end
config.after(:each) do
if example.exception
screenshot!('after')
save_html!('after')
end
end
def self.symbolized(hash)
r = hash.dup
hash.each_pair do |k, v|
if k.kind_of?(String)
if v.kind_of?(Hash)
v = symbolized v
end
r[k.to_sym] = v
end
end
r
end
end