capybara 0.3.0 → 0.3.5
Sign up to get free protection for your applications and to get access to all the features.
- data/Manifest.txt +4 -0
- data/README.rdoc +45 -5
- data/lib/capybara.rb +11 -4
- data/lib/capybara/driver/base.rb +3 -0
- data/lib/capybara/driver/celerity_driver.rb +44 -9
- data/lib/capybara/driver/rack_test_driver.rb +80 -16
- data/lib/capybara/driver/selenium_driver.rb +41 -9
- data/lib/capybara/dsl.rb +4 -10
- data/lib/capybara/node.rb +8 -0
- data/lib/capybara/rails.rb +8 -2
- data/lib/capybara/save_and_open_page.rb +5 -1
- data/lib/capybara/searchable.rb +17 -9
- data/lib/capybara/server.rb +35 -23
- data/lib/capybara/session.rb +91 -22
- data/lib/capybara/xpath.rb +66 -27
- data/spec/driver/celerity_driver_spec.rb +2 -2
- data/spec/driver/culerity_driver_spec.rb +1 -2
- data/spec/driver/rack_test_driver_spec.rb +0 -1
- data/spec/driver/remote_culerity_driver_spec.rb +9 -5
- data/spec/driver/selenium_driver_spec.rb +0 -1
- data/spec/drivers_spec.rb +24 -32
- data/spec/dsl/all_spec.rb +56 -25
- data/spec/dsl/attach_file_spec.rb +49 -51
- data/spec/dsl/check_spec.rb +12 -1
- data/spec/dsl/choose_spec.rb +19 -21
- data/spec/dsl/click_button_spec.rb +140 -87
- data/spec/dsl/click_link_spec.rb +88 -68
- data/spec/dsl/click_spec.rb +20 -22
- data/spec/dsl/current_url_spec.rb +6 -8
- data/spec/dsl/fill_in_spec.rb +75 -67
- data/spec/dsl/find_button_spec.rb +12 -14
- data/spec/dsl/find_by_id_spec.rb +16 -0
- data/spec/dsl/find_field_spec.rb +17 -19
- data/spec/dsl/find_link_spec.rb +13 -15
- data/spec/dsl/find_spec.rb +44 -23
- data/spec/dsl/has_button_spec.rb +32 -0
- data/spec/dsl/has_content_spec.rb +79 -81
- data/spec/dsl/has_css_spec.rb +81 -83
- data/spec/dsl/has_field_spec.rb +96 -0
- data/spec/dsl/has_link_spec.rb +33 -0
- data/spec/dsl/has_xpath_spec.rb +97 -89
- data/spec/dsl/locate_spec.rb +47 -26
- data/spec/dsl/select_spec.rb +61 -17
- data/spec/dsl/uncheck_spec.rb +17 -25
- data/spec/dsl/within_spec.rb +112 -104
- data/spec/public/test.js +3 -0
- data/spec/searchable_spec.rb +1 -1
- data/spec/server_spec.rb +7 -7
- data/spec/session/celerity_session_spec.rb +2 -2
- data/spec/session/culerity_session_spec.rb +1 -1
- data/spec/session_spec.rb +7 -0
- data/spec/session_with_javascript_support_spec.rb +139 -120
- data/spec/spec_helper.rb +7 -2
- data/spec/test_app.rb +8 -4
- data/spec/views/form.erb +50 -2
- data/spec/views/tables.erb +61 -1
- data/spec/views/with_html.erb +8 -2
- data/spec/views/with_js.erb +4 -0
- data/spec/xpath_spec.rb +17 -0
- metadata +6 -2
data/Manifest.txt
CHANGED
@@ -40,11 +40,15 @@ spec/dsl/click_spec.rb
|
|
40
40
|
spec/dsl/current_url_spec.rb
|
41
41
|
spec/dsl/fill_in_spec.rb
|
42
42
|
spec/dsl/find_button_spec.rb
|
43
|
+
spec/dsl/find_by_id_spec.rb
|
43
44
|
spec/dsl/find_field_spec.rb
|
44
45
|
spec/dsl/find_link_spec.rb
|
45
46
|
spec/dsl/find_spec.rb
|
47
|
+
spec/dsl/has_button_spec.rb
|
46
48
|
spec/dsl/has_content_spec.rb
|
47
49
|
spec/dsl/has_css_spec.rb
|
50
|
+
spec/dsl/has_field_spec.rb
|
51
|
+
spec/dsl/has_link_spec.rb
|
48
52
|
spec/dsl/has_xpath_spec.rb
|
49
53
|
spec/dsl/locate_spec.rb
|
50
54
|
spec/dsl/select_spec.rb
|
data/README.rdoc
CHANGED
@@ -12,16 +12,22 @@ Celerity and Selenium support built in.
|
|
12
12
|
|
13
13
|
== Install:
|
14
14
|
|
15
|
-
|
15
|
+
Install as a gem:
|
16
16
|
|
17
17
|
sudo gem install capybara
|
18
18
|
|
19
|
+
On OSX you may have to install libffi, you can install it via MacPorts with:
|
20
|
+
|
21
|
+
sudo port install libffi
|
22
|
+
|
19
23
|
== Development:
|
20
24
|
|
21
25
|
* Source hosted at {GitHub}[http://github.com/jnicklas/capybara].
|
22
26
|
* Please direct questions, discussions at the {mailing list}[http://groups.google.com/group/ruby-capybara].
|
23
27
|
* Report issues on {GitHub Issues}[http://github.com/jnicklas/capybara/issues]
|
24
|
-
|
28
|
+
|
29
|
+
Pull requests are very welcome! Make sure your patches are well tested, Capybara is
|
30
|
+
a testing tool after all.
|
25
31
|
|
26
32
|
== Using Capybara with Cucumber
|
27
33
|
|
@@ -110,7 +116,7 @@ Culerity doesn't seem to be working under Ruby 1.9 at the moment.
|
|
110
116
|
|
111
117
|
== The DSL
|
112
118
|
|
113
|
-
Capybara's DSL is inspired by Webrat. While backwards compatibility is retained
|
119
|
+
Capybara's DSL is inspired by Webrat. While backwards compatibility is retained
|
114
120
|
in a lot of cases, there are certain important differences.
|
115
121
|
|
116
122
|
Unlike in Webrat, all searches in Capybara are *case sensitive*. This is because
|
@@ -189,7 +195,7 @@ certain elements, and working with and manipulating those elements.
|
|
189
195
|
page.has_xpath?('//table/tr')
|
190
196
|
page.has_css?('table tr.foo')
|
191
197
|
page.has_content?('foo')
|
192
|
-
|
198
|
+
|
193
199
|
You can use with RSpecs magic matchers:
|
194
200
|
|
195
201
|
page.should have_xpath('//table/tr')
|
@@ -206,7 +212,7 @@ You can also find specific elements, in order to manipulate them:
|
|
206
212
|
find_field('First Name').value
|
207
213
|
find_link('Hello').visible?
|
208
214
|
find_button('Send').click
|
209
|
-
|
215
|
+
|
210
216
|
find('//table/tr').click
|
211
217
|
wait_for("//*[@id='overlay'").find("//h1").click
|
212
218
|
all('a').each { |a| a[:href] }
|
@@ -276,6 +282,27 @@ examples. Just load the dsl and include it anywhere:
|
|
276
282
|
end
|
277
283
|
click_link 'Sign in'
|
278
284
|
|
285
|
+
== Calling remote servers
|
286
|
+
|
287
|
+
Normally Capybara expects to be testing an in-process Rack application, but you can also use it to talk to a web server running anywhere on the internets, by setting app_host:
|
288
|
+
|
289
|
+
require 'capybara'
|
290
|
+
require 'capybara/dsl'
|
291
|
+
|
292
|
+
include Capybara
|
293
|
+
Capybara.current_driver = :selenium
|
294
|
+
Capybara.app_host = 'http://www.google.com'
|
295
|
+
|
296
|
+
visit('/')
|
297
|
+
|
298
|
+
Note that rack-test does not support running against a remote server. With drivers that support it, you can also visit any URL directly:
|
299
|
+
|
300
|
+
visit('http://www.google.com')
|
301
|
+
|
302
|
+
By default Capybara will try to boot a rack application automatically. You might want to switch off Capybara's rack server if you are running against a remote application:
|
303
|
+
|
304
|
+
Capybara.run_server = false
|
305
|
+
|
279
306
|
== Using the sessions manually
|
280
307
|
|
281
308
|
For ultimate control, you can instantiate and use a session manually.
|
@@ -296,12 +323,16 @@ if you want to use CSS with your 'within' declarations for example, you'll need
|
|
296
323
|
to do:
|
297
324
|
|
298
325
|
within(:css, 'ul li') { ... }
|
326
|
+
find(:css, 'ul li').text
|
327
|
+
locate(:css, 'input#name').value
|
299
328
|
|
300
329
|
Alternatively you can set the default selector to CSS, which may help if you are
|
301
330
|
moving from Webrat and used CSS a lot, or simply generally prefer CSS:
|
302
331
|
|
303
332
|
Capybara.default_selector = :css
|
304
333
|
within('ul li') { ... }
|
334
|
+
find('ul li').text
|
335
|
+
locate('input#name').value
|
305
336
|
|
306
337
|
== Gotchas:
|
307
338
|
|
@@ -338,6 +369,15 @@ The following people have dedicated their time and effort to Capybara:
|
|
338
369
|
* Dan Dofter
|
339
370
|
* Thorbjørn Hermansen
|
340
371
|
* Louis T.
|
372
|
+
* Stephan Hagemann
|
373
|
+
* Graham Ashton
|
374
|
+
* Joseph Wilk
|
375
|
+
* Matt Wynne
|
376
|
+
* Piotr Sarnacki
|
377
|
+
* Pavel Gabriel
|
378
|
+
* Bodaniel Jeanes
|
379
|
+
* Carl Porth
|
380
|
+
* Darrin Holst
|
341
381
|
|
342
382
|
== License:
|
343
383
|
|
data/lib/capybara.rb
CHANGED
@@ -2,19 +2,21 @@ require 'timeout'
|
|
2
2
|
require 'nokogiri'
|
3
3
|
|
4
4
|
module Capybara
|
5
|
-
VERSION = '0.3.
|
5
|
+
VERSION = '0.3.5'
|
6
6
|
|
7
7
|
class CapybaraError < StandardError; end
|
8
8
|
class DriverNotFoundError < CapybaraError; end
|
9
9
|
class ElementNotFound < CapybaraError; end
|
10
|
+
class OptionNotFound < ElementNotFound; end
|
11
|
+
class UnselectNotAllowed < CapybaraError; end
|
10
12
|
class NotSupportedByDriverError < CapybaraError; end
|
11
13
|
class TimeoutError < CapybaraError; end
|
14
|
+
class LocateHiddenElementError < CapybaraError; end
|
12
15
|
class InfiniteRedirectError < TimeoutError; end
|
13
16
|
|
14
17
|
class << self
|
15
|
-
attr_accessor :debug, :asset_root, :app_host
|
16
|
-
|
17
|
-
|
18
|
+
attr_accessor :debug, :asset_root, :app_host, :run_server, :default_host
|
19
|
+
attr_accessor :default_selector, :default_wait_time, :ignore_hidden_elements
|
18
20
|
|
19
21
|
def default_selector
|
20
22
|
@default_selector ||= :xpath
|
@@ -44,3 +46,8 @@ module Capybara
|
|
44
46
|
autoload :Selenium, 'capybara/driver/selenium_driver'
|
45
47
|
end
|
46
48
|
end
|
49
|
+
|
50
|
+
Capybara.run_server = true
|
51
|
+
Capybara.default_selector = :xpath
|
52
|
+
Capybara.default_wait_time = 2
|
53
|
+
Capybara.ignore_hidden_elements = false
|
data/lib/capybara/driver/base.rb
CHANGED
@@ -10,7 +10,15 @@ class Capybara::Driver::Celerity < Capybara::Driver::Base
|
|
10
10
|
else
|
11
11
|
node.send(name.to_sym)
|
12
12
|
end
|
13
|
-
return value if value and not value.empty?
|
13
|
+
return value if value and not value.to_s.empty?
|
14
|
+
end
|
15
|
+
|
16
|
+
def value
|
17
|
+
if tag_name == "select" and node.multiple?
|
18
|
+
node.selected_options
|
19
|
+
else
|
20
|
+
super
|
21
|
+
end
|
14
22
|
end
|
15
23
|
|
16
24
|
def set(value)
|
@@ -19,6 +27,26 @@ class Capybara::Driver::Celerity < Capybara::Driver::Base
|
|
19
27
|
|
20
28
|
def select(option)
|
21
29
|
node.select(option)
|
30
|
+
rescue
|
31
|
+
options = all(:xpath, "//option").map { |o| "'#{o.text}'" }.join(', ')
|
32
|
+
raise Capybara::OptionNotFound, "No such option '#{option}' in this select box. Available options: #{options}"
|
33
|
+
end
|
34
|
+
|
35
|
+
def unselect(option)
|
36
|
+
unless node.multiple?
|
37
|
+
raise Capybara::UnselectNotAllowed, "Cannot unselect option '#{option}' from single select box."
|
38
|
+
end
|
39
|
+
|
40
|
+
# FIXME: couldn't find a clean way to unselect, so clear and reselect
|
41
|
+
selected_options = node.selected_options
|
42
|
+
if unselect_option = selected_options.detect { |value| value == option } ||
|
43
|
+
selected_options.detect { |value| value.index(option) }
|
44
|
+
node.clear
|
45
|
+
(selected_options - [unselect_option]).each { |value| node.select_value(value) }
|
46
|
+
else
|
47
|
+
options = all(:xpath, "//option").map { |o| "'#{o.text}'" }.join(', ')
|
48
|
+
raise Capybara::OptionNotFound, "No such option '#{option}' in this select box. Available options: #{options}"
|
49
|
+
end
|
22
50
|
end
|
23
51
|
|
24
52
|
def click
|
@@ -44,6 +72,18 @@ class Capybara::Driver::Celerity < Capybara::Driver::Base
|
|
44
72
|
def path
|
45
73
|
node.xpath
|
46
74
|
end
|
75
|
+
|
76
|
+
def trigger(event)
|
77
|
+
node.fire_event(event.to_s)
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
def all_unfiltered(locator)
|
83
|
+
noko_node = Nokogiri::HTML(driver.body).xpath(node.xpath).first
|
84
|
+
all_nodes = noko_node.xpath(locator).map { |n| n.path }.join(' | ')
|
85
|
+
driver.find(all_nodes)
|
86
|
+
end
|
47
87
|
|
48
88
|
end
|
49
89
|
|
@@ -51,9 +91,8 @@ class Capybara::Driver::Celerity < Capybara::Driver::Base
|
|
51
91
|
|
52
92
|
def initialize(app)
|
53
93
|
@app = app
|
54
|
-
|
55
|
-
|
56
|
-
end
|
94
|
+
@rack_server = Capybara::Server.new(@app)
|
95
|
+
@rack_server.boot if Capybara.run_server
|
57
96
|
end
|
58
97
|
|
59
98
|
def visit(path)
|
@@ -98,11 +137,7 @@ class Capybara::Driver::Celerity < Capybara::Driver::Base
|
|
98
137
|
private
|
99
138
|
|
100
139
|
def url(path)
|
101
|
-
|
102
|
-
rack_server.url(path)
|
103
|
-
else
|
104
|
-
Capybara.app_host.to_s + path
|
105
|
-
end
|
140
|
+
rack_server.url(path)
|
106
141
|
end
|
107
142
|
|
108
143
|
end
|
@@ -10,10 +10,23 @@ class Capybara::Driver::RackTest < Capybara::Driver::Base
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def [](name)
|
13
|
-
|
14
|
-
|
13
|
+
attr_name = name.to_s
|
14
|
+
case
|
15
|
+
when 'select' == tag_name && 'value' == attr_name
|
16
|
+
if node['multiple'] == 'multiple'
|
17
|
+
node.xpath(".//option[@selected='selected']").map { |option| option.content }
|
18
|
+
else
|
19
|
+
option = node.xpath(".//option[@selected='selected']").first || node.xpath(".//option").first
|
20
|
+
option.content if option
|
21
|
+
end
|
22
|
+
when 'input' == tag_name && 'checkbox' == type && 'checked' == attr_name
|
23
|
+
node[attr_name] == 'checked' ? true : false
|
24
|
+
else
|
25
|
+
node[attr_name]
|
26
|
+
end
|
15
27
|
end
|
16
28
|
|
29
|
+
|
17
30
|
def set(value)
|
18
31
|
if tag_name == 'input' and %w(text password hidden file).include?(type)
|
19
32
|
node['value'] = value.to_s
|
@@ -32,8 +45,31 @@ class Capybara::Driver::RackTest < Capybara::Driver::Base
|
|
32
45
|
end
|
33
46
|
|
34
47
|
def select(option)
|
35
|
-
|
36
|
-
|
48
|
+
if node['multiple'] != 'multiple'
|
49
|
+
node.xpath(".//option[@selected]").each { |node| node.remove_attribute("selected") }
|
50
|
+
end
|
51
|
+
|
52
|
+
if option_node = node.xpath(".//option[text()='#{option}']").first ||
|
53
|
+
node.xpath(".//option[contains(.,'#{option}')]").first
|
54
|
+
option_node["selected"] = 'selected'
|
55
|
+
else
|
56
|
+
options = node.xpath(".//option").map { |o| "'#{o.text}'" }.join(', ')
|
57
|
+
raise Capybara::OptionNotFound, "No such option '#{option}' in this select box. Available options: #{options}"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def unselect(option)
|
62
|
+
if node['multiple'] != 'multiple'
|
63
|
+
raise Capybara::UnselectNotAllowed, "Cannot unselect option '#{option}' from single select box."
|
64
|
+
end
|
65
|
+
|
66
|
+
if option_node = node.xpath(".//option[text()='#{option}']").first ||
|
67
|
+
node.xpath(".//option[contains(.,'#{option}')]").first
|
68
|
+
option_node.remove_attribute('selected')
|
69
|
+
else
|
70
|
+
options = node.xpath(".//option").map { |o| "'#{o.text}'" }.join(', ')
|
71
|
+
raise Capybara::OptionNotFound, "No such option '#{option}' in this select box. Available options: #{options}"
|
72
|
+
end
|
37
73
|
end
|
38
74
|
|
39
75
|
def click
|
@@ -49,7 +85,7 @@ class Capybara::Driver::RackTest < Capybara::Driver::Base
|
|
49
85
|
end
|
50
86
|
|
51
87
|
def visible?
|
52
|
-
node.xpath("./ancestor-or-self::*[contains(@style, 'display:none')]").size == 0
|
88
|
+
node.xpath("./ancestor-or-self::*[contains(@style, 'display:none') or contains(@style, 'display: none')]").size == 0
|
53
89
|
end
|
54
90
|
|
55
91
|
def path
|
@@ -58,8 +94,12 @@ class Capybara::Driver::RackTest < Capybara::Driver::Base
|
|
58
94
|
|
59
95
|
private
|
60
96
|
|
97
|
+
def all_unfiltered(locator)
|
98
|
+
node.xpath(locator).map { |n| self.class.new(driver, n) }
|
99
|
+
end
|
100
|
+
|
61
101
|
def type
|
62
|
-
|
102
|
+
node[:type]
|
63
103
|
end
|
64
104
|
|
65
105
|
def form
|
@@ -70,7 +110,10 @@ class Capybara::Driver::RackTest < Capybara::Driver::Base
|
|
70
110
|
class Form < Node
|
71
111
|
def params(button)
|
72
112
|
params = {}
|
73
|
-
|
113
|
+
|
114
|
+
text_fields = %w[text hidden password url color tel email search].map{|f| "@type='#{f}'"}.join(' or ')
|
115
|
+
|
116
|
+
node.xpath(".//input[#{text_fields}]").map do |input|
|
74
117
|
merge_param!(params, input['name'].to_s, input['value'].to_s)
|
75
118
|
end
|
76
119
|
node.xpath(".//textarea").map do |textarea|
|
@@ -80,9 +123,16 @@ class Capybara::Driver::RackTest < Capybara::Driver::Base
|
|
80
123
|
merge_param!(params, input['name'].to_s, input['value'].to_s) if input['checked']
|
81
124
|
end
|
82
125
|
node.xpath(".//select").map do |select|
|
83
|
-
|
84
|
-
|
85
|
-
|
126
|
+
if select['multiple'] == 'multiple'
|
127
|
+
options = select.xpath(".//option[@selected]")
|
128
|
+
options.each do |option|
|
129
|
+
merge_param!(params, select['name'].to_s, (option['value'] || option.text).to_s)
|
130
|
+
end
|
131
|
+
else
|
132
|
+
option = select.xpath(".//option[@selected]").first
|
133
|
+
option ||= select.xpath('.//option').first
|
134
|
+
merge_param!(params, select['name'].to_s, (option['value'] || option.text).to_s) if option
|
135
|
+
end
|
86
136
|
end
|
87
137
|
node.xpath(".//input[@type='file']").map do |input|
|
88
138
|
unless input['value'].to_s.empty?
|
@@ -95,7 +145,7 @@ class Capybara::Driver::RackTest < Capybara::Driver::Base
|
|
95
145
|
end
|
96
146
|
end
|
97
147
|
end
|
98
|
-
merge_param!(params, button[:name], button[:value]) if button[:name]
|
148
|
+
merge_param!(params, button[:name], button[:value] || "") if button[:name]
|
99
149
|
params
|
100
150
|
end
|
101
151
|
|
@@ -108,7 +158,7 @@ class Capybara::Driver::RackTest < Capybara::Driver::Base
|
|
108
158
|
end
|
109
159
|
|
110
160
|
private
|
111
|
-
|
161
|
+
|
112
162
|
def method
|
113
163
|
self[:method] =~ /post/i ? :post : :get
|
114
164
|
end
|
@@ -140,7 +190,7 @@ class Capybara::Driver::RackTest < Capybara::Driver::Base
|
|
140
190
|
|
141
191
|
def visit(path, attributes = {})
|
142
192
|
return if path.gsub(/^#{current_path}/, '') =~ /^#/
|
143
|
-
get(path, attributes)
|
193
|
+
get(path, attributes, env)
|
144
194
|
follow_redirects!
|
145
195
|
cache_body
|
146
196
|
end
|
@@ -154,8 +204,8 @@ class Capybara::Driver::RackTest < Capybara::Driver::Base
|
|
154
204
|
end
|
155
205
|
|
156
206
|
def submit(method, path, attributes)
|
157
|
-
path = current_path if not path or path.empty?
|
158
|
-
send(method, path, attributes)
|
207
|
+
path = current_path if not path or path.empty?
|
208
|
+
send(method, path, attributes, env)
|
159
209
|
follow_redirects!
|
160
210
|
cache_body
|
161
211
|
end
|
@@ -166,10 +216,14 @@ class Capybara::Driver::RackTest < Capybara::Driver::Base
|
|
166
216
|
|
167
217
|
private
|
168
218
|
|
219
|
+
def build_rack_mock_session # :nodoc:
|
220
|
+
Rack::MockSession.new(app, Capybara.default_host || "example.org")
|
221
|
+
end
|
222
|
+
|
169
223
|
def current_path
|
170
224
|
request.path rescue ""
|
171
225
|
end
|
172
|
-
|
226
|
+
|
173
227
|
def follow_redirects!
|
174
228
|
Capybara::WaitUntil.timeout(4) do
|
175
229
|
redirect = response.redirect?
|
@@ -180,6 +234,16 @@ private
|
|
180
234
|
raise Capybara::InfiniteRedirectError, "infinite redirect detected!"
|
181
235
|
end
|
182
236
|
|
237
|
+
def env
|
238
|
+
env = {}
|
239
|
+
begin
|
240
|
+
env["HTTP_REFERER"] = request.url
|
241
|
+
rescue Rack::Test::Error
|
242
|
+
# no request yet
|
243
|
+
end
|
244
|
+
env
|
245
|
+
end
|
246
|
+
|
183
247
|
def cache_body
|
184
248
|
@body = response.body
|
185
249
|
@html = Nokogiri::HTML(body)
|
@@ -16,6 +16,14 @@ class Capybara::Driver::Selenium < Capybara::Driver::Base
|
|
16
16
|
nil
|
17
17
|
end
|
18
18
|
|
19
|
+
def value
|
20
|
+
if tag_name == "select" and self[:multiple]
|
21
|
+
node.find_elements(:xpath, ".//option").select { |n| n.selected? }.map { |n| n.text }
|
22
|
+
else
|
23
|
+
super
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
19
27
|
def set(value)
|
20
28
|
if tag_name == 'textarea' or (tag_name == 'input' and %w(text password hidden file).include?(type))
|
21
29
|
node.clear
|
@@ -28,7 +36,25 @@ class Capybara::Driver::Selenium < Capybara::Driver::Base
|
|
28
36
|
end
|
29
37
|
|
30
38
|
def select(option)
|
31
|
-
node.find_element(:xpath, ".//option[contains(.,'#{option}')]")
|
39
|
+
option_node = node.find_element(:xpath, ".//option[text()='#{option}']") || node.find_element(:xpath, ".//option[contains(.,'#{option}')]")
|
40
|
+
option_node.select
|
41
|
+
rescue
|
42
|
+
options = node.find_elements(:xpath, "//option").map { |o| "'#{o.text}'" }.join(', ')
|
43
|
+
raise Capybara::OptionNotFound, "No such option '#{option}' in this select box. Available options: #{options}"
|
44
|
+
end
|
45
|
+
|
46
|
+
def unselect(option)
|
47
|
+
if node['multiple'] != 'multiple'
|
48
|
+
raise Capybara::UnselectNotAllowed, "Cannot unselect option '#{option}' from single select box."
|
49
|
+
end
|
50
|
+
|
51
|
+
begin
|
52
|
+
option_node = node.find_element(:xpath, ".//option[text()='#{option}']") || node.find_element(:xpath, ".//option[contains(.,'#{option}')]")
|
53
|
+
option_node.clear
|
54
|
+
rescue
|
55
|
+
options = node.find_elements(:xpath, "//option").map { |o| "'#{o.text}'" }.join(', ')
|
56
|
+
raise Capybara::OptionNotFound, "No such option '#{option}' in this select box. Available options: #{options}"
|
57
|
+
end
|
32
58
|
end
|
33
59
|
|
34
60
|
def click
|
@@ -46,9 +72,16 @@ class Capybara::Driver::Selenium < Capybara::Driver::Base
|
|
46
72
|
def visible?
|
47
73
|
node.displayed? and node.displayed? != "false"
|
48
74
|
end
|
75
|
+
|
76
|
+
def trigger(event)
|
77
|
+
end
|
49
78
|
|
50
79
|
private
|
51
80
|
|
81
|
+
def all_unfiltered(locator)
|
82
|
+
node.find_elements(:xpath, locator).map { |n| self.class.new(driver, n) }
|
83
|
+
end
|
84
|
+
|
52
85
|
def type
|
53
86
|
self[:type]
|
54
87
|
end
|
@@ -69,9 +102,8 @@ class Capybara::Driver::Selenium < Capybara::Driver::Base
|
|
69
102
|
|
70
103
|
def initialize(app)
|
71
104
|
@app = app
|
72
|
-
|
73
|
-
|
74
|
-
end
|
105
|
+
@rack_server = Capybara::Server.new(@app)
|
106
|
+
@rack_server.boot if Capybara.run_server
|
75
107
|
end
|
76
108
|
|
77
109
|
def visit(path)
|
@@ -104,14 +136,14 @@ class Capybara::Driver::Selenium < Capybara::Driver::Base
|
|
104
136
|
self.class.driver
|
105
137
|
end
|
106
138
|
|
139
|
+
def cleanup!
|
140
|
+
browser.manage.delete_all_cookies
|
141
|
+
end
|
142
|
+
|
107
143
|
private
|
108
144
|
|
109
145
|
def url(path)
|
110
|
-
|
111
|
-
rack_server.url(path)
|
112
|
-
else
|
113
|
-
Capybara.app_host.to_s + path
|
114
|
-
end
|
146
|
+
rack_server.url(path)
|
115
147
|
end
|
116
148
|
|
117
149
|
end
|