capybara 2.11.0 → 2.12.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/History.md +30 -4
- data/README.md +4 -0
- data/lib/capybara.rb +4 -2
- data/lib/capybara/driver/base.rb +2 -2
- data/lib/capybara/helpers.rb +8 -2
- data/lib/capybara/node/actions.rb +52 -1
- data/lib/capybara/node/document_matchers.rb +1 -0
- data/lib/capybara/node/finders.rb +2 -1
- data/lib/capybara/node/matchers.rb +54 -0
- data/lib/capybara/node/simple.rb +1 -1
- data/lib/capybara/queries/current_path_query.rb +4 -2
- data/lib/capybara/queries/selector_query.rb +23 -3
- data/lib/capybara/queries/text_query.rb +15 -7
- data/lib/capybara/queries/title_query.rb +2 -2
- data/lib/capybara/rack_test/form.rb +1 -1
- data/lib/capybara/rack_test/node.rb +4 -4
- data/lib/capybara/result.rb +2 -2
- data/lib/capybara/selector.rb +16 -4
- data/lib/capybara/selenium/driver.rb +27 -22
- data/lib/capybara/selenium/node.rb +10 -1
- data/lib/capybara/session.rb +91 -30
- data/lib/capybara/spec/session/accept_prompt_spec.rb +3 -0
- data/lib/capybara/spec/session/assert_all_of_selectors_spec.rb +94 -0
- data/lib/capybara/spec/session/assert_current_path.rb +12 -0
- data/lib/capybara/spec/session/attach_file_spec.rb +30 -0
- data/lib/capybara/spec/session/click_link_spec.rb +12 -1
- data/lib/capybara/spec/session/current_url_spec.rb +8 -0
- data/lib/capybara/spec/session/evaluate_script_spec.rb +14 -0
- data/lib/capybara/spec/session/execute_script_spec.rb +13 -0
- data/lib/capybara/spec/session/fill_in_spec.rb +6 -0
- data/lib/capybara/spec/session/find_field_spec.rb +2 -0
- data/lib/capybara/spec/session/find_spec.rb +3 -3
- data/lib/capybara/spec/session/frame/switch_to_frame_spec.rb +103 -0
- data/lib/capybara/spec/session/{within_frame_spec.rb → frame/within_frame_spec.rb} +12 -0
- data/lib/capybara/spec/session/has_current_path_spec.rb +28 -0
- data/lib/capybara/spec/session/has_selector_spec.rb +21 -0
- data/lib/capybara/spec/session/has_text_spec.rb +13 -1
- data/lib/capybara/spec/session/has_title_spec.rb +15 -0
- data/lib/capybara/spec/session/node_spec.rb +34 -1
- data/lib/capybara/spec/session/within_spec.rb +7 -0
- data/lib/capybara/spec/spec_helper.rb +4 -0
- data/lib/capybara/spec/views/form.erb +48 -0
- data/lib/capybara/spec/views/with_js.erb +5 -0
- data/lib/capybara/spec/views/within_frames.erb +1 -1
- data/lib/capybara/version.rb +1 -1
- data/lib/capybara/window.rb +1 -1
- data/spec/capybara_spec.rb +2 -2
- data/spec/rack_test_spec.rb +10 -0
- data/spec/result_spec.rb +3 -3
- data/spec/rspec/shared_spec_matchers.rb +1 -1
- data/spec/session_spec.rb +10 -0
- data/spec/shared_selenium_session.rb +2 -1
- data/spec/spec_helper.rb +2 -0
- metadata +7 -4
@@ -9,7 +9,7 @@ module Capybara
|
|
9
9
|
unless @expected_title.is_a?(Regexp)
|
10
10
|
@expected_title = Capybara::Helpers.normalize_whitespace(@expected_title)
|
11
11
|
end
|
12
|
-
@search_regexp = Capybara::Helpers.to_regexp(@expected_title)
|
12
|
+
@search_regexp = Capybara::Helpers.to_regexp(@expected_title, nil, options.fetch(:exact, false))
|
13
13
|
assert_valid_keys
|
14
14
|
end
|
15
15
|
|
@@ -34,7 +34,7 @@ module Capybara
|
|
34
34
|
end
|
35
35
|
|
36
36
|
def valid_keys
|
37
|
-
[:wait]
|
37
|
+
[:wait, :exact]
|
38
38
|
end
|
39
39
|
end
|
40
40
|
end
|
@@ -65,7 +65,7 @@ class Capybara::RackTest::Form < Capybara::RackTest::Node
|
|
65
65
|
merge_param!(params, field['name'].to_s, (option['value'] || option.text).to_s) if option
|
66
66
|
end
|
67
67
|
when 'textarea'
|
68
|
-
merge_param!(params, field['name'].to_s, field.
|
68
|
+
merge_param!(params, field['name'].to_s, field['_capybara_raw_value'].to_s.gsub(/\n/, "\r\n"))
|
69
69
|
end
|
70
70
|
end
|
71
71
|
merge_param!(params, button[:name], button[:value] || "") if button[:name]
|
@@ -18,7 +18,7 @@ class Capybara::RackTest::Node < Capybara::Driver::Node
|
|
18
18
|
|
19
19
|
def set(value)
|
20
20
|
if (Array === value) && !multiple?
|
21
|
-
raise
|
21
|
+
raise TypeError.new "Value cannot be an Array when 'multiple' attribute is not present. Not a #{value.class}"
|
22
22
|
end
|
23
23
|
|
24
24
|
if radio?
|
@@ -31,7 +31,7 @@ class Capybara::RackTest::Node < Capybara::Driver::Node
|
|
31
31
|
if self[:readonly]
|
32
32
|
warn "Attempt to set readonly element with value: #{value} \n * This will raise an exception in a future version of Capybara"
|
33
33
|
else
|
34
|
-
native
|
34
|
+
native['_capybara_raw_value'] = value.to_s
|
35
35
|
end
|
36
36
|
end
|
37
37
|
end
|
@@ -91,9 +91,9 @@ class Capybara::RackTest::Node < Capybara::Driver::Node
|
|
91
91
|
|
92
92
|
def disabled?
|
93
93
|
if %w(option optgroup).include? tag_name
|
94
|
-
string_node.disabled? || find_xpath("parent::*")[0].disabled?
|
94
|
+
string_node.disabled? || find_xpath("parent::*[self::optgroup or self::select]")[0].disabled?
|
95
95
|
else
|
96
|
-
string_node.disabled?
|
96
|
+
string_node.disabled? || !find_xpath("parent::fieldset[@disabled] | ancestor::*[not(self::legend) or preceding-sibling::legend][parent::fieldset[@disabled]]").empty?
|
97
97
|
end
|
98
98
|
end
|
99
99
|
|
data/lib/capybara/result.rb
CHANGED
@@ -28,11 +28,11 @@ module Capybara
|
|
28
28
|
@result_cache = []
|
29
29
|
@results_enum = lazy_select_elements { |node| query.matches_filters?(node) }
|
30
30
|
@query = query
|
31
|
-
# JRuby has an issue with eagerly finding next in lazy enumerators which
|
31
|
+
# JRuby < 9.1.6.0 has an issue with eagerly finding next in lazy enumerators which
|
32
32
|
# causes a concurrency issue with network requests here
|
33
33
|
# https://github.com/jruby/jruby/issues/4212
|
34
34
|
# Just force all the results to be evaluated
|
35
|
-
full_results if RUBY_PLATFORM == 'java'
|
35
|
+
full_results if RUBY_PLATFORM == 'java' && (Gem::Version.new(JRUBY_VERSION) < Gem::Version.new('9.1.6.0'))
|
36
36
|
end
|
37
37
|
|
38
38
|
def_delegators :full_results, :size, :length, :last, :values_at, :inspect, :sample
|
data/lib/capybara/selector.rb
CHANGED
@@ -123,11 +123,16 @@ end
|
|
123
123
|
# @filter [String] :title Matches the title attribute
|
124
124
|
# @filter [String] :alt Matches the alt attribute of a contained img element
|
125
125
|
# @filter [String] :class Matches the class(es) provided
|
126
|
-
# @filter [String, Regexp] :href Matches the normalized href of the link
|
126
|
+
# @filter [String, Regexp,nil] :href Matches the normalized href of the link, if nil will find <a> elements with no href attribute
|
127
127
|
#
|
128
128
|
Capybara.add_selector(:link) do
|
129
129
|
xpath(:title, :alt) do |locator, options={}|
|
130
|
-
xpath = XPath.descendant(:a)
|
130
|
+
xpath = XPath.descendant(:a)
|
131
|
+
xpath = if options.fetch(:href, true).nil?
|
132
|
+
xpath[~XPath.attr(:href)]
|
133
|
+
else
|
134
|
+
xpath[XPath.attr(:href)]
|
135
|
+
end
|
131
136
|
unless locator.nil?
|
132
137
|
locator = locator.to_s
|
133
138
|
matchers = XPath.attr(:id).equals(locator) |
|
@@ -143,14 +148,21 @@ Capybara.add_selector(:link) do
|
|
143
148
|
end
|
144
149
|
|
145
150
|
filter(:href) do |node, href|
|
146
|
-
|
151
|
+
case href
|
152
|
+
when nil
|
153
|
+
true
|
154
|
+
when Regexp
|
147
155
|
node[:href].match href
|
148
156
|
else
|
149
157
|
node.first(:xpath, XPath.axis(:self)[XPath.attr(:href).equals(href.to_s)], minimum: 0)
|
150
158
|
end
|
151
159
|
end
|
152
160
|
|
153
|
-
describe
|
161
|
+
describe do |options|
|
162
|
+
desc = String.new()
|
163
|
+
desc << " with href #{options[:href].inspect}" if options[:href]
|
164
|
+
desc << " with no href attribute" if options.fetch(:href, true).nil?
|
165
|
+
end
|
154
166
|
end
|
155
167
|
|
156
168
|
##
|
@@ -86,12 +86,12 @@ class Capybara::Selenium::Driver < Capybara::Driver::Base
|
|
86
86
|
def wait?; true; end
|
87
87
|
def needs_server?; true; end
|
88
88
|
|
89
|
-
def execute_script(script)
|
90
|
-
browser.execute_script
|
89
|
+
def execute_script(script, *args)
|
90
|
+
browser.execute_script(script, *args.map { |arg| arg.is_a?(Capybara::Selenium::Node) ? arg.native : arg} )
|
91
91
|
end
|
92
92
|
|
93
|
-
def evaluate_script(script)
|
94
|
-
browser.execute_script
|
93
|
+
def evaluate_script(script, *args)
|
94
|
+
browser.execute_script("return #{script}", *args.map { |arg| arg.is_a?(Capybara::Selenium::Node) ? arg.native : arg} )
|
95
95
|
end
|
96
96
|
|
97
97
|
def save_screenshot(path, _options={})
|
@@ -213,24 +213,6 @@ class Capybara::Selenium::Driver < Capybara::Driver::Base
|
|
213
213
|
browser.switch_to.window handle
|
214
214
|
end
|
215
215
|
|
216
|
-
# @api private
|
217
|
-
def find_window(locator)
|
218
|
-
handles = browser.window_handles
|
219
|
-
return locator if handles.include? locator
|
220
|
-
|
221
|
-
original_handle = browser.window_handle
|
222
|
-
handles.each do |handle|
|
223
|
-
switch_to_window(handle)
|
224
|
-
if (locator == browser.execute_script("return window.name") ||
|
225
|
-
browser.title.include?(locator) ||
|
226
|
-
browser.current_url.include?(locator))
|
227
|
-
switch_to_window(original_handle)
|
228
|
-
return handle
|
229
|
-
end
|
230
|
-
end
|
231
|
-
raise Capybara::ElementNotFound, "Could not find a window identified by #{locator}"
|
232
|
-
end
|
233
|
-
|
234
216
|
def within_window(locator)
|
235
217
|
handle = find_window(locator)
|
236
218
|
browser.switch_to.window(handle) { yield }
|
@@ -277,6 +259,29 @@ class Capybara::Selenium::Driver < Capybara::Driver::Base
|
|
277
259
|
Selenium::WebDriver::Error::NoSuchWindowError
|
278
260
|
end
|
279
261
|
|
262
|
+
# @api private
|
263
|
+
def find_window(locator)
|
264
|
+
handles = browser.window_handles
|
265
|
+
return locator if handles.include? locator
|
266
|
+
|
267
|
+
original_handle = browser.window_handle
|
268
|
+
handles.each do |handle|
|
269
|
+
switch_to_window(handle)
|
270
|
+
if (locator == browser.execute_script("return window.name") ||
|
271
|
+
browser.title.include?(locator) ||
|
272
|
+
browser.current_url.include?(locator))
|
273
|
+
switch_to_window(original_handle)
|
274
|
+
return handle
|
275
|
+
end
|
276
|
+
end
|
277
|
+
raise Capybara::ElementNotFound, "Could not find a window identified by #{locator}"
|
278
|
+
end
|
279
|
+
|
280
|
+
#@api private
|
281
|
+
def marionette?
|
282
|
+
(options[:browser].to_s == "firefox") && browser.capabilities.is_a?(Selenium::WebDriver::Remote::W3CCapabilities)
|
283
|
+
end
|
284
|
+
|
280
285
|
# @deprecated This method is being removed
|
281
286
|
def browser_initialized?
|
282
287
|
super && !@browser.nil?
|
@@ -138,7 +138,16 @@ class Capybara::Selenium::Node < Capybara::Driver::Node
|
|
138
138
|
alias :checked? :selected?
|
139
139
|
|
140
140
|
def disabled?
|
141
|
-
|
141
|
+
# workaround for selenium-webdriver/geckodriver reporting elements as enabled when they are nested in disabling elements
|
142
|
+
if driver.marionette?
|
143
|
+
if %w(option optgroup).include? tag_name
|
144
|
+
!native.enabled? || find_xpath("parent::*[self::optgroup or self::select]")[0].disabled?
|
145
|
+
else
|
146
|
+
!native.enabled? || !find_xpath("parent::fieldset[@disabled] | ancestor::*[not(self::legend) or preceding-sibling::legend][parent::fieldset[@disabled]]").empty?
|
147
|
+
end
|
148
|
+
else
|
149
|
+
!native.enabled?
|
150
|
+
end
|
142
151
|
end
|
143
152
|
|
144
153
|
def readonly?
|
data/lib/capybara/session.rb
CHANGED
@@ -41,6 +41,7 @@ module Capybara
|
|
41
41
|
:has_no_table?, :has_table?, :unselect, :has_select?, :has_no_select?,
|
42
42
|
:has_selector?, :has_no_selector?, :click_on, :has_no_checked_field?,
|
43
43
|
:has_no_unchecked_field?, :query, :assert_selector, :assert_no_selector,
|
44
|
+
:assert_all_of_selectors, :assert_none_of_selectors,
|
44
45
|
:refute_selector, :assert_text, :assert_no_text
|
45
46
|
]
|
46
47
|
# @api private
|
@@ -50,8 +51,8 @@ module Capybara
|
|
50
51
|
SESSION_METHODS = [
|
51
52
|
:body, :html, :source, :current_url, :current_host, :current_path,
|
52
53
|
:execute_script, :evaluate_script, :visit, :go_back, :go_forward,
|
53
|
-
:within, :within_fieldset, :within_table, :within_frame, :
|
54
|
-
:windows, :open_new_window, :switch_to_window, :within_window, :window_opened_by,
|
54
|
+
:within, :within_element, :within_fieldset, :within_table, :within_frame, :switch_to_frame,
|
55
|
+
:current_window, :windows, :open_new_window, :switch_to_window, :within_window, :window_opened_by,
|
55
56
|
:save_page, :save_and_open_page, :save_screenshot,
|
56
57
|
:save_and_open_screenshot, :reset_session!, :response_headers,
|
57
58
|
:status_code, :current_scope,
|
@@ -67,6 +68,7 @@ module Capybara
|
|
67
68
|
attr_accessor :synchronized
|
68
69
|
|
69
70
|
def initialize(mode, app=nil)
|
71
|
+
raise TypeError, "The second parameter to Session::new should be a rack app if passed." if app && !app.respond_to?(:call)
|
70
72
|
@mode = mode
|
71
73
|
@app = app
|
72
74
|
if Capybara.run_server and @app and driver.needs_server?
|
@@ -171,6 +173,10 @@ module Capybara
|
|
171
173
|
def current_path
|
172
174
|
# Addressable parsing is more lenient than URI
|
173
175
|
uri = Addressable::URI.parse(current_url)
|
176
|
+
|
177
|
+
# If current_url ends up being nil, won't be able to call .path on a NilClass.
|
178
|
+
return nil if uri.nil?
|
179
|
+
|
174
180
|
# Addressable doesn't support opaque URIs - we want nil here
|
175
181
|
return nil if uri.scheme == "about"
|
176
182
|
path = uri.path
|
@@ -306,6 +312,7 @@ module Capybara
|
|
306
312
|
scopes.pop
|
307
313
|
end
|
308
314
|
end
|
315
|
+
alias_method :within_element, :within
|
309
316
|
|
310
317
|
##
|
311
318
|
#
|
@@ -331,6 +338,42 @@ module Capybara
|
|
331
338
|
end
|
332
339
|
end
|
333
340
|
|
341
|
+
##
|
342
|
+
#
|
343
|
+
# Switch to the given frame
|
344
|
+
#
|
345
|
+
# If you use this method you are responsible for making sure you switch back to the parent frame when done in the frame changed to.
|
346
|
+
# Capybara::Session#within_frame is preferred over this method and should be used when possible.
|
347
|
+
# May not be supported by all drivers.
|
348
|
+
#
|
349
|
+
# @overload switch_to_frame(element)
|
350
|
+
# @param [Capybara::Node::Element] iframe/frame element to switch to
|
351
|
+
# @overload switch_to_frame(:parent)
|
352
|
+
# Switch to the parent element
|
353
|
+
# @overload switch_to_frame(:top)
|
354
|
+
# Switch to the top level document
|
355
|
+
#
|
356
|
+
def switch_to_frame(frame)
|
357
|
+
case frame
|
358
|
+
when Capybara::Node::Element
|
359
|
+
driver.switch_to_frame(frame)
|
360
|
+
scopes.push(:frame)
|
361
|
+
when :parent
|
362
|
+
raise Capybara::ScopeError, "`switch_to_frame(:parent)` cannot be called from inside a descendant frame's "\
|
363
|
+
"`within` block." if scopes.last() != :frame
|
364
|
+
scopes.pop
|
365
|
+
driver.switch_to_frame(:parent)
|
366
|
+
when :top
|
367
|
+
idx = scopes.index(:frame)
|
368
|
+
if idx
|
369
|
+
raise Capybara::ScopeError, "`switch_to_frame(:top)` cannot be called from inside a descendant frame's "\
|
370
|
+
"`within` block." if scopes.slice(idx..-1).any? {|scope| ![:frame, nil].include?(scope)}
|
371
|
+
scopes.slice!(idx..-1)
|
372
|
+
driver.switch_to_frame(:top)
|
373
|
+
end
|
374
|
+
end
|
375
|
+
end
|
376
|
+
|
334
377
|
##
|
335
378
|
#
|
336
379
|
# Execute the given block within the given iframe using given frame, frame name/id or index.
|
@@ -338,45 +381,50 @@ module Capybara
|
|
338
381
|
#
|
339
382
|
# @overload within_frame(element)
|
340
383
|
# @param [Capybara::Node::Element] frame element
|
341
|
-
# @overload within_frame(
|
342
|
-
# @param [
|
384
|
+
# @overload within_frame([kind = :frame], locator, options = {})
|
385
|
+
# @param [Symobl] kind Optional selector type (:css, :xpath, :field, etc.) - Defaults to :frame
|
386
|
+
# @param [String] locator The locator for the given selector kind. For :frame this is the name/id of a frame/iframe element
|
343
387
|
# @overload within_frame(index)
|
344
|
-
# @param [Integer] index index of a frame
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
388
|
+
# @param [Integer] index index of a frame (0 based)
|
389
|
+
def within_frame(*args)
|
390
|
+
frame = within(document) do # Previous 2.x versions ignored current scope when finding frames - consider changing in 3.0
|
391
|
+
case args[0]
|
392
|
+
when Capybara::Node::Element
|
393
|
+
args[0]
|
394
|
+
when String, Hash
|
395
|
+
find(:frame, *args)
|
396
|
+
when Symbol
|
397
|
+
find(*args)
|
398
|
+
when Integer
|
399
|
+
idx = args[0]
|
400
|
+
all(:frame, minimum: idx+1)[idx]
|
401
|
+
else
|
402
|
+
raise TypeError
|
403
|
+
end
|
359
404
|
end
|
360
405
|
|
361
406
|
begin
|
362
|
-
|
407
|
+
switch_to_frame(frame)
|
363
408
|
begin
|
364
409
|
yield
|
365
410
|
ensure
|
366
|
-
|
411
|
+
switch_to_frame(:parent)
|
367
412
|
end
|
368
413
|
rescue Capybara::NotSupportedByDriverError
|
369
414
|
# Support older driver frame API for now
|
370
415
|
if driver.respond_to?(:within_frame)
|
371
|
-
|
372
|
-
|
416
|
+
begin
|
417
|
+
scopes.push(:frame)
|
418
|
+
driver.within_frame(frame) do
|
419
|
+
yield
|
420
|
+
end
|
421
|
+
ensure
|
422
|
+
scopes.pop
|
373
423
|
end
|
374
424
|
else
|
375
425
|
raise
|
376
426
|
end
|
377
427
|
end
|
378
|
-
ensure
|
379
|
-
scopes.pop
|
380
428
|
end
|
381
429
|
|
382
430
|
##
|
@@ -560,10 +608,16 @@ module Capybara
|
|
560
608
|
# +evaluate_script+ whenever possible.
|
561
609
|
#
|
562
610
|
# @param [String] script A string of JavaScript to execute
|
611
|
+
# @param args Optional arguments that will be passed to the script. Driver support for this is optional and types of objects supported may differ between drivers
|
563
612
|
#
|
564
|
-
def execute_script(script)
|
613
|
+
def execute_script(script, *args)
|
565
614
|
@touched = true
|
566
|
-
driver.execute_script
|
615
|
+
if driver.method(:execute_script).arity == 1
|
616
|
+
raise Capybara::NotSupportedByDriverError, "The current driver does not support arguments being passed with execute_script" unless args.empty?
|
617
|
+
driver.execute_script(script)
|
618
|
+
else
|
619
|
+
driver.execute_script(script, *args.map { |arg| arg.is_a?(Capybara::Node::Element) ? arg.base : arg} )
|
620
|
+
end
|
567
621
|
end
|
568
622
|
|
569
623
|
##
|
@@ -575,9 +629,14 @@ module Capybara
|
|
575
629
|
# @param [String] script A string of JavaScript to evaluate
|
576
630
|
# @return [Object] The result of the evaluated JavaScript (may be driver specific)
|
577
631
|
#
|
578
|
-
def evaluate_script(script)
|
632
|
+
def evaluate_script(script, *args)
|
579
633
|
@touched = true
|
580
|
-
driver.evaluate_script
|
634
|
+
if driver.method(:evaluate_script).arity == 1
|
635
|
+
raise Capybara::NotSupportedByDriverError, "The current driver does not support arguments being passed with execute_script" unless args.empty?
|
636
|
+
driver.evaluate_script(script)
|
637
|
+
else
|
638
|
+
driver.evaluate_script(script, *args.map { |arg| arg.is_a?(Capybara::Node::Element) ? arg.base : arg} )
|
639
|
+
end
|
581
640
|
end
|
582
641
|
|
583
642
|
##
|
@@ -733,7 +792,9 @@ module Capybara
|
|
733
792
|
end
|
734
793
|
|
735
794
|
def current_scope
|
736
|
-
scopes.last
|
795
|
+
scope = scopes.last
|
796
|
+
scope = document if [nil, :frame].include? scope
|
797
|
+
scope
|
737
798
|
end
|
738
799
|
|
739
800
|
private
|
@@ -19,6 +19,7 @@ Capybara::SpecHelper.spec '#accept_prompt', requires: [:modals] do
|
|
19
19
|
end
|
20
20
|
|
21
21
|
it "should accept the prompt with a response" do
|
22
|
+
pending "selenium-webdriver/geckodriver doesn't support sending a response to prompts" if marionette?(@session)
|
22
23
|
@session.accept_prompt with: 'the response' do
|
23
24
|
@session.click_link('Open prompt')
|
24
25
|
end
|
@@ -26,6 +27,7 @@ Capybara::SpecHelper.spec '#accept_prompt', requires: [:modals] do
|
|
26
27
|
end
|
27
28
|
|
28
29
|
it "should accept the prompt if the message matches" do
|
30
|
+
pending "selenium-webdriver/geckodriver doesn't support sending a response to prompts" if marionette?(@session)
|
29
31
|
@session.accept_prompt 'Prompt opened', with: 'matched' do
|
30
32
|
@session.click_link('Open prompt')
|
31
33
|
end
|
@@ -42,6 +44,7 @@ Capybara::SpecHelper.spec '#accept_prompt', requires: [:modals] do
|
|
42
44
|
|
43
45
|
|
44
46
|
it "should return the message presented" do
|
47
|
+
pending "selenium-webdriver/geckodriver doesn't support sending a response to prompts" if marionette?(@session)
|
45
48
|
message = @session.accept_prompt with: 'the response' do
|
46
49
|
@session.click_link('Open prompt')
|
47
50
|
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
Capybara::SpecHelper.spec '#assert_all_of_selectors' do
|
3
|
+
before do
|
4
|
+
@session.visit('/with_html')
|
5
|
+
end
|
6
|
+
|
7
|
+
it "should be true if the given selectors are on the page" do
|
8
|
+
@session.assert_all_of_selectors(:css, "p a#foo", "h2#h2one", "h2#h2two" )
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should be false if any of the given selectors are not on the page" do
|
12
|
+
expect { @session.assert_all_of_selectors(:css, "p a#foo", "h2#h2three", "h2#h2one")}.to raise_error(Capybara::ElementNotFound)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should use default selector" do
|
16
|
+
Capybara.default_selector = :css
|
17
|
+
expect { @session.assert_all_of_selectors("p a#foo", "h2#h2three", "h2#h2one")}.to raise_error(Capybara::ElementNotFound)
|
18
|
+
@session.assert_all_of_selectors("p a#foo", "h2#h2two", "h2#h2one" )
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should respect scopes" do
|
22
|
+
@session.within "//p[@id='first']" do
|
23
|
+
@session.assert_all_of_selectors(".//a[@id='foo']")
|
24
|
+
expect { @session.assert_all_of_selectors(".//a[@id='red']") }.to raise_error(Capybara::ElementNotFound)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context "with options" do
|
29
|
+
it "should apply options to all locators" do
|
30
|
+
@session.assert_all_of_selectors(:field, 'normal', 'additional_newline', type: :textarea)
|
31
|
+
expect { @session.assert_all_of_selectors(:field, 'normal', 'test_field', 'additional_newline', type: :textarea) }.to raise_error(Capybara::ElementNotFound)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context "with wait", requires: [:js] do
|
36
|
+
it "should not raise error if all the elements appear before given wait duration" do
|
37
|
+
Capybara.using_wait_time(0.1) do
|
38
|
+
@session.visit('/with_js')
|
39
|
+
@session.click_link('Click me')
|
40
|
+
@session.assert_all_of_selectors(:css, "a#clickable", "a#has-been-clicked", '#drag', wait: 0.9)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
Capybara::SpecHelper.spec '#assert_none_of_selectors' do
|
47
|
+
before do
|
48
|
+
@session.visit('/with_html')
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should be false if any of the given locators are on the page" do
|
52
|
+
expect { @session.assert_none_of_selectors(:xpath, "//p", "//a") }.to raise_error(Capybara::ElementNotFound)
|
53
|
+
expect { @session.assert_none_of_selectors(:xpath, "//abbr", "//a") }.to raise_error(Capybara::ElementNotFound)
|
54
|
+
expect { @session.assert_none_of_selectors(:css, "p a#foo") }.to raise_error(Capybara::ElementNotFound)
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should be true if none of the given locators are on the page" do
|
58
|
+
@session.assert_none_of_selectors(:xpath, "//abbr", "//td" )
|
59
|
+
@session.assert_none_of_selectors(:css, "p a#doesnotexist", "abbr")
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should use default selector" do
|
63
|
+
Capybara.default_selector = :css
|
64
|
+
@session.assert_none_of_selectors("p a#doesnotexist", "abbr")
|
65
|
+
expect { @session.assert_none_of_selectors("abbr", "p a#foo") }.to raise_error(Capybara::ElementNotFound)
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should respect scopes" do
|
69
|
+
@session.within "//p[@id='first']" do
|
70
|
+
expect { @session.assert_none_of_selectors(".//a[@id='foo']") }.to raise_error(Capybara::ElementNotFound)
|
71
|
+
@session.assert_none_of_selectors(".//a[@id='red']")
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
context "with options" do
|
76
|
+
it "should apply the options to all locators" do
|
77
|
+
expect { @session.assert_none_of_selectors("//p//a", text: "Redirect") }.to raise_error(Capybara::ElementNotFound)
|
78
|
+
@session.assert_none_of_selectors("//p", text: "Doesnotexist")
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should discard all matches where the given regexp is matched" do
|
82
|
+
expect { @session.assert_none_of_selectors("//p//a", text: /re[dab]i/i, count: 1) }.to raise_error(Capybara::ElementNotFound)
|
83
|
+
@session.assert_none_of_selectors("//p//a", text: /Red$/)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
context "with wait", requires: [:js] do
|
88
|
+
it "should not find elements if they appear after given wait duration" do
|
89
|
+
@session.visit('/with_js')
|
90
|
+
@session.click_link('Click me')
|
91
|
+
@session.assert_none_of_selectors(:css, "#new_field", "a#has-been-clicked", wait: 0.1)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|