testa_appium_driver 0.1.6 → 0.1.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: eb79ce18b9e98f651e83630eff7efe2d71d77031231f88c04521e7d4f1baf483
4
- data.tar.gz: 94d1b8a88844c8726b1b87cd500ca07842b7b92190df7ef223f2cac4f929c9d9
3
+ metadata.gz: 2dadb5244c71161bcdf995e9b057951ee4a5e979be496e65e828f7188baa85dc
4
+ data.tar.gz: bd5d23887285a260d5231525ad09d42f33219ac655432a74ba044b9b57805647
5
5
  SHA512:
6
- metadata.gz: 9c2abf9c966c5e8d192c52e48226fcf0d73994315b3d865e48ce03f41aced48f3785dcaf7d46fd26b6e21fa51e0035cae6b00e416fffde3ae1ab0a5cf703b982
7
- data.tar.gz: e7e087b4b4227eb4d355df738f53d4ea72903b80fe51d3408c8c7ec6ac855a2066f40882dbae55de3418a1827895bcbefa14aa9b3322d767e22cd94393c1a67c
6
+ metadata.gz: 463e52be3a9a6764bbcbc068a46cb0cdc5f6ff41e0651cd95b9bc26da6b2210ba8c90f6651e8f6a153b76b0d173905a8d4a3a3d8b68055ea1e07653af3f4ecf1
7
+ data.tar.gz: 7b6ba6de823bbfcc993e712fe11f846cabd3e263b63a23ebfab5bc08c980eeee2c27c9ed0b85690505ed1441e137b3495661a65ecec81db1c6bd8d3755de6638
data/.gitignore CHANGED
@@ -13,4 +13,4 @@
13
13
  /.idea/deployment.xml
14
14
  /.idea/workspace.xml
15
15
  /.idea/misc.xml
16
- Gemfile.lock
16
+ Gemfile.lock
data/.idea/deployment.xml CHANGED
@@ -1,6 +1,6 @@
1
1
  <?xml version="1.0" encoding="UTF-8"?>
2
2
  <project version="4">
3
- <component name="PublishConfigData" autoUpload="On explicit save action" serverName="supertesta.com" autoUploadExternalChanges="true">
3
+ <component name="PublishConfigData" autoUpload="On explicit save action" serverName="supertesta.com" preserveTimestamps="false" autoUploadExternalChanges="true">
4
4
  <serverData>
5
5
  <paths name="supertesta.com">
6
6
  <serverdata>
@@ -0,0 +1,10 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="RunConfigurationProducerService">
4
+ <option name="ignoredProducers">
5
+ <set>
6
+ <option value="com.android.tools.idea.compose.preview.runconfiguration.ComposePreviewRunConfigurationProducer" />
7
+ </set>
8
+ </option>
9
+ </component>
10
+ </project>
data/README.md CHANGED
@@ -202,12 +202,18 @@ siblings selector can only be used with xpath strategy.
202
202
  - search_views
203
203
  - spinner
204
204
  - spinners
205
+ - switch
206
+ - switches
205
207
  - toast
206
208
  - toasts
207
209
  - toolbar
208
210
  - toolbars
209
211
  - text_view
210
212
  - text_views
213
+ - web_view
214
+ - web_views
215
+ - card_view
216
+ - card_views
211
217
 
212
218
  Adjacent selectors
213
219
  - from_parent
@@ -323,11 +329,15 @@ Type Selector arguments
323
329
 
324
330
  # Scroll actions
325
331
  - each
326
- - align!
327
- - align_top!
328
- - align_bottom!
329
- - align_left!
330
- - align_right!
332
+ - each_down
333
+ - each_up
334
+ - each_left
335
+ - each_right
336
+ - align! (if does not exist, will scroll to find)
337
+ - align_top! (if does not exist, will scroll to find)
338
+ - align_bottom! (if does not exist, will scroll to find)
339
+ - align_left! (if does not exist, will scroll to find)
340
+ - align_right! (if does not exist, will scroll to find)
331
341
  - align
332
342
  - align_top
333
343
  - align_bottom
@@ -355,6 +365,9 @@ Type Selector arguments
355
365
  - as_scrollable
356
366
  - wait_until_exists
357
367
  - wait_while_exists
368
+ - wait_until
369
+ - wait_while
370
+ - when_exists
358
371
  - exists?
359
372
  - long_tap
360
373
 
@@ -24,6 +24,9 @@ module TestaAppiumDriver
24
24
  # @param selectors [Hash]
25
25
  # @return [TestaAppiumDriver::Locator] first element
26
26
  def element(selectors = {})
27
+ unless selectors[:image].nil?
28
+ selectors[:strategy] = FIND_STRATEGY_IMAGE
29
+ end
27
30
  add_selector(selectors)
28
31
  end
29
32
 
@@ -31,24 +34,9 @@ module TestaAppiumDriver
31
34
  # @param params [Hash]
32
35
  # @return [TestaAppiumDriver::Locator] all elements that match given selectors
33
36
  def elements(params = {})
34
- params[:single] = false
35
- add_selector(params)
36
- end
37
-
38
-
39
- # first element that has scrollable: true
40
- # @param selectors [Hash]
41
- # @return [TestaAppiumDriver::Locator] first scrollable element
42
- def scrollable(selectors = {})
43
- selectors[:scrollable] = true
44
- add_selector(selectors)
45
- end
46
-
47
- # all elements that have scrollable: true
48
- # @param params [Hash]
49
- # @return [TestaAppiumDriver::Locator] first scrollable element
50
- def scrollables(params = {})
51
- params[:scrollable] = true
37
+ unless params[:image].nil?
38
+ params[:strategy] = FIND_STRATEGY_IMAGE
39
+ end
52
40
  params[:single] = false
53
41
  add_selector(params)
54
42
  end
@@ -399,5 +387,52 @@ module TestaAppiumDriver
399
387
  add_selector(params)
400
388
  end
401
389
 
390
+
391
+ # first androidx.cardview.widget.CardView element that match given selectors
392
+ # @return [TestaAppiumDriver::Locator]
393
+ def card_view(params = {})
394
+ params[:class] = "androidx.cardview.widget.CardView"
395
+ add_selector(params)
396
+ end
397
+
398
+ # all androidx.cardview.widget.CardView elements that match given selectors
399
+ # @return [TestaAppiumDriver::Locator]
400
+ def card_views(params = {})
401
+ params[:class] = "androidx.cardview.widget.CardView"
402
+ params[:single] = false
403
+ add_selector(params)
404
+ end
405
+
406
+ # first android.widget.Switch element that match given selectors
407
+ # @return [TestaAppiumDriver::Locator]
408
+ def switch(params = {})
409
+ params[:class] = "android.widget.Switch"
410
+ add_selector(params)
411
+ end
412
+
413
+ # all android.widget.Switch elements that match given selectors
414
+ # @return [TestaAppiumDriver::Locator]
415
+ def switches(params = {})
416
+ params[:class] = "android.widget.Switch"
417
+ params[:single] = false
418
+ add_selector(params)
419
+ end
420
+
421
+
422
+ # first android.webkit.WebView element that match given selectors
423
+ # @return [TestaAppiumDriver::Locator]
424
+ def web_view(params = {})
425
+ params[:class] = "android.webkit.WebView"
426
+ add_selector(params)
427
+ end
428
+
429
+ # all android.webkit.WebView elements that match given selectors
430
+ # @return [TestaAppiumDriver::Locator]
431
+ def web_views(params = {})
432
+ params[:class] = "android.webkit.WebView"
433
+ params[:single] = false
434
+ add_selector(params)
435
+ end
436
+
402
437
  end
403
438
  end
@@ -24,6 +24,23 @@ module TestaAppiumDriver
24
24
  end
25
25
 
26
26
 
27
+ def scrollable
28
+ locator = Locator.new(self, self, {single: true})
29
+ locator.xpath_selector = "//androidx.recyclerview.widget.RecyclerView|//android.widget.ScrollView|//android.widget.ListView|//android.widget.HorizontalScrollView"
30
+ locator.ui_selector = "new UiSelector().scrollable(true).instance(0)"
31
+ locator
32
+ end
33
+
34
+
35
+ def scrollables
36
+ locator = Locator.new(self, self, {single: false})
37
+ locator.xpath_selector = "//androidx.recyclerview.widget.RecyclerView|//android.widget.ScrollView|//android.widget.ListView|//android.widget.HorizontalScrollView"
38
+ locator.ui_selector = "new UiSelector().scrollable(true)"
39
+ locator
40
+ end
41
+
42
+
43
+
27
44
  private
28
45
  def handle_testa_opts
29
46
  if @testa_opts[:default_find_strategy].nil?
@@ -48,6 +48,10 @@ module TestaAppiumDriver
48
48
  if @strategy.nil? || @strategy == FIND_STRATEGY_XPATH
49
49
  ss.push({"#{FIND_STRATEGY_XPATH}": @xpath_selector})
50
50
  end
51
+
52
+ if @strategy == FIND_STRATEGY_IMAGE
53
+ ss.push({"#{FIND_STRATEGY_IMAGE}": @image_selector})
54
+ end
51
55
  ss
52
56
  end
53
57
 
@@ -93,6 +97,8 @@ module TestaAppiumDriver
93
97
  add_xpath_child_selectors(locator, selectors, single)
94
98
  elsif @strategy == FIND_STRATEGY_UIAUTOMATOR
95
99
  locator = add_uiautomator_child_selector(locator, selectors, single)
100
+ elsif @strategy == FIND_STRATEGY_IMAGE
101
+ locator = add_image_child_selector(locator, selectors, single)
96
102
  else
97
103
  # both paths are valid
98
104
  add_xpath_child_selectors(locator, selectors, single)
@@ -127,5 +133,10 @@ module TestaAppiumDriver
127
133
  locator
128
134
  end
129
135
  end
136
+
137
+ def add_image_child_selector(locator, selectors, single)
138
+ params = selectors.merge({single: single, scrollable_locator: locator.scrollable_locator})
139
+ Locator.new(@driver, self, params)
140
+ end
130
141
  end
131
142
  end
@@ -4,8 +4,6 @@ module TestaAppiumDriver
4
4
  private
5
5
 
6
6
  def uiautomator_scroll_to_start_or_end(type)
7
- @driver.disable_wait_for_idle
8
- @driver.disable_implicit_wait
9
7
 
10
8
  scrollable_selector = @scrollable.ui_selector(false)
11
9
  orientation = @scrollable.scroll_orientation == :vertical ? ".setAsVerticalList()" : ".setAsHorizontalList()"
@@ -19,18 +17,12 @@ module TestaAppiumDriver
19
17
  end
20
18
 
21
19
 
22
- @driver.enable_implicit_wait
23
- @driver.enable_wait_for_idle
24
20
  end
25
21
 
26
22
 
27
23
  def uiautomator_scroll_to
28
24
  raise "UiAutomator scroll cannot work with specified direction" unless @direction.nil?
29
25
 
30
-
31
- @driver.disable_wait_for_idle
32
- @driver.disable_implicit_wait
33
-
34
26
  scrollable_selector = @scrollable.ui_selector(false)
35
27
  element_selector = @locator.ui_selector(false)
36
28
  orientation_command = @scrollable.scroll_orientation == :vertical ? ".setAsVerticalList()" : ".setAsHorizontalList()"
@@ -41,15 +33,11 @@ module TestaAppiumDriver
41
33
  rescue
42
34
  # Ignored
43
35
  ensure
44
- @driver.enable_implicit_wait
45
- @driver.enable_wait_for_idle
46
36
  end
47
37
  end
48
38
 
49
39
 
50
40
  def uiautomator_page_or_fling(type, direction)
51
- @driver.disable_wait_for_idle
52
- @driver.disable_implicit_wait
53
41
 
54
42
  scrollable_selector = @scrollable.ui_selector(false)
55
43
  orientation = direction == :up || direction == :down ? ".setAsVerticalList()" : ".setAsHorizontalList()"
@@ -67,8 +55,6 @@ module TestaAppiumDriver
67
55
  rescue
68
56
  # Ignored
69
57
  end
70
- @driver.enable_implicit_wait
71
- @driver.enable_wait_for_idle
72
58
  end
73
59
 
74
60
 
@@ -6,6 +6,7 @@ module TestaAppiumDriver
6
6
  FIND_STRATEGY_XPATH = :xpath
7
7
  FIND_STRATEGY_ID = :id
8
8
  FIND_STRATEGY_NAME = :name
9
+ FIND_STRATEGY_IMAGE = :image
9
10
 
10
11
  SCROLL_STRATEGY_UIAUTOMATOR = :uiautomator
11
12
  SCROLL_STRATEGY_W3C = :w3c
@@ -120,7 +120,9 @@ module TestaAppiumDriver
120
120
  command = "#{ command }[@focused=\"#{ hash[:focused] }\"]" unless hash[:focused].nil?
121
121
  command = "#{ command }[@index=\"#{ hash[:index] }\"]" unless hash[:index].nil?
122
122
  command = "#{ command }[@selected=\"#{ hash[:selected] }\"]" unless hash[:selected].nil?
123
- command = "#{ command }[@scrollable=\"#{ hash[:scrollable] }\"]" unless hash[:scrollable].nil?
123
+
124
+ # it seems like you cannot query by scrollable
125
+ # command = "#{ command }[@scrollable=\"#{ hash[:scrollable] }\"]" unless hash[:scrollable].nil?
124
126
  else
125
127
 
126
128
  hash[:type] = hash[:class] unless hash[:class].nil?
@@ -205,6 +207,8 @@ module TestaAppiumDriver
205
207
  :visible,
206
208
  :name,
207
209
  :value,
210
+
211
+ :image
208
212
  ].include?(key) }
209
213
  params = Hash[params.to_a - selectors.to_a]
210
214
 
@@ -250,6 +250,22 @@ module TestaAppiumDriver
250
250
  _fling(:right, _process_deadzone(top, bottom, right, left))
251
251
  end
252
252
 
253
+ def drag_up_by(amount)
254
+ drag_by(amount, direction: :top)
255
+ end
256
+
257
+ def drag_down_by(amount)
258
+ drag_by(amount, direction: :bottom)
259
+ end
260
+
261
+ def drag_left_by(amount)
262
+ drag_by(amount, direction: :left)
263
+ end
264
+
265
+ def drag_right_by(amount)
266
+ drag_by(amount, direction: :right)
267
+ end
268
+
253
269
 
254
270
  # @param [TestaAppiumDriver::Locator, Hash, Selenium::WebDriver::Element, String] to
255
271
  #noinspection RubyYardParamTypeMatch,RubyScope
@@ -17,6 +17,8 @@ module TestaAppiumDriver
17
17
  attr_accessor :last_selector_adjacent
18
18
  attr_accessor :can_use_id_strategy
19
19
 
20
+ attr_accessor :image_selector
21
+
20
22
  attr_accessor :from_element
21
23
  attr_accessor :scroll_orientation
22
24
  attr_accessor :scroll_deadzone
@@ -41,12 +43,21 @@ module TestaAppiumDriver
41
43
  # @type [TestaAppiumDriver::Driver]
42
44
  @driver = driver
43
45
  @index_for_multiple = nil
46
+ @image_selector = nil
44
47
 
45
48
  params, selectors = extract_selectors_from_params(params)
46
49
  single = params[:single]
47
50
 
48
51
  @single = single
49
52
 
53
+ if selectors[:image].nil?
54
+ if from_element.instance_of?(TestaAppiumDriver::Locator) && !from_element.image_selector.nil?
55
+ raise "Cannot chain non-image selectors to image selectors"
56
+ end
57
+ else
58
+ handle_image_selector(selectors, params)
59
+ end
60
+
50
61
  selectors[:id] = selectors[:name] unless selectors[:name].nil?
51
62
  if from_element.instance_of?(Selenium::WebDriver::Element)
52
63
  @xpath_selector = "//*" # to select current element
@@ -80,6 +91,8 @@ module TestaAppiumDriver
80
91
  end
81
92
 
82
93
 
94
+
95
+
83
96
  def is_only_id_selector?(selectors)
84
97
  # since, name and id is the same thing for iOS,
85
98
  if @driver.device == :android
@@ -95,7 +108,6 @@ module TestaAppiumDriver
95
108
  def method_missing(method, *args, &block)
96
109
  r = execute.send(method, *args, &block)
97
110
  @driver.invalidate_cache
98
- r = r[@index_for_multiple] if !@index_for_multiple.nil? && !@single
99
111
  r
100
112
  end
101
113
 
@@ -103,14 +115,16 @@ module TestaAppiumDriver
103
115
  # @param [Boolean] skip_cache if true it will skip cache check and store
104
116
  # @param [Selenium::WebDriver::Element] force_cache_element, for internal use where we have already the element, and want to execute custom locator methods on it
105
117
  # @return [Selenium::WebDriver::Element, Array]
106
- def execute(skip_cache: false, force_cache_element: nil)
118
+ def execute(skip_cache: false, force_cache_element: nil, ignore_implicit_wait: false)
107
119
  return force_cache_element unless force_cache_element.nil?
108
120
  # if we are looking for current element, then return from_element
109
121
  # for example when we have driver.element.elements[1].click
110
122
  # elements[2] will be resolved with xpath because we are looking for multiple elements from element
111
123
  # and since we are looking for instance 2, [](instance) method will return new "empty locator"
112
124
  # we are executing click on that "empty locator" so we have to return the instance 2 of elements for the click
113
- if @xpath_selector == "//*/*[1]" && @from_element.instance_of?(Selenium::WebDriver::Element)
125
+ if @xpath_selector == "//*[1]" && !@from_element.nil? && @image_selector.nil?
126
+ return @from_element if @from_element.instance_of?(Selenium::WebDriver::Element)
127
+ return @from_element.execute(skip_cache: skip_cache, force_cache_element: force_cache_element, ignore_implicit_wait: ignore_implicit_wait) if @from_element.instance_of?(TestaAppiumDriver::Locator)
114
128
  return @from_element
115
129
  end
116
130
 
@@ -119,11 +133,30 @@ module TestaAppiumDriver
119
133
 
120
134
 
121
135
 
122
- r = @driver.execute(@from_element, @single, strategies_and_selectors, skip_cache)
136
+ r = @driver.execute(@from_element, @single, strategies_and_selectors, skip_cache, ignore_implicit_wait)
123
137
  r = r[@index_for_multiple] if !@index_for_multiple.nil? && !@single
124
138
  r
125
139
  end
126
140
 
141
+ def when_exists(timeout = nil, &block)
142
+ timeout = @driver.get_timeouts["implicit"] / 1000 if timeout.nil?
143
+ found = false
144
+ begin
145
+ wait_until_exists(timeout)
146
+ found = true
147
+ rescue
148
+ #ignored
149
+ end
150
+ if found
151
+ if block_given? # block is given
152
+ block.call(self) # use call to execute the block
153
+ else # the value of block_argument becomes nil if you didn't give a block
154
+ # block was not given
155
+ end
156
+ end
157
+ self
158
+ end
159
+
127
160
 
128
161
  # @param [Integer] timeout in seconds
129
162
  # @return [TestaAppiumDriver::Locator]
@@ -157,16 +190,12 @@ module TestaAppiumDriver
157
190
  # all timeouts are disabled before check, and enabled after check
158
191
  # @return [boolean] true if it exists in the page regardless if visible or not
159
192
  def exists?
160
- @driver.disable_wait_for_idle
161
- @driver.disable_implicit_wait
162
193
  found = true
163
194
  begin
164
- execute(skip_cache: true)
195
+ execute(skip_cache: true, ignore_implicit_wait: true)
165
196
  rescue StandardError
166
197
  found = false
167
198
  end
168
- @driver.enable_implicit_wait
169
- @driver.enable_wait_for_idle
170
199
  found
171
200
  end
172
201
 
@@ -200,7 +229,8 @@ module TestaAppiumDriver
200
229
  locator.can_use_id_strategy = false
201
230
  locator
202
231
  else
203
- from_element = self.index_for_multiple = instance
232
+ from_element = self.dup
233
+ from_element.index_for_multiple = instance
204
234
  params = {}.merge({single: true, scrollable_locator: @scrollable_locator})
205
235
  #params[:strategy] = FIND_STRATEGY_XPATH
206
236
  #params[:strategy_reason] = "retrieved instance of a array"
@@ -482,6 +512,42 @@ module TestaAppiumDriver
482
512
  locator.single = false unless single # switching from single result to multiple
483
513
  locator.xpath_selector += hash_to_xpath(@driver.device, selectors, single)
484
514
  end
515
+
516
+
517
+ def handle_image_selector(selectors, params)
518
+ image_match_threshold = 0.4
519
+ image_match_threshold = params[:imageMatchThreshold] unless params[:imageMatchThreshold].nil?
520
+ image_match_threshold = params[:threshold] unless params[:threshold].nil?
521
+ fix_image_find_screenshot_dims = true
522
+ fix_image_find_screenshot_dims = params[:fixImageFindScreenshotDims] unless params[:fixImageFindScreenshotDims].nil?
523
+ fix_image_template_size = false
524
+ fix_image_template_size = params[:fixImageTemplateSize] unless params[:fixImageTemplateSize].nil?
525
+ fix_image_template_scale = false
526
+ fix_image_template_scale = params[:fixImageTemplateScale] unless params[:fixImageTemplateScale].nil?
527
+ default_image_template_scale = 1.0
528
+ default_image_template_scale = params[:defaultImageTemplateScale] unless params[:defaultImageTemplateScale].nil?
529
+ check_for_image_element_staleness = true
530
+ check_for_image_element_staleness = params[:checkForImageElementStaleness] unless params[:checkForImageElementStaleness].nil?
531
+ auto_update_image_element_position = false
532
+ auto_update_image_element_position = params[:autoUpdateImageElementPosition] unless params[:autoUpdateImageElementPosition].nil?
533
+ image_element_tap_strategy = "w3cActions"
534
+ image_element_tap_strategy = params[:imageElementTapStrategy] unless params[:imageElementTapStrategy].nil?
535
+ get_matched_image_result = false
536
+ get_matched_image_result = params[:getMatchedImageResult] unless params[:getMatchedImageResult].nil?
537
+
538
+ @image_selector = {
539
+ image: selectors[:image],
540
+ imageMatchThreshold: image_match_threshold,
541
+ fixImageFindScreenshotDims: fix_image_find_screenshot_dims,
542
+ fixImageTemplateSize: fix_image_template_size,
543
+ fixImageTemplateScale: fix_image_template_scale,
544
+ defaultImageTemplateScale: default_image_template_scale,
545
+ checkForImageElementStaleness: check_for_image_element_staleness,
546
+ autoUpdateImageElementPosition: auto_update_image_element_position,
547
+ imageElementTapStrategy: image_element_tap_strategy,
548
+ getMatchedImageResult: get_matched_image_result,
549
+ }
550
+ end
485
551
  end
486
552
 
487
553
  end
@@ -6,8 +6,6 @@ module TestaAppiumDriver
6
6
  def w3c_each(direction, &block)
7
7
  elements = []
8
8
  begin
9
- @driver.disable_wait_for_idle
10
- @driver.disable_implicit_wait
11
9
  default_deadzone!
12
10
 
13
11
  iterations = 0
@@ -38,15 +36,12 @@ module TestaAppiumDriver
38
36
  end
39
37
  rescue => e
40
38
  raise e
41
- ensure
42
- @driver.enable_implicit_wait
43
- @driver.enable_wait_for_idle
39
+
44
40
  end
45
41
  elements
46
42
  end
47
43
 
48
44
  def w3c_align(with, scroll_to_find)
49
- @driver.disable_wait_for_idle
50
45
  default_deadzone!
51
46
 
52
47
 
@@ -54,20 +49,6 @@ module TestaAppiumDriver
54
49
  @locator.scroll_to if scroll_to_find
55
50
 
56
51
  element = @locator.execute
57
- @driver.disable_implicit_wait
58
-
59
- case with
60
- when :top
61
- page_down if is_aligned?(with, element)
62
- when :bottom
63
- page_up if is_aligned?(with, element)
64
- when :right
65
- page_right if is_aligned?(with, element)
66
- when :left
67
- page_left if is_aligned?(with, element)
68
- else
69
- raise "Unsupported align with option: #{with}"
70
- end
71
52
 
72
53
  timeout = 0
73
54
  until is_aligned?(with, element) || timeout == 3
@@ -75,8 +56,6 @@ module TestaAppiumDriver
75
56
  timeout += 1
76
57
  end
77
58
 
78
- @driver.enable_implicit_wait
79
- @driver.enable_wait_for_idle
80
59
  end
81
60
 
82
61
 
@@ -150,8 +129,6 @@ module TestaAppiumDriver
150
129
  end
151
130
 
152
131
  def w3c_scroll_to_start_or_end(type)
153
- @driver.disable_wait_for_idle
154
- @driver.disable_implicit_wait
155
132
  default_deadzone!
156
133
 
157
134
  @previous_elements = nil
@@ -179,15 +156,10 @@ module TestaAppiumDriver
179
156
 
180
157
  # reset the flag for end of scroll elements
181
158
  @previous_elements = nil
182
-
183
- @driver.enable_implicit_wait
184
- @driver.enable_wait_for_idle
185
159
  end
186
160
 
187
161
 
188
162
  def w3c_page_or_fling(type, direction)
189
- @driver.disable_wait_for_idle
190
- @driver.disable_implicit_wait
191
163
  default_deadzone!
192
164
 
193
165
  if direction == :down || direction == :up
@@ -216,8 +188,6 @@ module TestaAppiumDriver
216
188
 
217
189
  w3c_action(x0, y0, x1, y1, type)
218
190
 
219
- @driver.enable_implicit_wait
220
- @driver.enable_wait_for_idle
221
191
  end
222
192
 
223
193
 
@@ -258,7 +228,7 @@ module TestaAppiumDriver
258
228
 
259
229
 
260
230
 
261
- def drag_to(x, y)
231
+ def w3c_drag_to(x, y)
262
232
  x0 = @bounds.center.x
263
233
  y0 = @bounds.center.y
264
234
  w3c_action(x0, y0, x, y, SCROLL_ACTION_TYPE_DRAG)
@@ -29,6 +29,8 @@ module TestaAppiumDriver
29
29
  def initialize(opts = {})
30
30
  @testa_opts = opts[:testa_appium_driver] || {}
31
31
 
32
+ @wait_for_idle_disabled = false
33
+ @implicit_wait_disabled = false
32
34
 
33
35
  core = Appium::Core.for(opts)
34
36
  extend_for(core.device, core.automation_name)
@@ -67,7 +69,7 @@ module TestaAppiumDriver
67
69
  # @param [Array<Hash>] strategies_and_selectors array of usable strategies and selectors
68
70
  # @param [Boolean] skip_cache to skip checking and storing cache
69
71
  # @return [Selenium::WebDriver::Element, Array] element is returned if single is true, array otherwise
70
- def execute(from_element, single, strategies_and_selectors, skip_cache = false)
72
+ def execute(from_element, single, strategies_and_selectors, skip_cache = false, ignore_implicit_wait = false)
71
73
 
72
74
  # if user wants to wait for element to exist, he can use wait_until_present
73
75
  disable_wait_for_idle
@@ -79,13 +81,13 @@ module TestaAppiumDriver
79
81
 
80
82
 
81
83
  # resolve from_element unique id, so that we can cache it properly
82
- from_element_id = from_element.kind_of?(TestaAppiumDriver::Locator) ? from_element.strategy_and_selector[1] : nil
84
+ from_element_id = from_element.instance_of?(TestaAppiumDriver::Locator) ? from_element.strategies_and_selectors : nil
83
85
 
84
86
  begin
85
87
  ss = strategies_and_selectors[ss_index % strategies_and_selectors.count]
86
88
  ss_index +=1
87
89
 
88
- puts "Executing #{from_element_id ? "from #{from_element.strategy}: #{from_element.strategy_and_selector} => " : ""}#{ss.keys[0]}: #{ss.values[0]}"
90
+ puts "Executing #{from_element_id ? "from #{from_element.strategy}: #{from_element.strategies_and_selectors} => " : ""}#{ss.keys[0]}: #{ss.values[0]}"
89
91
 
90
92
  if @cache[:selector] != ss.values[0] || # cache miss, selector is different
91
93
  @cache[:time] + 5 <= Time.now || # cache miss, older than 5 seconds
@@ -93,13 +95,24 @@ module TestaAppiumDriver
93
95
  @cache[:from_element_id] != from_element_id || # cache miss, search is started from different element
94
96
  skip_cache # cache is skipped
95
97
 
96
- if single
97
- execute_result = from_element.find_element(ss)
98
+ if ss.keys[0] == FIND_STRATEGY_IMAGE
99
+ set_find_by_image_settings(ss.values[0].dup)
100
+ if single
101
+ execute_result = from_element.find_element_by_image(ss.values[0][:image])
102
+ else
103
+ execute_result = from_element.find_elements_by_image(ss.values[0][:image])
104
+ end
105
+ restore_set_by_image_settings
98
106
  else
99
- execute_result = from_element.find_elements(ss)
107
+ if single
108
+ execute_result = from_element.find_element(ss)
109
+ else
110
+ execute_result = from_element.find_elements(ss)
111
+ end
100
112
  end
101
113
 
102
114
 
115
+
103
116
  unless skip_cache
104
117
  @cache[:selector] = ss.values[0]
105
118
  @cache[:strategy] = ss.keys[0]
@@ -113,7 +126,7 @@ module TestaAppiumDriver
113
126
  puts "Using cache from #{@cache[:time].strftime("%H:%M:%S.%L")}, strategy: #{@cache[:strategy]}"
114
127
  end
115
128
  rescue => e
116
- if start_time + @implicit_wait_ms/1000 < Time.now.to_f || ss_index < strategies_and_selectors.count
129
+ if (start_time + @implicit_wait_ms/1000 < Time.now.to_f && !ignore_implicit_wait) || ss_index < strategies_and_selectors.count
117
130
  sleep EXISTS_WAIT if ss_index >= strategies_and_selectors.count
118
131
  retry
119
132
  else
@@ -131,39 +144,71 @@ module TestaAppiumDriver
131
144
  # method missing is used to forward methods to the actual appium driver
132
145
  # after the method is executed, find element cache is invalidated
133
146
  def method_missing(method, *args, &block)
147
+ r = @driver.send(method, *args, &block)
134
148
  invalidate_cache
135
- @driver.send(method, *args, &block)
149
+ r
136
150
  end
137
151
 
138
152
  # disables implicit wait
139
153
  def disable_implicit_wait
140
- @implicit_wait_ms = @driver.get_timeouts["implicit"]
141
- @driver.manage.timeouts.implicit_wait = 0
154
+ unless @implicit_wait_disabled
155
+ @implicit_wait_ms = @driver.get_timeouts["implicit"]
156
+ @implicit_wait_uiautomator_ms = @driver.get_settings["waitForSelectorTimeout"]
157
+ @driver.manage.timeouts.implicit_wait = 0
158
+ @driver.update_settings({waitForSelectorTimeout: 0})
159
+ @implicit_wait_disabled = true
160
+ end
142
161
  end
143
162
 
144
163
  # enables implicit wait, can be called only after disabling implicit wait
145
164
  def enable_implicit_wait
146
- raise "Implicit wait is not disabled" if @implicit_wait_ms.nil?
165
+ raise "Implicit wait is not disabled" unless @implicit_wait_disabled
147
166
  # get_timeouts always returns in milliseconds, but we should set in seconds
148
167
  @driver.manage.timeouts.implicit_wait = @implicit_wait_ms / 1000
168
+ @driver.update_settings({waitForSelectorTimeout: @implicit_wait_uiautomator_ms})
169
+ @implicit_wait_disabled = false
149
170
  end
150
171
 
151
172
  # disables wait for idle, only executed for android devices
152
173
  def disable_wait_for_idle
153
- if @device == :android
154
- @wait_for_idle_timeout = @driver.settings.get["waitForIdleTimeout"]
155
- @driver.update_settings({waitForIdleTimeout: 0})
174
+ unless @wait_for_idle_disabled
175
+ if @device == :android
176
+ @wait_for_idle_timeout = @driver.settings.get["waitForIdleTimeout"]
177
+ @driver.update_settings({waitForIdleTimeout: 0})
178
+ end
179
+ @wait_for_idle_disabled = true
156
180
  end
157
181
  end
158
182
 
159
183
  # enables wait for idle, only executed for android devices
160
184
  def enable_wait_for_idle
161
185
  if @device == :android
162
- raise "Wait for idle is not disabled" if @wait_for_idle_timeout.nil?
186
+ raise "Wait for idle is not disabled" unless @wait_for_idle_disabled
163
187
  @driver.update_settings({waitForIdleTimeout: @wait_for_idle_timeout})
164
188
  end
165
189
  end
166
190
 
191
+ def set_find_by_image_settings(settings)
192
+ settings.delete(:image)
193
+ @default_find_image_settings = {}
194
+ old_settings = @driver.get_settings
195
+ @default_find_image_settings[:imageMatchThreshold] = old_settings["imageMatchThreshold"]
196
+ @default_find_image_settings[:fixImageFindScreenshotDims] = old_settings["fixImageFindScreenshotDims"]
197
+ @default_find_image_settings[:fixImageTemplateSize] = old_settings["fixImageTemplateSize"]
198
+ @default_find_image_settings[:fixImageTemplateScale] = old_settings["fixImageTemplateScale"]
199
+ @default_find_image_settings[:defaultImageTemplateScale] = old_settings["defaultImageTemplateScale"]
200
+ @default_find_image_settings[:checkForImageElementStaleness] = old_settings["checkForImageElementStaleness"]
201
+ @default_find_image_settings[:autoUpdateImageElementPosition] = old_settings["autoUpdateImageElementPosition"]
202
+ @default_find_image_settings[:imageElementTapStrategy] = old_settings["imageElementTapStrategy"]
203
+ @default_find_image_settings[:getMatchedImageResult] = old_settings["getMatchedImageResult"]
204
+
205
+ @driver.update_settings(settings)
206
+ end
207
+
208
+ def restore_set_by_image_settings
209
+ @driver.update_settings(@default_find_image_settings) if @default_find_image_settings
210
+ end
211
+
167
212
 
168
213
  # @@return [String] current package under test
169
214
  def current_package
@@ -197,6 +242,8 @@ module TestaAppiumDriver
197
242
  end
198
243
 
199
244
 
245
+
246
+
200
247
  # @return [Array<Selenium::WebDriver::Element] array of 2 elements, the first element without children and the last element without children in the current page
201
248
  def first_and_last_leaf(from_element = @driver)
202
249
  disable_wait_for_idle
@@ -7,6 +7,19 @@ module TestaAppiumDriver
7
7
  include TypeSelectors
8
8
 
9
9
 
10
+
11
+ # @param params [Hash]
12
+ # @return [TestaAppiumDriver::Locator] first scrollable element
13
+ def scrollable(params = {})
14
+ scroll_view(params)
15
+ end
16
+
17
+ # @param params [Hash]
18
+ # @return [TestaAppiumDriver::Locator] first scrollable element
19
+ def scrollables(params = {})
20
+ scroll_views(params)
21
+ end
22
+
10
23
  private
11
24
  def handle_testa_opts
12
25
  if @testa_opts[:default_find_strategy].nil?
@@ -29,7 +29,9 @@ module TestaAppiumDriver
29
29
  if @can_use_id_strategy
30
30
  ss.push({"#{FIND_STRATEGY_NAME}": @can_use_id_strategy})
31
31
  end
32
- ss.push({"#{FIND_STRATEGY_XPATH}": @xpath_selector})
32
+
33
+ ss.push({"#{FIND_STRATEGY_XPATH}": @xpath_selector}) if @strategy.nil? || @strategy == FIND_STRATEGY_XPATH
34
+ ss.push({"#{FIND_STRATEGY_IMAGE}": @image_selector}) if @strategy == FIND_STRATEGY_IMAGE
33
35
  ss
34
36
  end
35
37
 
@@ -111,19 +111,6 @@ module TestaAppiumDriver
111
111
  end
112
112
 
113
113
 
114
- # @param params [Hash]
115
- # @return [TestaAppiumDriver::Locator] first scrollable element
116
- def scrollable(params = {})
117
- scroll_view(params)
118
- end
119
-
120
- # @param params [Hash]
121
- # @return [TestaAppiumDriver::Locator] first scrollable element
122
- def scrollables(params = {})
123
- scroll_views(params)
124
- end
125
-
126
-
127
114
  # @return [TestaAppiumDriver::Locator]
128
115
  def scroll_view(params = {})
129
116
  params[:type] = "XCUIElementTypeScrollView"
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module TestaAppiumDriver
4
- VERSION = "0.1.6"
4
+ VERSION = "0.1.7"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: testa_appium_driver
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.6
4
+ version: 0.1.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - karlo.razumovic
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-09-03 00:00:00.000000000 Z
11
+ date: 2021-09-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: appium_lib_core
@@ -80,6 +80,7 @@ files:
80
80
  - ".idea/inspectionProfiles/Project_Default.xml"
81
81
  - ".idea/misc.xml"
82
82
  - ".idea/modules.xml"
83
+ - ".idea/runConfigurations.xml"
83
84
  - ".idea/runConfigurations/Android_Test.xml"
84
85
  - ".idea/sshConfigs.xml"
85
86
  - ".idea/vcs.xml"