capybara 3.6.0 → 3.7.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 +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
|
[![SemVer](https://api.dependabot.com/badges/compatibility_score?dependency-name=capybara&package-manager=bundler&version-scheme=semver)](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
|