capybara 2.11.0 → 2.12.0
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.
- 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
|