WATIR (Web Application Testing in Ruby) is a nice tool for functional testing using Internet Explorer automation (see http://wtr.rubyforge.org/). It is nice that you can see the IE window when the tests are running – the links are clicked, forms filled and submited. It is great to show this to our customers.
See Watir User Guide and API to get more details about Watir.
——
There is now a WatirOnRails plugin hosted at http://watir-on-rails.rubyforge.org/
——
Here is how to integrate Watir tests into Rails:
1) create test/watir directory in your rails app
2) create and modify test/watir/watir_setup.rb which starts webrick on test DB, creates IE instance and can perform some preparing tasks like user creation in test db, user login, language selection and so on.
END {
$ie.close if $ie
$test_server.shutdown
}require File.dirname(__FILE__) + ‘/../test_helper’
require ‘dispatcher’
require ‘watir’
require ‘webrick’
require ‘webrick_server’$BASE_URL = ‘http://localhost:3003/’
$USER_PASSWORD = ‘xxx’
$USER = User.new {|u|
u.username = ‘myuser’
u.new_password = $USER_PASSWORD
u.first_name = ‘Test’
u.last_name = ‘User’
}def create_user
$USER.save! unless User.find_by_username($USER.username)
enddef start_test_webrick
params = { :Port => options[:port].to_i, :ServerType => options[:server_type], :BindAddress => options[:ip], :AccessLog => [] } $test_server = WEBrick::HTTPServer.new(params) $test_server.mount(‘/’, DispatchServlet, options) trap("INT") { $test_server.shutdown } Thread.new do $test_server.start end
options = {
:port => 3003,
:ip => “0.0.0.0”,
:environment => “test”,
:server_root => File.expand_path(RAILS_ROOT + “/public/”),
:working_directory => File.expand_path(RAILS_ROOT),
:server_type => WEBrick::SimpleServer
}end
def start_and_setup_ie
$ie = Watir::IE.new
$ie.set_fast_speed
login
english_locale
enddef login
$ie.goto($BASE_URL + ‘users/login’)
$ie.text_field(:name, ‘user[username]’).set($USER.username)
$ie.text_field(:name, ‘user[password]’).set($USER_PASSWORD)
$ie.button(:name, ’commit’).click
enddef english_locale
- bindtextdomain(‘messages’, “#{RAILS_ROOT}/locale”, ‘en’, ‘utf-8’) # if gettext localization used
$ie.goto($BASE_URL + ’settings’)
$ie.select_list(:name, ‘settings[locale]’).option(:value, ’en’).select
$ie.button(:name, ’commit’).click
endcreate_user
start_test_webrick
start_and_setup_ie
It stops webrick and closes IE when the tests are finished.
3) create your tests. For example incoming_mails_web_test.rb
require File.dirname(__FILE__) + ‘/watir_setup’class IncomingMailsWebTest < Test::Unit::TestCase
def setup $ie.goto($BASE_URL + ’incoming_mails’) assert_equal ‘Suppliers .:. Incoming mails’, $ie.title
self.use_transactional_fixtures = false
fixtures :incoming_mails
- assert_equal “Suppliers .:. #{_(‘Incoming mails’)}”, $ie.title # if gettext localization used
assert $ie.contains_text(‘User: Metada Admin’)
end
def test_navigation
$ie.link(:text, ‘Incoming mails’).click
assert_equal ‘Suppliers .:. Incoming mails’, $ie.title
end
end
Notice that transactional fixtures must be disabled to make it work properly, because the browser is accessing the DB through webrick which is not in the same transaction as the test itself.
4) create rake task for running Watir tests. Create lib/tasks/test_watir.rake
desc “Run the watir web tests in test/watir”
Rake::TestTask.new("test_watir") { |t|
t.libs << “test”
t.pattern = ‘test/watir//_test.rb’
t.verbose = true
}
task :test_watir => [ :prepare_test_database ]
5) add test_watir to the default rake task to have watir tests to be run together with unit and functional test by creating lib/tasks/default.rake
task :default do # adds :test_watir task to default (:test_units and :test_functional are already there)
Rake::Task[:test_watir].invoke rescue got_error = true
raise “Test failures” if got_error
end
The watir_setup.rb makes the tests to run faster, because webrick and IE are initialized at the begining. But you must keep in mind
the fact that the information stored in http session can influence/interfere the tests, so you have to adjust it to your test scenarios.
Enjoy!
Karel Miarka
require File.dirname(__FILE__) + '/watir_setup'
class InternalSequencesWebTest < Test::Unit::TestCase
self.use_transactional_fixtures = false
fixtures :internal_sequences
def setup
$ie.goto($BASE_URL + 'internal_sequences')
assert_equal 'Suppliers .:. Internal sequences', $ie.title
assert $ie.contains_text('User: Metada Admin')
end
def test_navigation
$ie.link(:text, 'Internal sequences').click
assert_equal 'Suppliers .:. Internal sequences', $ie.title
end
def test_listing
assert $ie.contains_text('Partner\'s Sequence')
assert $ie.contains_text('PRN-0024/05')
assert $ie.contains_text('Payment Requests Sequence')
assert $ie.contains_text('PRQ-0004')
$ie.link(:text, 'Name').click unless $ie.table(:id, 'listingTable').row_values(2)[1] == 'Name *'
t = $ie.table(:id, 'listingTable')
assert_equal 7, t.row_count
assert_equal "Incoming Mails Sequence", t.row_values(3)[1]
assert_equal "INMAIL-0004", t.row_values(3)[7]
end
def test_validation
$ie.link(:text, 'Create').click
assert $ie.contains_text('New Internal sequence')
$ie.button(:name, 'commit').click
assert $ie.contains_text('2 errors prohibited')
assert $ie.contains_text("Name can't be blank")
assert $ie.contains_text("class must be selected")
end
def test_create
$ie.button(:name, 'create').click
assert_equal 'Suppliers .:. New Internal sequence', $ie.title
$ie.text_field(:name, "internal_sequence[name]").set('New Test Sequence')
$ie.select_list(:name, "internal_sequence[for_item_class]").select('Partner')
$ie.button(:name, 'commit').click
assert $ie.contains_text("Internal sequence was successfully created.")
$ie.button(:name, 'list').click
assert_equal 8, $ie.table(:id, 'listingTable').row_count
end
def test_edit
$ie.link(:url, $BASE_URL + 'internal_sequences/edit/1').click
assert $ie.contains_text("Change Internal sequence")
assert_equal "Partner's Sequence", $ie.text_field(:name, 'internal_sequence[name]').value
$ie.text_field(:name, 'internal_sequence[name]').set('Changed PRN Sequence')
$ie.button(:value, 'Update').click
assert $ie.contains_text("InternalSequence was successfully updated.")
assert $ie.contains_text("Changed PRN Sequence")
assert_nil $ie.contains_text("Partner's Sequence")
$ie.button(:value, 'List').click
assert $ie.contains_text("Changed PRN Sequence")
end
def test_delete
$ie.link(:url, $BASE_URL + 'internal_sequences/edit/1').click
assert $ie.contains_text("Change Internal sequence")
assert_equal "Partner's Sequence", $ie.text_field(:name, 'internal_sequence[name]').value
Thread.new { system("rubyw -e 'require \"watir/WindowHelper\"; WindowHelper.new.push_confirm_button_ok'") }
$ie.button(:value, "Delete").click
assert_equal 6, $ie.table(:id, 'listingTable').row_count
end
def test_list_ordering
$ie.link(:text, 'Name').click
assert_equal "Name ^", $ie.table(:id, 'listingTable').row_values(2)[1]
assert_equal "Payment Requests Sequence", $ie.table(:id, 'listingTable').row_values(3)[1]
$ie.link(:text, 'For item class').click
assert_equal "For item class *", $ie.table(:id, 'listingTable').row_values(2)[2]
$ie.link(:text, 'Prefix').click
assert_equal "Prefix *", $ie.table(:id, 'listingTable').row_values(2)[3]
$ie.link(:text, 'Digits').click
assert_equal "Digits *", $ie.table(:id, 'listingTable').row_values(2)[4]
$ie.link(:text, 'Digits').click
assert_equal "Digits ^", $ie.table(:id, 'listingTable').row_values(2)[4]
end
def test_list_filtering
$ie.text_field(:name, 'filter[name]').set('In*')
$ie.button(:name, 'set_filter').click
assert_equal 4, $ie.table(:id, 'listingTable').row_count
$ie.text_field(:name, 'filter[digits#max]').set('5')
$ie.button(:name, 'set_filter').click
assert_equal 3, $ie.table(:id, 'listingTable').row_count
$ie.button(:name, 'clear_filter').click
assert_equal 7, $ie.table(:id, 'listingTable').row_count
end
end