casebook-webrat 0.4.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +332 -0
- data/MIT-LICENSE.txt +19 -0
- data/README.rdoc +85 -0
- data/Rakefile +156 -0
- data/install.rb +1 -0
- data/lib/webrat.rb +34 -0
- data/lib/webrat/core.rb +14 -0
- data/lib/webrat/core/configuration.rb +104 -0
- data/lib/webrat/core/elements/area.rb +31 -0
- data/lib/webrat/core/elements/element.rb +33 -0
- data/lib/webrat/core/elements/field.rb +403 -0
- data/lib/webrat/core/elements/form.rb +103 -0
- data/lib/webrat/core/elements/label.rb +31 -0
- data/lib/webrat/core/elements/link.rb +92 -0
- data/lib/webrat/core/elements/select_option.rb +35 -0
- data/lib/webrat/core/locators.rb +20 -0
- data/lib/webrat/core/locators/area_locator.rb +38 -0
- data/lib/webrat/core/locators/button_locator.rb +54 -0
- data/lib/webrat/core/locators/field_by_id_locator.rb +37 -0
- data/lib/webrat/core/locators/field_labeled_locator.rb +56 -0
- data/lib/webrat/core/locators/field_locator.rb +25 -0
- data/lib/webrat/core/locators/field_named_locator.rb +41 -0
- data/lib/webrat/core/locators/form_locator.rb +19 -0
- data/lib/webrat/core/locators/label_locator.rb +34 -0
- data/lib/webrat/core/locators/link_locator.rb +66 -0
- data/lib/webrat/core/locators/locator.rb +20 -0
- data/lib/webrat/core/locators/select_option_locator.rb +59 -0
- data/lib/webrat/core/logging.rb +21 -0
- data/lib/webrat/core/matchers.rb +4 -0
- data/lib/webrat/core/matchers/have_content.rb +73 -0
- data/lib/webrat/core/matchers/have_selector.rb +74 -0
- data/lib/webrat/core/matchers/have_tag.rb +21 -0
- data/lib/webrat/core/matchers/have_xpath.rb +147 -0
- data/lib/webrat/core/methods.rb +61 -0
- data/lib/webrat/core/mime.rb +29 -0
- data/lib/webrat/core/save_and_open_page.rb +50 -0
- data/lib/webrat/core/scope.rb +350 -0
- data/lib/webrat/core/session.rb +281 -0
- data/lib/webrat/core/xml.rb +115 -0
- data/lib/webrat/core/xml/hpricot.rb +19 -0
- data/lib/webrat/core/xml/nokogiri.rb +76 -0
- data/lib/webrat/core/xml/rexml.rb +24 -0
- data/lib/webrat/core_extensions/blank.rb +58 -0
- data/lib/webrat/core_extensions/deprecate.rb +8 -0
- data/lib/webrat/core_extensions/detect_mapped.rb +12 -0
- data/lib/webrat/core_extensions/meta_class.rb +6 -0
- data/lib/webrat/core_extensions/nil_to_param.rb +5 -0
- data/lib/webrat/core_extensions/tcp_socket.rb +27 -0
- data/lib/webrat/mechanize.rb +74 -0
- data/lib/webrat/merb.rb +9 -0
- data/lib/webrat/merb_session.rb +65 -0
- data/lib/webrat/rack.rb +24 -0
- data/lib/webrat/rails.rb +105 -0
- data/lib/webrat/rspec-rails.rb +13 -0
- data/lib/webrat/selenium.rb +80 -0
- data/lib/webrat/selenium/application_server.rb +71 -0
- data/lib/webrat/selenium/location_strategy_javascript/button.js +12 -0
- data/lib/webrat/selenium/location_strategy_javascript/label.js +16 -0
- data/lib/webrat/selenium/location_strategy_javascript/webrat.js +5 -0
- data/lib/webrat/selenium/location_strategy_javascript/webratlink.js +9 -0
- data/lib/webrat/selenium/location_strategy_javascript/webratlinkwithin.js +15 -0
- data/lib/webrat/selenium/location_strategy_javascript/webratselectwithoption.js +5 -0
- data/lib/webrat/selenium/matchers.rb +4 -0
- data/lib/webrat/selenium/matchers/have_content.rb +66 -0
- data/lib/webrat/selenium/matchers/have_selector.rb +49 -0
- data/lib/webrat/selenium/matchers/have_tag.rb +72 -0
- data/lib/webrat/selenium/matchers/have_xpath.rb +45 -0
- data/lib/webrat/selenium/merb_application_server.rb +48 -0
- data/lib/webrat/selenium/rails_application_server.rb +42 -0
- data/lib/webrat/selenium/selenium_extensions.js +6 -0
- data/lib/webrat/selenium/selenium_rc_server.rb +81 -0
- data/lib/webrat/selenium/selenium_session.rb +241 -0
- data/lib/webrat/selenium/sinatra_application_server.rb +35 -0
- data/lib/webrat/sinatra.rb +44 -0
- data/vendor/selenium-server.jar +0 -0
- metadata +147 -0
@@ -0,0 +1,48 @@
|
|
1
|
+
module Webrat
|
2
|
+
module Selenium
|
3
|
+
|
4
|
+
class MerbApplicationServer < ApplicationServer
|
5
|
+
|
6
|
+
def start
|
7
|
+
system start_command
|
8
|
+
end
|
9
|
+
|
10
|
+
def stop
|
11
|
+
silence_stream(STDOUT) do
|
12
|
+
pid = File.read(pid_file)
|
13
|
+
system("kill -9 #{pid}")
|
14
|
+
FileUtils.rm_f pid_file
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def fail
|
19
|
+
$stderr.puts
|
20
|
+
$stderr.puts
|
21
|
+
$stderr.puts "==> Failed to boot the Merb application server... exiting!"
|
22
|
+
$stderr.puts
|
23
|
+
$stderr.puts "Verify you can start a Merb server on port #{Webrat.configuration.application_port} with the following command:"
|
24
|
+
$stderr.puts
|
25
|
+
$stderr.puts " #{start_command}"
|
26
|
+
exit
|
27
|
+
end
|
28
|
+
|
29
|
+
def pid_file
|
30
|
+
"log/merb.#{Webrat.configuration.application_port}.pid"
|
31
|
+
end
|
32
|
+
|
33
|
+
def start_command
|
34
|
+
"#{merb_command} -d -p #{Webrat.configuration.application_port} -e #{Webrat.configuration.application_environment}"
|
35
|
+
end
|
36
|
+
|
37
|
+
def merb_command
|
38
|
+
if File.exist?('bin/merb')
|
39
|
+
merb_cmd = 'bin/merb'
|
40
|
+
else
|
41
|
+
merb_cmd = 'merb'
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Webrat
|
2
|
+
module Selenium
|
3
|
+
|
4
|
+
class RailsApplicationServer < ApplicationServer
|
5
|
+
|
6
|
+
def start
|
7
|
+
system start_command
|
8
|
+
end
|
9
|
+
|
10
|
+
def stop
|
11
|
+
silence_stream(STDOUT) do
|
12
|
+
system stop_command
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def fail
|
17
|
+
$stderr.puts
|
18
|
+
$stderr.puts
|
19
|
+
$stderr.puts "==> Failed to boot the Rails application server... exiting!"
|
20
|
+
$stderr.puts
|
21
|
+
$stderr.puts "Verify you can start a Rails server on port #{Webrat.configuration.application_port} with the following command:"
|
22
|
+
$stderr.puts
|
23
|
+
$stderr.puts " #{start_command}"
|
24
|
+
exit
|
25
|
+
end
|
26
|
+
|
27
|
+
def pid_file
|
28
|
+
prepare_pid_file("#{RAILS_ROOT}/tmp/pids", "mongrel_selenium.pid")
|
29
|
+
end
|
30
|
+
|
31
|
+
def start_command
|
32
|
+
"mongrel_rails start -d --chdir='#{RAILS_ROOT}' --port=#{Webrat.configuration.application_port} --environment=#{Webrat.configuration.application_environment} --pid #{pid_file} &"
|
33
|
+
end
|
34
|
+
|
35
|
+
def stop_command
|
36
|
+
"mongrel_rails stop -c #{RAILS_ROOT} --pid #{pid_file}"
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
module Webrat
|
2
|
+
module Selenium
|
3
|
+
|
4
|
+
class SeleniumRCServer
|
5
|
+
|
6
|
+
def self.boot
|
7
|
+
new.boot
|
8
|
+
end
|
9
|
+
|
10
|
+
def boot
|
11
|
+
return if selenium_grid?
|
12
|
+
|
13
|
+
start
|
14
|
+
wait
|
15
|
+
stop_at_exit
|
16
|
+
end
|
17
|
+
|
18
|
+
def start
|
19
|
+
silence_stream(STDOUT) do
|
20
|
+
remote_control.start :background => true
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def stop_at_exit
|
25
|
+
at_exit do
|
26
|
+
stop
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def remote_control
|
31
|
+
return @remote_control if @remote_control
|
32
|
+
|
33
|
+
@remote_control = ::Selenium::RemoteControl::RemoteControl.new("0.0.0.0", Webrat.configuration.selenium_server_port, 5)
|
34
|
+
@remote_control.jar_file = jar_path
|
35
|
+
@remote_control.additional_args = Webrat.configuration.selenium_additional_startup_args
|
36
|
+
|
37
|
+
return @remote_control
|
38
|
+
end
|
39
|
+
|
40
|
+
def jar_path
|
41
|
+
File.expand_path(__FILE__ + "../../../../../vendor/selenium-server.jar")
|
42
|
+
end
|
43
|
+
|
44
|
+
def selenium_grid?
|
45
|
+
Webrat.configuration.selenium_server_address
|
46
|
+
end
|
47
|
+
|
48
|
+
def wait
|
49
|
+
$stderr.print "==> Waiting for Selenium RC server on port #{Webrat.configuration.selenium_server_port}... "
|
50
|
+
wait_for_socket
|
51
|
+
$stderr.print "Ready!\n"
|
52
|
+
rescue SocketError
|
53
|
+
fail
|
54
|
+
end
|
55
|
+
|
56
|
+
def wait_for_socket
|
57
|
+
silence_stream(STDOUT) do
|
58
|
+
TCPSocket.wait_for_service_with_timeout \
|
59
|
+
:host => (Webrat.configuration.selenium_server_address || "0.0.0.0"),
|
60
|
+
:port => Webrat.configuration.selenium_server_port,
|
61
|
+
:timeout => 15 # seconds
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def fail
|
66
|
+
$stderr.puts
|
67
|
+
$stderr.puts
|
68
|
+
$stderr.puts "==> Failed to boot the Selenium RC server... exiting!"
|
69
|
+
exit
|
70
|
+
end
|
71
|
+
|
72
|
+
def stop
|
73
|
+
silence_stream(STDOUT) do
|
74
|
+
::Selenium::RemoteControl::RemoteControl.new("0.0.0.0", Webrat.configuration.selenium_server_port, 5).stop
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,241 @@
|
|
1
|
+
require "webrat/core/save_and_open_page"
|
2
|
+
require "webrat/selenium/selenium_rc_server"
|
3
|
+
require "webrat/selenium/application_server"
|
4
|
+
|
5
|
+
module Webrat
|
6
|
+
class TimeoutError < WebratError
|
7
|
+
end
|
8
|
+
|
9
|
+
class SeleniumResponse
|
10
|
+
attr_reader :body
|
11
|
+
attr_reader :session
|
12
|
+
|
13
|
+
def initialize(session, body)
|
14
|
+
@session = session
|
15
|
+
@body = body
|
16
|
+
end
|
17
|
+
|
18
|
+
def selenium
|
19
|
+
session.selenium
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class SeleniumSession
|
24
|
+
include Webrat::SaveAndOpenPage
|
25
|
+
|
26
|
+
def initialize(*args) # :nodoc:
|
27
|
+
end
|
28
|
+
|
29
|
+
def simulate
|
30
|
+
end
|
31
|
+
|
32
|
+
def automate
|
33
|
+
yield
|
34
|
+
end
|
35
|
+
|
36
|
+
def visit(url)
|
37
|
+
selenium.open(url)
|
38
|
+
end
|
39
|
+
|
40
|
+
webrat_deprecate :visits, :visit
|
41
|
+
|
42
|
+
def fill_in(field_identifier, options)
|
43
|
+
locator = "webrat=#{Regexp.escape(field_identifier)}"
|
44
|
+
selenium.wait_for_element locator, :timeout_in_seconds => 5
|
45
|
+
selenium.type(locator, "#{options[:with]}")
|
46
|
+
end
|
47
|
+
|
48
|
+
webrat_deprecate :fills_in, :fill_in
|
49
|
+
|
50
|
+
def response
|
51
|
+
SeleniumResponse.new(self, response_body)
|
52
|
+
end
|
53
|
+
|
54
|
+
def response_body #:nodoc:
|
55
|
+
selenium.get_html_source
|
56
|
+
end
|
57
|
+
|
58
|
+
def click_button(button_text_or_regexp = nil, options = {})
|
59
|
+
if button_text_or_regexp.is_a?(Hash) && options == {}
|
60
|
+
pattern, options = nil, button_text_or_regexp
|
61
|
+
elsif button_text_or_regexp
|
62
|
+
pattern = adjust_if_regexp(button_text_or_regexp)
|
63
|
+
end
|
64
|
+
pattern ||= '*'
|
65
|
+
locator = "button=#{pattern}"
|
66
|
+
|
67
|
+
selenium.wait_for_element locator, :timeout_in_seconds => 5
|
68
|
+
selenium.click locator
|
69
|
+
end
|
70
|
+
|
71
|
+
webrat_deprecate :clicks_button, :click_button
|
72
|
+
|
73
|
+
def click_link(link_text_or_regexp, options = {})
|
74
|
+
pattern = adjust_if_regexp(link_text_or_regexp)
|
75
|
+
locator = "webratlink=#{pattern}"
|
76
|
+
selenium.wait_for_element locator, :timeout_in_seconds => 5
|
77
|
+
selenium.click locator
|
78
|
+
end
|
79
|
+
|
80
|
+
webrat_deprecate :clicks_link, :click_link
|
81
|
+
|
82
|
+
def click_link_within(selector, link_text, options = {})
|
83
|
+
locator = "webratlinkwithin=#{selector}|#{link_text}"
|
84
|
+
selenium.wait_for_element locator, :timeout_in_seconds => 5
|
85
|
+
selenium.click locator
|
86
|
+
end
|
87
|
+
|
88
|
+
webrat_deprecate :clicks_link_within, :click_link_within
|
89
|
+
|
90
|
+
def select(option_text, options = {})
|
91
|
+
id_or_name_or_label = options[:from]
|
92
|
+
|
93
|
+
if id_or_name_or_label
|
94
|
+
select_locator = "webrat=#{id_or_name_or_label}"
|
95
|
+
else
|
96
|
+
select_locator = "webratselectwithoption=#{option_text}"
|
97
|
+
end
|
98
|
+
|
99
|
+
selenium.wait_for_element select_locator, :timeout_in_seconds => 5
|
100
|
+
selenium.select(select_locator, option_text)
|
101
|
+
end
|
102
|
+
|
103
|
+
webrat_deprecate :selects, :select
|
104
|
+
|
105
|
+
def choose(label_text)
|
106
|
+
locator = "webrat=#{label_text}"
|
107
|
+
selenium.wait_for_element locator, :timeout_in_seconds => 5
|
108
|
+
selenium.click locator
|
109
|
+
end
|
110
|
+
|
111
|
+
webrat_deprecate :chooses, :choose
|
112
|
+
|
113
|
+
def check(label_text)
|
114
|
+
locator = "webrat=#{label_text}"
|
115
|
+
selenium.wait_for_element locator, :timeout_in_seconds => 5
|
116
|
+
selenium.click locator
|
117
|
+
end
|
118
|
+
alias_method :uncheck, :check
|
119
|
+
|
120
|
+
webrat_deprecate :checks, :check
|
121
|
+
|
122
|
+
def fire_event(field_identifier, event)
|
123
|
+
locator = "webrat=#{Regexp.escape(field_identifier)}"
|
124
|
+
selenium.fire_event(locator, "#{event}")
|
125
|
+
end
|
126
|
+
|
127
|
+
def key_down(field_identifier, key_code)
|
128
|
+
locator = "webrat=#{Regexp.escape(field_identifier)}"
|
129
|
+
selenium.key_down(locator, key_code)
|
130
|
+
end
|
131
|
+
|
132
|
+
def key_up(field_identifier, key_code)
|
133
|
+
locator = "webrat=#{Regexp.escape(field_identifier)}"
|
134
|
+
selenium.key_up(locator, key_code)
|
135
|
+
end
|
136
|
+
|
137
|
+
def wait_for(params={})
|
138
|
+
timeout = params[:timeout] || 5
|
139
|
+
message = params[:message] || "Timeout exceeded"
|
140
|
+
|
141
|
+
begin_time = Time.now
|
142
|
+
|
143
|
+
while (Time.now - begin_time) < timeout
|
144
|
+
value = nil
|
145
|
+
|
146
|
+
begin
|
147
|
+
value = yield
|
148
|
+
rescue ::Spec::Expectations::ExpectationNotMetError, ::Selenium::CommandError, Webrat::WebratError
|
149
|
+
value = nil
|
150
|
+
end
|
151
|
+
|
152
|
+
return value if value
|
153
|
+
|
154
|
+
sleep 0.25
|
155
|
+
end
|
156
|
+
|
157
|
+
raise Webrat::TimeoutError.new(message + " (after #{timeout} sec)")
|
158
|
+
true
|
159
|
+
end
|
160
|
+
|
161
|
+
def selenium
|
162
|
+
return $browser if $browser
|
163
|
+
setup
|
164
|
+
$browser
|
165
|
+
end
|
166
|
+
|
167
|
+
webrat_deprecate :browser, :selenium
|
168
|
+
|
169
|
+
|
170
|
+
def save_and_open_screengrab
|
171
|
+
return unless File.exist?(saved_page_dir)
|
172
|
+
|
173
|
+
filename = "#{saved_page_dir}/webrat-#{Time.now.to_i}.png"
|
174
|
+
|
175
|
+
if $browser.chrome_backend?
|
176
|
+
$browser.capture_entire_page_screenshot(filename, '')
|
177
|
+
else
|
178
|
+
$browser.capture_screenshot(filename)
|
179
|
+
end
|
180
|
+
open_in_browser(filename)
|
181
|
+
end
|
182
|
+
|
183
|
+
protected
|
184
|
+
|
185
|
+
def silence_stream(stream)
|
186
|
+
old_stream = stream.dup
|
187
|
+
stream.reopen(RUBY_PLATFORM =~ /mswin/ ? 'NUL:' : '/dev/null')
|
188
|
+
stream.sync = true
|
189
|
+
yield
|
190
|
+
ensure
|
191
|
+
stream.reopen(old_stream)
|
192
|
+
end
|
193
|
+
|
194
|
+
def setup #:nodoc:
|
195
|
+
Webrat::Selenium::SeleniumRCServer.boot
|
196
|
+
Webrat::Selenium::ApplicationServer.boot
|
197
|
+
|
198
|
+
create_browser
|
199
|
+
$browser.start
|
200
|
+
|
201
|
+
extend_selenium
|
202
|
+
define_location_strategies
|
203
|
+
$browser.window_maximize
|
204
|
+
end
|
205
|
+
|
206
|
+
|
207
|
+
def create_browser
|
208
|
+
$browser = ::Selenium::Client::Driver.new(Webrat.configuration.selenium_server_address || "localhost",
|
209
|
+
Webrat.configuration.selenium_server_port, Webrat.configuration.selenium_browser_key, "http://#{Webrat.configuration.application_address}:#{Webrat.configuration.application_port}")
|
210
|
+
$browser.set_speed(0) unless Webrat.configuration.selenium_server_address
|
211
|
+
|
212
|
+
at_exit do
|
213
|
+
silence_stream(STDOUT) do
|
214
|
+
$browser.stop
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
def adjust_if_regexp(text_or_regexp) #:nodoc:
|
220
|
+
if text_or_regexp.is_a?(Regexp)
|
221
|
+
"evalregex:#{text_or_regexp.inspect}"
|
222
|
+
else
|
223
|
+
"evalregex:/#{text_or_regexp}/"
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
def extend_selenium #:nodoc:
|
228
|
+
extensions_file = File.join(File.dirname(__FILE__), "selenium_extensions.js")
|
229
|
+
extenions_js = File.read(extensions_file)
|
230
|
+
selenium.get_eval(extenions_js)
|
231
|
+
end
|
232
|
+
|
233
|
+
def define_location_strategies #:nodoc:
|
234
|
+
Dir[File.join(File.dirname(__FILE__), "location_strategy_javascript", "*.js")].sort.each do |file|
|
235
|
+
strategy_js = File.read(file)
|
236
|
+
strategy_name = File.basename(file, '.js')
|
237
|
+
selenium.add_location_strategy(strategy_name, strategy_js)
|
238
|
+
end
|
239
|
+
end
|
240
|
+
end
|
241
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Webrat
|
2
|
+
module Selenium
|
3
|
+
|
4
|
+
class SinatraApplicationServer < ApplicationServer
|
5
|
+
|
6
|
+
def start
|
7
|
+
fork do
|
8
|
+
File.open('rack.pid', 'w') { |fp| fp.write Process.pid }
|
9
|
+
exec 'rackup', File.expand_path(Dir.pwd + '/config.ru'), '-p', Webrat.configuration.application_port.to_s
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def stop
|
14
|
+
silence_stream(STDOUT) do
|
15
|
+
pid = File.read(pid_file)
|
16
|
+
system("kill -9 #{pid}")
|
17
|
+
FileUtils.rm_f pid_file
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def fail
|
22
|
+
$stderr.puts
|
23
|
+
$stderr.puts
|
24
|
+
$stderr.puts "==> Failed to boot the Sinatra application server... exiting!"
|
25
|
+
exit
|
26
|
+
end
|
27
|
+
|
28
|
+
def pid_file
|
29
|
+
prepare_pid_file(Dir.pwd, 'rack.pid')
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|