capybara 3.1.1 → 3.2.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 +19 -0
- data/README.md +1 -1
- data/lib/capybara.rb +2 -0
- data/lib/capybara/config.rb +2 -1
- data/lib/capybara/driver/base.rb +1 -1
- data/lib/capybara/driver/node.rb +3 -3
- data/lib/capybara/node/actions.rb +90 -92
- data/lib/capybara/node/base.rb +2 -2
- data/lib/capybara/node/document_matchers.rb +5 -5
- data/lib/capybara/node/element.rb +47 -16
- data/lib/capybara/node/finders.rb +13 -13
- data/lib/capybara/node/matchers.rb +18 -17
- data/lib/capybara/node/simple.rb +6 -2
- data/lib/capybara/queries/ancestor_query.rb +1 -1
- data/lib/capybara/queries/base_query.rb +3 -3
- data/lib/capybara/queries/current_path_query.rb +1 -1
- data/lib/capybara/queries/match_query.rb +8 -0
- data/lib/capybara/queries/selector_query.rb +97 -42
- data/lib/capybara/queries/sibling_query.rb +1 -1
- data/lib/capybara/queries/text_query.rb +12 -7
- data/lib/capybara/rack_test/browser.rb +9 -7
- data/lib/capybara/rack_test/form.rb +15 -17
- data/lib/capybara/rack_test/node.rb +12 -12
- data/lib/capybara/result.rb +26 -15
- data/lib/capybara/rspec.rb +1 -2
- data/lib/capybara/rspec/compound.rb +4 -4
- data/lib/capybara/rspec/matchers.rb +2 -2
- data/lib/capybara/selector.rb +75 -225
- data/lib/capybara/selector/css.rb +2 -2
- data/lib/capybara/selector/filter_set.rb +17 -21
- data/lib/capybara/selector/filters/base.rb +24 -1
- data/lib/capybara/selector/filters/expression_filter.rb +3 -5
- data/lib/capybara/selector/filters/node_filter.rb +4 -4
- data/lib/capybara/selector/selector.rb +221 -69
- data/lib/capybara/selenium/driver.rb +15 -88
- data/lib/capybara/selenium/node.rb +25 -28
- data/lib/capybara/server.rb +10 -54
- data/lib/capybara/server/animation_disabler.rb +43 -0
- data/lib/capybara/server/middleware.rb +55 -0
- data/lib/capybara/session.rb +29 -30
- data/lib/capybara/session/config.rb +11 -1
- data/lib/capybara/session/matchers.rb +5 -5
- data/lib/capybara/spec/session/assert_text_spec.rb +1 -1
- data/lib/capybara/spec/session/body_spec.rb +10 -12
- data/lib/capybara/spec/session/click_link_spec.rb +3 -3
- data/lib/capybara/spec/session/element/assert_match_selector_spec.rb +1 -1
- data/lib/capybara/spec/session/fill_in_spec.rb +9 -0
- data/lib/capybara/spec/session/find_field_spec.rb +1 -1
- data/lib/capybara/spec/session/find_spec.rb +8 -3
- data/lib/capybara/spec/session/has_link_spec.rb +2 -2
- data/lib/capybara/spec/session/node_spec.rb +50 -0
- data/lib/capybara/spec/session/node_wrapper_spec.rb +5 -5
- data/lib/capybara/spec/session/save_and_open_screenshot_spec.rb +1 -1
- data/lib/capybara/spec/session/window/windows_spec.rb +3 -5
- data/lib/capybara/spec/spec_helper.rb +4 -2
- data/lib/capybara/spec/views/with_animation.erb +46 -0
- data/lib/capybara/version.rb +1 -1
- data/lib/capybara/window.rb +3 -2
- data/spec/filter_set_spec.rb +19 -2
- data/spec/result_spec.rb +33 -1
- data/spec/rspec/features_spec.rb +6 -10
- data/spec/rspec/shared_spec_matchers.rb +4 -4
- data/spec/selector_spec.rb +74 -4
- data/spec/selenium_spec_marionette.rb +2 -0
- data/spec/server_spec.rb +1 -1
- data/spec/session_spec.rb +12 -0
- data/spec/shared_selenium_session.rb +30 -0
- metadata +8 -9
- data/.yard/templates_custom/default/class/html/selectors.erb +0 -38
- data/.yard/templates_custom/default/class/html/setup.rb +0 -17
- data/.yard/yard_extensions.rb +0 -78
- data/.yardopts +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3f4ca4591c94a37a0a1c69adceb5165923d98c18d12f5522c709461d566ee1b2
|
4
|
+
data.tar.gz: a81064c22b5ad8a3c3967a155a481fc1c25c154056377c1d08188c15de5afe67
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bcdf15351d765a4c3112db4744b85ba02770cd8367fcb28970f89d2971a07e6643efd949458e124bf634f9d27204e5a2f6c582a0ef183ceeb59cf6f05d3bd826
|
7
|
+
data.tar.gz: 1b798cb089ce2a0524633345f61ff6471041418ae9b4d561f1be50b27b32946d61ebcf62fe4f6f34f0ff699cff9465baf933c7292256fb08d962aa244007eed4
|
data/History.md
CHANGED
@@ -1,3 +1,22 @@
|
|
1
|
+
# Version 3.2.0
|
2
|
+
Release date: 2018-06-01
|
3
|
+
|
4
|
+
### Changed
|
5
|
+
|
6
|
+
* Ruby 2.3.0+ is now required
|
7
|
+
* `ElementNotFound` errors raised in selector filters are interpreted as non-matches
|
8
|
+
|
9
|
+
### Added
|
10
|
+
|
11
|
+
* New global configuration `default_set_options` used in `Capybara::Node::Element#set` as default `options` hash [Champier Cyril]
|
12
|
+
* `execute_javascript` and `evaluate_javascript` can now be called on elements to run the JS in the context of the element [Thomas Walpole]
|
13
|
+
* Filters in custom selectors now support a `matcher` Regexp to handle multiple filter options [Thomas Walpole]
|
14
|
+
* `:element` selector type which will match on any attribute (other than the reserved names) passed as a filter option [Thomas Walpole]
|
15
|
+
* `:class` filter option now supports preceding class names with `!` to indicate not having that class [Thomas Walpole]
|
16
|
+
* `:class` and `:id` filter options now accept `XPath::Expression` objects to allow for more flexibility in matching [Thomas Walpole]
|
17
|
+
* `Capybara.disable_animation` setting which triggers loading of a middleware that attempts to disable animations in pages.
|
18
|
+
This is very much a beta feature and may change/disappear in the future. [Thomas Walpole]
|
19
|
+
|
1
20
|
# Version 3.1.1
|
2
21
|
Release date: 2018-05-25
|
3
22
|
|
data/README.md
CHANGED
@@ -7,7 +7,7 @@
|
|
7
7
|
[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/jnicklas/capybara?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
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.2_stable/README.md
|
11
11
|
|
12
12
|
|
13
13
|
Capybara helps you test web applications by simulating how a real user would
|
data/lib/capybara.rb
CHANGED
@@ -82,6 +82,7 @@ module Capybara
|
|
82
82
|
# [reuse_server = Boolean] Reuse the server thread between multiple sessions using the same app object (Default: true)
|
83
83
|
# [threadsafe = Boolean] Whether sessions can be configured individually (Default: false)
|
84
84
|
# [server = Symbol] The name of the registered server to use when running the app under test (Default: :webrick)
|
85
|
+
# [default_set_options = Hash] The default options passed to Node::set (Default: {})
|
85
86
|
#
|
86
87
|
# === DSL Options
|
87
88
|
#
|
@@ -479,6 +480,7 @@ Capybara.configure do |config|
|
|
479
480
|
config.automatic_label_click = false
|
480
481
|
config.enable_aria_label = false
|
481
482
|
config.reuse_server = true
|
483
|
+
config.default_set_options = {}
|
482
484
|
end
|
483
485
|
|
484
486
|
Capybara.register_driver :rack_test do |app|
|
data/lib/capybara/config.rb
CHANGED
@@ -20,6 +20,7 @@ module Capybara
|
|
20
20
|
|
21
21
|
def initialize
|
22
22
|
@session_options = Capybara::SessionConfig.new
|
23
|
+
@javascript_driver = nil
|
23
24
|
end
|
24
25
|
|
25
26
|
attr_writer :reuse_server
|
@@ -80,7 +81,7 @@ module Capybara
|
|
80
81
|
|
81
82
|
def deprecate(method, alternate_method, once = false)
|
82
83
|
@deprecation_notified ||= {}
|
83
|
-
warn "DEPRECATED: ##{method} is deprecated, please use ##{alternate_method} instead" unless once
|
84
|
+
warn "DEPRECATED: ##{method} is deprecated, please use ##{alternate_method} instead" unless once && @deprecation_notified[method]
|
84
85
|
@deprecation_notified[method] = true
|
85
86
|
end
|
86
87
|
end
|
data/lib/capybara/driver/base.rb
CHANGED
data/lib/capybara/driver/node.rb
CHANGED
@@ -40,15 +40,15 @@ module Capybara
|
|
40
40
|
raise NotImplementedError
|
41
41
|
end
|
42
42
|
|
43
|
-
def click(keys = [], options
|
43
|
+
def click(keys = [], **options)
|
44
44
|
raise NotImplementedError
|
45
45
|
end
|
46
46
|
|
47
|
-
def right_click(keys = [], options
|
47
|
+
def right_click(keys = [], **options)
|
48
48
|
raise NotImplementedError
|
49
49
|
end
|
50
50
|
|
51
|
-
def double_click(keys = [], options
|
51
|
+
def double_click(keys = [], **options)
|
52
52
|
raise NotImplementedError
|
53
53
|
end
|
54
54
|
|
@@ -50,7 +50,7 @@ module Capybara
|
|
50
50
|
#
|
51
51
|
# @macro waiting_behavior
|
52
52
|
#
|
53
|
-
# @overload click_button([locator], options)
|
53
|
+
# @overload click_button([locator], **options)
|
54
54
|
# @param [String] locator Which button to find
|
55
55
|
# @param options See {Capybara::Node::Finders#find_button}
|
56
56
|
# @return [Capybara::Node::Element] The element clicked
|
@@ -66,18 +66,18 @@ module Capybara
|
|
66
66
|
# page.fill_in 'Name', with: 'Bob'
|
67
67
|
#
|
68
68
|
#
|
69
|
-
# @overload fill_in([locator], options
|
69
|
+
# @overload fill_in([locator], with:, **options)
|
70
70
|
# @param [String] locator Which field to fill in
|
71
71
|
# @param [Hash] options
|
72
|
+
# @param with: [String] The value to fill_in
|
72
73
|
# @macro waiting_behavior
|
73
|
-
# @option options [String]
|
74
|
-
# @option options [
|
75
|
-
# @option options [String]
|
76
|
-
# @option options [
|
77
|
-
# @option options [String]
|
78
|
-
# @option options [String]
|
79
|
-
# @option options [
|
80
|
-
# @option options [String, Array<String>] :class Match fields that match the class(es) provided
|
74
|
+
# @option options [String] currently_with The current value property of the field to fill in
|
75
|
+
# @option options [Boolean] multiple Match fields that can have multiple values?
|
76
|
+
# @option options [String] id Match fields that match the id attribute
|
77
|
+
# @option options [String] name Match fields that match the name attribute
|
78
|
+
# @option options [String] placeholder Match fields that match the placeholder attribute
|
79
|
+
# @option options [String, Array<String>] class Match fields that match the class(es) provided
|
80
|
+
# @option options [Hash] fill_options Driver specific options regarding how to fill fields (Defaults come from Capybara.default_set_options)
|
81
81
|
#
|
82
82
|
# @return [Capybara::Node::Element] The element filled_in
|
83
83
|
def fill_in(locator = nil, with:, fill_options: {}, **options)
|
@@ -86,7 +86,7 @@ module Capybara
|
|
86
86
|
end
|
87
87
|
|
88
88
|
# @!macro label_click
|
89
|
-
# @option options [Boolean]
|
89
|
+
# @option options [Boolean] allow_label_click (Capybara.automatic_label_click) Attempt to click the label to toggle state if element is non-visible.
|
90
90
|
|
91
91
|
##
|
92
92
|
#
|
@@ -95,19 +95,19 @@ module Capybara
|
|
95
95
|
#
|
96
96
|
# page.choose('Male')
|
97
97
|
#
|
98
|
-
# @overload choose([locator], options)
|
98
|
+
# @overload choose([locator], **options)
|
99
99
|
# @param [String] locator Which radio button to choose
|
100
100
|
#
|
101
|
-
# @option options [String]
|
102
|
-
# @option options [String]
|
103
|
-
# @option options [String]
|
104
|
-
# @option options [String, Array<String>]
|
101
|
+
# @option options [String] option Value of the radio_button to choose
|
102
|
+
# @option options [String] id Match fields that match the id attribute
|
103
|
+
# @option options [String] name Match fields that match the name attribute
|
104
|
+
# @option options [String, Array<String>] class Match fields that match the class(es) provided
|
105
105
|
# @macro waiting_behavior
|
106
106
|
# @macro label_click
|
107
107
|
#
|
108
108
|
# @return [Capybara::Node::Element] The element chosen or the label clicked
|
109
109
|
def choose(locator = nil, **options)
|
110
|
-
_check_with_label(:radio_button, true, locator,
|
110
|
+
_check_with_label(:radio_button, true, locator, options)
|
111
111
|
end
|
112
112
|
|
113
113
|
##
|
@@ -118,19 +118,19 @@ module Capybara
|
|
118
118
|
# page.check('German')
|
119
119
|
#
|
120
120
|
#
|
121
|
-
# @overload check([locator], options)
|
121
|
+
# @overload check([locator], **options)
|
122
122
|
# @param [String] locator Which check box to check
|
123
123
|
#
|
124
|
-
# @option options [String]
|
124
|
+
# @option options [String] option Value of the checkbox to select
|
125
125
|
# @option options [String] id Match fields that match the id attribute
|
126
126
|
# @option options [String] name Match fields that match the name attribute
|
127
|
-
# @option options [String, Array<String>]
|
127
|
+
# @option options [String, Array<String>] class Match fields that match the class(es) provided
|
128
128
|
# @macro label_click
|
129
129
|
# @macro waiting_behavior
|
130
130
|
#
|
131
131
|
# @return [Capybara::Node::Element] The element checked or the label clicked
|
132
132
|
def check(locator = nil, **options)
|
133
|
-
_check_with_label(:checkbox, true, locator,
|
133
|
+
_check_with_label(:checkbox, true, locator, options)
|
134
134
|
end
|
135
135
|
|
136
136
|
##
|
@@ -141,19 +141,19 @@ module Capybara
|
|
141
141
|
# page.uncheck('German')
|
142
142
|
#
|
143
143
|
#
|
144
|
-
# @overload uncheck([locator], options)
|
144
|
+
# @overload uncheck([locator], **options)
|
145
145
|
# @param [String] locator Which check box to uncheck
|
146
146
|
#
|
147
|
-
# @option options [String]
|
147
|
+
# @option options [String] option Value of the checkbox to deselect
|
148
148
|
# @option options [String] id Match fields that match the id attribute
|
149
149
|
# @option options [String] name Match fields that match the name attribute
|
150
|
-
# @option options [String, Array<String>]
|
150
|
+
# @option options [String, Array<String>] class Match fields that match the class(es) provided
|
151
151
|
# @macro label_click
|
152
152
|
# @macro waiting_behavior
|
153
153
|
#
|
154
154
|
# @return [Capybara::Node::Element] The element unchecked or the label clicked
|
155
155
|
def uncheck(locator = nil, **options)
|
156
|
-
_check_with_label(:checkbox, false, locator,
|
156
|
+
_check_with_label(:checkbox, false, locator, options)
|
157
157
|
end
|
158
158
|
|
159
159
|
##
|
@@ -169,46 +169,17 @@ module Capybara
|
|
169
169
|
#
|
170
170
|
# @macro waiting_behavior
|
171
171
|
#
|
172
|
-
# @param [String]
|
173
|
-
# @
|
172
|
+
# @param value [String] Which option to select
|
173
|
+
# @param from: [String] The id, name or label of the select box
|
174
174
|
#
|
175
175
|
# @return [Capybara::Node::Element] The option element selected
|
176
176
|
def select(value = nil, from: nil, **options)
|
177
|
-
|
178
|
-
synchronize(Capybara::Queries::BaseQuery.wait(options, session_options.default_max_wait_time)) do
|
179
|
-
begin
|
180
|
-
find(:select, from, options)
|
181
|
-
rescue Capybara::ElementNotFound => select_error
|
182
|
-
raise if %i[selected with_selected multiple].any? { |option| options.key?(option) }
|
183
|
-
begin
|
184
|
-
find(:datalist_input, from, options)
|
185
|
-
rescue Capybara::ElementNotFound => dlinput_error
|
186
|
-
raise Capybara::ElementNotFound, "#{select_error.message} and #{dlinput_error.message}"
|
187
|
-
end
|
188
|
-
end
|
189
|
-
end
|
190
|
-
else
|
191
|
-
self
|
192
|
-
end
|
177
|
+
el = from ? find_select_or_datalist_input(from, options) : self
|
193
178
|
|
194
|
-
if
|
195
|
-
|
196
|
-
# TODO: this is a more efficient but won't work with non-JS drivers
|
197
|
-
# datalist_options = session.evaluate_script('Array.prototype.slice.call((arguments[0].list||{}).options || []).filter(function(el){ return !el.disabled }).map(function(el){ return { "value": el.value, "label": el.label} })', scope)
|
198
|
-
datalist_options = session.evaluate_script(DATALIST_OPTIONS_SCRIPT, scope)
|
199
|
-
if (option = datalist_options.find { |o| o['value'] == value || o['label'] == value })
|
200
|
-
scope.set(option["value"])
|
201
|
-
else
|
202
|
-
raise ::Capybara::ElementNotFound, "Unable to find datalist option \"#{value}\""
|
203
|
-
end
|
204
|
-
rescue ::Capybara::NotSupportedByDriverError
|
205
|
-
# Implement for drivers that don't support JS
|
206
|
-
datalist = find(:xpath, XPath.descendant(:datalist)[XPath.attr(:id) == scope[:list]], visible: false)
|
207
|
-
option = datalist.find(:datalist_option, value, disabled: false)
|
208
|
-
scope.set(option.value)
|
209
|
-
end
|
179
|
+
if el.respond_to?(:tag_name) && (el.tag_name == "input")
|
180
|
+
select_datalist_option(el, value)
|
210
181
|
else
|
211
|
-
|
182
|
+
el.find(:option, value, options).select_option
|
212
183
|
end
|
213
184
|
end
|
214
185
|
|
@@ -222,8 +193,8 @@ module Capybara
|
|
222
193
|
#
|
223
194
|
# @macro waiting_behavior
|
224
195
|
#
|
225
|
-
# @param [String]
|
226
|
-
# @param
|
196
|
+
# @param value [String] Which option to unselect
|
197
|
+
# @param from: [String] The id, name or label of the select box
|
227
198
|
#
|
228
199
|
# @return [Capybara::Node::Element] The option element unselected
|
229
200
|
def unselect(value = nil, from: nil, **options)
|
@@ -238,20 +209,21 @@ module Capybara
|
|
238
209
|
#
|
239
210
|
# page.attach_file(locator, '/path/to/file.png')
|
240
211
|
#
|
241
|
-
# @
|
212
|
+
# @overload attach_file([locator], path, **options)
|
213
|
+
# @macro waiting_behavior
|
242
214
|
#
|
243
|
-
#
|
244
|
-
#
|
215
|
+
# @param [String] locator Which field to attach the file to
|
216
|
+
# @param [String] path The path of the file that will be attached, or an array of paths
|
245
217
|
#
|
246
|
-
#
|
247
|
-
#
|
248
|
-
#
|
249
|
-
#
|
250
|
-
#
|
251
|
-
#
|
252
|
-
#
|
218
|
+
# @option options [Symbol] match (Capybara.match) The matching strategy to use (:one, :first, :prefer_exact, :smart).
|
219
|
+
# @option options [Boolean] exact (Capybara.exact) Match the exact label name/contents or accept a partial match.
|
220
|
+
# @option options [Boolean] multiple Match field which allows multiple file selection
|
221
|
+
# @option options [String] id Match fields that match the id attribute
|
222
|
+
# @option options [String] name Match fields that match the name attribute
|
223
|
+
# @option options [String, Array<String>] class Match fields that match the class(es) provided
|
224
|
+
# @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)
|
253
225
|
#
|
254
|
-
#
|
226
|
+
# @return [Capybara::Node::Element] The file field element
|
255
227
|
def attach_file(locator = nil, path, make_visible: nil, **options) # rubocop:disable Style/OptionalArguments
|
256
228
|
Array(path).each do |p|
|
257
229
|
raise Capybara::FileNotFound, "cannot attach file, #{p} does not exist" unless File.exist?(p.to_s)
|
@@ -267,6 +239,35 @@ module Capybara
|
|
267
239
|
|
268
240
|
private
|
269
241
|
|
242
|
+
def find_select_or_datalist_input(from, options)
|
243
|
+
synchronize(Capybara::Queries::BaseQuery.wait(options, session_options.default_max_wait_time)) do
|
244
|
+
begin
|
245
|
+
find(:select, from, options)
|
246
|
+
rescue Capybara::ElementNotFound => select_error
|
247
|
+
raise if %i[selected with_selected multiple].any? { |option| options.key?(option) }
|
248
|
+
begin
|
249
|
+
find(:datalist_input, from, options)
|
250
|
+
rescue Capybara::ElementNotFound => dlinput_error
|
251
|
+
raise Capybara::ElementNotFound, "#{select_error.message} and #{dlinput_error.message}"
|
252
|
+
end
|
253
|
+
end
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
def select_datalist_option(input, value)
|
258
|
+
datalist_options = input.evaluate_script(DATALIST_OPTIONS_SCRIPT)
|
259
|
+
if (option = datalist_options.find { |o| o['value'] == value || o['label'] == value })
|
260
|
+
input.set(option['value'])
|
261
|
+
else
|
262
|
+
raise ::Capybara::ElementNotFound, %(Unable to find datalist option "#{value}")
|
263
|
+
end
|
264
|
+
rescue ::Capybara::NotSupportedByDriverError
|
265
|
+
# Implement for drivers that don't support JS
|
266
|
+
datalist = find(:xpath, XPath.descendant(:datalist)[XPath.attr(:id) == input[:list]], visible: false)
|
267
|
+
option = datalist.find(:datalist_option, value, disabled: false)
|
268
|
+
input.set(option.value)
|
269
|
+
end
|
270
|
+
|
270
271
|
def while_visible(element, visible_css)
|
271
272
|
visible_css = { opacity: 1, display: 'block', visibility: 'visible' } if visible_css == true
|
272
273
|
_update_style(element, visible_css)
|
@@ -279,14 +280,14 @@ module Capybara
|
|
279
280
|
end
|
280
281
|
|
281
282
|
def _update_style(element, style)
|
282
|
-
|
283
|
+
element.execute_script(UPDATE_STYLE_SCRIPT, style)
|
283
284
|
rescue Capybara::NotSupportedByDriverError
|
284
285
|
warn "The :make_visible option is not supported by the current driver - ignoring"
|
285
286
|
end
|
286
287
|
|
287
288
|
def _reset_style(element)
|
288
|
-
|
289
|
-
rescue # swallow extra errors
|
289
|
+
element.execute_script(RESET_STYLE_SCRIPT)
|
290
|
+
rescue StandardError # rubocop:disable Lint/HandleExceptions swallow extra errors
|
290
291
|
end
|
291
292
|
|
292
293
|
def _check_with_label(selector, checked, locator, allow_label_click: session_options.automatic_label_click, **options)
|
@@ -294,40 +295,37 @@ module Capybara
|
|
294
295
|
begin
|
295
296
|
el = find(selector, locator, options)
|
296
297
|
el.set(checked)
|
297
|
-
rescue => e
|
298
|
+
rescue StandardError => e
|
298
299
|
raise unless allow_label_click && catch_error?(e)
|
299
300
|
begin
|
300
301
|
el ||= find(selector, locator, options.merge(visible: :all))
|
301
|
-
|
302
|
-
|
303
|
-
rescue # swallow extra errors - raise original
|
302
|
+
find(:label, for: el, visible: true).click unless el.checked? == checked
|
303
|
+
rescue StandardError # swallow extra errors - raise original
|
304
304
|
raise e
|
305
305
|
end
|
306
306
|
end
|
307
307
|
end
|
308
308
|
end
|
309
309
|
|
310
|
-
UPDATE_STYLE_SCRIPT =
|
311
|
-
|
312
|
-
|
313
|
-
var css = arguments[1];
|
310
|
+
UPDATE_STYLE_SCRIPT = <<~'JS'
|
311
|
+
this.capybara_style_cache = this.style.cssText;
|
312
|
+
var css = arguments[0];
|
314
313
|
for (var prop in css){
|
315
314
|
if (css.hasOwnProperty(prop)) {
|
316
|
-
|
315
|
+
this.style[prop] = css[prop]
|
317
316
|
}
|
318
317
|
}
|
319
318
|
JS
|
320
319
|
|
321
|
-
RESET_STYLE_SCRIPT =
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
delete el.capybara_style_cache;
|
320
|
+
RESET_STYLE_SCRIPT = <<~'JS'
|
321
|
+
if (this.hasOwnProperty('capybara_style_cache')) {
|
322
|
+
this.style.cssText = this.capybara_style_cache;
|
323
|
+
delete this.capybara_style_cache;
|
326
324
|
}
|
327
325
|
JS
|
328
326
|
|
329
|
-
DATALIST_OPTIONS_SCRIPT =
|
330
|
-
Array.prototype.slice.call((
|
327
|
+
DATALIST_OPTIONS_SCRIPT = <<~'JS'
|
328
|
+
Array.prototype.slice.call((this.list||{}).options || []).
|
331
329
|
filter(function(el){ return !el.disabled }).
|
332
330
|
map(function(el){ return { "value": el.value, "label": el.label} })
|
333
331
|
JS
|
data/lib/capybara/node/base.rb
CHANGED
@@ -81,12 +81,12 @@ module Capybara
|
|
81
81
|
start_time = Capybara::Helpers.monotonic_time
|
82
82
|
begin
|
83
83
|
yield
|
84
|
-
rescue => e
|
84
|
+
rescue StandardError => e
|
85
85
|
session.raise_server_error!
|
86
86
|
raise e unless driver.wait? && catch_error?(e, errors)
|
87
87
|
raise e if (Capybara::Helpers.monotonic_time - start_time) >= seconds
|
88
88
|
sleep(0.05)
|
89
|
-
raise Capybara::FrozenInTime, "
|
89
|
+
raise Capybara::FrozenInTime, "Time appears to be frozen. Capybara does not work with libraries which freeze time, consider using time travelling instead" if Capybara::Helpers.monotonic_time == start_time
|
90
90
|
reload if session_options.automatic_reload
|
91
91
|
retry
|
92
92
|
ensure
|
@@ -7,9 +7,9 @@ module Capybara
|
|
7
7
|
# Asserts that the page has the given title.
|
8
8
|
#
|
9
9
|
# @!macro title_query_params
|
10
|
-
# @overload $0(string, options
|
10
|
+
# @overload $0(string, **options)
|
11
11
|
# @param string [String] The string that title should include
|
12
|
-
# @overload $0(regexp, options
|
12
|
+
# @overload $0(regexp, **options)
|
13
13
|
# @param regexp [Regexp] The regexp that title should match to
|
14
14
|
# @option options [Numeric] :wait (Capybara.default_max_wait_time) Maximum time that Capybara will wait for title to eq/match given string/regexp argument
|
15
15
|
# @option options [Boolean] :exact (false) When passed a string should the match be exact or just substring
|
@@ -40,7 +40,7 @@ module Capybara
|
|
40
40
|
def has_title?(title, **options)
|
41
41
|
assert_title(title, options)
|
42
42
|
rescue Capybara::ExpectationNotMet
|
43
|
-
|
43
|
+
false
|
44
44
|
end
|
45
45
|
|
46
46
|
##
|
@@ -52,7 +52,7 @@ module Capybara
|
|
52
52
|
def has_no_title?(title, **options)
|
53
53
|
assert_no_title(title, options)
|
54
54
|
rescue Capybara::ExpectationNotMet
|
55
|
-
|
55
|
+
false
|
56
56
|
end
|
57
57
|
|
58
58
|
private
|
@@ -62,7 +62,7 @@ module Capybara
|
|
62
62
|
synchronize(query.wait) do
|
63
63
|
yield(query)
|
64
64
|
end
|
65
|
-
|
65
|
+
true
|
66
66
|
end
|
67
67
|
end
|
68
68
|
end
|