mirror of
https://github.com/TracksApp/tracks.git
synced 2025-12-18 16:20:12 +01:00
Upgrade Selenium on Rails to r140
This commit is contained in:
parent
156862200b
commit
40074c71ad
117 changed files with 16789 additions and 8867 deletions
|
|
@ -1,214 +1,214 @@
|
|||
$: << File.expand_path(File.dirname(__FILE__) + "/")
|
||||
$: << File.expand_path(File.dirname(__FILE__) + "/../")
|
||||
require 'paths'
|
||||
require 'net/http'
|
||||
require 'tempfile'
|
||||
|
||||
|
||||
def c(var, default = nil) SeleniumOnRailsConfig.new.get var, default end
|
||||
def c_b(var, default = nil) SeleniumOnRailsConfig.new.get(var, default) { yield } end
|
||||
|
||||
BROWSERS = c :browsers, {}
|
||||
REUSE_EXISTING_SERVER = c :reuse_existing_server, true
|
||||
START_SERVER = c :start_server, false #TODO can't get it to work reliably on Windows, perhaps it's just on my computer, but I leave it off by default for now
|
||||
HOST = c :host, 'localhost'
|
||||
PORTS = c(:port_start, 3000)..c(:port_end, 3005)
|
||||
BASE_URL_PATH = c :base_url_path, '/'
|
||||
TEST_RUNNER_URL = c :test_runner_url, '/selenium/TestRunner.html'
|
||||
MAX_BROWSER_DURATION = c :max_browser_duration, 2*60
|
||||
MULTI_WINDOW = c :multi_window, false
|
||||
SERVER_COMMAND = c_b :server_command do
|
||||
server_path = File.expand_path(File.dirname(__FILE__) + '/../../../../../script/server')
|
||||
if RUBY_PLATFORM =~ /mswin/
|
||||
"ruby #{server_path} webrick -p %d -e test > NUL 2>&1"
|
||||
else
|
||||
# don't use redirects to /dev/nul since it makes the fork return wrong pid
|
||||
# see UnixSubProcess
|
||||
"#{server_path} webrick -p %d -e test"
|
||||
end
|
||||
end
|
||||
|
||||
module SeleniumOnRails
|
||||
class AcceptanceTestRunner
|
||||
include SeleniumOnRails::Paths
|
||||
|
||||
def run
|
||||
raise 'no browser specified, edit/create config.yml' if BROWSERS.empty?
|
||||
start_server
|
||||
has_error = false
|
||||
begin
|
||||
BROWSERS.each_pair do |browser, path|
|
||||
log_file = start_browser browser, path
|
||||
wait_for_completion log_file
|
||||
stop_browser
|
||||
result = YAML::load_file log_file
|
||||
print_result result
|
||||
has_error ||= result['numTestFailures'].to_i > 0
|
||||
# File.delete log_file unless has_error
|
||||
end
|
||||
rescue
|
||||
stop_server
|
||||
raise
|
||||
end
|
||||
stop_server
|
||||
raise 'Test failures' if has_error
|
||||
end
|
||||
|
||||
private
|
||||
def start_server
|
||||
PORTS.each do |p|
|
||||
@port = p
|
||||
case server_check
|
||||
when :success
|
||||
return if REUSE_EXISTING_SERVER
|
||||
next
|
||||
when Fixnum
|
||||
next
|
||||
when :no_response
|
||||
next unless START_SERVER
|
||||
do_start_server
|
||||
return
|
||||
end
|
||||
end
|
||||
raise START_SERVER ? 'failed to start server': 'failed to find existing server, run script/server -e test'
|
||||
end
|
||||
|
||||
def do_start_server
|
||||
puts 'Starting server'
|
||||
@server = start_subprocess(format(SERVER_COMMAND, @port))
|
||||
while true
|
||||
print '.'
|
||||
r = server_check
|
||||
if r == :success
|
||||
puts
|
||||
return
|
||||
end
|
||||
raise "server returned error: #{r}" if r.instance_of? Fixnum
|
||||
sleep 3
|
||||
end
|
||||
end
|
||||
|
||||
def server_check
|
||||
begin
|
||||
res = Net::HTTP.get_response HOST, TEST_RUNNER_URL, @port
|
||||
return :success if (200..399).include? res.code.to_i
|
||||
return res.code.to_i
|
||||
rescue Errno::ECONNREFUSED
|
||||
return :no_response
|
||||
end
|
||||
end
|
||||
|
||||
def stop_server
|
||||
return unless defined? @server
|
||||
puts
|
||||
@server.stop 'server'
|
||||
end
|
||||
|
||||
def start_browser browser, path
|
||||
puts
|
||||
puts "Starting #{browser}"
|
||||
base_url = "http://#{HOST}:#{@port}#{BASE_URL_PATH}"
|
||||
log = log_file browser
|
||||
command = "\"#{path}\" \"http://#{HOST}:#{@port}#{TEST_RUNNER_URL}?test=tests&auto=true&baseUrl=#{base_url}&resultsUrl=postResults/#{log}&multiWindow=#{MULTI_WINDOW}\""
|
||||
@browser = start_subprocess command
|
||||
log_path log
|
||||
end
|
||||
|
||||
def stop_browser
|
||||
@browser.stop 'browser'
|
||||
end
|
||||
|
||||
def start_subprocess command
|
||||
if RUBY_PLATFORM =~ /mswin/
|
||||
SeleniumOnRails::AcceptanceTestRunner::Win32SubProcess.new command
|
||||
elsif RUBY_PLATFORM =~ /darwin/i && command =~ /safari/i
|
||||
SeleniumOnRails::AcceptanceTestRunner::SafariSubProcess.new command
|
||||
else
|
||||
SeleniumOnRails::AcceptanceTestRunner::UnixSubProcess.new command
|
||||
end
|
||||
end
|
||||
|
||||
def log_file browser
|
||||
FileUtils.mkdir_p(log_path(''))
|
||||
(0..100).each do |i|
|
||||
name = browser + (i==0 ? '' : "(#{i})") + '.yml'
|
||||
return name unless File.exist?(log_path(name))
|
||||
end
|
||||
raise 'there are way too many files in the log directory...'
|
||||
end
|
||||
|
||||
def wait_for_completion log_file
|
||||
duration = 0
|
||||
while true
|
||||
raise 'browser takes too long' if duration > MAX_BROWSER_DURATION
|
||||
print '.'
|
||||
break if File.exist? log_file
|
||||
sleep 5
|
||||
duration += 5
|
||||
end
|
||||
puts
|
||||
end
|
||||
|
||||
def print_result result
|
||||
puts "Finished in #{result['totalTime']} seconds."
|
||||
puts
|
||||
puts "#{result['numTestPasses']} tests passed, #{result['numTestFailures']} tests failed"
|
||||
puts "(Results stored in '#{result['resultDir']}')" if result['resultDir']
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
class SeleniumOnRails::AcceptanceTestRunner::SubProcess
|
||||
def stop what
|
||||
begin
|
||||
puts "Stopping #{what} (pid=#{@pid}) ..."
|
||||
Process.kill 9, @pid
|
||||
rescue Errno::EPERM #such as the process is already closed (tabbed browser)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class SeleniumOnRails::AcceptanceTestRunner::Win32SubProcess < SeleniumOnRails::AcceptanceTestRunner::SubProcess
|
||||
def initialize command
|
||||
require 'win32/open3' #win32-open3 http://raa.ruby-lang.org/project/win32-open3/
|
||||
|
||||
puts command
|
||||
input, output, error, @pid = Open4.popen4 command, 't', true
|
||||
end
|
||||
end
|
||||
|
||||
class SeleniumOnRails::AcceptanceTestRunner::UnixSubProcess < SeleniumOnRails::AcceptanceTestRunner::SubProcess
|
||||
def initialize command
|
||||
puts command
|
||||
@pid = fork do
|
||||
# Since we can't use shell redirects without screwing
|
||||
# up the pid, we'll reopen stdin and stdout instead
|
||||
# to get the same effect.
|
||||
[STDOUT,STDERR].each {|f| f.reopen '/dev/null', 'w' }
|
||||
exec command
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# The path to Safari should look like this: /Applications/Safari.app/Contents/MacOS/Safari
|
||||
class SeleniumOnRails::AcceptanceTestRunner::SafariSubProcess < SeleniumOnRails::AcceptanceTestRunner::UnixSubProcess
|
||||
def initialize command
|
||||
f = File.open(Tempfile.new('selenium-on-rails').path, 'w')
|
||||
f.puts <<-HTML
|
||||
<html>
|
||||
<head>
|
||||
<script type="text/javascript" charset="utf-8">
|
||||
window.location.href = #{command.split.last};
|
||||
</script>
|
||||
</head>
|
||||
<body></body>
|
||||
</html>
|
||||
HTML
|
||||
f.close
|
||||
|
||||
super "#{command.split.first} #{f.path}"
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
$: << File.expand_path(File.dirname(__FILE__) + "/")
|
||||
$: << File.expand_path(File.dirname(__FILE__) + "/../")
|
||||
require 'paths'
|
||||
require 'net/http'
|
||||
require 'tempfile'
|
||||
|
||||
|
||||
def c(var, default = nil) SeleniumOnRailsConfig.get var, default end
|
||||
def c_b(var, default = nil) SeleniumOnRailsConfig.get(var, default) { yield } end
|
||||
|
||||
BROWSERS = c :browsers, {}
|
||||
REUSE_EXISTING_SERVER = c :reuse_existing_server, true
|
||||
START_SERVER = c :start_server, false #TODO can't get it to work reliably on Windows, perhaps it's just on my computer, but I leave it off by default for now
|
||||
HOST = c :host, 'localhost'
|
||||
PORTS = c(:port_start, 3000)..c(:port_end, 3005)
|
||||
BASE_URL_PATH = c :base_url_path, '/'
|
||||
TEST_RUNNER_URL = c :test_runner_url, '/selenium/TestRunner.html'
|
||||
MAX_BROWSER_DURATION = c :max_browser_duration, 2*60
|
||||
MULTI_WINDOW = c :multi_window, false
|
||||
SERVER_COMMAND = c_b :server_command do
|
||||
server_path = File.expand_path(File.dirname(__FILE__) + '/../../../../../script/server')
|
||||
if RUBY_PLATFORM =~ /mswin/
|
||||
"ruby #{server_path} webrick -p %d -e test > NUL 2>&1"
|
||||
else
|
||||
# don't use redirects to /dev/nul since it makes the fork return wrong pid
|
||||
# see UnixSubProcess
|
||||
"#{server_path} webrick -p %d -e test"
|
||||
end
|
||||
end
|
||||
|
||||
module SeleniumOnRails
|
||||
class AcceptanceTestRunner
|
||||
include SeleniumOnRails::Paths
|
||||
|
||||
def run
|
||||
raise 'no browser specified, edit/create config.yml' if BROWSERS.empty?
|
||||
start_server
|
||||
has_error = false
|
||||
begin
|
||||
BROWSERS.each_pair do |browser, path|
|
||||
log_file = start_browser browser, path
|
||||
wait_for_completion log_file
|
||||
stop_browser
|
||||
result = YAML::load_file log_file
|
||||
print_result result
|
||||
has_error ||= result['numTestFailures'].to_i > 0
|
||||
# File.delete log_file unless has_error
|
||||
end
|
||||
rescue
|
||||
stop_server
|
||||
raise
|
||||
end
|
||||
stop_server
|
||||
raise 'Test failures' if has_error
|
||||
end
|
||||
|
||||
private
|
||||
def start_server
|
||||
PORTS.each do |p|
|
||||
@port = p
|
||||
case server_check
|
||||
when :success
|
||||
return if REUSE_EXISTING_SERVER
|
||||
next
|
||||
when Fixnum
|
||||
next
|
||||
when :no_response
|
||||
next unless START_SERVER
|
||||
do_start_server
|
||||
return
|
||||
end
|
||||
end
|
||||
raise START_SERVER ? 'failed to start server': 'failed to find existing server, run script/server -e test'
|
||||
end
|
||||
|
||||
def do_start_server
|
||||
puts 'Starting server'
|
||||
@server = start_subprocess(format(SERVER_COMMAND, @port))
|
||||
while true
|
||||
print '.'
|
||||
r = server_check
|
||||
if r == :success
|
||||
puts
|
||||
return
|
||||
end
|
||||
raise "server returned error: #{r}" if r.instance_of? Fixnum
|
||||
sleep 3
|
||||
end
|
||||
end
|
||||
|
||||
def server_check
|
||||
begin
|
||||
res = Net::HTTP.get_response HOST, TEST_RUNNER_URL, @port
|
||||
return :success if (200..399).include? res.code.to_i
|
||||
return res.code.to_i
|
||||
rescue Errno::ECONNREFUSED
|
||||
return :no_response
|
||||
end
|
||||
end
|
||||
|
||||
def stop_server
|
||||
return unless defined? @server
|
||||
puts
|
||||
@server.stop 'server'
|
||||
end
|
||||
|
||||
def start_browser browser, path
|
||||
puts
|
||||
puts "Starting #{browser}"
|
||||
base_url = "http://#{HOST}:#{@port}#{BASE_URL_PATH}"
|
||||
log = log_file browser
|
||||
command = "\"#{path}\" \"http://#{HOST}:#{@port}#{TEST_RUNNER_URL}?test=tests&auto=true&baseUrl=#{base_url}&resultsUrl=postResults/#{log}&multiWindow=#{MULTI_WINDOW}\""
|
||||
@browser = start_subprocess command
|
||||
log_path log
|
||||
end
|
||||
|
||||
def stop_browser
|
||||
@browser.stop 'browser'
|
||||
end
|
||||
|
||||
def start_subprocess command
|
||||
if RUBY_PLATFORM =~ /mswin/
|
||||
SeleniumOnRails::AcceptanceTestRunner::Win32SubProcess.new command
|
||||
elsif RUBY_PLATFORM =~ /darwin/i && command =~ /safari/i
|
||||
SeleniumOnRails::AcceptanceTestRunner::SafariSubProcess.new command
|
||||
else
|
||||
SeleniumOnRails::AcceptanceTestRunner::UnixSubProcess.new command
|
||||
end
|
||||
end
|
||||
|
||||
def log_file browser
|
||||
FileUtils.mkdir_p(log_path(''))
|
||||
(0..100).each do |i|
|
||||
name = browser + (i==0 ? '' : "(#{i})") + '.yml'
|
||||
return name unless File.exist?(log_path(name))
|
||||
end
|
||||
raise 'there are way too many files in the log directory...'
|
||||
end
|
||||
|
||||
def wait_for_completion log_file
|
||||
duration = 0
|
||||
while true
|
||||
raise 'browser takes too long' if duration > MAX_BROWSER_DURATION
|
||||
print '.'
|
||||
break if File.exist? log_file
|
||||
sleep 5
|
||||
duration += 5
|
||||
end
|
||||
puts
|
||||
end
|
||||
|
||||
def print_result result
|
||||
puts "Finished in #{result['totalTime']} seconds."
|
||||
puts
|
||||
puts "#{result['numTestPasses']} tests passed, #{result['numTestFailures']} tests failed"
|
||||
puts "(Results stored in '#{result['resultDir']}')" if result['resultDir']
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
class SeleniumOnRails::AcceptanceTestRunner::SubProcess
|
||||
def stop what
|
||||
begin
|
||||
puts "Stopping #{what} (pid=#{@pid}) ..."
|
||||
Process.kill 9, @pid
|
||||
rescue Errno::EPERM #such as the process is already closed (tabbed browser)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class SeleniumOnRails::AcceptanceTestRunner::Win32SubProcess < SeleniumOnRails::AcceptanceTestRunner::SubProcess
|
||||
def initialize command
|
||||
require 'win32/open3' #win32-open3 http://raa.ruby-lang.org/project/win32-open3/
|
||||
|
||||
puts command
|
||||
input, output, error, @pid = Open4.popen4 command, 't', true
|
||||
end
|
||||
end
|
||||
|
||||
class SeleniumOnRails::AcceptanceTestRunner::UnixSubProcess < SeleniumOnRails::AcceptanceTestRunner::SubProcess
|
||||
def initialize command
|
||||
puts command
|
||||
@pid = fork do
|
||||
# Since we can't use shell redirects without screwing
|
||||
# up the pid, we'll reopen stdin and stdout instead
|
||||
# to get the same effect.
|
||||
[STDOUT,STDERR].each {|f| f.reopen '/dev/null', 'w' }
|
||||
exec command
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# The path to Safari should look like this: /Applications/Safari.app/Contents/MacOS/Safari
|
||||
class SeleniumOnRails::AcceptanceTestRunner::SafariSubProcess < SeleniumOnRails::AcceptanceTestRunner::UnixSubProcess
|
||||
def initialize command
|
||||
f = File.open(Tempfile.new('selenium-on-rails').path, 'w')
|
||||
f.puts <<-HTML
|
||||
<html>
|
||||
<head>
|
||||
<script type="text/javascript" charset="utf-8">
|
||||
window.location.href = #{command.split.last};
|
||||
</script>
|
||||
</head>
|
||||
<body></body>
|
||||
</html>
|
||||
HTML
|
||||
f.close
|
||||
|
||||
super "#{command.split.first} #{f.path}"
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -1,57 +1,57 @@
|
|||
require 'test/unit'
|
||||
require 'active_record'
|
||||
require 'active_record/fixtures'
|
||||
|
||||
module SeleniumOnRails::FixtureLoader
|
||||
include SeleniumOnRails::Paths
|
||||
|
||||
def available_fixtures
|
||||
fixtures = {}
|
||||
path = fixtures_path + '/'
|
||||
files = Dir["#{path}**/*.{yml,csv}"]
|
||||
files.each do |file|
|
||||
rel_path = file.sub(path, '')
|
||||
next if skip_file? rel_path
|
||||
fixture_set = File.dirname(rel_path)
|
||||
fixture_set = '' if fixture_set == '.'
|
||||
fixture = rel_path.sub /\.[^.]*$/, ''
|
||||
fixtures[fixture_set] ||= []
|
||||
fixtures[fixture_set] << fixture
|
||||
end
|
||||
|
||||
fixtures
|
||||
end
|
||||
|
||||
def load_fixtures fixtures_param
|
||||
available = nil
|
||||
fixtures = fixtures_param.split(/\s*,\s*/).collect do |f|
|
||||
fixture_set = File.dirname f
|
||||
fixture_set = '' if fixture_set == '.'
|
||||
fixture = File.basename f
|
||||
if fixture == 'all'
|
||||
available ||= available_fixtures
|
||||
available[fixture_set]
|
||||
else
|
||||
f
|
||||
end
|
||||
end
|
||||
fixtures.flatten!
|
||||
fixtures.reject! {|f| f.blank? }
|
||||
|
||||
if fixtures.any?
|
||||
Fixtures.reset_cache # in case they've already been loaded and things have changed
|
||||
Fixtures.create_fixtures fixtures_path, fixtures
|
||||
end
|
||||
fixtures
|
||||
end
|
||||
|
||||
def clear_tables tables
|
||||
table_names = tables.split /\s*,\s*/
|
||||
connection = ActiveRecord::Base.connection
|
||||
table_names.each do |table|
|
||||
connection.execute "DELETE FROM #{table}"
|
||||
end
|
||||
table_names
|
||||
end
|
||||
|
||||
end
|
||||
require 'test/unit'
|
||||
require 'active_record'
|
||||
require 'active_record/fixtures'
|
||||
|
||||
module SeleniumOnRails::FixtureLoader
|
||||
include SeleniumOnRails::Paths
|
||||
|
||||
def available_fixtures
|
||||
fixtures = {}
|
||||
path = fixtures_path + '/'
|
||||
files = Dir["#{path}**/*.{yml,csv}"]
|
||||
files.each do |file|
|
||||
rel_path = file.sub(path, '')
|
||||
next if skip_file? rel_path
|
||||
fixture_set = File.dirname(rel_path)
|
||||
fixture_set = '' if fixture_set == '.'
|
||||
fixture = rel_path.sub /\.[^.]*$/, ''
|
||||
fixtures[fixture_set] ||= []
|
||||
fixtures[fixture_set] << fixture
|
||||
end
|
||||
|
||||
fixtures
|
||||
end
|
||||
|
||||
def load_fixtures fixtures_param
|
||||
available = nil
|
||||
fixtures = fixtures_param.split(/\s*,\s*/).collect do |f|
|
||||
fixture_set = File.dirname f
|
||||
fixture_set = '' if fixture_set == '.'
|
||||
fixture = File.basename f
|
||||
if fixture == 'all'
|
||||
available ||= available_fixtures
|
||||
available[fixture_set]
|
||||
else
|
||||
f
|
||||
end
|
||||
end
|
||||
fixtures.flatten!
|
||||
fixtures.reject! {|f| f.blank? }
|
||||
|
||||
if fixtures.any?
|
||||
Fixtures.reset_cache # in case they've already been loaded and things have changed
|
||||
Fixtures.create_fixtures fixtures_path, fixtures
|
||||
end
|
||||
fixtures
|
||||
end
|
||||
|
||||
def clear_tables tables
|
||||
table_names = tables.split /\s*,\s*/
|
||||
connection = ActiveRecord::Base.connection
|
||||
table_names.each do |table|
|
||||
connection.execute "DELETE FROM #{table}"
|
||||
end
|
||||
table_names
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,36 +1,36 @@
|
|||
require 'selenium_on_rails/paths'
|
||||
|
||||
module SeleniumOnRails::PartialsSupport
|
||||
include SeleniumOnRails::Paths
|
||||
|
||||
# Overrides where the partial is searched for, and returns only the command table rows.
|
||||
def render_partial(options)
|
||||
pattern = partial_pattern options[:partial]
|
||||
filename = Dir[pattern].first
|
||||
raise "Partial '#{partial_path}' cannot be found! (Looking for file: '#{pattern}')" unless filename
|
||||
partial = render :file => filename, :use_full_path => false, :locals => options[:locals]
|
||||
extract_commands_from_partial partial
|
||||
end
|
||||
|
||||
# Extracts the commands from a partial. The partial must contain a html table
|
||||
# and the first row is ignored since it cannot contain a command.
|
||||
def extract_commands_from_partial partial
|
||||
partial = partial.match(/.*<table>.*?<tr>.*?<\/tr>(.*?)<\/table>/im)[1]
|
||||
raise "Partial '#{name}' doesn't contain any table" unless partial
|
||||
partial
|
||||
end
|
||||
|
||||
private
|
||||
# Generates the file pattern from the provided partial path.
|
||||
# The starting _ and file extension don't have too be provided.
|
||||
def partial_pattern partial_path
|
||||
path = partial_path.split '/'
|
||||
filename = path.delete_at(-1)
|
||||
filename = '_' + filename unless filename.starts_with? '_'
|
||||
filename << '.*' unless filename.include? '.'
|
||||
pattern = selenium_tests_path + '/'
|
||||
pattern << path.join('/') + '/' if path
|
||||
pattern << filename
|
||||
end
|
||||
|
||||
require 'selenium_on_rails/paths'
|
||||
|
||||
module SeleniumOnRails::PartialsSupport
|
||||
include SeleniumOnRails::Paths
|
||||
|
||||
# Overrides where the partial is searched for, and returns only the command table rows.
|
||||
def render_partial(options)
|
||||
pattern = partial_pattern options[:partial]
|
||||
filename = Dir[pattern].first
|
||||
raise "Partial '#{partial_path}' cannot be found! (Looking for file: '#{pattern}')" unless filename
|
||||
partial = render :file => filename, :use_full_path => false, :locals => options[:locals]
|
||||
extract_commands_from_partial partial
|
||||
end
|
||||
|
||||
# Extracts the commands from a partial. The partial must contain a html table
|
||||
# and the first row is ignored since it cannot contain a command.
|
||||
def extract_commands_from_partial partial
|
||||
partial = partial.match(/.*<table>.*?<tr>.*?<\/tr>(.*?)<\/table>/im)[1]
|
||||
raise "Partial '#{name}' doesn't contain any table" unless partial
|
||||
partial
|
||||
end
|
||||
|
||||
private
|
||||
# Generates the file pattern from the provided partial path.
|
||||
# The starting _ and file extension don't have too be provided.
|
||||
def partial_pattern partial_path
|
||||
path = partial_path.split '/'
|
||||
filename = path.delete_at(-1)
|
||||
filename = '_' + filename unless filename.starts_with? '_'
|
||||
filename << '.*' unless filename.include? '.'
|
||||
pattern = selenium_tests_path + '/'
|
||||
pattern << path.join('/') + '/' if path
|
||||
pattern << filename
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -1,60 +1,61 @@
|
|||
require 'selenium_on_rails_config'
|
||||
|
||||
module SeleniumOnRails
|
||||
module Paths
|
||||
attr_accessor :config
|
||||
|
||||
def selenium_path
|
||||
@@selenium_path ||= find_selenium_path
|
||||
@@selenium_path
|
||||
end
|
||||
|
||||
def selenium_tests_path
|
||||
File.expand_path(File.join(RAILS_ROOT, 'test/selenium'))
|
||||
end
|
||||
|
||||
def view_path view
|
||||
File.expand_path(File.dirname(__FILE__) + '/../views/' + view)
|
||||
end
|
||||
|
||||
# Returns the path to the layout template. The path is relative in relation
|
||||
# to the app/views/ directory since Rails doesn't support absolute paths
|
||||
# to layout templates.
|
||||
def layout_path
|
||||
'layout.rhtml'
|
||||
end
|
||||
|
||||
def fixtures_path
|
||||
File.expand_path File.join(RAILS_ROOT, 'test/fixtures')
|
||||
end
|
||||
|
||||
def log_path log_file
|
||||
File.expand_path(File.dirname(__FILE__) + '/../../log/' + File.basename(log_file))
|
||||
end
|
||||
|
||||
def skip_file? file
|
||||
file.split('/').each do |f|
|
||||
return true if f.upcase == 'CVS' or f.starts_with?('.') or f.ends_with?('~') or f.starts_with?('_')
|
||||
end
|
||||
false
|
||||
end
|
||||
|
||||
private ###############################################
|
||||
|
||||
def find_selenium_path
|
||||
sel_dirs = @config.get :selenium_path do
|
||||
File.expand_path(File.dirname(__FILE__) + '/../../selenium-core')
|
||||
end
|
||||
|
||||
sel_dirs.to_a.each do |seleniumdir|
|
||||
['', 'core', 'selenium', 'javascript'].each do |subdir|
|
||||
path = File.join seleniumdir, subdir
|
||||
return path if File.exist?(File.join(path, 'TestRunner.html'))
|
||||
end
|
||||
end
|
||||
|
||||
raise 'Could not find Selenium Core installation'
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
require 'selenium_on_rails_config'
|
||||
|
||||
module SeleniumOnRails
|
||||
module Paths
|
||||
|
||||
def selenium_path
|
||||
@@selenium_path ||= find_selenium_path
|
||||
@@selenium_path
|
||||
end
|
||||
|
||||
def selenium_tests_path
|
||||
return SeleniumOnRailsConfig.get("selenium_tests_path") if SeleniumOnRailsConfig.get("selenium_tests_path")
|
||||
File.expand_path(File.join(RAILS_ROOT, 'test/selenium'))
|
||||
end
|
||||
|
||||
def view_path view
|
||||
File.expand_path(File.dirname(__FILE__) + '/../views/' + view)
|
||||
end
|
||||
|
||||
# Returns the path to the layout template. The path is relative in relation
|
||||
# to the app/views/ directory since Rails doesn't support absolute paths
|
||||
# to layout templates.
|
||||
def layout_path
|
||||
'layout.rhtml'
|
||||
end
|
||||
|
||||
def fixtures_path
|
||||
return SeleniumOnRailsConfig.get("fixtures_path") if SeleniumOnRailsConfig.get("fixtures_path")
|
||||
File.expand_path File.join(RAILS_ROOT, 'test/fixtures')
|
||||
end
|
||||
|
||||
def log_path log_file
|
||||
File.expand_path(File.dirname(__FILE__) + '/../../log/' + File.basename(log_file))
|
||||
end
|
||||
|
||||
def skip_file? file
|
||||
file.split('/').each do |f|
|
||||
return true if f.upcase == 'CVS' or f.starts_with?('.') or f.ends_with?('~') or f.starts_with?('_')
|
||||
end
|
||||
false
|
||||
end
|
||||
|
||||
private ###############################################
|
||||
|
||||
def find_selenium_path
|
||||
sel_dirs = SeleniumOnRailsConfig.get :selenium_path do
|
||||
File.expand_path(File.dirname(__FILE__) + '/../../selenium-core')
|
||||
end
|
||||
|
||||
sel_dirs.to_a.each do |seleniumdir|
|
||||
['', 'core', 'selenium', 'javascript'].each do |subdir|
|
||||
path = File.join seleniumdir, subdir
|
||||
return path if File.exist?(File.join(path, 'TestRunner.html'))
|
||||
end
|
||||
end
|
||||
|
||||
raise 'Could not find Selenium Core installation'
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,20 +1,20 @@
|
|||
module SeleniumOnRails::Renderer
|
||||
include SeleniumOnRails::Paths
|
||||
|
||||
def render_test_case filename
|
||||
@template.extend SeleniumOnRails::PartialsSupport
|
||||
@page_title = test_case_name filename
|
||||
output = render_to_string :file => filename, :locals => {"page_title" => @page_title}
|
||||
layout = (output =~ /<html>/i ? false : layout_path)
|
||||
render :text => output, :layout => layout
|
||||
|
||||
headers['Cache-control'] = 'no-cache'
|
||||
headers['Pragma'] = 'no-cache'
|
||||
headers['Expires'] = '-1'
|
||||
end
|
||||
|
||||
def test_case_name filename
|
||||
File.basename(filename).sub(/\..*/,'').humanize
|
||||
end
|
||||
|
||||
module SeleniumOnRails::Renderer
|
||||
include SeleniumOnRails::Paths
|
||||
|
||||
def render_test_case filename
|
||||
@template.extend SeleniumOnRails::PartialsSupport
|
||||
@page_title = test_case_name filename
|
||||
output = render_to_string :file => filename, :locals => {"page_title" => @page_title}
|
||||
layout = (output =~ /<html>/i ? false : layout_path)
|
||||
render :text => output, :layout => layout
|
||||
|
||||
headers['Cache-control'] = 'no-cache'
|
||||
headers['Pragma'] = 'no-cache'
|
||||
headers['Expires'] = '-1'
|
||||
end
|
||||
|
||||
def test_case_name filename
|
||||
File.basename(filename).sub(/\..*/,'').humanize
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -10,7 +10,7 @@ class SeleniumOnRails::RSelenese < SeleniumOnRails::TestBuilder
|
|||
end
|
||||
ActionView::Template.register_template_handler 'rsel', SeleniumOnRails::RSelenese
|
||||
|
||||
class SeleniumOnRails::RSelenese < SeleniumOnRails::TestBuilder
|
||||
class SeleniumOnRails::RSelenese
|
||||
attr_accessor :view
|
||||
|
||||
def initialize view
|
||||
|
|
@ -18,19 +18,27 @@ class SeleniumOnRails::RSelenese < SeleniumOnRails::TestBuilder
|
|||
@view = view
|
||||
end
|
||||
|
||||
def render template, local_assigns
|
||||
def render template, local_assigns = {}
|
||||
title = (@view.assigns['page_title'] or local_assigns['page_title'])
|
||||
table(title) do
|
||||
test = self #to enable test.command
|
||||
|
||||
assign_locals_code = ''
|
||||
local_assigns.each_key {|key| assign_locals_code << "#{key} = local_assigns[#{key.inspect}];"}
|
||||
|
||||
eval assign_locals_code + "\n" + template.source
|
||||
end
|
||||
evaluator = Evaluator.new(@view)
|
||||
evaluator.run_script title, assign_locals_code_from(local_assigns) + "\n" + template.source, local_assigns
|
||||
end
|
||||
|
||||
def assign_locals_code_from(local_assigns)
|
||||
return local_assigns.keys.collect {|key| "#{key} = local_assigns[#{key.inspect}];"}.join
|
||||
end
|
||||
|
||||
def self.call(template)
|
||||
"#{name}.new(self).render(template, local_assigns)"
|
||||
end
|
||||
|
||||
class Evaluator < SeleniumOnRails::TestBuilder
|
||||
def run_script(title, script, local_assigns)
|
||||
table(title) do
|
||||
test = self #to enable test.command
|
||||
eval script
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,87 +1,87 @@
|
|||
require 'selenium_on_rails/partials_support'
|
||||
|
||||
class SeleniumOnRails::Selenese
|
||||
end
|
||||
ActionView::Template.register_template_handler 'sel', SeleniumOnRails::Selenese
|
||||
|
||||
|
||||
class SeleniumOnRails::Selenese
|
||||
def initialize view
|
||||
@view = view
|
||||
end
|
||||
|
||||
def render template, local_assigns = {}
|
||||
name = (@view.assigns['page_title'] or local_assigns['page_title'])
|
||||
lines = template.source.strip.split "\n"
|
||||
html = ''
|
||||
html << extract_comments(lines)
|
||||
html << extract_commands(lines, name)
|
||||
html << extract_comments(lines)
|
||||
raise 'You cannot have comments in the middle of commands!' if next_line lines, :any
|
||||
html
|
||||
end
|
||||
|
||||
private
|
||||
def next_line lines, expects
|
||||
while lines.any?
|
||||
l = lines.shift.strip
|
||||
next if (l.empty? and expects != :comment)
|
||||
comment = (l =~ /^\|.*\|$/).nil?
|
||||
if (comment and expects == :command) or (!comment and expects == :comment)
|
||||
lines.unshift l
|
||||
return nil
|
||||
end
|
||||
return l
|
||||
end
|
||||
end
|
||||
|
||||
def self.call(template)
|
||||
"#{name}.new(self).render(template, local_assigns)"
|
||||
end
|
||||
|
||||
def extract_comments lines
|
||||
comments = ''
|
||||
while (line = next_line lines, :comment)
|
||||
comments << line + "\n"
|
||||
end
|
||||
if defined? RedCloth
|
||||
comments = RedCloth.new(comments).to_html
|
||||
end
|
||||
comments += "\n" unless comments.empty?
|
||||
comments
|
||||
end
|
||||
|
||||
def extract_commands lines, name
|
||||
html = "<table>\n<tr><th colspan=\"3\">#{name}</th></tr>\n"
|
||||
while (line = next_line lines, :command)
|
||||
line = line[1..-2] #remove starting and ending |
|
||||
cells = line.split '|'
|
||||
if cells.first == 'includePartial'
|
||||
html << include_partial(cells[1..-1])
|
||||
next
|
||||
end
|
||||
raise 'There might only be a maximum of three cells!' if cells.length > 3
|
||||
html << '<tr>'
|
||||
(1..3).each do
|
||||
cell = cells.shift
|
||||
cell = (cell ? CGI.escapeHTML(cell.strip) : ' ')
|
||||
html << "<td>#{cell}</td>"
|
||||
end
|
||||
html << "</tr>\n"
|
||||
end
|
||||
html << "</table>\n"
|
||||
end
|
||||
|
||||
def include_partial params
|
||||
partial = params.shift
|
||||
locals = {}
|
||||
params.each do |assignment|
|
||||
next if assignment.empty?
|
||||
_, var, value = assignment.split(/^([a-z_][a-zA-Z0-9_]*)\s*=\s*(.*)$/)
|
||||
raise "Invalid format '#{assignment}'. Should be '|includePartial|partial|var1=value|var2=value|." unless var
|
||||
locals[var.to_sym] = value or ''
|
||||
end
|
||||
@view.render :partial => partial, :locals => locals
|
||||
end
|
||||
|
||||
require 'selenium_on_rails/partials_support'
|
||||
|
||||
class SeleniumOnRails::Selenese
|
||||
end
|
||||
ActionView::Template.register_template_handler 'sel', SeleniumOnRails::Selenese
|
||||
|
||||
|
||||
class SeleniumOnRails::Selenese
|
||||
def initialize view
|
||||
@view = view
|
||||
end
|
||||
|
||||
def render template, local_assigns = {}
|
||||
name = (@view.assigns['page_title'] or local_assigns['page_title'])
|
||||
lines = template.source.strip.split "\n"
|
||||
html = ''
|
||||
html << extract_comments(lines)
|
||||
html << extract_commands(lines, name)
|
||||
html << extract_comments(lines)
|
||||
raise 'You cannot have comments in the middle of commands!' if next_line lines, :any
|
||||
html
|
||||
end
|
||||
|
||||
private
|
||||
def next_line lines, expects
|
||||
while lines.any?
|
||||
l = lines.shift.strip
|
||||
next if (l.empty? and expects != :comment)
|
||||
comment = (l =~ /^\|.*\|$/).nil?
|
||||
if (comment and expects == :command) or (!comment and expects == :comment)
|
||||
lines.unshift l
|
||||
return nil
|
||||
end
|
||||
return l
|
||||
end
|
||||
end
|
||||
|
||||
def self.call(template)
|
||||
"#{name}.new(self).render(template, local_assigns)"
|
||||
end
|
||||
|
||||
def extract_comments lines
|
||||
comments = ''
|
||||
while (line = next_line lines, :comment)
|
||||
comments << line + "\n"
|
||||
end
|
||||
if defined? RedCloth
|
||||
comments = RedCloth.new(comments).to_html
|
||||
end
|
||||
comments += "\n" unless comments.empty?
|
||||
comments
|
||||
end
|
||||
|
||||
def extract_commands lines, name
|
||||
html = "<table>\n<tr><th colspan=\"3\">#{name}</th></tr>\n"
|
||||
while (line = next_line lines, :command)
|
||||
line = line[1..-2] #remove starting and ending |
|
||||
cells = line.split '|'
|
||||
if cells.first == 'includePartial'
|
||||
html << include_partial(cells[1..-1])
|
||||
next
|
||||
end
|
||||
raise 'There might only be a maximum of three cells!' if cells.length > 3
|
||||
html << '<tr>'
|
||||
(1..3).each do
|
||||
cell = cells.shift
|
||||
cell = (cell ? CGI.escapeHTML(cell.strip) : ' ')
|
||||
html << "<td>#{cell}</td>"
|
||||
end
|
||||
html << "</tr>\n"
|
||||
end
|
||||
html << "</table>\n"
|
||||
end
|
||||
|
||||
def include_partial params
|
||||
partial = params.shift
|
||||
locals = {}
|
||||
params.each do |assignment|
|
||||
next if assignment.empty?
|
||||
_, var, value = assignment.split(/^([a-z_][a-zA-Z0-9_]*)\s*=\s*(.*)$/)
|
||||
raise "Invalid format '#{assignment}'. Should be '|includePartial|partial|var1=value|var2=value|." unless var
|
||||
locals[var.to_sym] = value or ''
|
||||
end
|
||||
@view.render :partial => partial, :locals => locals
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -1,56 +1,56 @@
|
|||
require 'selenium_on_rails'
|
||||
|
||||
module SeleniumOnRails
|
||||
module SuiteRenderer
|
||||
def test_suite_name path
|
||||
return 'All test cases' if [nil, '/'].include? path_to_relative_url(path)
|
||||
File.split(path)[-1].humanize
|
||||
end
|
||||
|
||||
def test_suites path
|
||||
suites = []
|
||||
|
||||
parent_path = File.join(File.split(path).slice(0..-2)) #all but last
|
||||
parent_path = path_to_relative_url parent_path
|
||||
suites << ['..', parent_path] unless parent_path.nil?
|
||||
|
||||
visit_all_tests path, '', Proc.new {|n, p| suites << [n,path_to_relative_url(p)]}, nil
|
||||
suites
|
||||
end
|
||||
|
||||
def test_cases path
|
||||
tests = []
|
||||
visit_all_tests path, '', nil, Proc.new {|n, p| tests << [n,p]}
|
||||
tests
|
||||
end
|
||||
|
||||
def link_to_test_case suite_name, filename
|
||||
name = suite_name + test_case_name(filename)
|
||||
link_to name, :action => :test_file, :testname => path_to_relative_url(filename).sub(/^\//,'')
|
||||
end
|
||||
|
||||
private ###############################################
|
||||
|
||||
def path_to_relative_url path
|
||||
slt = @controller.selenium_tests_path
|
||||
return nil unless path.index slt
|
||||
path.sub slt, ''
|
||||
end
|
||||
|
||||
def visit_all_tests path, suite_name, suite_consumer, test_consumer
|
||||
dirs = [] #add dirs to an array in order for files to be processed before dirs
|
||||
Dir.entries(path).sort.each do |e|
|
||||
next if skip_file?(e) or ['.','..'].include?(e)
|
||||
filename = File.join path, e
|
||||
if File.directory? filename
|
||||
dirs << [filename, "#{suite_name}#{e.humanize}."]
|
||||
suite_consumer.call("#{suite_name}#{e.humanize}", filename) if suite_consumer
|
||||
else
|
||||
test_consumer.call(suite_name, filename) if test_consumer
|
||||
end
|
||||
end
|
||||
#recurse through dirs
|
||||
dirs.each {|p, n| visit_all_tests p, n, suite_consumer, test_consumer }
|
||||
end
|
||||
end
|
||||
end
|
||||
require 'selenium_on_rails'
|
||||
|
||||
module SeleniumOnRails
|
||||
module SuiteRenderer
|
||||
def test_suite_name path
|
||||
return 'All test cases' if [nil, '/'].include? path_to_relative_url(path)
|
||||
File.split(path)[-1].humanize
|
||||
end
|
||||
|
||||
def test_suites path
|
||||
suites = []
|
||||
|
||||
parent_path = File.join(File.split(path).slice(0..-2)) #all but last
|
||||
parent_path = path_to_relative_url parent_path
|
||||
suites << ['..', parent_path] unless parent_path.nil?
|
||||
|
||||
visit_all_tests path, '', Proc.new {|n, p| suites << [n,path_to_relative_url(p)]}, nil
|
||||
suites
|
||||
end
|
||||
|
||||
def test_cases path
|
||||
tests = []
|
||||
visit_all_tests path, '', nil, Proc.new {|n, p| tests << [n,p]}
|
||||
tests
|
||||
end
|
||||
|
||||
def link_to_test_case suite_name, filename
|
||||
name = suite_name + test_case_name(filename)
|
||||
link_to name, :action => :test_file, :testname => path_to_relative_url(filename).sub(/^\//,'')
|
||||
end
|
||||
|
||||
private ###############################################
|
||||
|
||||
def path_to_relative_url path
|
||||
slt = @controller.selenium_tests_path
|
||||
return nil unless path.index slt
|
||||
path.sub slt, ''
|
||||
end
|
||||
|
||||
def visit_all_tests path, suite_name, suite_consumer, test_consumer
|
||||
dirs = [] #add dirs to an array in order for files to be processed before dirs
|
||||
Dir.entries(path).sort.each do |e|
|
||||
next if skip_file?(e) or ['.','..'].include?(e)
|
||||
filename = File.join path, e
|
||||
if File.directory? filename
|
||||
dirs << [filename, "#{suite_name}#{e.humanize}."]
|
||||
suite_consumer.call("#{suite_name}#{e.humanize}", filename) if suite_consumer
|
||||
else
|
||||
test_consumer.call(suite_name, filename) if test_consumer
|
||||
end
|
||||
end
|
||||
#recurse through dirs
|
||||
dirs.each {|p, n| visit_all_tests p, n, suite_consumer, test_consumer }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,116 +1,116 @@
|
|||
require 'selenium_on_rails/test_builder_actions'
|
||||
require 'selenium_on_rails/test_builder_accessors'
|
||||
|
||||
# Create test_builder_user_actions.rb to support actions included
|
||||
# in selenium-core's user-extensions.js
|
||||
#
|
||||
# See test_builder_user_actions.rb.example for examples matching
|
||||
# selenium-core's user-extensions.js.sample
|
||||
module SeleniumOnRails::TestBuilderUserActions
|
||||
end
|
||||
require 'selenium_on_rails/test_builder_user_actions' if File.exist?(File.expand_path(File.join(File.dirname(__FILE__), 'test_builder_user_actions.rb')))
|
||||
|
||||
|
||||
# Create test_builder_user_accessors.rb to support accessors
|
||||
# included in selenium-core's user-extensions.js
|
||||
#
|
||||
# See test_builder_user_accessors.rb.example for examples matching
|
||||
# selenium-core's user-extensions.js.sample
|
||||
module SeleniumOnRails::TestBuilderUserAccessors
|
||||
end
|
||||
require 'selenium_on_rails/test_builder_user_accessors' if File.exist?(File.expand_path(File.join(File.dirname(__FILE__), 'test_builder_user_accessors.rb')))
|
||||
|
||||
# Builds Selenium test table using a high-level Ruby interface. Normally
|
||||
# invoked through SeleniumOnRails::RSelenese.
|
||||
#
|
||||
# See SeleniumOnRails::TestBuilderActions for the available actions and
|
||||
# SeleniumOnRails::TestBuilderAccessors for the available checks.
|
||||
#
|
||||
# For more information on the commands supported by TestBuilder, see the
|
||||
# Selenium Commands Documentation at
|
||||
# http://release.openqa.org/selenium-core/nightly/reference.html.
|
||||
class SeleniumOnRails::TestBuilder
|
||||
include SeleniumOnRails::TestBuilderActions
|
||||
include SeleniumOnRails::TestBuilderAccessors
|
||||
include SeleniumOnRails::TestBuilderUserActions
|
||||
include SeleniumOnRails::TestBuilderUserAccessors
|
||||
|
||||
# Convert _str_ to a Selenium command name.
|
||||
def self.selenize str
|
||||
str.camelize.gsub(/^[A-Z]/) {|s| s.downcase }
|
||||
end
|
||||
|
||||
# Prepends _pattern_ with 'exact:' if it would be considered containing
|
||||
# string-match pattern otherwise.
|
||||
def exactize pattern
|
||||
pattern.include?(':') ? "exact:#{pattern}" : pattern
|
||||
end
|
||||
|
||||
# Create a new TestBuilder for _view_.
|
||||
def initialize view
|
||||
@view = view
|
||||
@output = ''
|
||||
@xml = Builder::XmlMarkup.new :indent => 2, :target => @output
|
||||
end
|
||||
|
||||
# Add a new table of tests, and return the HTML.
|
||||
def table title
|
||||
@xml.table do
|
||||
@xml.tr do @xml.th(title, :colspan => 3) end
|
||||
yield self
|
||||
end
|
||||
end
|
||||
|
||||
# Add a new test command using _cmd_, _target_ and _value_.
|
||||
def command cmd, target=nil, value=nil
|
||||
@xml.tr do
|
||||
_tdata cmd
|
||||
_tdata target
|
||||
_tdata value
|
||||
end
|
||||
end
|
||||
# :nodoc
|
||||
alias_method :command_verbatim, :command
|
||||
|
||||
# Same as _command_ but add _AndWait_ to the name of _cmd_.
|
||||
def command_and_wait cmd, target=nil, value=nil
|
||||
command_verbatim cmd.to_s + 'AndWait', target, value
|
||||
end
|
||||
|
||||
# Re routes commands in the provided block to #command_and_wait instead of
|
||||
# #command.
|
||||
def make_command_waiting
|
||||
self.class.send :alias_method, :command, :command_and_wait
|
||||
yield
|
||||
self.class.send :alias_method, :command, :command_verbatim
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
# If _url_ is a string, return unchanged. Otherwise, pass it to
|
||||
# ActionView#UrlHelper#url_for.
|
||||
def url_arg url
|
||||
if url.instance_of?(String) then url else exactize(@view.url_for(url)) end
|
||||
end
|
||||
|
||||
# If _arg_ is an array formats _arg_ to a textual representation.
|
||||
# Otherwise return unchanged.
|
||||
def collection_arg arg
|
||||
if arg.is_a? Array
|
||||
arg.collect {|e| e.gsub(/[\\,]/) {|s| "\\#{s}" } }.join(',')
|
||||
else
|
||||
arg
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Output a single TD element.
|
||||
def _tdata value
|
||||
if value
|
||||
@xml.td(value.to_s)
|
||||
else
|
||||
@xml.td do @xml.target! << ' ' end
|
||||
end
|
||||
end
|
||||
end
|
||||
require 'selenium_on_rails/test_builder_actions'
|
||||
require 'selenium_on_rails/test_builder_accessors'
|
||||
|
||||
# Create test_builder_user_actions.rb to support actions included
|
||||
# in selenium-core's user-extensions.js
|
||||
#
|
||||
# See test_builder_user_actions.rb.example for examples matching
|
||||
# selenium-core's user-extensions.js.sample
|
||||
module SeleniumOnRails::TestBuilderUserActions
|
||||
end
|
||||
require 'selenium_on_rails/test_builder_user_actions' if File.exist?(File.expand_path(File.join(File.dirname(__FILE__), 'test_builder_user_actions.rb')))
|
||||
|
||||
|
||||
# Create test_builder_user_accessors.rb to support accessors
|
||||
# included in selenium-core's user-extensions.js
|
||||
#
|
||||
# See test_builder_user_accessors.rb.example for examples matching
|
||||
# selenium-core's user-extensions.js.sample
|
||||
module SeleniumOnRails::TestBuilderUserAccessors
|
||||
end
|
||||
require 'selenium_on_rails/test_builder_user_accessors' if File.exist?(File.expand_path(File.join(File.dirname(__FILE__), 'test_builder_user_accessors.rb')))
|
||||
|
||||
# Builds Selenium test table using a high-level Ruby interface. Normally
|
||||
# invoked through SeleniumOnRails::RSelenese.
|
||||
#
|
||||
# See SeleniumOnRails::TestBuilderActions for the available actions and
|
||||
# SeleniumOnRails::TestBuilderAccessors for the available checks.
|
||||
#
|
||||
# For more information on the commands supported by TestBuilder, see the
|
||||
# Selenium Commands Documentation at
|
||||
# http://release.openqa.org/selenium-core/nightly/reference.html.
|
||||
class SeleniumOnRails::TestBuilder
|
||||
include SeleniumOnRails::TestBuilderActions
|
||||
include SeleniumOnRails::TestBuilderAccessors
|
||||
include SeleniumOnRails::TestBuilderUserActions
|
||||
include SeleniumOnRails::TestBuilderUserAccessors
|
||||
|
||||
# Convert _str_ to a Selenium command name.
|
||||
def self.selenize str
|
||||
str.camelize.gsub(/^[A-Z]/) {|s| s.downcase }
|
||||
end
|
||||
|
||||
# Prepends _pattern_ with 'exact:' if it would be considered containing
|
||||
# string-match pattern otherwise.
|
||||
def exactize pattern
|
||||
pattern.include?(':') ? "exact:#{pattern}" : pattern
|
||||
end
|
||||
|
||||
# Create a new TestBuilder for _view_.
|
||||
def initialize view
|
||||
@view = view
|
||||
@output = ''
|
||||
@xml = Builder::XmlMarkup.new :indent => 2, :target => @output
|
||||
end
|
||||
|
||||
# Add a new table of tests, and return the HTML.
|
||||
def table title
|
||||
@xml.table do
|
||||
@xml.tr do @xml.th(title, :colspan => 3) end
|
||||
yield self
|
||||
end
|
||||
end
|
||||
|
||||
# Add a new test command using _cmd_, _target_ and _value_.
|
||||
def command cmd, target=nil, value=nil
|
||||
@xml.tr do
|
||||
_tdata cmd
|
||||
_tdata target
|
||||
_tdata value
|
||||
end
|
||||
end
|
||||
# :nodoc
|
||||
alias_method :command_verbatim, :command
|
||||
|
||||
# Same as _command_ but add _AndWait_ to the name of _cmd_.
|
||||
def command_and_wait cmd, target=nil, value=nil
|
||||
command_verbatim cmd.to_s + 'AndWait', target, value
|
||||
end
|
||||
|
||||
# Re routes commands in the provided block to #command_and_wait instead of
|
||||
# #command.
|
||||
def make_command_waiting
|
||||
self.class.send :alias_method, :command, :command_and_wait
|
||||
yield
|
||||
self.class.send :alias_method, :command, :command_verbatim
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
# If _url_ is a string, return unchanged. Otherwise, pass it to
|
||||
# ActionView#UrlHelper#url_for.
|
||||
def url_arg url
|
||||
if url.instance_of?(String) then url else exactize(@view.url_for(url)) end
|
||||
end
|
||||
|
||||
# If _arg_ is an array formats _arg_ to a textual representation.
|
||||
# Otherwise return unchanged.
|
||||
def collection_arg arg
|
||||
if arg.is_a? Array
|
||||
arg.collect {|e| e.gsub(/[\\,]/) {|s| "\\#{s}" } }.join(',')
|
||||
else
|
||||
arg
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Output a single TD element.
|
||||
def _tdata value
|
||||
if value
|
||||
@xml.td(value.to_s)
|
||||
else
|
||||
@xml.td do @xml.target! << ' ' end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue