capybara 3.6.0 → 3.7.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 +16 -0
- data/README.md +5 -1
- data/lib/capybara.rb +2 -0
- data/lib/capybara/minitest/spec.rb +1 -1
- data/lib/capybara/node/actions.rb +34 -25
- data/lib/capybara/node/base.rb +15 -17
- data/lib/capybara/node/document_matchers.rb +1 -3
- data/lib/capybara/node/element.rb +11 -12
- data/lib/capybara/node/finders.rb +2 -1
- data/lib/capybara/node/simple.rb +13 -6
- data/lib/capybara/queries/base_query.rb +4 -4
- data/lib/capybara/queries/selector_query.rb +119 -94
- data/lib/capybara/queries/text_query.rb +2 -1
- data/lib/capybara/rack_test/form.rb +4 -4
- data/lib/capybara/rack_test/node.rb +5 -5
- data/lib/capybara/result.rb +23 -32
- data/lib/capybara/rspec/compound.rb +1 -1
- data/lib/capybara/rspec/matchers.rb +63 -61
- data/lib/capybara/selector.rb +28 -10
- data/lib/capybara/selector/css.rb +17 -17
- data/lib/capybara/selector/filter_set.rb +9 -9
- data/lib/capybara/selector/selector.rb +3 -4
- data/lib/capybara/selenium/driver.rb +73 -95
- data/lib/capybara/selenium/driver_specializations/chrome_driver.rb +4 -4
- data/lib/capybara/selenium/driver_specializations/marionette_driver.rb +9 -0
- data/lib/capybara/selenium/node.rb +127 -67
- data/lib/capybara/selenium/nodes/chrome_node.rb +3 -3
- data/lib/capybara/selenium/nodes/marionette_node.rb +14 -8
- data/lib/capybara/server.rb +2 -2
- data/lib/capybara/server/animation_disabler.rb +17 -3
- data/lib/capybara/server/middleware.rb +8 -4
- data/lib/capybara/session.rb +43 -37
- data/lib/capybara/session/config.rb +8 -6
- data/lib/capybara/spec/session/assert_text_spec.rb +14 -0
- data/lib/capybara/spec/session/attach_file_spec.rb +7 -0
- data/lib/capybara/spec/session/check_spec.rb +21 -0
- data/lib/capybara/spec/session/choose_spec.rb +15 -1
- data/lib/capybara/spec/session/fill_in_spec.rb +7 -0
- data/lib/capybara/spec/session/find_spec.rb +2 -1
- data/lib/capybara/spec/session/has_selector_spec.rb +18 -0
- data/lib/capybara/spec/session/has_text_spec.rb +14 -0
- data/lib/capybara/spec/session/node_spec.rb +2 -1
- data/lib/capybara/spec/session/reset_session_spec.rb +4 -4
- data/lib/capybara/spec/session/text_spec.rb +2 -1
- data/lib/capybara/spec/session/title_spec.rb +2 -1
- data/lib/capybara/spec/session/uncheck_spec.rb +8 -0
- data/lib/capybara/spec/session/within_spec.rb +2 -1
- data/lib/capybara/spec/spec_helper.rb +1 -32
- data/lib/capybara/spec/views/with_js.erb +3 -4
- data/lib/capybara/version.rb +1 -1
- data/spec/minitest_spec.rb +4 -0
- data/spec/minitest_spec_spec.rb +4 -0
- data/spec/rack_test_spec.rb +4 -4
- data/spec/rspec/shared_spec_matchers.rb +4 -2
- data/spec/selector_spec.rb +15 -1
- data/spec/selenium_spec_chrome.rb +1 -6
- data/spec/selenium_spec_chrome_remote.rb +1 -1
- data/spec/selenium_spec_firefox_remote.rb +2 -5
- data/spec/selenium_spec_ie.rb +41 -4
- data/spec/selenium_spec_marionette.rb +1 -25
- data/spec/shared_selenium_session.rb +74 -16
- data/spec/spec_helper.rb +41 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e081025be98ae57e3e43ef0fb2a156b3bfb3ff4d54f8f25bfc09a4bcff2fc59c
|
4
|
+
data.tar.gz: 95e8d6fffe004d4802cd0f97d3bddeae5394041dc774d341c3ad10a60d0b04eb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 93e42ca9e9ad0bde5911fe2c7e86ad2d0ac1c40428dfcd256aa01b21b6a8c2e1755df018a272f1917e0628c5c7e1a68b35eb930c3abdb5ffec4e9079187ca5b8
|
7
|
+
data.tar.gz: c7faa43983241d170cf725c22fcc595d2fde4572a71abcf3271d32993bbb6e2874a96c74b850090089598d277b8793b072315fc1e34c9e7a876daeb64a007f7e
|
data/History.md
CHANGED
@@ -1,3 +1,19 @@
|
|
1
|
+
# Version 3.7.0
|
2
|
+
Release date: 2018-09-02
|
3
|
+
|
4
|
+
### Added
|
5
|
+
|
6
|
+
* `Capybara.disable_animation` can be set to a CSS selector to identify which elements will have animation disabled [Michael Glass]
|
7
|
+
* `Capybara.default_normalize_ws` option which sets whether or not text predicates and matchers (`has_text?`, `has_content?`, `assert_text`, etc) use `normalize_ws` option by default. Defaults to false. [Stegalin Ivan]
|
8
|
+
* Selector based predicates, matchers, and finders now support the `:normalize_ws` option for the `:text`/`:exact_text` filters. Defaults to the `Capybara.default_normalize_ws`setting above.
|
9
|
+
* Element `choose`/`check`/`uncheck`/`attach_file`/`fill_in` can now operate on the element they're called on or a descendant if no locator is passed.
|
10
|
+
|
11
|
+
### Fixed
|
12
|
+
|
13
|
+
* All CSS styles applied by the `Element#attach_file` `:make_visible` option will now have `!important` priority set to ensure they override any other specified style.
|
14
|
+
* Firefox file inputs are only manually cleared when necessary.
|
15
|
+
*
|
16
|
+
|
1
17
|
# Version 3.6.0
|
2
18
|
Release date: 2018-08-14
|
3
19
|
|
data/README.md
CHANGED
@@ -7,7 +7,7 @@
|
|
7
7
|
[](https://dependabot.com/compatibility-score.html?dependency-name=capybara&package-manager=bundler&version-scheme=semver)
|
8
8
|
|
9
9
|
**Note** You are viewing the README for the development version of Capybara. If you are using the current release version
|
10
|
-
you can find the README at https://github.com/teamcapybara/capybara/blob/3.
|
10
|
+
you can find the README at https://github.com/teamcapybara/capybara/blob/3.7_stable/README.md
|
11
11
|
|
12
12
|
|
13
13
|
Capybara helps you test web applications by simulating how a real user would
|
@@ -409,6 +409,8 @@ and test server, see "Transactions and database setup" below.
|
|
409
409
|
|
410
410
|
### <a name="capybara-webkit"></a>Capybara-webkit
|
411
411
|
|
412
|
+
Note: `capybara-webkit` depends on QtWebkit which went EOL quite some time ago. There has been an attempt to revive the project but `capybara-webkit` is not yet (AFAIK) compatible with the revived version of QtWebKit (could be a good OSS project for someone) and as such is still limited to an old version of QtWebKit. This means its support for modern JS and CSS is severely limited. Y
|
413
|
+
|
412
414
|
The [capybara-webkit driver](https://github.com/thoughtbot/capybara-webkit) is for true headless
|
413
415
|
testing. It uses QtWebKit to start a rendering engine process. It can execute JavaScript as well.
|
414
416
|
It is significantly faster than drivers like Selenium since it does not load an entire browser.
|
@@ -427,6 +429,8 @@ Capybara.javascript_driver = :webkit
|
|
427
429
|
|
428
430
|
### <a name="poltergeist"></a>Poltergeist
|
429
431
|
|
432
|
+
Note: `poltergeist` depends on PhantomJS for which active development ended quite some time ago (2.1.1). As such it is roughly equivalent to a 6-7 year old version of Safari, meaning lack of support for modern JS And CSS. If any effort to update PhantomJS succeeds in the future this situation could change.
|
433
|
+
|
430
434
|
[Poltergeist](https://github.com/teampoltergeist/poltergeist) is another
|
431
435
|
headless driver which integrates Capybara with
|
432
436
|
[PhantomJS](http://phantomjs.org/). It is truly headless, so doesn't
|
data/lib/capybara.rb
CHANGED
@@ -85,6 +85,7 @@ module Capybara
|
|
85
85
|
# [default_set_options = Hash] The default options passed to Node::set (Default: {})
|
86
86
|
# [test_id = Symbol/String/nil] Optional attribute to match locator aginst with builtin selectors along with id (Default: nil)
|
87
87
|
# [predicates_wait = Boolean] Whether Capybaras predicate matchers use waiting behavior by default (Default: true)
|
88
|
+
# [default_normalize_ws = Boolean] Whether text predicates and matchers use normalize whitespace behaviour (Default: false)
|
88
89
|
#
|
89
90
|
# === DSL Options
|
90
91
|
#
|
@@ -486,6 +487,7 @@ Capybara.configure do |config|
|
|
486
487
|
config.default_set_options = {}
|
487
488
|
config.test_id = nil
|
488
489
|
config.predicates_wait = true
|
490
|
+
config.default_normalize_ws = false
|
489
491
|
end
|
490
492
|
|
491
493
|
Capybara.register_driver :rack_test do |app|
|
@@ -62,6 +62,7 @@ module Capybara
|
|
62
62
|
#
|
63
63
|
# Locate a text field or text area and fill it in with the given text
|
64
64
|
# The field can be found via its name, id, Capybara.test_id attribute, or label text.
|
65
|
+
# If no locator is provided will operate on self or a descendant
|
65
66
|
#
|
66
67
|
# page.fill_in 'Name', with: 'Bob'
|
67
68
|
#
|
@@ -82,6 +83,7 @@ module Capybara
|
|
82
83
|
# @return [Capybara::Node::Element] The element filled_in
|
83
84
|
def fill_in(locator = nil, with:, currently_with: nil, fill_options: {}, **find_options)
|
84
85
|
find_options[:with] = currently_with if currently_with
|
86
|
+
find_options[:allow_self] = true if locator.nil?
|
85
87
|
find(:fillable_field, locator, find_options).set(with, fill_options)
|
86
88
|
end
|
87
89
|
|
@@ -90,8 +92,9 @@ module Capybara
|
|
90
92
|
|
91
93
|
##
|
92
94
|
#
|
93
|
-
# Find a radio button and mark it as checked. The radio button can be found
|
94
|
-
# via name, id or label text.
|
95
|
+
# Find a descendant radio button and mark it as checked. The radio button can be found
|
96
|
+
# via name, id or label text. If no locator is provided this will match against self or
|
97
|
+
# a descendant.
|
95
98
|
#
|
96
99
|
# page.choose('Male')
|
97
100
|
#
|
@@ -112,8 +115,9 @@ module Capybara
|
|
112
115
|
|
113
116
|
##
|
114
117
|
#
|
115
|
-
# Find a check box and mark it as checked. The check box can be found
|
116
|
-
# via name, id or label text.
|
118
|
+
# Find a descendant check box and mark it as checked. The check box can be found
|
119
|
+
# via name, id or label text. If no locator is provided this will match against
|
120
|
+
# self or a descendant.
|
117
121
|
#
|
118
122
|
# page.check('German')
|
119
123
|
#
|
@@ -135,8 +139,9 @@ module Capybara
|
|
135
139
|
|
136
140
|
##
|
137
141
|
#
|
138
|
-
# Find a check box and mark uncheck it. The check box can be found
|
139
|
-
# via name, id or label text.
|
142
|
+
# Find a descendant check box and mark uncheck it. The check box can be found
|
143
|
+
# via name, id or label text. If no locator is provided this will match against
|
144
|
+
# self or a descendant.
|
140
145
|
#
|
141
146
|
# page.uncheck('German')
|
142
147
|
#
|
@@ -170,7 +175,7 @@ module Capybara
|
|
170
175
|
# @macro waiting_behavior
|
171
176
|
#
|
172
177
|
# @param value [String] Which option to select
|
173
|
-
# @param from
|
178
|
+
# @param from [String] The id, Capybara.test_id atrtribute, name or label of the select box
|
174
179
|
#
|
175
180
|
# @return [Capybara::Node::Element] The option element selected
|
176
181
|
def select(value = nil, from: nil, **options)
|
@@ -193,8 +198,8 @@ module Capybara
|
|
193
198
|
#
|
194
199
|
# @macro waiting_behavior
|
195
200
|
#
|
196
|
-
# @param value [String]
|
197
|
-
# @param from
|
201
|
+
# @param value [String] Which option to unselect
|
202
|
+
# @param from [String] The id, Capybara.test_id attribute, name or label of the select box
|
198
203
|
#
|
199
204
|
# @return [Capybara::Node::Element] The option element unselected
|
200
205
|
def unselect(value = nil, from: nil, **options)
|
@@ -204,18 +209,19 @@ module Capybara
|
|
204
209
|
|
205
210
|
##
|
206
211
|
#
|
207
|
-
# Find a file field on the page and attach a file given its path. The file field can
|
212
|
+
# Find a descendant file field on the page and attach a file given its path. The file field can
|
208
213
|
# be found via its name, id or label text. In the case of the file field being hidden for
|
209
214
|
# styling reasons the `make_visible` option can be used to temporarily change the CSS of
|
210
|
-
# the file field, attach the file, and then revert the CSS back to original.
|
215
|
+
# the file field, attach the file, and then revert the CSS back to original. If no locator is
|
216
|
+
# passed this will match self or a descendant.
|
211
217
|
#
|
212
218
|
# page.attach_file(locator, '/path/to/file.png')
|
213
219
|
#
|
214
|
-
# @overload attach_file([locator],
|
220
|
+
# @overload attach_file([locator], paths, **options)
|
215
221
|
# @macro waiting_behavior
|
216
222
|
#
|
217
|
-
# @param [String] locator
|
218
|
-
# @param [String]
|
223
|
+
# @param [String] locator Which field to attach the file to
|
224
|
+
# @param [String, Array<String>] paths The path(s) of the file(s) that will be attached
|
219
225
|
#
|
220
226
|
# @option options [Symbol] match (Capybara.match) The matching strategy to use (:one, :first, :prefer_exact, :smart).
|
221
227
|
# @option options [Boolean] exact (Capybara.exact) Match the exact label name/contents or accept a partial match.
|
@@ -226,16 +232,17 @@ module Capybara
|
|
226
232
|
# @option options [true, Hash] make_visible A Hash of CSS styles to change before attempting to attach the file, if `true` { opacity: 1, display: 'block', visibility: 'visible' } is used (may not be supported by all drivers)
|
227
233
|
#
|
228
234
|
# @return [Capybara::Node::Element] The file field element
|
229
|
-
def attach_file(locator = nil,
|
230
|
-
Array(
|
231
|
-
raise Capybara::FileNotFound, "cannot attach file, #{
|
235
|
+
def attach_file(locator = nil, paths, make_visible: nil, **options) # rubocop:disable Style/OptionalArguments
|
236
|
+
Array(paths).each do |path|
|
237
|
+
raise Capybara::FileNotFound, "cannot attach file, #{path} does not exist" unless File.exist?(path.to_s)
|
232
238
|
end
|
239
|
+
options[:allow_self] = true if locator.nil?
|
233
240
|
# Allow user to update the CSS style of the file input since they are so often hidden on a page
|
234
241
|
if make_visible
|
235
242
|
ff = find(:file_field, locator, options.merge(visible: :all))
|
236
|
-
while_visible(ff, make_visible) { |el| el.set(
|
243
|
+
while_visible(ff, make_visible) { |el| el.set(paths) }
|
237
244
|
else
|
238
|
-
find(:file_field, locator, options).set(
|
245
|
+
find(:file_field, locator, options).set(paths)
|
239
246
|
end
|
240
247
|
end
|
241
248
|
|
@@ -258,7 +265,7 @@ module Capybara
|
|
258
265
|
|
259
266
|
def select_datalist_option(input, value)
|
260
267
|
datalist_options = input.evaluate_script(DATALIST_OPTIONS_SCRIPT)
|
261
|
-
option = datalist_options.find { |
|
268
|
+
option = datalist_options.find { |opt| opt.values_at('value', 'label').include?(value) }
|
262
269
|
raise ::Capybara::ElementNotFound, %(Unable to find datalist option "#{value}") unless option
|
263
270
|
input.set(option['value'])
|
264
271
|
rescue ::Capybara::NotSupportedByDriverError
|
@@ -291,17 +298,19 @@ module Capybara
|
|
291
298
|
end
|
292
299
|
|
293
300
|
def _check_with_label(selector, checked, locator, allow_label_click: session_options.automatic_label_click, **options)
|
301
|
+
options[:allow_self] = true if locator.nil?
|
302
|
+
|
294
303
|
synchronize(Capybara::Queries::BaseQuery.wait(options, session_options.default_max_wait_time)) do
|
295
304
|
begin
|
296
305
|
el = find(selector, locator, options)
|
297
306
|
el.set(checked)
|
298
|
-
rescue StandardError =>
|
299
|
-
raise unless allow_label_click && catch_error?(
|
307
|
+
rescue StandardError => err
|
308
|
+
raise unless allow_label_click && catch_error?(err)
|
300
309
|
begin
|
301
310
|
el ||= find(selector, locator, options.merge(visible: :all))
|
302
|
-
find(:label, for: el, visible: true).click unless el.checked? == checked
|
311
|
+
el.session.find(:label, for: el, visible: true).click unless el.checked? == checked
|
303
312
|
rescue StandardError # swallow extra errors - raise original
|
304
|
-
raise
|
313
|
+
raise err
|
305
314
|
end
|
306
315
|
end
|
307
316
|
end
|
@@ -312,7 +321,7 @@ module Capybara
|
|
312
321
|
var css = arguments[0];
|
313
322
|
for (var prop in css){
|
314
323
|
if (css.hasOwnProperty(prop)) {
|
315
|
-
this.style
|
324
|
+
this.style.setProperty(prop, css[prop], "important");
|
316
325
|
}
|
317
326
|
}
|
318
327
|
JS
|
data/lib/capybara/node/base.rb
CHANGED
@@ -74,24 +74,22 @@ module Capybara
|
|
74
74
|
# @raise [Capybara::FrozenInTime] If the return value of `Time.now` appears stuck
|
75
75
|
#
|
76
76
|
def synchronize(seconds = session_options.default_max_wait_time, errors: nil)
|
77
|
-
if session.synchronized
|
77
|
+
return yield if session.synchronized
|
78
|
+
|
79
|
+
session.synchronized = true
|
80
|
+
timer = Capybara::Helpers.timer(expire_in: seconds)
|
81
|
+
begin
|
78
82
|
yield
|
79
|
-
|
80
|
-
session.
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
raise Capybara::FrozenInTime, 'Time appears to be frozen. Capybara does not work with libraries which freeze time, consider using time travelling instead' if timer.stalled?
|
90
|
-
reload if session_options.automatic_reload
|
91
|
-
retry
|
92
|
-
ensure
|
93
|
-
session.synchronized = false
|
94
|
-
end
|
83
|
+
rescue StandardError => err
|
84
|
+
session.raise_server_error!
|
85
|
+
raise err unless driver.wait? && catch_error?(err, errors)
|
86
|
+
raise err if timer.expired?
|
87
|
+
sleep(0.05)
|
88
|
+
raise Capybara::FrozenInTime, 'Time appears to be frozen. Capybara does not work with libraries which freeze time, consider using time travelling instead' if timer.stalled?
|
89
|
+
reload if session_options.automatic_reload
|
90
|
+
retry
|
91
|
+
ensure
|
92
|
+
session.synchronized = false
|
95
93
|
end
|
96
94
|
end
|
97
95
|
|
@@ -55,8 +55,8 @@ module Capybara
|
|
55
55
|
#
|
56
56
|
def text(type = nil, normalize_ws: false)
|
57
57
|
type ||= :all unless session_options.ignore_hidden_elements || session_options.visible_text_only
|
58
|
-
|
59
|
-
normalize_ws ?
|
58
|
+
txt = synchronize { type == :all ? base.all_text : base.visible_text }
|
59
|
+
normalize_ws ? txt.gsub(/[[:space:]]+/, ' ').strip : txt
|
60
60
|
end
|
61
61
|
|
62
62
|
##
|
@@ -78,19 +78,19 @@ module Capybara
|
|
78
78
|
#
|
79
79
|
# element.style('color', 'font-size') # => Computed values of CSS 'color' and 'font-size' styles
|
80
80
|
#
|
81
|
-
# @param [String]
|
82
|
-
# @return [Hash]
|
81
|
+
# @param [Array<String>] styles Names of the desired CSS properties
|
82
|
+
# @return [Hash] Hash of the CSS property names to computed values
|
83
83
|
#
|
84
84
|
def style(*styles)
|
85
85
|
styles = styles.flatten.map(&:to_s)
|
86
86
|
raise ArgumentError, 'You must specify at least one CSS style' if styles.empty?
|
87
87
|
begin
|
88
88
|
synchronize { base.style(styles) }
|
89
|
-
rescue NotImplementedError =>
|
89
|
+
rescue NotImplementedError => err
|
90
90
|
begin
|
91
91
|
evaluate_script(STYLE_SCRIPT, *styles)
|
92
92
|
rescue Capybara::NotSupportedByDriverError
|
93
|
-
raise
|
93
|
+
raise err
|
94
94
|
end
|
95
95
|
end
|
96
96
|
end
|
@@ -108,7 +108,7 @@ module Capybara
|
|
108
108
|
# Set the value of the form element to the given value.
|
109
109
|
#
|
110
110
|
# @param [String] value The new value
|
111
|
-
# @param [Hash{}] options Driver specific options for how to set the value. Take default values from
|
111
|
+
# @param [Hash{}] options Driver specific options for how to set the value. Take default values from `Capybara#default_set_options` - See {Capybara::configure}
|
112
112
|
#
|
113
113
|
# @return [Capybara::Node::Element] The element
|
114
114
|
def set(value, **options)
|
@@ -429,8 +429,8 @@ module Capybara
|
|
429
429
|
begin
|
430
430
|
reloaded = query_scope.reload.first(@query.name, @query.locator, @query.options)
|
431
431
|
@base = reloaded.base if reloaded
|
432
|
-
rescue StandardError =>
|
433
|
-
raise
|
432
|
+
rescue StandardError => err
|
433
|
+
raise err unless catch_error?(err)
|
434
434
|
end
|
435
435
|
end
|
436
436
|
self
|
@@ -440,9 +440,8 @@ module Capybara
|
|
440
440
|
%(#<Capybara::Node::Element tag="#{base.tag_name}" path="#{base.path}">)
|
441
441
|
rescue NotSupportedByDriverError
|
442
442
|
%(#<Capybara::Node::Element tag="#{base.tag_name}">)
|
443
|
-
rescue StandardError =>
|
444
|
-
raise unless session.driver.invalid_element_errors.any? { |et|
|
445
|
-
|
443
|
+
rescue StandardError => err
|
444
|
+
raise unless session.driver.invalid_element_errors.any? { |et| err.is_a?(et) }
|
446
445
|
%(Obsolete #<Capybara::Node::Element>)
|
447
446
|
end
|
448
447
|
|
@@ -223,6 +223,7 @@ module Capybara
|
|
223
223
|
# @param [String] locator The locator for the specified selector
|
224
224
|
# @option options [String, Regexp] text Only find elements which contain this text or match this regexp
|
225
225
|
# @option options [String, Boolean] exact_text (Capybara.exact_text) When String the elements contained text must match exactly, when Boolean controls whether the :text option must match exactly
|
226
|
+
# @option options [Boolean] normalize_ws (Capybara.default_normalize_ws) Whether the `text`/`exact_text` options are compared against elment text with whitespace normalized or as returned by the driver
|
226
227
|
# @option options [Boolean, Symbol] visible Only find elements with the specified visibility:
|
227
228
|
# * true - only finds visible elements.
|
228
229
|
# * false - finds invisible _and_ visible elements.
|
@@ -306,7 +307,7 @@ module Capybara
|
|
306
307
|
end
|
307
308
|
|
308
309
|
def options_include_minimum?(opts)
|
309
|
-
%i[count minimum between].any? { |
|
310
|
+
%i[count minimum between].any? { |key| opts.key?(key) }
|
310
311
|
end
|
311
312
|
end
|
312
313
|
end
|
data/lib/capybara/node/simple.rb
CHANGED
@@ -29,8 +29,8 @@ module Capybara
|
|
29
29
|
# @return [String] The text of the element
|
30
30
|
#
|
31
31
|
def text(_type = nil, normalize_ws: false)
|
32
|
-
|
33
|
-
normalize_ws ?
|
32
|
+
txt = native.text
|
33
|
+
normalize_ws ? txt.gsub(/[[:space:]]+/, ' ').strip : txt
|
34
34
|
end
|
35
35
|
|
36
36
|
##
|
@@ -79,11 +79,11 @@ module Capybara
|
|
79
79
|
if tag_name == 'textarea'
|
80
80
|
native['_capybara_raw_value']
|
81
81
|
elsif tag_name == 'select'
|
82
|
+
selected_options = find_xpath('.//option[@selected]')
|
82
83
|
if multiple?
|
83
|
-
|
84
|
+
selected_options.map(&method(:option_value))
|
84
85
|
else
|
85
|
-
|
86
|
-
option[:value] || option.content if option
|
86
|
+
option_value(selected_options.first || find_xpath('.//option').first)
|
87
87
|
end
|
88
88
|
elsif tag_name == 'input' && %w[radio checkbox].include?(native[:type])
|
89
89
|
native[:value] || 'on'
|
@@ -104,7 +104,7 @@ module Capybara
|
|
104
104
|
return false if (tag_name == 'input') && (native[:type] == 'hidden')
|
105
105
|
|
106
106
|
if check_ancestors
|
107
|
-
!
|
107
|
+
!find_xpath("boolean(./ancestor-or-self::*[contains(@style, 'display:none') or contains(@style, 'display: none') or @hidden or name()='script' or name()='head'])")
|
108
108
|
else
|
109
109
|
# No need for an xpath if only checking the current element
|
110
110
|
!(native.has_attribute?('hidden') || (native[:style] =~ /display:\s?none/) || %w[script head].include?(tag_name))
|
@@ -177,6 +177,13 @@ module Capybara
|
|
177
177
|
def session_options
|
178
178
|
Capybara.session_options
|
179
179
|
end
|
180
|
+
|
181
|
+
private
|
182
|
+
|
183
|
+
def option_value(option)
|
184
|
+
return nil if option.nil?
|
185
|
+
option[:value] || option.content
|
186
|
+
end
|
180
187
|
end
|
181
188
|
end
|
182
189
|
end
|
@@ -23,9 +23,9 @@ module Capybara
|
|
23
23
|
|
24
24
|
def self.wait(options, default = Capybara.default_max_wait_time)
|
25
25
|
# if no value or nil for the :wait option is passed it should default to the default
|
26
|
-
|
27
|
-
|
28
|
-
|
26
|
+
wait = options.fetch(:wait, nil)
|
27
|
+
wait = default if wait.nil?
|
28
|
+
wait || 0
|
29
29
|
end
|
30
30
|
|
31
31
|
##
|
@@ -69,7 +69,7 @@ module Capybara
|
|
69
69
|
private
|
70
70
|
|
71
71
|
def count_specified?
|
72
|
-
COUNT_KEYS.any? { |
|
72
|
+
COUNT_KEYS.any? { |key| options.key? key }
|
73
73
|
end
|
74
74
|
|
75
75
|
def count_message
|