capybara 2.6.2 → 2.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 +40 -15
- data/README.md +45 -38
- data/lib/capybara.rb +86 -10
- data/lib/capybara/cucumber.rb +1 -0
- data/lib/capybara/driver/base.rb +5 -2
- data/lib/capybara/driver/node.rb +1 -0
- data/lib/capybara/dsl.rb +1 -0
- data/lib/capybara/helpers.rb +3 -2
- data/lib/capybara/node/actions.rb +6 -0
- data/lib/capybara/node/base.rb +1 -0
- data/lib/capybara/node/document.rb +1 -0
- data/lib/capybara/node/document_matchers.rb +1 -0
- data/lib/capybara/node/element.rb +1 -0
- data/lib/capybara/node/finders.rb +3 -2
- data/lib/capybara/node/matchers.rb +72 -2
- data/lib/capybara/node/simple.rb +6 -3
- data/lib/capybara/queries/base_query.rb +1 -0
- data/lib/capybara/queries/current_path_query.rb +1 -0
- data/lib/capybara/queries/match_query.rb +21 -0
- data/lib/capybara/queries/selector_query.rb +138 -0
- data/lib/capybara/queries/text_query.rb +1 -0
- data/lib/capybara/queries/title_query.rb +1 -0
- data/lib/capybara/query.rb +3 -131
- data/lib/capybara/rack_test/browser.rb +1 -0
- data/lib/capybara/rack_test/css_handlers.rb +1 -0
- data/lib/capybara/rack_test/driver.rb +6 -4
- data/lib/capybara/rack_test/form.rb +1 -0
- data/lib/capybara/rack_test/node.rb +1 -0
- data/lib/capybara/rails.rb +2 -1
- data/lib/capybara/result.rb +1 -0
- data/lib/capybara/rspec.rb +1 -0
- data/lib/capybara/rspec/features.rb +1 -0
- data/lib/capybara/rspec/matchers.rb +54 -3
- data/lib/capybara/selector.rb +175 -75
- data/lib/capybara/selector/filter.rb +48 -0
- data/lib/capybara/selenium/driver.rb +24 -7
- data/lib/capybara/selenium/node.rb +1 -0
- data/lib/capybara/server.rb +38 -6
- data/lib/capybara/session.rb +30 -14
- data/lib/capybara/session/matchers.rb +2 -1
- data/lib/capybara/spec/public/test.js +6 -0
- data/lib/capybara/spec/session/accept_alert_spec.rb +2 -1
- data/lib/capybara/spec/session/accept_confirm_spec.rb +2 -1
- data/lib/capybara/spec/session/accept_prompt_spec.rb +2 -1
- data/lib/capybara/spec/session/all_spec.rb +1 -0
- data/lib/capybara/spec/session/assert_current_path.rb +1 -0
- data/lib/capybara/spec/session/assert_selector.rb +1 -0
- data/lib/capybara/spec/session/assert_text.rb +1 -0
- data/lib/capybara/spec/session/assert_title.rb +1 -0
- data/lib/capybara/spec/session/attach_file_spec.rb +1 -0
- data/lib/capybara/spec/session/body_spec.rb +1 -0
- data/lib/capybara/spec/session/check_spec.rb +1 -0
- data/lib/capybara/spec/session/choose_spec.rb +1 -0
- data/lib/capybara/spec/session/click_button_spec.rb +1 -0
- data/lib/capybara/spec/session/click_link_or_button_spec.rb +1 -0
- data/lib/capybara/spec/session/click_link_spec.rb +1 -0
- data/lib/capybara/spec/session/current_scope_spec.rb +2 -1
- data/lib/capybara/spec/session/current_url_spec.rb +1 -0
- data/lib/capybara/spec/session/dismiss_confirm_spec.rb +2 -1
- data/lib/capybara/spec/session/dismiss_prompt_spec.rb +2 -1
- data/lib/capybara/spec/session/element/assert_match_selector.rb +31 -0
- data/lib/capybara/spec/session/element/match_css_spec.rb +17 -0
- data/lib/capybara/spec/session/element/match_xpath_spec.rb +23 -0
- data/lib/capybara/spec/session/element/matches_selector_spec.rb +63 -0
- data/lib/capybara/spec/session/evaluate_script_spec.rb +1 -0
- data/lib/capybara/spec/session/execute_script_spec.rb +1 -0
- data/lib/capybara/spec/session/fill_in_spec.rb +1 -0
- data/lib/capybara/spec/session/find_button_spec.rb +1 -0
- data/lib/capybara/spec/session/find_by_id_spec.rb +1 -0
- data/lib/capybara/spec/session/find_field_spec.rb +1 -0
- data/lib/capybara/spec/session/find_link_spec.rb +1 -0
- data/lib/capybara/spec/session/find_spec.rb +1 -0
- data/lib/capybara/spec/session/first_spec.rb +1 -0
- data/lib/capybara/spec/session/go_back_spec.rb +1 -0
- data/lib/capybara/spec/session/go_forward_spec.rb +1 -0
- data/lib/capybara/spec/session/has_button_spec.rb +1 -0
- data/lib/capybara/spec/session/has_css_spec.rb +1 -0
- data/lib/capybara/spec/session/has_current_path_spec.rb +1 -0
- data/lib/capybara/spec/session/has_field_spec.rb +13 -0
- data/lib/capybara/spec/session/has_link_spec.rb +1 -0
- data/lib/capybara/spec/session/has_select_spec.rb +19 -0
- data/lib/capybara/spec/session/has_selector_spec.rb +6 -0
- data/lib/capybara/spec/session/has_table_spec.rb +1 -0
- data/lib/capybara/spec/session/has_text_spec.rb +1 -0
- data/lib/capybara/spec/session/has_title_spec.rb +1 -0
- data/lib/capybara/spec/session/has_xpath_spec.rb +1 -0
- data/lib/capybara/spec/session/headers.rb +1 -0
- data/lib/capybara/spec/session/html_spec.rb +1 -0
- data/lib/capybara/spec/session/node_spec.rb +29 -0
- data/lib/capybara/spec/session/reset_session_spec.rb +35 -1
- data/lib/capybara/spec/session/response_code.rb +1 -0
- data/lib/capybara/spec/session/save_and_open_page_spec.rb +1 -0
- data/lib/capybara/spec/session/save_and_open_screenshot_spec.rb +3 -2
- data/lib/capybara/spec/session/save_page_spec.rb +34 -2
- data/lib/capybara/spec/session/save_screenshot_spec.rb +31 -1
- data/lib/capybara/spec/session/screenshot_spec.rb +3 -1
- data/lib/capybara/spec/session/select_spec.rb +1 -0
- data/lib/capybara/spec/session/selectors_spec.rb +35 -0
- data/lib/capybara/spec/session/text_spec.rb +1 -0
- data/lib/capybara/spec/session/title_spec.rb +2 -1
- data/lib/capybara/spec/session/uncheck_spec.rb +1 -0
- data/lib/capybara/spec/session/unselect_spec.rb +1 -0
- data/lib/capybara/spec/session/visit_spec.rb +1 -0
- data/lib/capybara/spec/session/window/become_closed_spec.rb +1 -0
- data/lib/capybara/spec/session/window/current_window_spec.rb +1 -0
- data/lib/capybara/spec/session/window/open_new_window_spec.rb +1 -0
- data/lib/capybara/spec/session/window/switch_to_window_spec.rb +1 -0
- data/lib/capybara/spec/session/window/window_opened_by_spec.rb +1 -0
- data/lib/capybara/spec/session/window/window_spec.rb +1 -8
- data/lib/capybara/spec/session/window/windows_spec.rb +1 -0
- data/lib/capybara/spec/session/window/within_window_spec.rb +2 -3
- data/lib/capybara/spec/session/within_frame_spec.rb +1 -0
- data/lib/capybara/spec/session/within_spec.rb +1 -0
- data/lib/capybara/spec/spec_helper.rb +2 -0
- data/lib/capybara/spec/test_app.rb +1 -0
- data/lib/capybara/spec/views/buttons.erb +1 -0
- data/lib/capybara/spec/views/fieldsets.erb +2 -1
- data/lib/capybara/spec/views/form.erb +24 -0
- data/lib/capybara/spec/views/frame_child.erb +2 -1
- data/lib/capybara/spec/views/frame_one.erb +2 -1
- data/lib/capybara/spec/views/frame_parent.erb +2 -1
- data/lib/capybara/spec/views/frame_two.erb +2 -1
- data/lib/capybara/spec/views/header_links.erb +1 -0
- data/lib/capybara/spec/views/host_links.erb +1 -0
- data/lib/capybara/spec/views/path.erb +1 -0
- data/lib/capybara/spec/views/popup_one.erb +1 -0
- data/lib/capybara/spec/views/popup_two.erb +1 -0
- data/lib/capybara/spec/views/postback.erb +2 -1
- data/lib/capybara/spec/views/tables.erb +1 -0
- data/lib/capybara/spec/views/with_base_tag.erb +1 -0
- data/lib/capybara/spec/views/with_count.erb +2 -1
- data/lib/capybara/spec/views/with_hover.erb +2 -1
- data/lib/capybara/spec/views/with_html.erb +3 -0
- data/lib/capybara/spec/views/with_html_entities.erb +1 -0
- data/lib/capybara/spec/views/with_js.erb +5 -0
- data/lib/capybara/spec/views/with_scope.erb +1 -0
- data/lib/capybara/spec/views/with_simple_html.erb +2 -1
- data/lib/capybara/spec/views/with_slow_unload.erb +17 -0
- data/lib/capybara/spec/views/with_title.erb +2 -1
- data/lib/capybara/spec/views/with_unload_alert.erb +12 -0
- data/lib/capybara/spec/views/with_windows.erb +1 -0
- data/lib/capybara/spec/views/within_frames.erb +2 -1
- data/lib/capybara/version.rb +2 -1
- data/lib/capybara/window.rb +1 -0
- data/spec/basic_node_spec.rb +1 -0
- data/spec/capybara_spec.rb +28 -1
- data/spec/dsl_spec.rb +1 -0
- data/spec/fixtures/selenium_driver_rspec_failure.rb +1 -0
- data/spec/fixtures/selenium_driver_rspec_success.rb +1 -0
- data/spec/rack_test_spec.rb +1 -0
- data/spec/result_spec.rb +1 -0
- data/spec/rspec/features_spec.rb +1 -0
- data/spec/rspec/matchers_spec.rb +1 -0
- data/spec/rspec/scenarios_spec.rb +1 -0
- data/spec/rspec/views_spec.rb +1 -0
- data/spec/rspec_spec.rb +1 -0
- data/spec/selector_spec.rb +55 -1
- data/spec/selenium_spec.rb +6 -2
- data/spec/selenium_spec_chrome.rb +1 -0
- data/spec/server_spec.rb +101 -13
- data/spec/spec_helper.rb +1 -0
- metadata +16 -6
data/lib/capybara/cucumber.rb
CHANGED
data/lib/capybara/driver/base.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
class Capybara::Driver::Base
|
2
3
|
def current_url
|
3
4
|
raise NotImplementedError
|
@@ -90,8 +91,8 @@ class Capybara::Driver::Base
|
|
90
91
|
def no_such_window_error
|
91
92
|
raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#no_such_window_error'
|
92
93
|
end
|
93
|
-
|
94
|
-
|
94
|
+
|
95
|
+
|
95
96
|
##
|
96
97
|
#
|
97
98
|
# Execute the block, and then accept the modal opened.
|
@@ -134,7 +135,9 @@ class Capybara::Driver::Base
|
|
134
135
|
false
|
135
136
|
end
|
136
137
|
|
138
|
+
# @deprecated This method is being removed
|
137
139
|
def browser_initialized?
|
140
|
+
warn "DEPRECATED: #browser_initialized? is deprecated and will be removed in the next version of Capybara"
|
138
141
|
true
|
139
142
|
end
|
140
143
|
end
|
data/lib/capybara/driver/node.rb
CHANGED
data/lib/capybara/dsl.rb
CHANGED
data/lib/capybara/helpers.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# encoding: UTF-8
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
4
|
module Capybara
|
4
5
|
|
@@ -96,7 +97,7 @@ module Capybara
|
|
96
97
|
# @option [Integer] minimum Count should have been larger than or equal to this value
|
97
98
|
#
|
98
99
|
def failure_message(description, options={})
|
99
|
-
message = "expected to find #{description}"
|
100
|
+
message = String.new("expected to find #{description}")
|
100
101
|
if options[:count]
|
101
102
|
message << " #{options[:count]} #{declension('time', 'times', options[:count])}"
|
102
103
|
elsif options[:between]
|
@@ -129,7 +130,7 @@ module Capybara
|
|
129
130
|
|
130
131
|
if defined?(Process::CLOCK_MONOTONIC)
|
131
132
|
def monotonic_time
|
132
|
-
|
133
|
+
Process.clock_gettime Process::CLOCK_MONOTONIC
|
133
134
|
end
|
134
135
|
else
|
135
136
|
def monotonic_time
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module Capybara
|
2
3
|
module Node
|
3
4
|
module Actions
|
@@ -150,6 +151,11 @@ module Capybara
|
|
150
151
|
# @param [String] locator Which field to attach the file to
|
151
152
|
# @param [String] path The path of the file that will be attached, or an array of paths
|
152
153
|
#
|
154
|
+
# @option options [Symbol] match (Capybara.match) The matching strategy to use (:one, :first, :prefer_exact, :smart).
|
155
|
+
# @option options [Boolean] exact (Capybara.exact) Match the exact label name/contents or accept a partial match.
|
156
|
+
# @option options [Fixnum] wait (Capybara.default_max_wait_time) If using a Javascript driver, maximum number of seconds during which the element will be searched for.
|
157
|
+
# @option options [Boolean] multiple Match field which allows multiple file selection
|
158
|
+
#
|
153
159
|
def attach_file(locator, path, options={})
|
154
160
|
Array(path).each do |p|
|
155
161
|
raise Capybara::FileNotFound, "cannot attach file, #{p} does not exist" unless File.exist?(p.to_s)
|
data/lib/capybara/node/base.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module Capybara
|
2
3
|
module Node
|
3
4
|
module Finders
|
@@ -28,7 +29,7 @@ module Capybara
|
|
28
29
|
# @raise [Capybara::ElementNotFound] If the element can't be found before time expires
|
29
30
|
#
|
30
31
|
def find(*args)
|
31
|
-
query = Capybara::
|
32
|
+
query = Capybara::Queries::SelectorQuery.new(*args)
|
32
33
|
synchronize(query.wait) do
|
33
34
|
if query.match == :smart or query.match == :prefer_exact
|
34
35
|
result = query.resolve_for(self, true)
|
@@ -177,7 +178,7 @@ module Capybara
|
|
177
178
|
# @return [Capybara::Result] A collection of found elements
|
178
179
|
#
|
179
180
|
def all(*args)
|
180
|
-
query = Capybara::
|
181
|
+
query = Capybara::Queries::SelectorQuery.new(*args)
|
181
182
|
synchronize(query.wait) do
|
182
183
|
result = query.resolve_for(self)
|
183
184
|
raise Capybara::ExpectationNotMet, result.failure_message unless result.matches_count?
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module Capybara
|
2
3
|
module Node
|
3
4
|
module Matchers
|
@@ -55,6 +56,36 @@ module Capybara
|
|
55
56
|
return false
|
56
57
|
end
|
57
58
|
|
59
|
+
##
|
60
|
+
#
|
61
|
+
# Checks if the current node matches given selector
|
62
|
+
# Usage is identical to Capybara::Node::Matchers#has_selector?
|
63
|
+
#
|
64
|
+
# @param (see Capybara::Node::Finders#has_selector?)
|
65
|
+
# @return [Boolean]
|
66
|
+
#
|
67
|
+
def matches_selector?(*args)
|
68
|
+
assert_matches_selector(*args)
|
69
|
+
rescue Capybara::ExpectationNotMet
|
70
|
+
return false
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
##
|
75
|
+
#
|
76
|
+
# Checks if the current node does not match given selector
|
77
|
+
# Usage is identical to Capybara::Node::Matchers#has_selector?
|
78
|
+
#
|
79
|
+
# @param (see Capybara::Node::Finders#has_selector?)
|
80
|
+
# @return [Boolean]
|
81
|
+
#
|
82
|
+
def not_matches_selector?(*args)
|
83
|
+
assert_not_matches_selector(*args)
|
84
|
+
rescue Capybara::ExpectationNotMet
|
85
|
+
return false
|
86
|
+
end
|
87
|
+
|
88
|
+
|
58
89
|
##
|
59
90
|
#
|
60
91
|
# Asserts that a given selector is on the page or current node.
|
@@ -89,7 +120,7 @@ module Capybara
|
|
89
120
|
# @raise [Capybara::ExpectationNotMet] If the selector does not exist
|
90
121
|
#
|
91
122
|
def assert_selector(*args)
|
92
|
-
query = Capybara::
|
123
|
+
query = Capybara::Queries::SelectorQuery.new(*args)
|
93
124
|
synchronize(query.wait) do
|
94
125
|
result = query.resolve_for(self)
|
95
126
|
matches_count = Capybara::Helpers.matches_count?(result.size, query.options)
|
@@ -117,7 +148,7 @@ module Capybara
|
|
117
148
|
# @raise [Capybara::ExpectationNotMet] If the selector exists
|
118
149
|
#
|
119
150
|
def assert_no_selector(*args)
|
120
|
-
query = Capybara::
|
151
|
+
query = Capybara::Queries::SelectorQuery.new(*args)
|
121
152
|
synchronize(query.wait) do
|
122
153
|
result = query.resolve_for(self)
|
123
154
|
matches_count = Capybara::Helpers.matches_count?(result.size, query.options)
|
@@ -129,6 +160,45 @@ module Capybara
|
|
129
160
|
end
|
130
161
|
alias_method :refute_selector, :assert_no_selector
|
131
162
|
|
163
|
+
##
|
164
|
+
#
|
165
|
+
# Asserts that the current_node matches a given selector
|
166
|
+
#
|
167
|
+
# node.assert_matches_selector('p#foo')
|
168
|
+
# node.assert_matches_selector(:xpath, '//p[@id="foo"]')
|
169
|
+
# node.assert_matches_selector(:foo)
|
170
|
+
#
|
171
|
+
# It also accepts all options that {Capybara::Node::Finders#all} accepts,
|
172
|
+
# such as :text and :visible.
|
173
|
+
#
|
174
|
+
# node.assert_matches_selector('li', :text => 'Horse', :visible => true)
|
175
|
+
#
|
176
|
+
# @param (see Capybara::Node::Finders#all)
|
177
|
+
# @raise [Capybara::ExpectationNotMet] If the selector does not match
|
178
|
+
#
|
179
|
+
def assert_matches_selector(*args)
|
180
|
+
query = Capybara::Queries::MatchQuery.new(*args)
|
181
|
+
synchronize(query.wait) do
|
182
|
+
result = query.resolve_for(self.parent)
|
183
|
+
unless result.include? self
|
184
|
+
raise Capybara::ExpectationNotMet, "Item does not match the provided selector"
|
185
|
+
end
|
186
|
+
end
|
187
|
+
return true
|
188
|
+
end
|
189
|
+
|
190
|
+
def assert_not_matches_selector(*args)
|
191
|
+
query = Capybara::Queries::MatchQuery.new(*args)
|
192
|
+
synchronize(query.wait) do
|
193
|
+
result = query.resolve_for(self.parent)
|
194
|
+
if result.include? self
|
195
|
+
raise Capybara::ExpectationNotMet, 'Item matched the provided selector'
|
196
|
+
end
|
197
|
+
end
|
198
|
+
return true
|
199
|
+
end
|
200
|
+
alias_method :refute_matches_selector, :assert_not_matches_selector
|
201
|
+
|
132
202
|
##
|
133
203
|
#
|
134
204
|
# Checks if a given XPath expression is on the page or current node.
|
data/lib/capybara/node/simple.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module Capybara
|
2
3
|
module Node
|
3
4
|
|
@@ -99,6 +100,8 @@ module Capybara
|
|
99
100
|
# @return [Boolean] Whether the element is visible
|
100
101
|
#
|
101
102
|
def visible?(check_ancestors = true)
|
103
|
+
return false if (tag_name == 'input') && (native[:type]=="hidden")
|
104
|
+
|
102
105
|
if check_ancestors
|
103
106
|
#check size because oldest supported nokogiri doesnt support xpath boolean() function
|
104
107
|
native.xpath("./ancestor-or-self::*[contains(@style, 'display:none') or contains(@style, 'display: none') or @hidden or name()='script' or name()='head']").size() == 0
|
@@ -115,7 +118,7 @@ module Capybara
|
|
115
118
|
# @return [Boolean] Whether the element is checked
|
116
119
|
#
|
117
120
|
def checked?
|
118
|
-
native
|
121
|
+
native.has_attribute?('checked')
|
119
122
|
end
|
120
123
|
|
121
124
|
##
|
@@ -124,7 +127,7 @@ module Capybara
|
|
124
127
|
#
|
125
128
|
# @return [Boolean] Whether the element is disabled
|
126
129
|
def disabled?
|
127
|
-
native
|
130
|
+
native.has_attribute?('disabled')
|
128
131
|
end
|
129
132
|
|
130
133
|
##
|
@@ -134,7 +137,7 @@ module Capybara
|
|
134
137
|
# @return [Boolean] Whether the element is selected
|
135
138
|
#
|
136
139
|
def selected?
|
137
|
-
native
|
140
|
+
native.has_attribute?('selected')
|
138
141
|
end
|
139
142
|
|
140
143
|
def synchronize(seconds=nil)
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Capybara
|
2
|
+
module Queries
|
3
|
+
class MatchQuery < Capybara::Queries::SelectorQuery
|
4
|
+
VALID_KEYS = [:text, :visible, :exact, :wait]
|
5
|
+
|
6
|
+
def visible
|
7
|
+
if options.has_key?(:visible)
|
8
|
+
super
|
9
|
+
else
|
10
|
+
:all
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def valid_keys
|
17
|
+
VALID_KEYS + @selector.custom_filters.keys
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,138 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Capybara
|
3
|
+
module Queries
|
4
|
+
class SelectorQuery < Queries::BaseQuery
|
5
|
+
attr_accessor :selector, :locator, :options, :expression, :find, :negative
|
6
|
+
|
7
|
+
VALID_KEYS = [:text, :visible, :between, :count, :maximum, :minimum, :exact, :match, :wait]
|
8
|
+
VALID_MATCH = [:first, :smart, :prefer_exact, :one]
|
9
|
+
|
10
|
+
def initialize(*args)
|
11
|
+
@options = if args.last.is_a?(Hash) then args.pop.dup else {} end
|
12
|
+
|
13
|
+
if args[0].is_a?(Symbol)
|
14
|
+
@selector = Selector.all[args.shift]
|
15
|
+
@locator = args.shift
|
16
|
+
else
|
17
|
+
@selector = Selector.all.values.find { |s| s.match?(args[0]) }
|
18
|
+
@locator = args.shift
|
19
|
+
end
|
20
|
+
@selector ||= Selector.all[Capybara.default_selector]
|
21
|
+
|
22
|
+
warn "Unused parameters passed to #{self.class.name} : #{args.to_s}" unless args.empty?
|
23
|
+
|
24
|
+
# for compatibility with Capybara 2.0
|
25
|
+
if Capybara.exact_options and @selector == Selector.all[:option]
|
26
|
+
@options[:exact] = true
|
27
|
+
end
|
28
|
+
|
29
|
+
@expression = @selector.call(@locator)
|
30
|
+
assert_valid_keys
|
31
|
+
end
|
32
|
+
|
33
|
+
def name; selector.name; end
|
34
|
+
def label; selector.label or selector.name; end
|
35
|
+
|
36
|
+
def description
|
37
|
+
@description = String.new("#{label} #{locator.inspect}")
|
38
|
+
@description << " with text #{options[:text].inspect}" if options[:text]
|
39
|
+
@description << selector.description(options)
|
40
|
+
@description
|
41
|
+
end
|
42
|
+
|
43
|
+
def matches_filters?(node)
|
44
|
+
if options[:text]
|
45
|
+
regexp = options[:text].is_a?(Regexp) ? options[:text] : Regexp.escape(options[:text].to_s)
|
46
|
+
return false if not node.text(visible).match(regexp)
|
47
|
+
end
|
48
|
+
case visible
|
49
|
+
when :visible then return false unless node.visible?
|
50
|
+
when :hidden then return false if node.visible?
|
51
|
+
end
|
52
|
+
selector.custom_filters.each do |name, filter|
|
53
|
+
if options.has_key?(name)
|
54
|
+
return false unless filter.matches?(node, options[name])
|
55
|
+
elsif filter.default?
|
56
|
+
return false unless filter.matches?(node, filter.default)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def visible
|
62
|
+
if options.has_key?(:visible)
|
63
|
+
case @options[:visible]
|
64
|
+
when true then :visible
|
65
|
+
when false then :all
|
66
|
+
else @options[:visible]
|
67
|
+
end
|
68
|
+
else
|
69
|
+
if Capybara.ignore_hidden_elements
|
70
|
+
:visible
|
71
|
+
else
|
72
|
+
:all
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def exact?
|
78
|
+
if options.has_key?(:exact)
|
79
|
+
@options[:exact]
|
80
|
+
else
|
81
|
+
Capybara.exact
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def match
|
86
|
+
if options.has_key?(:match)
|
87
|
+
@options[:match]
|
88
|
+
else
|
89
|
+
Capybara.match
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def xpath(exact=nil)
|
94
|
+
exact = self.exact? if exact == nil
|
95
|
+
if @expression.respond_to?(:to_xpath) and exact
|
96
|
+
@expression.to_xpath(:exact)
|
97
|
+
else
|
98
|
+
@expression.to_s
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def css
|
103
|
+
@expression
|
104
|
+
end
|
105
|
+
|
106
|
+
# @api private
|
107
|
+
def resolve_for(node, exact = nil)
|
108
|
+
node.synchronize do
|
109
|
+
children = if selector.format == :css
|
110
|
+
node.find_css(self.css)
|
111
|
+
else
|
112
|
+
node.find_xpath(self.xpath(exact))
|
113
|
+
end.map do |child|
|
114
|
+
if node.is_a?(Capybara::Node::Base)
|
115
|
+
Capybara::Node::Element.new(node.session, child, node, self)
|
116
|
+
else
|
117
|
+
Capybara::Node::Simple.new(child)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
Capybara::Result.new(children, self)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
private
|
125
|
+
|
126
|
+
def valid_keys
|
127
|
+
COUNT_KEYS + [:text, :visible, :exact, :match, :wait] + @selector.custom_filters.keys
|
128
|
+
end
|
129
|
+
|
130
|
+
def assert_valid_keys
|
131
|
+
super
|
132
|
+
unless VALID_MATCH.include?(match)
|
133
|
+
raise ArgumentError, "invalid option #{match.inspect} for :match, should be one of #{VALID_MATCH.map(&:inspect).join(", ")}"
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|