testcentricity_web 4.3.1 → 4.4.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/CHANGELOG.md +42 -12
- data/LICENSE.md +1 -1
- data/README.md +1794 -697
- data/lib/devices/devices.yml +144 -216
- data/lib/testcentricity_web/browser_helper.rb +33 -4
- data/lib/testcentricity_web/data_objects/environment.rb +96 -13
- data/lib/testcentricity_web/exception_queue_helper.rb +5 -6
- data/lib/testcentricity_web/version.rb +1 -1
- data/lib/testcentricity_web/web_core/page_object.rb +53 -49
- data/lib/testcentricity_web/web_core/page_objects_helper.rb +20 -11
- data/lib/testcentricity_web/web_core/page_section.rb +31 -34
- data/lib/testcentricity_web/web_core/webdriver_helper.rb +379 -252
- data/lib/testcentricity_web/web_elements/audio.rb +6 -4
- data/lib/testcentricity_web/web_elements/button.rb +7 -4
- data/lib/testcentricity_web/web_elements/checkbox.rb +149 -147
- data/lib/testcentricity_web/web_elements/file_field.rb +38 -36
- data/lib/testcentricity_web/web_elements/image.rb +75 -70
- data/lib/testcentricity_web/web_elements/label.rb +6 -4
- data/lib/testcentricity_web/web_elements/link.rb +15 -13
- data/lib/testcentricity_web/web_elements/list.rb +171 -169
- data/lib/testcentricity_web/web_elements/media.rb +384 -379
- data/lib/testcentricity_web/web_elements/radio.rb +135 -133
- data/lib/testcentricity_web/web_elements/range.rb +16 -29
- data/lib/testcentricity_web/web_elements/select_list.rb +247 -245
- data/lib/testcentricity_web/web_elements/table.rb +575 -573
- data/lib/testcentricity_web/web_elements/textfield.rb +143 -139
- data/lib/testcentricity_web/web_elements/ui_element.rb +1171 -0
- data/lib/testcentricity_web/web_elements/video.rb +39 -37
- data/lib/testcentricity_web/world_extensions.rb +37 -4
- data/lib/testcentricity_web.rb +4 -23
- metadata +27 -79
- data/lib/testcentricity_web/web_elements/ui_elements_helper.rb +0 -1148
@@ -1,1148 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'test/unit'
|
4
|
-
|
5
|
-
Capybara::Node::Element.class_eval do
|
6
|
-
def click_at(x, y)
|
7
|
-
right = x - (native.size.width / 2)
|
8
|
-
top = y - (native.size.height / 2)
|
9
|
-
driver.browser.action.move_to(native).move_by(right.to_i, top.to_i).click.perform
|
10
|
-
end
|
11
|
-
|
12
|
-
def hover_at(x, y)
|
13
|
-
right = x - (native.size.width / 2)
|
14
|
-
top = y - (native.size.height / 2)
|
15
|
-
driver.browser.action.move_to(native).move_by(right.to_i, top.to_i).perform
|
16
|
-
end
|
17
|
-
|
18
|
-
def get_width
|
19
|
-
native.size.width
|
20
|
-
end
|
21
|
-
|
22
|
-
def get_height
|
23
|
-
native.size.height
|
24
|
-
end
|
25
|
-
|
26
|
-
def get_x
|
27
|
-
native.location.x
|
28
|
-
end
|
29
|
-
|
30
|
-
def get_y
|
31
|
-
native.location.y
|
32
|
-
end
|
33
|
-
|
34
|
-
def displayed?
|
35
|
-
native.displayed?
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
|
40
|
-
module TestCentricity
|
41
|
-
class UIElement
|
42
|
-
include Capybara::DSL
|
43
|
-
include Test::Unit::Assertions
|
44
|
-
|
45
|
-
attr_reader :parent, :locator, :context, :type, :name
|
46
|
-
attr_accessor :alt_locator, :locator_type, :original_style
|
47
|
-
attr_accessor :base_object
|
48
|
-
|
49
|
-
XPATH_SELECTORS = ['//', '[@', '[contains(']
|
50
|
-
CSS_SELECTORS = %w[# :nth-child( :first-child :last-child :nth-of-type( :first-of-type :last-of-type ^= $= *= :contains(]
|
51
|
-
|
52
|
-
def initialize(name, parent, locator, context)
|
53
|
-
@name = name
|
54
|
-
@parent = parent
|
55
|
-
@locator = locator
|
56
|
-
@context = context
|
57
|
-
@type = nil
|
58
|
-
@alt_locator = nil
|
59
|
-
@original_style = nil
|
60
|
-
set_locator_type
|
61
|
-
end
|
62
|
-
|
63
|
-
def set_locator_type(locator = nil)
|
64
|
-
locator = @locator if locator.nil?
|
65
|
-
is_xpath = XPATH_SELECTORS.any? { |selector| locator.include?(selector) }
|
66
|
-
is_css = CSS_SELECTORS.any? { |selector| locator.include?(selector) }
|
67
|
-
@locator_type = if is_xpath && !is_css
|
68
|
-
:xpath
|
69
|
-
elsif is_css && !is_xpath
|
70
|
-
:css
|
71
|
-
elsif !is_css && !is_xpath
|
72
|
-
:css
|
73
|
-
else
|
74
|
-
:css
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
def get_locator_type
|
79
|
-
@locator_type
|
80
|
-
end
|
81
|
-
|
82
|
-
def get_object_type
|
83
|
-
if @type
|
84
|
-
@type
|
85
|
-
else
|
86
|
-
obj, type = find_element
|
87
|
-
object_not_found_exception(obj, type)
|
88
|
-
if obj.tag_name
|
89
|
-
obj.tag_name
|
90
|
-
elsif obj.native.attribute('type')
|
91
|
-
obj.native.attribute('type')
|
92
|
-
end
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
def get_locator
|
97
|
-
@locator
|
98
|
-
end
|
99
|
-
|
100
|
-
def get_name
|
101
|
-
@name
|
102
|
-
end
|
103
|
-
|
104
|
-
def set_alt_locator(temp_locator)
|
105
|
-
@alt_locator = temp_locator
|
106
|
-
end
|
107
|
-
|
108
|
-
def clear_alt_locator
|
109
|
-
@alt_locator = nil
|
110
|
-
end
|
111
|
-
|
112
|
-
# Click on an object
|
113
|
-
#
|
114
|
-
# @example
|
115
|
-
# basket_link.click
|
116
|
-
#
|
117
|
-
def click
|
118
|
-
obj, type = find_element
|
119
|
-
object_not_found_exception(obj, type)
|
120
|
-
begin
|
121
|
-
obj.click
|
122
|
-
rescue StandardError
|
123
|
-
obj.click_at(10, 10)
|
124
|
-
end
|
125
|
-
end
|
126
|
-
|
127
|
-
# Double-click on an object
|
128
|
-
#
|
129
|
-
# @example
|
130
|
-
# file_image.double_click
|
131
|
-
#
|
132
|
-
def double_click
|
133
|
-
obj, type = find_element
|
134
|
-
object_not_found_exception(obj, type)
|
135
|
-
page.driver.browser.action.double_click(obj.native).perform
|
136
|
-
end
|
137
|
-
|
138
|
-
# Right-click on an object
|
139
|
-
#
|
140
|
-
# @example
|
141
|
-
# basket_item_image.right_click
|
142
|
-
#
|
143
|
-
def right_click
|
144
|
-
obj, type = find_element
|
145
|
-
object_not_found_exception(obj, type)
|
146
|
-
page.driver.browser.action.context_click(obj.native).perform
|
147
|
-
end
|
148
|
-
|
149
|
-
# Click at a specific location within an object
|
150
|
-
#
|
151
|
-
# @param x [Integer] X offset
|
152
|
-
# @param y [Integer] Y offset
|
153
|
-
# @example
|
154
|
-
# basket_item_image.click_at(10, 10)
|
155
|
-
#
|
156
|
-
def click_at(x, y)
|
157
|
-
obj, = find_element
|
158
|
-
raise "UI #{object_ref_message} not found" unless obj
|
159
|
-
obj.click_at(x, y)
|
160
|
-
end
|
161
|
-
|
162
|
-
# Scroll the object to its top, middle, or bottom
|
163
|
-
#
|
164
|
-
# @param position [Symbol] :top, :bottom, :center
|
165
|
-
# @example
|
166
|
-
# cue_list.scroll_to(:bottom)
|
167
|
-
#
|
168
|
-
def scroll_to(position)
|
169
|
-
obj, type = find_element
|
170
|
-
object_not_found_exception(obj, type)
|
171
|
-
page.scroll_to(obj, align: position)
|
172
|
-
end
|
173
|
-
|
174
|
-
def set(value)
|
175
|
-
obj, type = find_element
|
176
|
-
object_not_found_exception(obj, type)
|
177
|
-
obj.set(value)
|
178
|
-
end
|
179
|
-
|
180
|
-
# Send keystrokes to this object.
|
181
|
-
#
|
182
|
-
# @param keys [String] keys
|
183
|
-
# @example
|
184
|
-
# comment_field.send_keys(:enter)
|
185
|
-
#
|
186
|
-
def send_keys(*keys)
|
187
|
-
obj, type = find_element
|
188
|
-
object_not_found_exception(obj, type)
|
189
|
-
obj.send_keys(*keys)
|
190
|
-
end
|
191
|
-
|
192
|
-
# Does UI object exists?
|
193
|
-
#
|
194
|
-
# @return [Boolean]
|
195
|
-
# @example
|
196
|
-
# basket_link.exists?
|
197
|
-
#
|
198
|
-
def exists?(visible = true)
|
199
|
-
obj, = find_object(visible)
|
200
|
-
!obj.nil?
|
201
|
-
end
|
202
|
-
|
203
|
-
# Is UI object visible?
|
204
|
-
#
|
205
|
-
# @return [Boolean]
|
206
|
-
# @example
|
207
|
-
# remember_me_checkbox.visible?
|
208
|
-
#
|
209
|
-
def visible?
|
210
|
-
obj, type = find_element
|
211
|
-
exists = obj
|
212
|
-
invisible = false
|
213
|
-
if type == :css
|
214
|
-
Capybara.using_wait_time 0.1 do
|
215
|
-
# is object itself hidden with .ui-helper-hidden class?
|
216
|
-
self_hidden = page.has_css?("#{@locator}.ui-helper-hidden")
|
217
|
-
# is parent of object hidden, thus hiding the object?
|
218
|
-
parent_hidden = page.has_css?(".ui-helper-hidden > #{@locator}")
|
219
|
-
# is grandparent of object, or any other ancestor, hidden?
|
220
|
-
other_ancestor_hidden = page.has_css?(".ui-helper-hidden * #{@locator}")
|
221
|
-
# if any of the above conditions are true, then object is invisible
|
222
|
-
invisible = self_hidden || parent_hidden || other_ancestor_hidden
|
223
|
-
end
|
224
|
-
else
|
225
|
-
invisible = !obj.visible? if exists
|
226
|
-
end
|
227
|
-
# the object is visible if it exists and it is not invisible
|
228
|
-
if exists && !invisible
|
229
|
-
true
|
230
|
-
else
|
231
|
-
false
|
232
|
-
end
|
233
|
-
end
|
234
|
-
|
235
|
-
# Is UI object hidden (not visible)?
|
236
|
-
#
|
237
|
-
# @return [Boolean]
|
238
|
-
# @example
|
239
|
-
# remember_me_checkbox.hidden?
|
240
|
-
#
|
241
|
-
def hidden?
|
242
|
-
!visible?
|
243
|
-
end
|
244
|
-
|
245
|
-
# Is UI object enabled?
|
246
|
-
#
|
247
|
-
# @return [Boolean]
|
248
|
-
# @example
|
249
|
-
# login_button.enabled?
|
250
|
-
#
|
251
|
-
def enabled?
|
252
|
-
!disabled?
|
253
|
-
end
|
254
|
-
|
255
|
-
# Is UI object disabled (not enabled)?
|
256
|
-
#
|
257
|
-
# @return [Boolean]
|
258
|
-
# @example
|
259
|
-
# login_button.disabled?
|
260
|
-
#
|
261
|
-
def disabled?
|
262
|
-
obj, type = find_element
|
263
|
-
object_not_found_exception(obj, type)
|
264
|
-
obj.disabled?
|
265
|
-
end
|
266
|
-
|
267
|
-
# Is UI object's required attribute set?
|
268
|
-
#
|
269
|
-
# @return [Boolean]
|
270
|
-
# @example
|
271
|
-
# first_name_field.required?
|
272
|
-
#
|
273
|
-
def required?
|
274
|
-
obj, type = find_element
|
275
|
-
object_not_found_exception(obj, type)
|
276
|
-
state = get_attribute(:required)
|
277
|
-
state.boolean? ? state : state == 'true'
|
278
|
-
end
|
279
|
-
|
280
|
-
# Is UI object obscured (not currently in viewport and not clickable)?
|
281
|
-
#
|
282
|
-
# @return [Boolean]
|
283
|
-
# @example
|
284
|
-
# buy_now_button.obscured?
|
285
|
-
#
|
286
|
-
def obscured?
|
287
|
-
obj, type = find_element
|
288
|
-
object_not_found_exception(obj, type)
|
289
|
-
obj.obscured?
|
290
|
-
end
|
291
|
-
|
292
|
-
# Does UI object have the current focus?
|
293
|
-
#
|
294
|
-
# @return [Boolean]
|
295
|
-
# @example
|
296
|
-
# first_name_field.focused?
|
297
|
-
#
|
298
|
-
def focused?
|
299
|
-
obj, type = find_element(visible = :all)
|
300
|
-
object_not_found_exception(obj, type)
|
301
|
-
focused_obj = page.driver.browser.switch_to.active_element
|
302
|
-
focused_obj == obj.native
|
303
|
-
end
|
304
|
-
|
305
|
-
# Return a human readable representation of the UI element
|
306
|
-
#
|
307
|
-
# @return [String]
|
308
|
-
# @example
|
309
|
-
# buy_now_button.inspect
|
310
|
-
#
|
311
|
-
def inspect
|
312
|
-
obj, type = find_element
|
313
|
-
object_not_found_exception(obj, type)
|
314
|
-
obj.inspect
|
315
|
-
end
|
316
|
-
|
317
|
-
# Wait until the object exists, or until the specified wait time has expired. If the wait time is nil, then the wait
|
318
|
-
# time will be Capybara.default_max_wait_time.
|
319
|
-
#
|
320
|
-
# @param seconds [Integer or Float] wait time in seconds
|
321
|
-
# @example
|
322
|
-
# run_button.wait_until_exists(0.5)
|
323
|
-
#
|
324
|
-
def wait_until_exists(seconds = nil, post_exception = true)
|
325
|
-
timeout = seconds.nil? ? Capybara.default_max_wait_time : seconds
|
326
|
-
wait = Selenium::WebDriver::Wait.new(timeout: timeout)
|
327
|
-
wait.until { exists? }
|
328
|
-
rescue StandardError
|
329
|
-
if post_exception
|
330
|
-
raise "Could not find UI #{object_ref_message} after #{timeout} seconds" unless exists?
|
331
|
-
else
|
332
|
-
exists?
|
333
|
-
end
|
334
|
-
end
|
335
|
-
|
336
|
-
# Wait until the object no longer exists, or until the specified wait time has expired. If the wait time is nil, then
|
337
|
-
# the wait time will be Capybara.default_max_wait_time.
|
338
|
-
#
|
339
|
-
# @param seconds [Integer or Float] wait time in seconds
|
340
|
-
# @example
|
341
|
-
# logout_button.wait_until_gone(5)
|
342
|
-
#
|
343
|
-
def wait_until_gone(seconds = nil, post_exception = true)
|
344
|
-
timeout = seconds.nil? ? Capybara.default_max_wait_time : seconds
|
345
|
-
wait = Selenium::WebDriver::Wait.new(timeout: timeout)
|
346
|
-
wait.until { !exists? }
|
347
|
-
rescue StandardError
|
348
|
-
if post_exception
|
349
|
-
raise "UI #{object_ref_message} remained visible after #{timeout} seconds" if exists?
|
350
|
-
else
|
351
|
-
exists?
|
352
|
-
end
|
353
|
-
end
|
354
|
-
|
355
|
-
# Wait until the object is visible, or until the specified wait time has expired. If the wait time is nil, then the
|
356
|
-
# wait time will be Capybara.default_max_wait_time.
|
357
|
-
#
|
358
|
-
# @param seconds [Integer or Float] wait time in seconds
|
359
|
-
# @example
|
360
|
-
# run_button.wait_until_visible(0.5)
|
361
|
-
#
|
362
|
-
def wait_until_visible(seconds = nil, post_exception = true)
|
363
|
-
timeout = seconds.nil? ? Capybara.default_max_wait_time : seconds
|
364
|
-
wait = Selenium::WebDriver::Wait.new(timeout: timeout)
|
365
|
-
wait.until { visible? }
|
366
|
-
rescue StandardError
|
367
|
-
if post_exception
|
368
|
-
raise "Could not find UI #{object_ref_message} after #{timeout} seconds" unless visible?
|
369
|
-
else
|
370
|
-
visible?
|
371
|
-
end
|
372
|
-
end
|
373
|
-
|
374
|
-
# Wait until the object is hidden, or until the specified wait time has expired. If the wait time is nil, then the
|
375
|
-
# wait time will be Capybara.default_max_wait_time.
|
376
|
-
#
|
377
|
-
# @param seconds [Integer or Float] wait time in seconds
|
378
|
-
# @example
|
379
|
-
# run_button.wait_until_hidden(10)
|
380
|
-
#
|
381
|
-
def wait_until_hidden(seconds = nil, post_exception = true)
|
382
|
-
timeout = seconds.nil? ? Capybara.default_max_wait_time : seconds
|
383
|
-
wait = Selenium::WebDriver::Wait.new(timeout: timeout)
|
384
|
-
wait.until { hidden? }
|
385
|
-
rescue StandardError
|
386
|
-
if post_exception
|
387
|
-
raise "UI #{object_ref_message} remained visible after #{timeout} seconds" if visible?
|
388
|
-
else
|
389
|
-
visible?
|
390
|
-
end
|
391
|
-
end
|
392
|
-
|
393
|
-
# Wait until the object is enabled, or until the specified wait time has expired. If the wait time is nil, then the
|
394
|
-
# wait time will be Capybara.default_max_wait_time.
|
395
|
-
#
|
396
|
-
# @param seconds [Integer or Float] wait time in seconds
|
397
|
-
# @example
|
398
|
-
# run_button.wait_until_enabled(10)
|
399
|
-
#
|
400
|
-
def wait_until_enabled(seconds = nil, post_exception = true)
|
401
|
-
timeout = seconds.nil? ? Capybara.default_max_wait_time : seconds
|
402
|
-
wait = Selenium::WebDriver::Wait.new(timeout: timeout)
|
403
|
-
wait.until { enabled? }
|
404
|
-
rescue StandardError
|
405
|
-
if post_exception
|
406
|
-
raise "UI #{object_ref_message} remained disabled after #{timeout} seconds" unless enabled?
|
407
|
-
else
|
408
|
-
enabled?
|
409
|
-
end
|
410
|
-
end
|
411
|
-
|
412
|
-
# Wait until the object is no longer in a busy state, or until the specified wait time has expired. If the wait time
|
413
|
-
# is nil, then the wait time will be Capybara.default_max_wait_time.
|
414
|
-
#
|
415
|
-
# @param seconds [Integer or Float] wait time in seconds
|
416
|
-
# @example
|
417
|
-
# login_button.wait_while_busy(10)
|
418
|
-
#
|
419
|
-
def wait_while_busy(seconds = nil, post_exception = true)
|
420
|
-
timeout = seconds.nil? ? Capybara.default_max_wait_time : seconds
|
421
|
-
wait = Selenium::WebDriver::Wait.new(timeout: timeout)
|
422
|
-
wait.until { aria_busy? }
|
423
|
-
rescue StandardError
|
424
|
-
if post_exception
|
425
|
-
raise "UI #{object_ref_message} remained in busy state after #{timeout} seconds" if aria_busy?
|
426
|
-
else
|
427
|
-
aria_busy?
|
428
|
-
end
|
429
|
-
end
|
430
|
-
|
431
|
-
# Wait until the object's value equals the specified value, or until the specified wait time has expired. If the wait
|
432
|
-
# time is nil, then the wait time will be Capybara.default_max_wait_time.
|
433
|
-
#
|
434
|
-
# @param value [String or Hash] value expected or comparison hash
|
435
|
-
# @param seconds [Integer or Float] wait time in seconds
|
436
|
-
# @example
|
437
|
-
# card_authorized_label.wait_until_value_is('Card authorized', 5)
|
438
|
-
# or
|
439
|
-
# total_weight_field.wait_until_value_is({ greater_than: '250' }, 5)
|
440
|
-
#
|
441
|
-
def wait_until_value_is(value, seconds = nil, post_exception = true)
|
442
|
-
timeout = seconds.nil? ? Capybara.default_max_wait_time : seconds
|
443
|
-
wait = Selenium::WebDriver::Wait.new(timeout: timeout)
|
444
|
-
wait.until { compare(value, get_value) }
|
445
|
-
rescue StandardError
|
446
|
-
if post_exception
|
447
|
-
raise "Value of UI #{object_ref_message} failed to equal '#{value}' after #{timeout} seconds" unless get_value == value
|
448
|
-
else
|
449
|
-
get_value == value
|
450
|
-
end
|
451
|
-
end
|
452
|
-
|
453
|
-
# Wait until the object's value changes to a different value, or until the specified wait time has expired. If the
|
454
|
-
# wait time is nil, then the wait time will be Capybara.default_max_wait_time.
|
455
|
-
#
|
456
|
-
# @param seconds [Integer or Float] wait time in seconds
|
457
|
-
# @example
|
458
|
-
# basket_grand_total_label.wait_until_value_changes(5)
|
459
|
-
#
|
460
|
-
def wait_until_value_changes(seconds = nil, post_exception = true)
|
461
|
-
value = get_value
|
462
|
-
timeout = seconds.nil? ? Capybara.default_max_wait_time : seconds
|
463
|
-
wait = Selenium::WebDriver::Wait.new(timeout: timeout)
|
464
|
-
wait.until { get_value != value }
|
465
|
-
rescue StandardError
|
466
|
-
if post_exception
|
467
|
-
raise "Value of UI #{object_ref_message} failed to change from '#{value}' after #{timeout} seconds" if get_value == value
|
468
|
-
else
|
469
|
-
get_value == value
|
470
|
-
end
|
471
|
-
end
|
472
|
-
|
473
|
-
# Return the number of occurrences of an object with an ambiguous locator that evaluates to multiple UI elements.
|
474
|
-
#
|
475
|
-
# @param visible [Boolean, Symbol] Only find elements with the specified visibility:
|
476
|
-
# * true - only finds visible elements.
|
477
|
-
# * false - finds invisible _and_ visible elements.
|
478
|
-
# * :all - same as false; finds visible and invisible elements.
|
479
|
-
# * :hidden - only finds invisible elements.
|
480
|
-
# * :visible - same as true; only finds visible elements.
|
481
|
-
# @example
|
482
|
-
# num_uploads = upload_progress_bars.count(:all)
|
483
|
-
#
|
484
|
-
def count(visible = true)
|
485
|
-
obj_locator = @alt_locator.nil? ? @locator : @alt_locator
|
486
|
-
page.all(@locator_type, obj_locator, wait: 0.01, visible: visible, minimum: 0).count
|
487
|
-
end
|
488
|
-
|
489
|
-
# Return width of object.
|
490
|
-
#
|
491
|
-
# @return [Integer]
|
492
|
-
# @example
|
493
|
-
# button_width = my_button.width
|
494
|
-
#
|
495
|
-
def width
|
496
|
-
obj, type = find_element(visible = false)
|
497
|
-
object_not_found_exception(obj, type)
|
498
|
-
obj.get_width
|
499
|
-
end
|
500
|
-
|
501
|
-
# Return height of object.
|
502
|
-
#
|
503
|
-
# @return [Integer]
|
504
|
-
# @example
|
505
|
-
# button_height = my_button.height
|
506
|
-
#
|
507
|
-
def height
|
508
|
-
obj, type = find_element(visible = false)
|
509
|
-
object_not_found_exception(obj, type)
|
510
|
-
obj.get_height
|
511
|
-
end
|
512
|
-
|
513
|
-
# Return x coordinate of object's location.
|
514
|
-
#
|
515
|
-
# @return [Integer]
|
516
|
-
# @example
|
517
|
-
# button_x = my_button.x
|
518
|
-
#
|
519
|
-
def x
|
520
|
-
obj, type = find_element(visible = false)
|
521
|
-
object_not_found_exception(obj, type)
|
522
|
-
obj.get_x
|
523
|
-
end
|
524
|
-
|
525
|
-
# Return y coordinate of object's location.
|
526
|
-
#
|
527
|
-
# @return [Integer]
|
528
|
-
# @example
|
529
|
-
# button_y = my_button.y
|
530
|
-
#
|
531
|
-
def y
|
532
|
-
obj, type = find_element(visible = false)
|
533
|
-
object_not_found_exception(obj, type)
|
534
|
-
obj.get_y
|
535
|
-
end
|
536
|
-
|
537
|
-
# Return UI object's title property
|
538
|
-
#
|
539
|
-
# @return [String]
|
540
|
-
# @example
|
541
|
-
# buy_now_button.title
|
542
|
-
#
|
543
|
-
def title
|
544
|
-
get_attribute(:title)
|
545
|
-
end
|
546
|
-
|
547
|
-
# Is UI object displayed in browser window?
|
548
|
-
#
|
549
|
-
# @return [Boolean]
|
550
|
-
# @example
|
551
|
-
# basket_link.displayed??
|
552
|
-
#
|
553
|
-
def displayed?
|
554
|
-
obj, type = find_element(visible = false)
|
555
|
-
object_not_found_exception(obj, type)
|
556
|
-
obj.displayed?
|
557
|
-
end
|
558
|
-
|
559
|
-
def get_value(visible = true)
|
560
|
-
obj, type = find_element(visible)
|
561
|
-
object_not_found_exception(obj, type)
|
562
|
-
text = case obj.tag_name.downcase
|
563
|
-
when 'input', 'select', 'textarea'
|
564
|
-
obj.value
|
565
|
-
else
|
566
|
-
obj.text
|
567
|
-
end
|
568
|
-
text.gsub(/[[:space:]]+/, ' ').strip unless text.nil?
|
569
|
-
end
|
570
|
-
|
571
|
-
alias get_caption get_value
|
572
|
-
alias caption get_value
|
573
|
-
alias value get_value
|
574
|
-
|
575
|
-
def verify_value(expected, enqueue = false)
|
576
|
-
actual = get_value
|
577
|
-
enqueue ?
|
578
|
-
ExceptionQueue.enqueue_assert_equal(expected.strip, actual.strip, "Expected UI #{object_ref_message}") :
|
579
|
-
assert_equal(expected.strip, actual.strip, "Expected UI #{object_ref_message} to display '#{expected}' but found '#{actual}'")
|
580
|
-
end
|
581
|
-
|
582
|
-
alias verify_caption verify_value
|
583
|
-
|
584
|
-
# Hover the cursor over an object
|
585
|
-
#
|
586
|
-
# @param visible [Boolean, Symbol] Only find elements with the specified visibility:
|
587
|
-
# * true - only finds visible elements.
|
588
|
-
# * false - finds invisible _and_ visible elements.
|
589
|
-
# * :all - same as false; finds visible and invisible elements.
|
590
|
-
# * :hidden - only finds invisible elements.
|
591
|
-
# * :visible - same as true; only finds visible elements.
|
592
|
-
# @example
|
593
|
-
# basket_link.hover
|
594
|
-
#
|
595
|
-
def hover(visible = true)
|
596
|
-
obj, type = find_element(visible)
|
597
|
-
object_not_found_exception(obj, type)
|
598
|
-
obj.hover
|
599
|
-
end
|
600
|
-
|
601
|
-
# Hover at a specific location within an object
|
602
|
-
#
|
603
|
-
# @param x [Integer] X offset
|
604
|
-
# @param y [Integer] Y offset
|
605
|
-
# @param visible [Boolean, Symbol] Only find elements with the specified visibility:
|
606
|
-
# * true - only finds visible elements.
|
607
|
-
# * false - finds invisible _and_ visible elements.
|
608
|
-
# * :all - same as false; finds visible and invisible elements.
|
609
|
-
# * :hidden - only finds invisible elements.
|
610
|
-
# * :visible - same as true; only finds visible elements.
|
611
|
-
# @example
|
612
|
-
# timeline_bar.hover_at(100, 5)
|
613
|
-
#
|
614
|
-
def hover_at(x, y, visible = true)
|
615
|
-
obj, = find_element(visible)
|
616
|
-
raise "UI #{object_ref_message} not found" unless obj
|
617
|
-
obj.hover_at(x, y)
|
618
|
-
end
|
619
|
-
|
620
|
-
def drag_by(right_offset, down_offset)
|
621
|
-
obj, type = find_element
|
622
|
-
object_not_found_exception(obj, type)
|
623
|
-
page.driver.browser.action.click_and_hold(obj.native).perform
|
624
|
-
sleep(1)
|
625
|
-
obj.drag_by(right_offset, down_offset)
|
626
|
-
end
|
627
|
-
|
628
|
-
def drag_and_drop(target, right_offset = nil, down_offset = nil)
|
629
|
-
source, type = find_element
|
630
|
-
object_not_found_exception(source, type)
|
631
|
-
page.driver.browser.action.click_and_hold(source.native).perform
|
632
|
-
sleep(1)
|
633
|
-
target_drop, = target.find_element
|
634
|
-
page.driver.browser.action.move_to(target_drop.native, right_offset.to_i, down_offset.to_i).release.perform
|
635
|
-
end
|
636
|
-
|
637
|
-
# Highlight an object with a 3 pixel wide, red dashed border for the specified wait time.
|
638
|
-
# If wait time is zero, then the highlight will remain until the page is refreshed
|
639
|
-
#
|
640
|
-
# @param duration [Integer or Float] wait time in seconds
|
641
|
-
# @example
|
642
|
-
# error_message.highlight(3)
|
643
|
-
#
|
644
|
-
def highlight(duration = 1)
|
645
|
-
obj, type = find_element
|
646
|
-
object_not_found_exception(obj, type)
|
647
|
-
# store original style so it can be reset later
|
648
|
-
@original_style = obj.native.attribute('style')
|
649
|
-
# style element with red border
|
650
|
-
page.execute_script(
|
651
|
-
'arguments[0].setAttribute(arguments[1], arguments[2])',
|
652
|
-
obj,
|
653
|
-
'style',
|
654
|
-
'border: 3px solid red; border-style: dashed;'
|
655
|
-
)
|
656
|
-
# keep element highlighted for duration and then revert to original style
|
657
|
-
if duration.positive?
|
658
|
-
sleep duration
|
659
|
-
page.execute_script(
|
660
|
-
'arguments[0].setAttribute(arguments[1], arguments[2])',
|
661
|
-
obj,
|
662
|
-
'style',
|
663
|
-
@original_style
|
664
|
-
)
|
665
|
-
end
|
666
|
-
end
|
667
|
-
|
668
|
-
# Restore a highlighted object's original style
|
669
|
-
#
|
670
|
-
# @example
|
671
|
-
# store_link.unhighlight
|
672
|
-
#
|
673
|
-
def unhighlight
|
674
|
-
obj, type = find_element
|
675
|
-
object_not_found_exception(obj, type)
|
676
|
-
return if @original_style.nil?
|
677
|
-
page.execute_script(
|
678
|
-
'arguments[0].setAttribute(arguments[1], arguments[2])',
|
679
|
-
obj,
|
680
|
-
'style',
|
681
|
-
@original_style
|
682
|
-
)
|
683
|
-
end
|
684
|
-
|
685
|
-
# Return UI object's style property
|
686
|
-
#
|
687
|
-
# @return [String]
|
688
|
-
# @example
|
689
|
-
# buy_now_button.style
|
690
|
-
#
|
691
|
-
def style
|
692
|
-
get_attribute('style')
|
693
|
-
end
|
694
|
-
|
695
|
-
# Return state of UI object's role property
|
696
|
-
#
|
697
|
-
# @return [String]
|
698
|
-
# @example
|
699
|
-
# buy_now_button.role
|
700
|
-
#
|
701
|
-
def role
|
702
|
-
get_attribute('role')
|
703
|
-
end
|
704
|
-
|
705
|
-
# Return state of UI object's tabindex property
|
706
|
-
#
|
707
|
-
# @return [String]
|
708
|
-
# @example
|
709
|
-
# buy_now_button.tabindex
|
710
|
-
#
|
711
|
-
def tabindex
|
712
|
-
get_attribute('tabindex')
|
713
|
-
end
|
714
|
-
|
715
|
-
# Return state of UI object's aria-label property
|
716
|
-
#
|
717
|
-
# @return [String]
|
718
|
-
# @example
|
719
|
-
# buy_now_button.aria_label
|
720
|
-
#
|
721
|
-
def aria_label
|
722
|
-
get_attribute('aria-label')
|
723
|
-
end
|
724
|
-
|
725
|
-
# Return state of UI object's aria-labelledby property
|
726
|
-
#
|
727
|
-
# @return [String]
|
728
|
-
# @example
|
729
|
-
# buy_now_button.aria_labelledby
|
730
|
-
#
|
731
|
-
def aria_labelledby
|
732
|
-
get_attribute('aria-labelledby')
|
733
|
-
end
|
734
|
-
|
735
|
-
# Return state of UI object's aria-describedby property
|
736
|
-
#
|
737
|
-
# @return [String]
|
738
|
-
# @example
|
739
|
-
# buy_now_button.aria_describedby
|
740
|
-
#
|
741
|
-
def aria_describedby
|
742
|
-
get_attribute('aria-describedby')
|
743
|
-
end
|
744
|
-
|
745
|
-
# Return state of UI object's aria-live property
|
746
|
-
#
|
747
|
-
# @return [String]
|
748
|
-
# @example
|
749
|
-
# properties_list.aria_live
|
750
|
-
#
|
751
|
-
def aria_live
|
752
|
-
get_attribute('aria-live')
|
753
|
-
end
|
754
|
-
|
755
|
-
# Return state of UI object's aria-sort property
|
756
|
-
#
|
757
|
-
# @return [String]
|
758
|
-
# @example
|
759
|
-
# name_column.aria_sort
|
760
|
-
#
|
761
|
-
def aria_sort
|
762
|
-
get_attribute('aria-sort')
|
763
|
-
end
|
764
|
-
|
765
|
-
# Return state of UI object's aria-rowcount property
|
766
|
-
#
|
767
|
-
# @return [Integer]
|
768
|
-
# @example
|
769
|
-
# user_grid.aria_rowcount
|
770
|
-
#
|
771
|
-
def aria_rowcount
|
772
|
-
get_attribute('aria-rowcount')
|
773
|
-
end
|
774
|
-
|
775
|
-
# Return state of UI object's aria-colcount property
|
776
|
-
#
|
777
|
-
# @return [Integer]
|
778
|
-
# @example
|
779
|
-
# user_grid.aria_colcount
|
780
|
-
#
|
781
|
-
def aria_colcount
|
782
|
-
get_attribute('aria-colcount')
|
783
|
-
end
|
784
|
-
|
785
|
-
# Return state of UI object's aria-valuemax property
|
786
|
-
#
|
787
|
-
# @return [Integer]
|
788
|
-
# @example
|
789
|
-
# volume_slider.aria_valuemax
|
790
|
-
#
|
791
|
-
def aria_valuemax
|
792
|
-
get_attribute('aria-valuemax')
|
793
|
-
end
|
794
|
-
|
795
|
-
# Return state of UI object's aria-valuemin property
|
796
|
-
#
|
797
|
-
# @return [Integer]
|
798
|
-
# @example
|
799
|
-
# volume_slider.aria_valuemin
|
800
|
-
#
|
801
|
-
def aria_valuemin
|
802
|
-
get_attribute('aria-valuemin')
|
803
|
-
end
|
804
|
-
|
805
|
-
# Return state of UI object's aria-valuenow property
|
806
|
-
#
|
807
|
-
# @return [Integer]
|
808
|
-
# @example
|
809
|
-
# volume_slider.aria_valuenow
|
810
|
-
#
|
811
|
-
def aria_valuenow
|
812
|
-
get_attribute('aria-valuenow')
|
813
|
-
end
|
814
|
-
|
815
|
-
# Return state of UI object's aria-valuetext property
|
816
|
-
#
|
817
|
-
# @return [Integer]
|
818
|
-
# @example
|
819
|
-
# volume_slider.aria_valuetext
|
820
|
-
#
|
821
|
-
def aria_valuetext
|
822
|
-
get_attribute('aria-valuetext')
|
823
|
-
end
|
824
|
-
|
825
|
-
# Return state of UI object's aria-orientation property
|
826
|
-
#
|
827
|
-
# @return [Integer]
|
828
|
-
# @example
|
829
|
-
# volume_slider.aria_orientation
|
830
|
-
#
|
831
|
-
def aria_orientation
|
832
|
-
get_attribute('aria-orientation')
|
833
|
-
end
|
834
|
-
|
835
|
-
# Return state of UI object's aria-keyshortcuts property
|
836
|
-
#
|
837
|
-
# @return [Integer]
|
838
|
-
# @example
|
839
|
-
# play_button.aria_keyshortcuts
|
840
|
-
#
|
841
|
-
def aria_keyshortcuts
|
842
|
-
get_attribute('aria-keyshortcuts')
|
843
|
-
end
|
844
|
-
|
845
|
-
# Return state of UI object's aria-roledescription property
|
846
|
-
#
|
847
|
-
# @return [Integer]
|
848
|
-
# @example
|
849
|
-
# editor_button.aria_roledescription
|
850
|
-
#
|
851
|
-
def aria_roledescription
|
852
|
-
get_attribute('aria-roledescription')
|
853
|
-
end
|
854
|
-
|
855
|
-
# Return state of UI object's aria-autocomplete property
|
856
|
-
#
|
857
|
-
# @return [Integer]
|
858
|
-
# @example
|
859
|
-
# email_field.aria_autocomplete
|
860
|
-
#
|
861
|
-
def aria_autocomplete
|
862
|
-
get_attribute('aria-autocomplete')
|
863
|
-
end
|
864
|
-
|
865
|
-
# Return state of UI object's aria-controls property
|
866
|
-
#
|
867
|
-
# @return [Integer]
|
868
|
-
# @example
|
869
|
-
# video_menu.aria_controls
|
870
|
-
#
|
871
|
-
def aria_controls
|
872
|
-
get_attribute('aria-controls')
|
873
|
-
end
|
874
|
-
|
875
|
-
# Return state of UI object's aria-disabled property
|
876
|
-
#
|
877
|
-
# @return [Boolean]
|
878
|
-
# @example
|
879
|
-
# buy_now_button.aria_disabled?
|
880
|
-
#
|
881
|
-
def aria_disabled?
|
882
|
-
state = get_attribute('aria-disabled')
|
883
|
-
state.boolean? ? state : state == 'true'
|
884
|
-
end
|
885
|
-
|
886
|
-
# Return state of UI object's aria-selected property
|
887
|
-
#
|
888
|
-
# @return [Boolean]
|
889
|
-
# @example
|
890
|
-
# nutrition_info_tab.aria_selected?
|
891
|
-
#
|
892
|
-
def aria_selected?
|
893
|
-
state = get_attribute('aria-selected')
|
894
|
-
state.boolean? ? state : state == 'true'
|
895
|
-
end
|
896
|
-
|
897
|
-
# Return state of UI object's aria-hidden property
|
898
|
-
#
|
899
|
-
# @return [Boolean]
|
900
|
-
# @example
|
901
|
-
# nutrition_info_tab.aria_hidden?
|
902
|
-
#
|
903
|
-
def aria_hidden?
|
904
|
-
state = get_attribute('aria-hidden')
|
905
|
-
state.boolean? ? state : state == 'true'
|
906
|
-
end
|
907
|
-
|
908
|
-
# Return state of UI object's aria-expanded property
|
909
|
-
#
|
910
|
-
# @return [Boolean]
|
911
|
-
# @example
|
912
|
-
# catalog_tree.aria_expanded?
|
913
|
-
#
|
914
|
-
def aria_expanded?
|
915
|
-
state = get_attribute('aria-expanded')
|
916
|
-
state.boolean? ? state : state == 'true'
|
917
|
-
end
|
918
|
-
|
919
|
-
# Return state of UI object's aria-required property
|
920
|
-
#
|
921
|
-
# @return [Boolean]
|
922
|
-
# @example
|
923
|
-
# home_phone_field.aria_required?
|
924
|
-
#
|
925
|
-
def aria_required?
|
926
|
-
state = get_attribute('aria-required')
|
927
|
-
state.boolean? ? state : state == 'true'
|
928
|
-
end
|
929
|
-
|
930
|
-
# Return state of UI object's aria-invalid property
|
931
|
-
#
|
932
|
-
# @return [Boolean]
|
933
|
-
# @example
|
934
|
-
# home_phone_field.aria_invalid?
|
935
|
-
#
|
936
|
-
def aria_invalid?
|
937
|
-
state = get_attribute('aria-invalid')
|
938
|
-
state.boolean? ? state : state == 'true'
|
939
|
-
end
|
940
|
-
|
941
|
-
# Return state of UI object's aria-checked property
|
942
|
-
#
|
943
|
-
# @return [Boolean]
|
944
|
-
# @example
|
945
|
-
# allow_new_users_checkbox.aria_checked?
|
946
|
-
#
|
947
|
-
def aria_checked?
|
948
|
-
state = get_attribute('aria-checked')
|
949
|
-
state.boolean? ? state : state == 'true'
|
950
|
-
end
|
951
|
-
|
952
|
-
# Return state of UI object's aria-haspopup property
|
953
|
-
#
|
954
|
-
# @return [Boolean]
|
955
|
-
# @example
|
956
|
-
# user_avatar.aria_haspopup?
|
957
|
-
#
|
958
|
-
def aria_haspopup?
|
959
|
-
state = get_attribute('aria-haspopup')
|
960
|
-
state.boolean? ? state : state == 'true'
|
961
|
-
end
|
962
|
-
|
963
|
-
# Return state of UI object's aria-pressed property
|
964
|
-
#
|
965
|
-
# @return [Boolean]
|
966
|
-
# @example
|
967
|
-
# option1_button.aria_pressed?
|
968
|
-
#
|
969
|
-
def aria_pressed?
|
970
|
-
state = get_attribute('aria-pressed')
|
971
|
-
state.boolean? ? state : state == 'true'
|
972
|
-
end
|
973
|
-
|
974
|
-
# Return state of UI object's aria-readonly property
|
975
|
-
#
|
976
|
-
# @return [Boolean]
|
977
|
-
# @example
|
978
|
-
# home_phone_field.aria_readonly?
|
979
|
-
#
|
980
|
-
def aria_readonly?
|
981
|
-
state = get_attribute('aria-readonly')
|
982
|
-
state.boolean? ? state : state == 'true'
|
983
|
-
end
|
984
|
-
|
985
|
-
# Return state of UI object's aria-busy property
|
986
|
-
#
|
987
|
-
# @return [Boolean]
|
988
|
-
# @example
|
989
|
-
# home_phone_field.aria_busy?
|
990
|
-
#
|
991
|
-
def aria_busy?
|
992
|
-
state = get_attribute('aria-busy')
|
993
|
-
state.boolean? ? state : state == 'true'
|
994
|
-
end
|
995
|
-
|
996
|
-
# Return state of UI object's aria-modal property
|
997
|
-
#
|
998
|
-
# @return [Boolean]
|
999
|
-
# @example
|
1000
|
-
# add_user_modal.aria_modal?
|
1001
|
-
#
|
1002
|
-
def aria_modal?
|
1003
|
-
state = get_attribute('aria-modal')
|
1004
|
-
state.boolean? ? state : state == 'true'
|
1005
|
-
end
|
1006
|
-
|
1007
|
-
# Return state of UI object's aria-multiline property
|
1008
|
-
#
|
1009
|
-
# @return [Boolean]
|
1010
|
-
# @example
|
1011
|
-
# description_field.aria_multiline?
|
1012
|
-
#
|
1013
|
-
def aria_multiline?
|
1014
|
-
state = get_attribute('aria-multiline')
|
1015
|
-
state.boolean? ? state : state == 'true'
|
1016
|
-
end
|
1017
|
-
|
1018
|
-
# Return state of UI object's aria-multiselectable property
|
1019
|
-
#
|
1020
|
-
# @return [Boolean]
|
1021
|
-
# @example
|
1022
|
-
# channels_select.aria_multiselectable?
|
1023
|
-
#
|
1024
|
-
def aria_multiselectable?
|
1025
|
-
state = get_attribute('aria-multiselectable')
|
1026
|
-
state.boolean? ? state : state == 'true'
|
1027
|
-
end
|
1028
|
-
|
1029
|
-
# Return state of UI object's contenteditable property
|
1030
|
-
#
|
1031
|
-
# @return [Boolean]
|
1032
|
-
# @example
|
1033
|
-
# description_field.content_editable?
|
1034
|
-
#
|
1035
|
-
def content_editable?
|
1036
|
-
state = get_attribute('contenteditable')
|
1037
|
-
state.boolean? ? state : state == 'true'
|
1038
|
-
end
|
1039
|
-
|
1040
|
-
# Return crossorigin property
|
1041
|
-
#
|
1042
|
-
# @return crossorigin value
|
1043
|
-
# @example
|
1044
|
-
# with_creds = media_player.crossorigin == 'use-credentials'
|
1045
|
-
#
|
1046
|
-
def crossorigin
|
1047
|
-
obj, = find_element
|
1048
|
-
object_not_found_exception(obj, @type)
|
1049
|
-
obj.native.attribute('crossorigin')
|
1050
|
-
end
|
1051
|
-
|
1052
|
-
def get_attribute(attrib)
|
1053
|
-
obj, type = find_element(visible = false)
|
1054
|
-
object_not_found_exception(obj, type)
|
1055
|
-
obj[attrib]
|
1056
|
-
end
|
1057
|
-
|
1058
|
-
def get_native_attribute(attrib)
|
1059
|
-
obj, type = find_element(visible = false)
|
1060
|
-
object_not_found_exception(obj, type)
|
1061
|
-
obj.native.attribute(attrib)
|
1062
|
-
end
|
1063
|
-
|
1064
|
-
def find_element(visible = true)
|
1065
|
-
wait = Selenium::WebDriver::Wait.new(timeout: Capybara.default_max_wait_time)
|
1066
|
-
wait.until { find_object(visible) }
|
1067
|
-
end
|
1068
|
-
|
1069
|
-
private
|
1070
|
-
|
1071
|
-
def find_object(visible = true)
|
1072
|
-
obj_locator = @alt_locator.nil? ? @locator : @alt_locator
|
1073
|
-
parent_section = @context == :section && !@parent.get_locator.nil?
|
1074
|
-
tries ||= parent_section ? 2 : 1
|
1075
|
-
if parent_section && tries == 2
|
1076
|
-
parent_locator = @parent.get_locator
|
1077
|
-
parent_locator = parent_locator.tr('|', ' ')
|
1078
|
-
parent_locator_type = @parent.get_locator_type
|
1079
|
-
obj = page.find(parent_locator_type, parent_locator, visible: :all, wait: 0.01).find(@locator_type, obj_locator, wait: 0.01, visible: visible)
|
1080
|
-
else
|
1081
|
-
obj = page.find(@locator_type, obj_locator, wait: 0.01, visible: visible)
|
1082
|
-
end
|
1083
|
-
[obj, @locator_type]
|
1084
|
-
rescue StandardError
|
1085
|
-
retry if (tries -= 1).positive?
|
1086
|
-
[nil, nil]
|
1087
|
-
end
|
1088
|
-
|
1089
|
-
def object_not_found_exception(obj, obj_type)
|
1090
|
-
locator = @alt_locator.nil? ? @locator : @alt_locator
|
1091
|
-
object_type = obj_type.nil? ? 'Object' : obj_type
|
1092
|
-
raise ObjectNotFoundError, "#{object_type} named '#{@name}' (#{locator}) not found" unless obj
|
1093
|
-
end
|
1094
|
-
|
1095
|
-
def invalid_object_type_exception(obj, obj_type)
|
1096
|
-
unless obj.tag_name == obj_type || obj.native.attribute('type') == obj_type
|
1097
|
-
locator = @alt_locator.nil? ? @locator : @alt_locator
|
1098
|
-
raise "#{locator} is not a #{obj_type} element"
|
1099
|
-
end
|
1100
|
-
end
|
1101
|
-
|
1102
|
-
def object_ref_message
|
1103
|
-
"object '#{get_name}' (#{get_locator})"
|
1104
|
-
end
|
1105
|
-
|
1106
|
-
def compare(expected, actual)
|
1107
|
-
if expected.is_a?(Hash) && expected.length == 1
|
1108
|
-
expected.each do |key, value|
|
1109
|
-
case key
|
1110
|
-
when :lt, :less_than
|
1111
|
-
actual < value
|
1112
|
-
when :lt_eq, :less_than_or_equal
|
1113
|
-
actual <= value
|
1114
|
-
when :gt, :greater_than
|
1115
|
-
actual > value
|
1116
|
-
when :gt_eq, :greater_than_or_equal
|
1117
|
-
actual >= value
|
1118
|
-
when :starts_with
|
1119
|
-
actual.start_with?(value)
|
1120
|
-
when :ends_with
|
1121
|
-
actual.end_with?(value)
|
1122
|
-
when :contains
|
1123
|
-
actual.include?(value)
|
1124
|
-
when :not_contains, :does_not_contain
|
1125
|
-
!actual.include?(value)
|
1126
|
-
when :not_equal
|
1127
|
-
actual != value
|
1128
|
-
end
|
1129
|
-
end
|
1130
|
-
else
|
1131
|
-
expected == actual
|
1132
|
-
end
|
1133
|
-
end
|
1134
|
-
|
1135
|
-
def find_component(component, component_name)
|
1136
|
-
begin
|
1137
|
-
element = @base_object.find(:css, component, visible: :all, minimum: 0, wait: 1)
|
1138
|
-
rescue
|
1139
|
-
begin
|
1140
|
-
element = page.find(:css, component, visible: :all, minimum: 0, wait: 2)
|
1141
|
-
rescue
|
1142
|
-
raise "Component #{component_name} (#{component}) for #{@type} named '#{@name}' (#{locator}) not found"
|
1143
|
-
end
|
1144
|
-
end
|
1145
|
-
element
|
1146
|
-
end
|
1147
|
-
end
|
1148
|
-
end
|