Class: TestaAppiumDriver::Locator

Inherits:
Object
  • Object
show all
Includes:
Attributes, ClassSelectors, Helpers, TypeSelectors
Defined in:
lib/testa_appium_driver/common/locator.rb,
lib/testa_appium_driver/ios/locator.rb,
lib/testa_appium_driver/android/locator.rb,
lib/testa_appium_driver/android/locator/attributes.rb,
lib/testa_appium_driver/common/locator/scroll_actions.rb

Overview

noinspection RubyTooManyMethodsInspection

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from ClassSelectors

#add_selector, #button, #buttons, #card_view, #card_views, #check_box, #check_boxes, #edit_text, #edit_texts, #element, #elements, #frame_layout, #frame_layouts, #horizontal_scroll_view, #horizontal_scroll_views, #image_button, #image_buttons, #image_view, #image_views, #linear_layout, #linear_layouts, #list_view, #list_views, #progress_bar, #progress_bars, #radio_button, #radio_buttons, #radio_group, #radio_groups, #recycler_view, #recycler_views, #relative_layout, #relative_layouts, #scroll_view, #scroll_views, #search_view, #search_views, #spinner, #spinners, #switch, #switches, #text_view, #text_views, #toast, #toasts, #toolbar, #toolbars, #view, #view_group, #view_groups, #view_pager, #view_pagers, #views, #web_view, #web_views

Methods included from Helpers

#extract_selectors_from_params, #hash_to_class_chain, #hash_to_uiautomator, #hash_to_xpath, #is_scrollable_selector?, #resolve_id

Methods included from Attributes

#accessibility_container, #accessible?, #checkable?, #checked?, #class_name, #clickable?, #desc, #displayed?, #enabled?, #focusable?, #focused?, #frame, #id, #label, #long_clickable?, #name, #package, #password?, #rect, #scrollable?, #selected?, #selection_end, #selection_start, #testa_attribute, #type, #value, #visible?

Methods included from TypeSelectors

#add_selector, #button, #buttons, #cell, #cells, #collection_view, #collection_views, #element, #elements, #image, #images, #navigation_bar, #navigation_bars, #other, #others, #scroll_view, #scroll_views, #secure_text_field, #secure_text_fields, #static_text, #static_texts, #table, #tables, #text_field, #text_fields, #window, #windows

Constructor Details

#initialize(driver, from_element, params = {}) ⇒ Locator

locator parameters are:

single: true or false
scrollable_locator: [TestaAppiumDriver::Locator, nil] for scrolling if needed later
default_find_strategy: default strategy if find element strategy is not enforced
default_scroll_strategy: default strategy for scrolling if not enforced

Parameters:



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/testa_appium_driver/common/locator.rb', line 24

def initialize(driver, from_element, params = {})
  # @type [TestaAppiumDriver::Driver]
  @driver = driver
  @index_for_multiple = nil
  @image_selector = nil

  params, selectors = extract_selectors_from_params(params)
  single = params[:single]

  @single = single

  if selectors[:image].nil?
    if from_element.instance_of?(TestaAppiumDriver::Locator) && !from_element.image_selector.nil?
      raise "Cannot chain non-image selectors to image selectors"
    end
  else
    handle_image_selector(selectors, params)
  end

  selectors[:id] = selectors[:name] unless selectors[:name].nil?
  if from_element.instance_of?(::Selenium::WebDriver::Element) ||
    from_element.instance_of?(::Appium::Core::Element) ||
    from_element.instance_of?(::TestaAppiumDriver::Locator)
    @xpath_selector = "."
    @xpath_selector += hash_to_xpath(@driver.device, selectors, single)
  else
    @xpath_selector = hash_to_xpath(@driver.device, selectors, single)
  end

  @from_element = from_element
  @default_find_strategy = params[:default_find_strategy]
  @default_scroll_strategy = params[:default_scroll_strategy]

  @can_use_id_strategy = is_only_id_selector?(selectors)
  if @can_use_id_strategy
    if @driver.device == :android
      @can_use_id_strategy = resolve_id(selectors[:id])
    else
      @can_use_id_strategy = selectors[:id]
    end
  end

  @strategy = params[:strategy]
  @strategy_reason = params[:strategy_reason]

  @last_selector_adjacent = false

  init(params, selectors, single)
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *args, &block) ⇒ Object

method missing is used to fetch the element before executing additional commands like click, send_key, count



98
99
100
101
102
# File 'lib/testa_appium_driver/common/locator.rb', line 98

def method_missing(method, *args, &block)
  r = execute.send(method, *args, &block)
  @driver.invalidate_cache
  r
end

Instance Attribute Details

#can_use_id_strategyObject

Returns the value of attribute can_use_id_strategy.



8
9
10
# File 'lib/testa_appium_driver/common/locator.rb', line 8

def can_use_id_strategy
  @can_use_id_strategy
end

#class_chain_selectorObject

Returns the value of attribute class_chain_selector.



7
8
9
# File 'lib/testa_appium_driver/ios/locator.rb', line 7

def class_chain_selector
  @class_chain_selector
end

#closing_parenthesisObject

Returns the value of attribute closing_parenthesis.



6
7
8
# File 'lib/testa_appium_driver/android/locator.rb', line 6

def closing_parenthesis
  @closing_parenthesis
end

#default_find_strategyObject

Returns the value of attribute default_find_strategy.



8
9
10
# File 'lib/testa_appium_driver/common/locator.rb', line 8

def default_find_strategy
  @default_find_strategy
end

#default_scroll_strategyObject

Returns the value of attribute default_scroll_strategy.



8
9
10
# File 'lib/testa_appium_driver/common/locator.rb', line 8

def default_scroll_strategy
  @default_scroll_strategy
end

#driverObject

Returns the value of attribute driver.



8
9
10
# File 'lib/testa_appium_driver/common/locator.rb', line 8

def driver
  @driver
end

#from_elementObject

Returns the value of attribute from_element.



8
9
10
# File 'lib/testa_appium_driver/common/locator.rb', line 8

def from_element
  @from_element
end

#image_selectorObject

Returns the value of attribute image_selector.



8
9
10
# File 'lib/testa_appium_driver/common/locator.rb', line 8

def image_selector
  @image_selector
end

#index_for_multipleObject

Returns the value of attribute index_for_multiple.



8
9
10
# File 'lib/testa_appium_driver/common/locator.rb', line 8

def index_for_multiple
  @index_for_multiple
end

#last_selector_adjacentObject

Returns the value of attribute last_selector_adjacent.



13
14
15
# File 'lib/testa_appium_driver/common/locator.rb', line 13

def last_selector_adjacent
  @last_selector_adjacent
end

#scroll_deadzoneObject

Returns the value of attribute scroll_deadzone.



8
9
10
# File 'lib/testa_appium_driver/common/locator.rb', line 8

def scroll_deadzone
  @scroll_deadzone
end

#scroll_orientationObject

Returns the value of attribute scroll_orientation.



8
9
10
# File 'lib/testa_appium_driver/common/locator.rb', line 8

def scroll_orientation
  @scroll_orientation
end

#scrollable_locatorObject

Returns the value of attribute scrollable_locator.



8
9
10
# File 'lib/testa_appium_driver/common/locator.rb', line 8

def scrollable_locator
  @scrollable_locator
end

#singleObject

Returns the value of attribute single.



8
9
10
# File 'lib/testa_appium_driver/common/locator.rb', line 8

def single
  @single
end

#strategyObject

Returns the value of attribute strategy.



8
9
10
# File 'lib/testa_appium_driver/common/locator.rb', line 8

def strategy
  @strategy
end

#strategy_reasonObject

Returns the value of attribute strategy_reason.



8
9
10
# File 'lib/testa_appium_driver/common/locator.rb', line 8

def strategy_reason
  @strategy_reason
end

#xpath_selectorObject

Returns the value of attribute xpath_selector.



8
9
10
# File 'lib/testa_appium_driver/common/locator.rb', line 8

def xpath_selector
  @xpath_selector
end

Instance Method Details

#==(other) ⇒ Object

noinspection RubyNilAnalysis,RubyUnnecessaryReturnStatement

Parameters:



270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
# File 'lib/testa_appium_driver/common/locator.rb', line 270

def ==(other)
  elements = execute
  other = other.execute if other.is_a?(TestaAppiumDriver::Locator)

  if elements.is_a?(Array)
    return false unless other.is_a?(Array)
    return false if other.count != elements.count

    (elements - other).empty?
  else
    return false if other.is_a?(Array)

    elements == other
  end
end

#[](instance) ⇒ Object



239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
# File 'lib/testa_appium_driver/common/locator.rb', line 239

def [](instance)
  raise "Cannot add index selector to non-Array" if @single

  if ((@strategy.nil? && !@last_selector_adjacent && @driver.device == :android) || @strategy == FIND_STRATEGY_UIAUTOMATOR) && instance >= 0
    locator = self.dup
    locator.strategy = FIND_STRATEGY_UIAUTOMATOR
    locator.ui_selector = "#{@ui_selector}.instance(#{instance})"
    locator.single = true
    locator.can_use_id_strategy = false
    locator
  elsif (@driver.device == :ios && !@last_selector_adjacent && @strategy.nil?) || @strategy == FIND_STRATEGY_CLASS_CHAIN
    locator = self.dup
    locator.strategy = FIND_STRATEGY_CLASS_CHAIN
    locator.class_chain_selector += "[#{instance + 1}]"
    locator.single = true
    locator.can_use_id_strategy = false
    locator
  else
    from_element = self.dup
    from_element.index_for_multiple = instance
    params = {}.merge({ single: true, scrollable_locator: @scrollable_locator })
    # params[:strategy] = FIND_STRATEGY_XPATH
    # params[:strategy_reason] = "retrieved instance of a array"
    params[:default_find_strategy] = @default_find_strategy
    params[:default_scroll_strategy] = @default_scroll_strategy
    Locator.new(@driver, from_element, params)
  end
end

#add_child_selector(params) ⇒ Locator

Returns new child locator element.

Returns:

  • (Locator)

    new child locator element



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/testa_appium_driver/ios/locator.rb', line 46

def add_child_selector(params)
  params, selectors = extract_selectors_from_params(params)
  single = params[:single]
  raise "Cannot add child selector to Array" if single && !@single

  locator = self.dup
  locator.can_use_id_strategy = false
  add_xpath_child_selectors(locator, selectors, single)
  if @strategy.nil? || @strategy == FIND_STRATEGY_CLASS_CHAIN
    add_class_chain_child_selectors(locator, selectors, single)
  end

  if is_scrollable_selector?(selectors, single)
    locator.scrollable_locator.scroll_orientation = :vertical
    locator.scrollable_locator = locator
  end

  locator.last_selector_adjacent = false
  locator
end

#add_class_chain_child_selectors(locator, selectors, single) ⇒ Object



68
69
70
71
# File 'lib/testa_appium_driver/ios/locator.rb', line 68

def add_class_chain_child_selectors(locator, selectors, single)
  locator.single = false unless single # switching from single result to multiple
  locator.class_chain_selector += "/" + hash_to_class_chain(selectors, single)
end

#align(with = :top, top: nil, bottom: nil, right: nil, left: nil, scroll_to_find: false, max_attempts: 3) ⇒ TestaAppiumDriver::Locator

Aligns element (by default) on top of the scrollable container, if the element does not exists it will scroll to find it The element is aligned if the the distance from the top/bottom/right/left of the scrollable container is less than [TestaAppiumDriver::SCROLL_ALIGNMENT_THRESHOLD] If the distance is greater than the threshold, it will attempt to realign it up to 2 more times. The retry mechanism allows alignment even for dynamic layouts when elements are hidden/show when scrolling to certain direction



70
71
72
73
74
75
76
77
78
79
# File 'lib/testa_appium_driver/common/locator/scroll_actions.rb', line 70

def align(with = :top, top: nil, bottom: nil, right: nil, left: nil, scroll_to_find: false, max_attempts: 3)
  deadzone = _process_deadzone(top, bottom, right, left)
  deadzone = @scrollable_locator.scroll_deadzone if deadzone.nil? && !@scrollable_locator.nil?
  sa = ScrollActions.new(@scrollable_locator,
                         locator: self,
                         deadzone: deadzone,
                         default_scroll_strategy: @default_scroll_strategy)
  sa.align(with, scroll_to_find, max_attempts)
  self
end

#align!(with = :top, top: nil, bottom: nil, right: nil, left: nil, max_attempts: 3) ⇒ TestaAppiumDriver::Locator

Aligns element (by default) on top of the scrollable container, if the element does not exists it raise an exception The element is aligned if the the distance from the top/bottom/right/left of the scrollable container is less than [TestaAppiumDriver::SCROLL_ALIGNMENT_THRESHOLD] If the distance is greater than the threshold, it will attempt to realign it up to 2 more times. The retry mechanism allows alignment even for dynamic layouts when elements are hidden/show when scrolling to certain direction



122
123
124
# File 'lib/testa_appium_driver/common/locator/scroll_actions.rb', line 122

def align!(with = :top, top: nil, bottom: nil, right: nil, left: nil, max_attempts: 3)
  align(with, top: top, bottom: bottom, right: right, left: left, scroll_to_find: true, max_attempts: max_attempts)
end

#align_bottom(top: nil, bottom: nil, right: nil, left: nil, max_attempts: 3) ⇒ TestaAppiumDriver::Locator

Aligns element on bottom of the scrollable container, if the element does not exists it will scroll to find it The element is aligned if the the distance from the bottom of the scrollable container is less than [TestaAppiumDriver::SCROLL_ALIGNMENT_THRESHOLD] If the distance is greater than the threshold, it will attempt to realign it up to 2 more times. The retry mechanism allows alignment even for dynamic layouts when elements are hidden/show when scrolling to certain direction



95
96
97
# File 'lib/testa_appium_driver/common/locator/scroll_actions.rb', line 95

def align_bottom(top: nil, bottom: nil, right: nil, left: nil, max_attempts: 3)
  align(:bottom, top: top, bottom: bottom, right: right, left: left, max_attempts: max_attempts)
end

#align_bottom!(top: nil, bottom: nil, right: nil, left: nil, max_attempts: 3) ⇒ TestaAppiumDriver::Locator

Aligns element on bottom of the scrollable container, if the element does not exists it raise an exception The element is aligned if the the distance from the bottom of the scrollable container is less than [TestaAppiumDriver::SCROLL_ALIGNMENT_THRESHOLD] If the distance is greater than the threshold, it will attempt to realign it up to 2 more times. The retry mechanism allows alignment even for dynamic layouts when elements are hidden/show when scrolling to certain direction



140
141
142
# File 'lib/testa_appium_driver/common/locator/scroll_actions.rb', line 140

def align_bottom!(top: nil, bottom: nil, right: nil, left: nil, max_attempts: 3)
  align(:bottom, top: top, bottom: bottom, right: right, left: left, scroll_to_find: true, max_attempts: max_attempts)
end

#align_left(top: nil, bottom: nil, right: nil, left: nil, max_attempts: 3) ⇒ TestaAppiumDriver::Locator

Aligns element on left of the scrollable container, if the element does not exists it will scroll to find it The element is aligned if the the distance from the left of the scrollable container is less than [TestaAppiumDriver::SCROLL_ALIGNMENT_THRESHOLD] If the distance is greater than the threshold, it will attempt to realign it up to 2 more times. The retry mechanism allows alignment even for dynamic layouts when elements are hidden/show when scrolling to certain direction



104
105
106
# File 'lib/testa_appium_driver/common/locator/scroll_actions.rb', line 104

def align_left(top: nil, bottom: nil, right: nil, left: nil, max_attempts: 3)
  align(:left, top: top, bottom: bottom, right: right, left: left, max_attempts: max_attempts)
end

#align_left!(top: nil, bottom: nil, right: nil, left: nil, max_attempts: 3) ⇒ TestaAppiumDriver::Locator

Aligns element on left of the scrollable container, if the element does not exists it raise an exception The element is aligned if the the distance from the left of the scrollable container is less than [TestaAppiumDriver::SCROLL_ALIGNMENT_THRESHOLD] If the distance is greater than the threshold, it will attempt to realign it up to 2 more times. The retry mechanism allows alignment even for dynamic layouts when elements are hidden/show when scrolling to certain direction



149
150
151
# File 'lib/testa_appium_driver/common/locator/scroll_actions.rb', line 149

def align_left!(top: nil, bottom: nil, right: nil, left: nil, max_attempts: 3)
  align(:left, top: top, bottom: bottom, right: right, left: left, scroll_to_find: true, max_attempts: max_attempts)
end

#align_right(top: nil, bottom: nil, right: nil, left: nil, max_attempts: 3) ⇒ TestaAppiumDriver::Locator

Aligns element on right of the scrollable container, if the element does not exists it will scroll to find it The element is aligned if the the distance from the right of the scrollable container is less than [TestaAppiumDriver::SCROLL_ALIGNMENT_THRESHOLD] If the distance is greater than the threshold, it will attempt to realign it up to 2 more times. The retry mechanism allows alignment even for dynamic layouts when elements are hidden/show when scrolling to certain direction



113
114
115
# File 'lib/testa_appium_driver/common/locator/scroll_actions.rb', line 113

def align_right(top: nil, bottom: nil, right: nil, left: nil, max_attempts: 3)
  align(:right, top: top, bottom: bottom, right: right, left: left, max_attempts: max_attempts)
end

#align_right!(top: nil, bottom: nil, right: nil, left: nil, max_attempts: 3) ⇒ TestaAppiumDriver::Locator

Aligns element on right of the scrollable container, if the element does not exists it raise an exception The element is aligned if the the distance from the right of the scrollable container is less than [TestaAppiumDriver::SCROLL_ALIGNMENT_THRESHOLD] If the distance is greater than the threshold, it will attempt to realign it up to 2 more times. The retry mechanism allows alignment even for dynamic layouts when elements are hidden/show when scrolling to certain direction



158
159
160
# File 'lib/testa_appium_driver/common/locator/scroll_actions.rb', line 158

def align_right!(top: nil, bottom: nil, right: nil, left: nil, max_attempts: 3)
  align(:right, top: top, bottom: bottom, right: right, left: left, scroll_to_find: true, max_attempts: max_attempts)
end

#align_top(top: nil, bottom: nil, right: nil, left: nil, max_attempts: 3) ⇒ TestaAppiumDriver::Locator

Aligns element on top of the scrollable container, if the element does not exists it will scroll to find it The element is aligned if the the distance from the top of the scrollable container is less than [TestaAppiumDriver::SCROLL_ALIGNMENT_THRESHOLD] If the distance is greater than the threshold, it will attempt to realign it up to 2 more times. The retry mechanism allows alignment even for dynamic layouts when elements are hidden/show when scrolling to certain direction



86
87
88
# File 'lib/testa_appium_driver/common/locator/scroll_actions.rb', line 86

def align_top(top: nil, bottom: nil, right: nil, left: nil, max_attempts: 3)
  align(:top, top: top, bottom: bottom, right: right, left: left, max_attempts: max_attempts)
end

#align_top!(top: nil, bottom: nil, right: nil, left: nil, max_attempts: 3) ⇒ TestaAppiumDriver::Locator

Aligns element on top of the scrollable container, if the element does not exists it raise an exception The element is aligned if the the distance from the top of the scrollable container is less than [TestaAppiumDriver::SCROLL_ALIGNMENT_THRESHOLD] If the distance is greater than the threshold, it will attempt to realign it up to 2 more times. The retry mechanism allows alignment even for dynamic layouts when elements are hidden/show when scrolling to certain direction



131
132
133
# File 'lib/testa_appium_driver/common/locator/scroll_actions.rb', line 131

def align_top!(top: nil, bottom: nil, right: nil, left: nil, max_attempts: 3)
  align(:top, top: top, bottom: bottom, right: right, left: left, scroll_to_find: true, max_attempts: max_attempts)
end

#as_jsonObject



286
287
288
289
290
291
292
293
294
295
296
297
# File 'lib/testa_appium_driver/common/locator.rb', line 286

def as_json
  {
    strategy: @strategy,
    default_strategy: @default_find_strategy,
    single: @single,
    uiautomator: defined?(self.ui_selector) ? ui_selector : nil,
    xpath: @xpath_selector,
    scroll_orientation: @scroll_orientation,
    resolved: strategies_and_selectors,
    index_for_multiple: @index_for_multiple,
  }
end

#as_scrollable(orientation: :vertical, top: nil, bottom: nil, right: nil, left: nil) ⇒ TestaAppiumDriver::Locator



308
309
310
311
312
313
314
315
316
317
318
319
# File 'lib/testa_appium_driver/common/locator.rb', line 308

def as_scrollable(orientation: :vertical, top: nil, bottom: nil, right: nil, left: nil)
  @scroll_orientation = orientation
  if !top.nil? || !bottom.nil? || !right.nil? || !left.nil?
    @scroll_deadzone = {}
    @scroll_deadzone[:top] = top.to_f unless top.nil?
    @scroll_deadzone[:bottom] = bottom.to_f unless bottom.nil?
    @scroll_deadzone[:right] = right.to_f unless right.nil?
    @scroll_deadzone[:left] = left.to_f unless left.nil?
  end
  @scrollable_locator = self.dup
  self
end

#childTestaAppiumDriver::Locator

Return first child element



431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
# File 'lib/testa_appium_driver/common/locator.rb', line 431

def child
  raise "Cannot add children selector to array" unless @single
  raise StrategyMixException.new(@strategy, @strategy_reason, FIND_STRATEGY_XPATH, "child") if @strategy != FIND_STRATEGY_XPATH && @strategy != FIND_STRATEGY_CLASS_CHAIN && !@strategy.nil?

  locator = self.dup

  locator.strategy_reason = "child"
  locator.xpath_selector += "/*[1]"
  locator.single = true
  locator.can_use_id_strategy = false

  if @driver.device == :android
    locator.strategy = FIND_STRATEGY_XPATH
  else
    locator.class_chain_selector += "/*[1]"
  end
  locator
end

#childrenTestaAppiumDriver::Locator

Return all children elements



410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
# File 'lib/testa_appium_driver/common/locator.rb', line 410

def children
  raise "Cannot add children selector to array" unless @single
  raise StrategyMixException.new(@strategy, @strategy_reason, FIND_STRATEGY_XPATH, "children") if @strategy != FIND_STRATEGY_XPATH && @strategy != FIND_STRATEGY_CLASS_CHAIN && !@strategy.nil?

  locator = self.dup
  locator.strategy_reason = "children"
  locator.xpath_selector += "/*"
  locator.single = false
  locator.last_selector_adjacent = true
  locator.can_use_id_strategy = false

  if @driver.device == :android
    locator.strategy = FIND_STRATEGY_XPATH
  else
    locator.class_chain_selector += "/*"
  end
  locator
end

#clearObject



390
391
392
# File 'lib/testa_appium_driver/common/locator.rb', line 390

def clear
  perform_driver_method(:clear)
end

#click(x = nil, y = nil, double: false) ⇒ Object Also known as: tap

if both x or y, or both are not given, will click in the center of the element

Parameters:

  • x (defaults to: nil)

    If positive integer, will offset the click from the left side, if negative integer, will offset the click from the right. If float value is given, it will threat it as percentage offset, giving it 0.5 will click in the middle

  • y (defaults to: nil)

    If positive integer, will offset the click from the bottom side, if negative integer, will offset the click from the top. If float value is given, it will threat it as percentage offset, giving it 0.5 will click in the middle



336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
# File 'lib/testa_appium_driver/common/locator.rb', line 336

def click(x = nil, y = nil, double: false)
  x = 0.5 if x.nil?
  y = 0.5 if y.nil?

  b = self.bounds
  if x.is_a?(Integer)
    if x >= 0
      x = b.top_left.x + x
    else
      x = b.bottom_right.x + x
    end
  elsif x.is_a?(Float) && x <= 1.0 && x >= 0
    x = b.top_left.x + b.width * x
  else
    raise "x value #{x} not supported. Use integer as pixel or float (0..1) as percentage of element width"
  end

  if y.is_a?(Integer)
    if y >= 0
      y = b.top_left.y + y
    else
      y = b.bottom_right + y
    end
  elsif y.is_a?(Float) && y <= 1.0 && y >= 0
    y = b.top_left.y + b.height * y
  else
    raise "y value #{x} not supported. Use integer as pixel or float (0..1) as percentage of element height"
  end

  action_builder = @driver.action
  f1 = action_builder.add_pointer_input(:touch, "finger1")
  f1.create_pointer_move(duration: 0.1, x: x, y: y, origin: ::Selenium::WebDriver::Interactions::PointerMove::VIEWPORT)
  f1.create_pointer_down(:left)
  f1.create_pointer_up(:left)
  if double
    if @driver.ios?
      # NOTE: ios is stupid, we have to do another move
      # NOTE: ios is stupid, works very wierd if duration is 0
      f1.create_pointer_move(duration: 0.1, x: x, y: y, origin: ::Selenium::WebDriver::Interactions::PointerMove::VIEWPORT)
    end
    f1.create_pause(0.1)
    f1.create_pointer_down(:left)
    f1.create_pointer_up(:left)
  end
  @driver.perform_actions [f1]
end

#double_click(x = nil, y = nil) ⇒ Object Also known as: double_tap



329
330
331
# File 'lib/testa_appium_driver/common/locator.rb', line 329

def double_click(x = nil, y = nil)
  click(x, y, double: true)
end

#drag_by(amount, direction: :top) ⇒ Object



296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
# File 'lib/testa_appium_driver/common/locator/scroll_actions.rb', line 296

def drag_by(amount, direction: :top)
  b = bounds
  x = b.center.x
  y = b.center.y
  case direction
  when :top
    y -= amount.to_i
  when :bottom
    y += amount.to_i
  when :left
    x -= amount.to_i
  when :right
    x += amount.to_i
  else
    raise "Unknown direction #{direction}"
  end
  _drag_to(b.center.x, b.center.y, x, y)
end

#drag_down_by(amount) ⇒ Object



252
253
254
# File 'lib/testa_appium_driver/common/locator/scroll_actions.rb', line 252

def drag_down_by(amount)
  drag_by(amount, direction: :bottom)
end

#drag_left_by(amount) ⇒ Object



256
257
258
# File 'lib/testa_appium_driver/common/locator/scroll_actions.rb', line 256

def drag_left_by(amount)
  drag_by(amount, direction: :left)
end

#drag_right_by(amount) ⇒ Object



260
261
262
# File 'lib/testa_appium_driver/common/locator/scroll_actions.rb', line 260

def drag_right_by(amount)
  drag_by(amount, direction: :right)
end

#drag_to(to) ⇒ Object

noinspection RubyYardParamTypeMatch,RubyScope

Parameters:



266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
# File 'lib/testa_appium_driver/common/locator/scroll_actions.rb', line 266

def drag_to(to)
  if !to.kind_of?(::Selenium::WebDriver::Element) && !to.kind_of?(::Appium::Core::Element) && !to.kind_of?(TestaAppiumDriver::Locator) && !to.kind_of?(Hash)
    raise "Parameter not accepted, acceptable instances of [TestaAppiumDriver::Locator, Hash, Selenium::WebDriver::Element]"
  end

  if to.kind_of?(::Selenium::WebDriver::Element) || to.kind_of?(::Appium::Core::Element)
    if @driver.device == :android
      bounds = TestaAppiumDriver::Bounds.from_android(to.bounds, @driver)
    else
      bounds = TestaAppiumDriver::Bounds.from_ios(to.bounds, @driver)
    end

    x = bounds.center.x
    y = bounds.center.y
  end
  if to.kind_of?(TestaAppiumDriver::Locator)
    bounds = to.bounds
    x = bounds.center.x
    y = bounds.center.y
  end
  if to.kind_of?(Hash)
    raise "Missing x coordinate" if to[:x].nil?
    raise "Missing y coordinate" if to[:y].nil?

    x = to[:x]
    y = to[:y]
  end
  _drag_to(bounds.center.x, bounds.center.y, x, y)
end

#drag_up_by(amount) ⇒ Object



248
249
250
# File 'lib/testa_appium_driver/common/locator/scroll_actions.rb', line 248

def drag_up_by(amount)
  drag_by(amount, direction: :top)
end

#execute(skip_cache: false, force_cache_element: nil, ignore_implicit_wait: false) ⇒ Selenium::WebDriver::Element, Array

Parameters:

  • skip_cache (Boolean) (defaults to: false)

    if true it will skip cache check and store

  • force_cache_element, (Selenium::WebDriver::Element)

    for internal use where we have already the element, and want to execute custom locator methods on it

Returns:

  • (Selenium::WebDriver::Element, Array)


107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/testa_appium_driver/common/locator.rb', line 107

def execute(skip_cache: false, force_cache_element: nil, ignore_implicit_wait: false)
  return force_cache_element unless force_cache_element.nil?

  # if we are looking for current element, then return from_element
  # for example when we have driver.element.elements[1].click
  # elements[2] will be resolved with xpath because we are looking for multiple elements from element
  # and since we are looking for instance 2, [](instance) method will return new "empty locator"
  # we are executing click on that "empty locator" so we have to return the instance 2 of elements for the click
  if @xpath_selector == ".//*[1]" && !@from_element.nil? && @image_selector.nil?
    if @from_element.instance_of?(::Selenium::WebDriver::Element) ||
      @from_element.instance_of?(::Appium::Core::Element)
      return @from_element
    end

    if @from_element.instance_of?(TestaAppiumDriver::Locator)
      return @from_element.execute(
        skip_cache: skip_cache,
        force_cache_element: force_cache_element,
        ignore_implicit_wait: ignore_implicit_wait
      )
    end

    return @from_element
  end

  r = @driver.execute(@from_element, @single, strategies_and_selectors,
                      skip_cache: skip_cache,
                      ignore_implicit_wait: ignore_implicit_wait)
  r = r[@index_for_multiple] if !@index_for_multiple.nil? && !@single
  r
end

#exists?boolean

all timeouts are disabled before check, and enabled after check

Returns:

  • (boolean)


184
185
186
187
188
189
190
191
192
193
194
195
196
# File 'lib/testa_appium_driver/common/locator.rb', line 184

def exists?
  # TODO: should be called visible? or present?
  found = true
  begin
    r = execute(skip_cache: true, ignore_implicit_wait: true)
    return r.count.positive? if r.is_a?(Array)
    # ios17 has phantom child elements that overlap parent so this returns false positive
    # return r.displayed? if @driver.ios?
  rescue StandardError
    found = false
  end
  found
end

#firstTestaAppiumDriver::Locator



220
221
222
# File 'lib/testa_appium_driver/common/locator.rb', line 220

def first
  self[0]
end

#first_and_last_childObject



325
326
327
# File 'lib/testa_appium_driver/common/locator.rb', line 325

def first_and_last_child
  @driver.first_and_last_child(execute)
end

#first_and_last_leafObject



321
322
323
# File 'lib/testa_appium_driver/common/locator.rb', line 321

def first_and_last_leaf
  @driver.first_and_last_leaf(execute)
end

#fling_down(top: nil, bottom: nil, right: nil, left: nil) ⇒ TestaAppiumDriver::Locator



229
230
231
# File 'lib/testa_appium_driver/common/locator/scroll_actions.rb', line 229

def fling_down(top: nil, bottom: nil, right: nil, left: nil)
  _fling(:down, _process_deadzone(top, bottom, right, left))
end

#fling_left(top: nil, bottom: nil, right: nil, left: nil) ⇒ TestaAppiumDriver::Locator



239
240
241
# File 'lib/testa_appium_driver/common/locator/scroll_actions.rb', line 239

def fling_left(top: nil, bottom: nil, right: nil, left: nil)
  _fling(:left, _process_deadzone(top, bottom, right, left))
end

#fling_right(top: nil, bottom: nil, right: nil, left: nil) ⇒ TestaAppiumDriver::Locator



244
245
246
# File 'lib/testa_appium_driver/common/locator/scroll_actions.rb', line 244

def fling_right(top: nil, bottom: nil, right: nil, left: nil)
  _fling(:right, _process_deadzone(top, bottom, right, left))
end

#fling_up(top: nil, bottom: nil, right: nil, left: nil) ⇒ TestaAppiumDriver::Locator



234
235
236
# File 'lib/testa_appium_driver/common/locator/scroll_actions.rb', line 234

def fling_up(top: nil, bottom: nil, right: nil, left: nil)
  _fling(:up, _process_deadzone(top, bottom, right, left))
end

#following_siblingTestaAppiumDriver::Locator



519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
# File 'lib/testa_appium_driver/common/locator.rb', line 519

def following_sibling
  raise "Cannot add following_sibling selector to array" unless @single
  raise StrategyMixException.new(@strategy, @strategy_reason, FIND_STRATEGY_XPATH, "following_sibling") if @strategy != FIND_STRATEGY_XPATH && !@strategy.nil?
  raise "Cannot add following_sibling selector to a retrieved instance of a class array" if (@xpath_selector == ".//*" || @xpath_selector == ".//*[1]") && !@from_element.nil?
  locator = self.dup
  locator.strategy = FIND_STRATEGY_XPATH
  locator.strategy_reason = "following_sibling"
  i = index.to_i
  locator.single = true

  # in ios, the index can be false (0 when casted to_i), but inspector shows index as 0
  # return nil if i.zero?

  locator.xpath_selector += "/../*[@index=\"#{i + 1}\"]"
  locator.last_selector_adjacent = true
  locator.can_use_id_strategy = false
  locator
end

#following_siblingsTestaAppiumDriver::Locator



502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
# File 'lib/testa_appium_driver/common/locator.rb', line 502

def following_siblings
  raise "Cannot add following_siblings selector to array" unless @single
  raise StrategyMixException.new(@strategy, @strategy_reason, FIND_STRATEGY_XPATH, "following_siblings") if @strategy != FIND_STRATEGY_XPATH && !@strategy.nil?
  raise "Cannot add following_siblings selector to a retrieved instance of a class array" if (@xpath_selector == ".//*" || @xpath_selector == ".//*[1]") && !@from_element.nil?

  locator = self.dup
  locator.strategy = FIND_STRATEGY_XPATH
  locator.strategy_reason = "following_siblings"
  i = index.to_i
  locator.xpath_selector += "/../*[position() > #{i + 1}]" # position() starts from 1
  locator.single = false
  locator.last_selector_adjacent = true
  locator.can_use_id_strategy = false
  locator
end

#from_parent(selectors = {}) ⇒ TestaAppiumDriver::Locator



73
74
75
76
77
78
79
80
81
82
83
# File 'lib/testa_appium_driver/android/locator.rb', line 73

def from_parent(selectors = {})
  raise "Cannot add from_parent selector to array" unless @single
  raise StrategyMixException.new(@strategy, @strategy_reason, FIND_STRATEGY_UIAUTOMATOR, "from_parent") if @strategy != FIND_STRATEGY_UIAUTOMATOR

  locator = self.dup
  locator.strategy = FIND_STRATEGY_UIAUTOMATOR
  locator.strategy_reason = "from_parent"
  locator.closing_parenthesis += 1
  locator.ui_selector = "#{locator.ui_selector}.fromParent(#{hash_to_uiautomator(selectors)}"
  locator
end

#in_viewport?Boolean

Returns:

  • (Boolean)


198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
# File 'lib/testa_appium_driver/common/locator.rb', line 198

def in_viewport?
  ws = @driver.window_size
  viewport_height = ws.height
  viewport_width = ws.width

  check = proc do |b|
    !(b.bottom_right.y.negative? || b.top_left.y > viewport_height ||
      b.top_left.x.negative? || b.bottom_right.x > viewport_width)
  end

  begin
    r = execute(skip_cache: true, ignore_implicit_wait: true)
    r = [r] unless r.is_a?(Array)
    return false if r.count.zero?

    r.all? { |e| check.call(e.bounds) }
  rescue StandardError
    return false
  end
end

#index(*args) ⇒ Integer?

element index in parent element, starts from 0 noinspection RubyNilAnalysis,RubyYardReturnMatch

Returns:

  • (Integer, nil)

    index of element



112
113
114
115
116
117
118
119
# File 'lib/testa_appium_driver/android/locator/attributes.rb', line 112

def index(*args)
  raise "Index not supported for uiautomator strategy" if @strategy == FIND_STRATEGY_UIAUTOMATOR
  this = execute(*args)
  children = self.dup.parent.children.execute
  index = children.index(this)
  raise "Index not found" if index.nil?
  index.to_i
end

#init(params, selectors, single) ⇒ Object



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/testa_appium_driver/ios/locator.rb', line 9

def init(params, selectors, single)
  if is_scrollable_selector?(selectors, single)
    @scroll_orientation = :vertical

    if !params[:top].nil? || !params[:bottom].nil? || !params[:right].nil? || !params[:left].nil?
      @scroll_deadzone = {}
      @scroll_deadzone[:top] = params[:top].to_f unless params[:top].nil?
      @scroll_deadzone[:bottom] = params[:bottom].to_f unless params[:bottom].nil?
      @scroll_deadzone[:right] = params[:right].to_f unless params[:right].nil?
      @scroll_deadzone[:left] = params[:left].to_f unless params[:left].nil?
    end

    params[:scrollable_locator] = self.dup
  end

  @class_chain_selector = hash_to_class_chain(selectors, single)


  @scrollable_locator = params[:scrollable_locator] if params[:scrollable_locator]
end

#is_only_id_selector?(selectors) ⇒ Boolean

Returns:

  • (Boolean)


74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/testa_appium_driver/common/locator.rb', line 74

def is_only_id_selector?(selectors)
  # since, name and id is the same thing for iOS,
  if @driver.device == :android
    selectors.keys.count == 1 && !selectors[:id].nil? && !selectors[:id].is_a?(Regexp)
  else
    selector = nil
    if selectors.keys.count == 2
      if !selectors[:id].nil? && !selectors[:id].nil? && selectors[:id] == selectors[:name]
        selector = selectors[:id]
      else
        selector = nil
      end
    elsif selectors.keys.count == 1
      selector = selectors[:id] unless selectors[:id].nil?
      selector = selectors[:name] unless selectors[:name].nil?
    end

    return false if selector.nil?

    !selector.is_a?(Regexp)
  end
end

#lastTestaAppiumDriver::Locator



235
236
237
# File 'lib/testa_appium_driver/common/locator.rb', line 235

def last
  self[-1]
end

#long_tap(duration = LONG_TAP_DURATION) ⇒ Object

performs a long tap on the retrieved element

Parameters:

  • duration (Float) (defaults to: LONG_TAP_DURATION)

    in seconds



6
7
8
9
10
11
12
13
14
15
16
# File 'lib/testa_appium_driver/common/locator/scroll_actions.rb', line 6

def long_tap(duration = LONG_TAP_DURATION)
  action_builder = @driver.action
  b = bounds
  f1 = action_builder.add_pointer_input(:touch, "finger1")
  f1.create_pointer_move(duration: 0, x: b.center.x, y: b.center.y, origin: ::Selenium::WebDriver::Interactions::PointerMove::VIEWPORT)
  f1.create_pointer_down(:left)
  f1.create_pause(duration)
  f1.create_pointer_up(:left)
  puts "long tap execute:  {x: #{b.center.x}, y: #{b.center.y}}"
  @driver.perform_actions [f1]
end

#page_down(top: nil, bottom: nil, right: nil, left: nil) ⇒ TestaAppiumDriver::Locator



209
210
211
# File 'lib/testa_appium_driver/common/locator/scroll_actions.rb', line 209

def page_down(top: nil, bottom: nil, right: nil, left: nil)
  _page(:down, _process_deadzone(top, bottom, right, left))
end

#page_left(top: nil, bottom: nil, right: nil, left: nil) ⇒ TestaAppiumDriver::Locator



219
220
221
# File 'lib/testa_appium_driver/common/locator/scroll_actions.rb', line 219

def page_left(top: nil, bottom: nil, right: nil, left: nil)
  _page(:left, _process_deadzone(top, bottom, right, left))
end

#page_right(top: nil, bottom: nil, right: nil, left: nil) ⇒ TestaAppiumDriver::Locator



224
225
226
# File 'lib/testa_appium_driver/common/locator/scroll_actions.rb', line 224

def page_right(top: nil, bottom: nil, right: nil, left: nil)
  _page(:right, _process_deadzone(top, bottom, right, left))
end

#page_up(top: nil, bottom: nil, right: nil, left: nil) ⇒ TestaAppiumDriver::Locator



214
215
216
# File 'lib/testa_appium_driver/common/locator/scroll_actions.rb', line 214

def page_up(top: nil, bottom: nil, right: nil, left: nil)
  _page(:up, _process_deadzone(top, bottom, right, left))
end

#parentTestaAppiumDriver::Locator

Return parent element



396
397
398
399
400
401
402
403
404
405
406
# File 'lib/testa_appium_driver/common/locator.rb', line 396

def parent
  raise StrategyMixException.new(@strategy, @strategy_reason, FIND_STRATEGY_XPATH, "parent") if @strategy != FIND_STRATEGY_XPATH && !@strategy.nil?
  raise "Cannot add parent selector to a retrieved instance of a class array" if (@xpath_selector == ".//*" || @xpath_selector == ".//*[1]") && !@from_element.nil?

  locator = self.dup
  locator.strategy = FIND_STRATEGY_XPATH
  locator.strategy_reason = "parent"
  locator.xpath_selector += "/.."
  locator.can_use_id_strategy = false
  locator
end

#preceding_siblingTestaAppiumDriver::Locator



483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
# File 'lib/testa_appium_driver/common/locator.rb', line 483

def preceding_sibling
  raise "Cannot add preceding_sibling selector to array" unless @single
  raise StrategyMixException.new(@strategy, @strategy_reason, FIND_STRATEGY_XPATH, "preceding_sibling") if @strategy != FIND_STRATEGY_XPATH && !@strategy.nil?
  raise "Cannot add preceding siblings selector to a retrieved instance of a class array" if (@xpath_selector == ".//*" || @xpath_selector == ".//*[1]") && !@from_element.nil?

  locator = self.dup
  locator.strategy = FIND_STRATEGY_XPATH
  locator.strategy_reason = "preceding_sibling"
  i = index
  locator.single = true
  return nil if i.zero?

  locator.xpath_selector += "/../*[@index=\"#{i - 1}\"]"
  locator.last_selector_adjacent = true
  locator.can_use_id_strategy = false
  locator
end

#preceding_siblingsTestaAppiumDriver::Locator



467
468
469
470
471
472
473
474
475
476
477
478
479
480
# File 'lib/testa_appium_driver/common/locator.rb', line 467

def preceding_siblings
  raise "Cannot add preceding_siblings selector to array" unless @single
  raise StrategyMixException.new(@strategy, @strategy_reason, FIND_STRATEGY_XPATH, "preceding_siblings") if @strategy != FIND_STRATEGY_XPATH && !@strategy.nil?
  raise "Cannot add preceding_siblings selector to a retrieved instance of a class array" if (@xpath_selector == ".//*" || @xpath_selector == ".//*[1]") && !@from_element.nil?

  locator = self.dup
  locator.strategy = FIND_STRATEGY_XPATH
  locator.strategy_reason = "preceding_siblings"
  locator.xpath_selector += "/../*[position() < #{index + 1}]" # position() starts from 1
  locator.single = false
  locator.last_selector_adjacent = true
  locator.can_use_id_strategy = false
  locator
end

#scroll_down_to(top: nil, bottom: nil, right: nil, left: nil, max_scrolls: nil) ⇒ TestaAppiumDriver::Locator

Scrolls down until element is found or end is reached



174
175
176
# File 'lib/testa_appium_driver/common/locator/scroll_actions.rb', line 174

def scroll_down_to(top: nil, bottom: nil, right: nil, left: nil, max_scrolls: nil)
  _scroll_dir_to(_process_deadzone(top, bottom, right, left), max_scrolls, :down)
end

#scroll_each(top: nil, bottom: nil, right: nil, left: nil, direction: nil, &block) ⇒ Array<Selenium::WebDriver::Element>

scrolls to the start of the scrollable containers and scrolls to the end, everytime a locator element is found the given block is executed

Returns:

  • (Array<Selenium::WebDriver::Element>)


21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/testa_appium_driver/common/locator/scroll_actions.rb', line 21

def scroll_each(top: nil, bottom: nil, right: nil, left: nil, direction: nil, &block)
  deadzone = _process_deadzone(top, bottom, right, left)
  raise "Each can only be performed on multiple elements locator" if @single

  deadzone = @scrollable_locator.scroll_deadzone if deadzone.nil? && !@scrollable_locator.nil?
  sa = ScrollActions.new(@scrollable_locator,
                         locator: self,
                         deadzone: deadzone,
                         default_scroll_strategy: @default_scroll_strategy)
  if direction.nil?
    sa.scroll_each(&block)
  else
    sa.send("scroll_each_#{direction}", &block)
  end
end

#scroll_each_down(top: nil, bottom: nil, right: nil, left: nil, &block) ⇒ Array<Selenium::WebDriver::Element>

scrolls down from the current page view (without prior scrolling to the top) and everytime a locator element is found the given block is executed

Returns:

  • (Array<Selenium::WebDriver::Element>)


40
41
42
# File 'lib/testa_appium_driver/common/locator/scroll_actions.rb', line 40

def scroll_each_down(top: nil, bottom: nil, right: nil, left: nil, &block)
  scroll_each(top: top, bottom: bottom, right: right, left: left, direction: :down, &block)
end

#scroll_each_left(top: nil, bottom: nil, right: nil, left: nil, &block) ⇒ Array<Selenium::WebDriver::Element>

scrolls left from the current page view (without prior scrolling to the right) and everytime a locator element is found the given block is executed

Returns:

  • (Array<Selenium::WebDriver::Element>)


61
62
63
# File 'lib/testa_appium_driver/common/locator/scroll_actions.rb', line 61

def scroll_each_left(top: nil, bottom: nil, right: nil, left: nil, &block)
  scroll_each(top: top, bottom: bottom, right: right, left: left, direction: :left, &block)
end

#scroll_each_right(top: nil, bottom: nil, right: nil, left: nil, &block) ⇒ Array<Selenium::WebDriver::Element>

scrolls right from the current page view (without prior scrolling to the left) and everytime a locator element is found the given block is executed

Returns:

  • (Array<Selenium::WebDriver::Element>)


54
55
56
# File 'lib/testa_appium_driver/common/locator/scroll_actions.rb', line 54

def scroll_each_right(top: nil, bottom: nil, right: nil, left: nil, &block)
  scroll_each(top: top, bottom: bottom, right: right, left: left, direction: :right, &block)
end

#scroll_each_up(top: nil, bottom: nil, right: nil, left: nil, &block) ⇒ Array<Selenium::WebDriver::Element>

scrolls up from the current page view (without prior scrolling to the bottom) and everytime a locator element is found the given block is executed

Returns:

  • (Array<Selenium::WebDriver::Element>)


47
48
49
# File 'lib/testa_appium_driver/common/locator/scroll_actions.rb', line 47

def scroll_each_up(top: nil, bottom: nil, right: nil, left: nil, &block)
  scroll_each(top: top, bottom: bottom, right: right, left: left, direction: :up, &block)
end

#scroll_left_to(top: nil, bottom: nil, right: nil, left: nil, max_scrolls: nil) ⇒ TestaAppiumDriver::Locator

Scrolls left until element is found or end is reached



192
193
194
# File 'lib/testa_appium_driver/common/locator/scroll_actions.rb', line 192

def scroll_left_to(top: nil, bottom: nil, right: nil, left: nil, max_scrolls: nil)
  _scroll_dir_to(_process_deadzone(top, bottom, right, left), max_scrolls, :left)
end

#scroll_right_to(top: nil, bottom: nil, right: nil, left: nil, max_scrolls: nil) ⇒ TestaAppiumDriver::Locator

Scrolls right until element is found or end is reached



186
187
188
# File 'lib/testa_appium_driver/common/locator/scroll_actions.rb', line 186

def scroll_right_to(top: nil, bottom: nil, right: nil, left: nil, max_scrolls: nil)
  _scroll_dir_to(_process_deadzone(top, bottom, right, left), max_scrolls, :right)
end

#scroll_to(top: nil, bottom: nil, right: nil, left: nil, max_scrolls: nil, direction: nil) ⇒ TestaAppiumDriver::Locator

First scrolls to the beginning of the scrollable container and then scrolls down until element is found or end is reached



164
165
166
167
168
169
170
# File 'lib/testa_appium_driver/common/locator/scroll_actions.rb', line 164

def scroll_to(top: nil, bottom: nil, right: nil, left: nil, max_scrolls: nil, direction: nil)
  if direction
    _scroll_dir_to(_process_deadzone(top, bottom, right, left), max_scrolls, direction)
  else
    _scroll_to(_process_deadzone(top, bottom, right, left), max_scrolls)
  end
end

#scroll_to_end(top: nil, bottom: nil, right: nil, left: nil) ⇒ TestaAppiumDriver::Locator

Scrolls to the end of the scrollable container (bottom on vertical container, right on horizontal)



204
205
206
# File 'lib/testa_appium_driver/common/locator/scroll_actions.rb', line 204

def scroll_to_end(top: nil, bottom: nil, right: nil, left: nil)
  _scroll_to_start_or_end(:end, _process_deadzone(top, bottom, right, left))
end

#scroll_to_start(top: nil, bottom: nil, right: nil, left: nil) ⇒ TestaAppiumDriver::Locator

Scrolls to the start of the scrollable container (top on vertical container, left on horizontal)



198
199
200
# File 'lib/testa_appium_driver/common/locator/scroll_actions.rb', line 198

def scroll_to_start(top: nil, bottom: nil, right: nil, left: nil)
  _scroll_to_start_or_end(:start, _process_deadzone(top, bottom, right, left))
end

#scroll_up_to(top: nil, bottom: nil, right: nil, left: nil, max_scrolls: nil) ⇒ TestaAppiumDriver::Locator

Scrolls up until element is found or end is reached



180
181
182
# File 'lib/testa_appium_driver/common/locator/scroll_actions.rb', line 180

def scroll_up_to(top: nil, bottom: nil, right: nil, left: nil, max_scrolls: nil)
  _scroll_dir_to(_process_deadzone(top, bottom, right, left), max_scrolls, :up)
end

#secondTestaAppiumDriver::Locator



225
226
227
# File 'lib/testa_appium_driver/common/locator.rb', line 225

def second
  self[1]
end

#send_key(*args) ⇒ Object



386
387
388
# File 'lib/testa_appium_driver/common/locator.rb', line 386

def send_key(*args)
  perform_driver_method(:send_keys, *args)
end

#siblingsTestaAppiumDriver::Locator



451
452
453
454
455
456
457
458
459
460
461
462
463
464
# File 'lib/testa_appium_driver/common/locator.rb', line 451

def siblings
  raise "Cannot add siblings selector to array" unless @single
  raise StrategyMixException.new(@strategy, @strategy_reason, FIND_STRATEGY_XPATH, "siblings") if @strategy != FIND_STRATEGY_XPATH && !@strategy.nil?
  raise "Cannot add siblings selector to a retrieved instance of a class array" if (@xpath_selector == ".//*" || @xpath_selector == ".//*[1]") && !@from_element.nil?

  locator = self.dup
  locator.strategy = FIND_STRATEGY_XPATH
  locator.strategy_reason = "siblings"
  locator.xpath_selector += "/../*[not(@index=\"#{index}\")]"
  locator.single = false
  locator.last_selector_adjacent = true
  locator.can_use_id_strategy = false
  locator
end

#strategies_and_selectorsObject

resolve selector which will be used for finding element



32
33
34
35
36
37
38
39
40
41
# File 'lib/testa_appium_driver/ios/locator.rb', line 32

def strategies_and_selectors
  ss = []
  if @can_use_id_strategy
    ss.push({"#{FIND_STRATEGY_NAME}": @can_use_id_strategy})
  end
  ss.push({"#{FIND_STRATEGY_CLASS_CHAIN}": @class_chain_selector}) if @strategy.nil? || @strategy == FIND_STRATEGY_CLASS_CHAIN
  ss.push({"#{FIND_STRATEGY_XPATH}": @xpath_selector}) if @strategy.nil? || @strategy == FIND_STRATEGY_XPATH
  ss.push({"#{FIND_STRATEGY_IMAGE}": @image_selector}) if @strategy == FIND_STRATEGY_IMAGE
  ss
end

#thirdTestaAppiumDriver::Locator



230
231
232
# File 'lib/testa_appium_driver/common/locator.rb', line 230

def third
  self[2]
end

#to_aryObject



303
304
305
# File 'lib/testa_appium_driver/common/locator.rb', line 303

def to_ary
  [self.to_s]
end

#to_sObject



299
300
301
# File 'lib/testa_appium_driver/common/locator.rb', line 299

def to_s
  JSON.dump(as_json)
end

#ui_selector(include_semicolon = true) ⇒ Object

Returns ui_selector for uiautomator find strategy.

Parameters:

  • include_semicolon (Boolean) (defaults to: true)

    should the semicolon be included at the end

Returns:

  • ui_selector for uiautomator find strategy



61
62
63
# File 'lib/testa_appium_driver/android/locator.rb', line 61

def ui_selector(include_semicolon = true)
  @ui_selector + ")" * @closing_parenthesis + (include_semicolon ? ";" : "");
end

#ui_selector=(value) ⇒ Object



65
66
67
# File 'lib/testa_appium_driver/android/locator.rb', line 65

def ui_selector=(value)
  @ui_selector = value
end

#wait_until(timeout = nil, args = {}) ⇒ Object



177
178
179
180
# File 'lib/testa_appium_driver/common/locator.rb', line 177

def wait_until(timeout = nil, args = {})
  args[:timeout] = timeout
  _wait(:until, args)
end

#wait_until_exists(timeout = nil) ⇒ TestaAppiumDriver::Locator

Parameters:

  • timeout (Integer) (defaults to: nil)

    in seconds

Returns:



160
161
162
163
# File 'lib/testa_appium_driver/common/locator.rb', line 160

def wait_until_exists(timeout = nil)
  args = { timeout: timeout }
  _wait(:until, args)
end

#wait_while(timeout = nil, args = {}) ⇒ Object



172
173
174
175
# File 'lib/testa_appium_driver/common/locator.rb', line 172

def wait_while(timeout = nil, args = {})
  args[:timeout] = timeout
  _wait(:while, args)
end

#wait_while_exists(timeout = nil) ⇒ TestaAppiumDriver::Locator

Parameters:

  • timeout (Integer) (defaults to: nil)

    in seconds

Returns:



167
168
169
170
# File 'lib/testa_appium_driver/common/locator.rb', line 167

def wait_while_exists(timeout = nil)
  args = { timeout: timeout }
  _wait(:while, args)
end

#when_exists(timeout = nil, &block) ⇒ Object



139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
# File 'lib/testa_appium_driver/common/locator.rb', line 139

def when_exists(timeout = nil, &block)
  found = false
  begin
    wait_until_exists(timeout)
    found = true
  rescue StandardError
    # ignored
  end
  if found
    if block_given? # block is given
      block.call(self) # use call to execute the block
    else
      # the value of block_argument becomes nil if you didn't give a block
      # block was not given
    end
  end
  self
end