Class: Watir::ElementLocator
- Inherits:
-
Object
- Object
- Watir::ElementLocator
show all
- Includes:
- Selenium, Exception
- Defined in:
- lib/watir-webdriver/locators/element_locator.rb
Constant Summary
collapse
- WD_FINDERS =
[
:class,
:class_name,
:css,
:id,
:link,
:link_text,
:name,
:partial_link_text,
:tag_name,
:xpath
]
Instance Method Summary
collapse
-
#assert_valid_as_attribute(attribute) ⇒ Object
-
#attribute_expression(selectors) ⇒ Object
-
#build_xpath(selectors) ⇒ Object
-
#by_id ⇒ Object
-
#check_type(how, what) ⇒ Object
-
#delete_regexps_from(selector) ⇒ Object
-
#equal_pair(key, value) ⇒ Object
-
#fetch_value(how, element) ⇒ Object
-
#find_all_by_multiple ⇒ Object
-
#find_all_by_one ⇒ Object
-
#find_first_by_multiple ⇒ Object
-
#find_first_by_one ⇒ Object
-
#initialize(wd, selector, valid_attributes) ⇒ ElementLocator
constructor
A new instance of ElementLocator.
-
#lhs_for(key) ⇒ Object
-
#locate ⇒ Object
-
#locate_all ⇒ Object
-
#matches_selector?(selector, element) ⇒ Boolean
-
#normalize_selector(how, what) ⇒ Object
-
#normalized_selector ⇒ Object
-
#tag_name_matches?(element, tag_name) ⇒ Boolean
-
#wd_find_all_by(how, what) ⇒ Object
-
#wd_find_by_regexp_selector(selector, method = :find) ⇒ Object
-
#wd_find_first_by(how, what) ⇒ Object
Constructor Details
#initialize(wd, selector, valid_attributes) ⇒ ElementLocator
Returns a new instance of ElementLocator.
20
21
22
23
24
|
# File 'lib/watir-webdriver/locators/element_locator.rb', line 20
def initialize(wd, selector, valid_attributes)
@wd = wd
@selector = selector.dup
@valid_attributes = valid_attributes
end
|
Instance Method Details
#assert_valid_as_attribute(attribute) ⇒ Object
204
205
206
207
208
|
# File 'lib/watir-webdriver/locators/element_locator.rb', line 204
def assert_valid_as_attribute(attribute)
if @valid_attributes && !@valid_attributes.include?(attribute)
raise MissingWayOfFindingObjectException, "invalid attribute: #{attribute.inspect}"
end
end
|
#attribute_expression(selectors) ⇒ Object
252
253
254
255
256
257
258
259
260
|
# File 'lib/watir-webdriver/locators/element_locator.rb', line 252
def attribute_expression(selectors)
selectors.map do |key, val|
if val.kind_of?(Array)
"( " + val.map { |v| equal_pair(key, v) }.join(" or ") + " )"
else
equal_pair(key, val)
end
end.join(" and ")
end
|
#build_xpath(selectors) ⇒ Object
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
|
# File 'lib/watir-webdriver/locators/element_locator.rb', line 230
def build_xpath(selectors)
return if selectors.values.any? { |e| e.kind_of? Regexp }
xpath = ".//"
xpath << (selectors.delete(:tag_name) || '*').to_s
idx = selectors.delete(:index)
unless selectors.empty?
xpath << "[" << attribute_expression(selectors) << "]"
end
if idx
xpath << "[#{idx + 1}]"
end
p :xpath => xpath, :selectors => selectors if $DEBUG
xpath
end
|
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
|
# File 'lib/watir-webdriver/locators/element_locator.rb', line 210
def by_id
selector = @selector.dup
id = selector.delete(:id)
return unless id && id.kind_of?(String)
tag_name = selector.delete(:tag_name)
return unless selector.empty?
element = @wd.find_element(:id, id)
return if tag_name && !tag_name_matches?(element, tag_name)
element
rescue WebDriver::Error::NoSuchElementError => wde
nil
end
|
#check_type(how, what) ⇒ Object
133
134
135
136
137
138
139
140
141
142
|
# File 'lib/watir-webdriver/locators/element_locator.rb', line 133
def check_type(how, what)
case how
when :index
raise TypeError, "expected Fixnum, got #{what.class}" unless what.kind_of?(Fixnum)
else
unless [String, Regexp].any? { |t| what.kind_of? t }
raise TypeError, "expected String or Regexp, got #{what.inspect}:#{what.class}"
end
end
end
|
#delete_regexps_from(selector) ⇒ Object
192
193
194
195
196
197
198
199
200
201
202
|
# File 'lib/watir-webdriver/locators/element_locator.rb', line 192
def delete_regexps_from(selector)
rx_selector = {}
selector.dup.each do |how, what|
next unless what.kind_of?(Regexp)
rx_selector[how] = what
selector.delete how
end
rx_selector
end
|
#equal_pair(key, value) ⇒ Object
262
263
264
|
# File 'lib/watir-webdriver/locators/element_locator.rb', line 262
def equal_pair(key, value)
"#{lhs_for(key)}='#{value}'"
end
|
#fetch_value(how, element) ⇒ Object
144
145
146
147
148
149
150
151
152
153
|
# File 'lib/watir-webdriver/locators/element_locator.rb', line 144
def fetch_value(how, element)
case how
when :text
element.text
when :tag_name
element.tag_name
else
element.attribute(how)
end
end
|
#find_all_by_multiple ⇒ Object
94
95
96
97
98
99
100
101
102
103
104
105
106
107
|
# File 'lib/watir-webdriver/locators/element_locator.rb', line 94
def find_all_by_multiple
selector = normalized_selector
if selector.has_key? :index
raise Error, "can't locate all elements by :index"
end
xpath = selector[:xpath] || build_xpath(selector)
if xpath
@wd.find_elements(:xpath, xpath)
else
wd_find_by_regexp_selector(selector, :select)
end
end
|
#find_all_by_one ⇒ Object
60
61
62
63
64
65
66
67
68
69
|
# File 'lib/watir-webdriver/locators/element_locator.rb', line 60
def find_all_by_one
how, what = @selector.shift
check_type how, what
if WD_FINDERS.include?(how)
wd_find_all_by(how, what)
else
raise NotImplementedError, "find all by attribute/other"
end
end
|
#find_first_by_multiple ⇒ Object
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
# File 'lib/watir-webdriver/locators/element_locator.rb', line 71
def find_first_by_multiple
selector = normalized_selector
idx = selector.delete(:index)
xpath = selector[:xpath] || build_xpath(selector)
if xpath
if idx
@wd.find_elements(:xpath, xpath)[idx]
else
@wd.find_element(:xpath, xpath)
end
else
if idx
wd_find_by_regexp_selector(selector, :select)[idx]
else
wd_find_by_regexp_selector(selector, :find)
end
end
end
|
#find_first_by_one ⇒ Object
49
50
51
52
53
54
55
56
57
58
|
# File 'lib/watir-webdriver/locators/element_locator.rb', line 49
def find_first_by_one
how, what = @selector.shift
check_type how, what
if WD_FINDERS.include?(how)
wd_find_first_by(how, what)
else
raise NotImplementedError, "find first by attribute/other"
end
end
|
#lhs_for(key) ⇒ Object
266
267
268
269
270
271
272
273
274
275
276
|
# File 'lib/watir-webdriver/locators/element_locator.rb', line 266
def lhs_for(key)
case key
when :text, 'text'
'normalize-space()'
when :href
'normalize-space(@href)'
else
"@#{key.to_s.gsub("_", "-")}"
end
end
|
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
# File 'lib/watir-webdriver/locators/element_locator.rb', line 26
def locate
if e = by_id
return e
end
if @selector.size == 1
find_first_by_one
else
find_first_by_multiple
end
rescue WebDriver::Error::NoSuchElementError => wde
nil
end
|
#locate_all ⇒ Object
41
42
43
44
45
46
47
|
# File 'lib/watir-webdriver/locators/element_locator.rb', line 41
def locate_all
if @selector.size == 1
find_all_by_one
else
find_all_by_multiple
end
end
|
#matches_selector?(selector, element) ⇒ Boolean
155
156
157
158
159
160
161
|
# File 'lib/watir-webdriver/locators/element_locator.rb', line 155
def matches_selector?(selector, element)
selector.all? do |how, what|
what === fetch_value(how, element)
end
end
|
#normalize_selector(how, what) ⇒ Object
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
|
# File 'lib/watir-webdriver/locators/element_locator.rb', line 176
def normalize_selector(how, what)
case how
when :url
[:href, what]
when :caption
[:text, what]
when :class_name
[:class, what]
when :tag_name, :text, :xpath, :index, :class [how, what]
else
assert_valid_as_attribute how
[how, what]
end
end
|
#normalized_selector ⇒ Object
163
164
165
166
167
168
169
170
171
172
173
174
|
# File 'lib/watir-webdriver/locators/element_locator.rb', line 163
def normalized_selector
selector = {}
@selector.each do |how, what|
check_type(how, what)
how, what = normalize_selector(how, what)
selector[how] = what
end
selector
end
|
#tag_name_matches?(element, tag_name) ⇒ Boolean
226
227
228
|
# File 'lib/watir-webdriver/locators/element_locator.rb', line 226
def tag_name_matches?(element, tag_name)
tag_name === element.tag_name
end
|
#wd_find_all_by(how, what) ⇒ Object
117
118
119
120
121
122
123
|
# File 'lib/watir-webdriver/locators/element_locator.rb', line 117
def wd_find_all_by(how, what)
if what.kind_of? String
@wd.find_elements(how, what)
else
all_elements.select { |e| fetch_value(how, e) =~ what }
end
end
|
#wd_find_by_regexp_selector(selector, method = :find) ⇒ Object
125
126
127
128
129
130
131
|
# File 'lib/watir-webdriver/locators/element_locator.rb', line 125
def wd_find_by_regexp_selector(selector, method = :find)
rx_selector = delete_regexps_from(selector)
xpath = build_xpath(selector) || raise("internal error: unable to build xpath from #{@selector.inspect}")
elements = @wd.find_elements(:xpath, xpath)
elements.send(method) { |e| matches_selector?(rx_selector, e) }
end
|
#wd_find_first_by(how, what) ⇒ Object
109
110
111
112
113
114
115
|
# File 'lib/watir-webdriver/locators/element_locator.rb', line 109
def wd_find_first_by(how, what)
if what.kind_of? String
@wd.find_element(how, what)
else
all_elements.find { |e| fetch_value(how, e) =~ what }
end
end
|