testa_appium_driver 0.1.8 → 0.1.12

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.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +15 -15
  3. data/.idea/deployment.xml +21 -21
  4. data/.idea/inspectionProfiles/Project_Default.xml +8 -8
  5. data/.idea/misc.xml +5 -5
  6. data/.idea/modules.xml +7 -7
  7. data/.idea/runConfigurations/Android_Test.xml +41 -41
  8. data/.idea/runConfigurations.xml +9 -9
  9. data/.idea/sshConfigs.xml +12 -12
  10. data/.idea/vcs.xml +5 -5
  11. data/.idea/webServers.xml +20 -20
  12. data/.rspec +3 -3
  13. data/.rubocop.yml +13 -13
  14. data/CHANGELOG.md +5 -5
  15. data/CODE_OF_CONDUCT.md +102 -102
  16. data/Gemfile +12 -12
  17. data/LICENSE.txt +21 -21
  18. data/README.md +378 -378
  19. data/Rakefile +12 -12
  20. data/bin/console +17 -17
  21. data/bin/setup +8 -8
  22. data/lib/testa_appium_driver/android/class_selectors.rb +437 -437
  23. data/lib/testa_appium_driver/android/driver.rb +69 -69
  24. data/lib/testa_appium_driver/android/locator/attributes.rb +113 -113
  25. data/lib/testa_appium_driver/android/locator.rb +141 -141
  26. data/lib/testa_appium_driver/android/scroll_actions/uiautomator_scroll_actions.rb +61 -63
  27. data/lib/testa_appium_driver/android/selenium_element.rb +7 -7
  28. data/lib/testa_appium_driver/common/bounds.rb +149 -149
  29. data/lib/testa_appium_driver/common/constants.rb +36 -36
  30. data/lib/testa_appium_driver/common/exceptions/strategy_mix_exception.rb +11 -11
  31. data/lib/testa_appium_driver/common/helpers.rb +270 -270
  32. data/lib/testa_appium_driver/common/locator/scroll_actions.rb +397 -396
  33. data/lib/testa_appium_driver/common/locator.rb +610 -578
  34. data/lib/testa_appium_driver/common/scroll_actions/json_wire_scroll_actions.rb +3 -3
  35. data/lib/testa_appium_driver/common/scroll_actions/w3c_scroll_actions.rb +237 -237
  36. data/lib/testa_appium_driver/common/scroll_actions.rb +246 -246
  37. data/lib/testa_appium_driver/common/selenium_element.rb +19 -19
  38. data/lib/testa_appium_driver/driver.rb +312 -278
  39. data/lib/testa_appium_driver/ios/driver.rb +48 -48
  40. data/lib/testa_appium_driver/ios/locator/attributes.rb +80 -80
  41. data/lib/testa_appium_driver/ios/locator.rb +70 -70
  42. data/lib/testa_appium_driver/ios/selenium_element.rb +6 -6
  43. data/lib/testa_appium_driver/ios/type_selectors.rb +187 -187
  44. data/lib/testa_appium_driver/version.rb +5 -5
  45. data/lib/testa_appium_driver.rb +6 -6
  46. data/testa_appium_driver.gemspec +41 -41
  47. data/testa_appium_driver.iml +27 -78
  48. metadata +3 -3
@@ -1,397 +1,398 @@
1
- module TestaAppiumDriver
2
- #noinspection RubyTooManyMethodsInspection
3
- class Locator
4
-
5
- # performs a long tap on the retrieved element
6
- # @param [Float] duration in seconds
7
- def long_tap(duration = LONG_TAP_DURATION)
8
- action_builder = @driver.action
9
- b = bounds
10
- f1 = action_builder.add_pointer_input(:touch, "finger1")
11
- f1.create_pointer_move(duration: 0, x: b.center.x, y: b.center.y, origin: ::Selenium::WebDriver::Interactions::PointerMove::VIEWPORT)
12
- f1.create_pointer_down(:left)
13
- f1.create_pause(duration)
14
- f1.create_pointer_up(:left)
15
- puts "long tap execute: {x: #{b.center.x}, y: #{b.center.y}}"
16
- @driver.perform_actions [f1]
17
- end
18
-
19
-
20
- # scrolls to the start of the scrollable containers and scrolls to the end,
21
- # everytime a locator element is found the given block is executed
22
- # @return [Array<Selenium::WebDriver::Element>]
23
- def each(top: nil, bottom: nil, right: nil, left: nil, direction: nil, &block)
24
- deadzone = _process_deadzone(top, bottom, right, left)
25
- raise "Each can only be performed on multiple elements locator" if @single
26
- deadzone = @scrollable_locator.scroll_deadzone if deadzone.nil? && !@scrollable_locator.nil?
27
- sa = ScrollActions.new(@scrollable_locator,
28
- locator: self,
29
- deadzone: deadzone,
30
- default_scroll_strategy: @default_scroll_strategy)
31
- if direction.nil?
32
- sa.each(&block)
33
- else
34
- sa.send("each_#{direction}", &block)
35
- end
36
- end
37
-
38
- # scrolls down from the current page view (without prior scrolling to the top) and
39
- # everytime a locator element is found the given block is executed
40
- # @return [Array<Selenium::WebDriver::Element>]
41
- def each_down(top: nil, bottom: nil, right: nil, left: nil, &block)
42
- each(top: top, bottom: bottom, right: right, left: left, direction: :down, &block)
43
- end
44
-
45
- # scrolls up from the current page view (without prior scrolling to the bottom) and
46
- # everytime a locator element is found the given block is executed
47
- # @return [Array<Selenium::WebDriver::Element>]
48
- def each_up(top: nil, bottom: nil, right: nil, left: nil, &block)
49
- each(top: top, bottom: bottom, right: right, left: left, direction: :up, &block)
50
- end
51
-
52
- # scrolls right from the current page view (without prior scrolling to the left) and
53
- # everytime a locator element is found the given block is executed
54
- # @return [Array<Selenium::WebDriver::Element>]
55
- def each_right(top: nil, bottom: nil, right: nil, left: nil, &block)
56
- each(top: top, bottom: bottom, right: right, left: left, direction: :right, &block)
57
- end
58
-
59
- # scrolls left from the current page view (without prior scrolling to the right) and
60
- # everytime a locator element is found the given block is executed
61
- # @return [Array<Selenium::WebDriver::Element>]
62
- def each_left(top: nil, bottom: nil, right: nil, left: nil, &block)
63
- each(top: top, bottom: bottom, right: right, left: left, direction: :left, &block)
64
- end
65
-
66
-
67
- # Aligns element (by default) on top of the scrollable container, if the element does not exists it will scroll to find it
68
- # 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]
69
- # If the distance is greater than the threshold, it will attempt to realign it up to 2 more times.
70
- # The retry mechanism allows alignment even for dynamic layouts when elements are hidden/show when scrolling to certain direction
71
- # @return [TestaAppiumDriver::Locator]
72
- def align(with = :top, top: nil, bottom: nil, right: nil, left: nil, scroll_to_find: false)
73
- deadzone = @scrollable_locator.scroll_deadzone if deadzone.nil? && !@scrollable_locator.nil?
74
- sa = ScrollActions.new(@scrollable_locator,
75
- locator: self,
76
- deadzone: deadzone,
77
- default_scroll_strategy: @default_scroll_strategy)
78
- sa.align(with, scroll_to_find)
79
- self
80
- end
81
-
82
- # Aligns element on top of the scrollable container, if the element does not exists it will scroll to find it
83
- # The element is aligned if the the distance from the top of the scrollable container is less than [TestaAppiumDriver::SCROLL_ALIGNMENT_THRESHOLD]
84
- # If the distance is greater than the threshold, it will attempt to realign it up to 2 more times.
85
- # The retry mechanism allows alignment even for dynamic layouts when elements are hidden/show when scrolling to certain direction
86
- # @return [TestaAppiumDriver::Locator]
87
- def align_top(top: nil, bottom: nil, right: nil, left: nil)
88
- align(:top, top: top, bottom: bottom, right: right, left: left)
89
- end
90
-
91
- # Aligns element on bottom of the scrollable container, if the element does not exists it will scroll to find it
92
- # The element is aligned if the the distance from the bottom of the scrollable container is less than [TestaAppiumDriver::SCROLL_ALIGNMENT_THRESHOLD]
93
- # If the distance is greater than the threshold, it will attempt to realign it up to 2 more times.
94
- # The retry mechanism allows alignment even for dynamic layouts when elements are hidden/show when scrolling to certain direction
95
- # @return [TestaAppiumDriver::Locator]
96
- def align_bottom(top: nil, bottom: nil, right: nil, left: nil)
97
- align(:bottom, top: top, bottom: bottom, right: right, left: left)
98
- end
99
-
100
- # Aligns element on left of the scrollable container, if the element does not exists it will scroll to find it
101
- # The element is aligned if the the distance from the left of the scrollable container is less than [TestaAppiumDriver::SCROLL_ALIGNMENT_THRESHOLD]
102
- # If the distance is greater than the threshold, it will attempt to realign it up to 2 more times.
103
- # The retry mechanism allows alignment even for dynamic layouts when elements are hidden/show when scrolling to certain direction
104
- # @return [TestaAppiumDriver::Locator]
105
- def align_left(top: nil, bottom: nil, right: nil, left: nil)
106
- align(:left, top: top, bottom: bottom, right: right, left: left)
107
- end
108
-
109
- # Aligns element on right of the scrollable container, if the element does not exists it will scroll to find it
110
- # The element is aligned if the the distance from the right of the scrollable container is less than [TestaAppiumDriver::SCROLL_ALIGNMENT_THRESHOLD]
111
- # If the distance is greater than the threshold, it will attempt to realign it up to 2 more times.
112
- # The retry mechanism allows alignment even for dynamic layouts when elements are hidden/show when scrolling to certain direction
113
- # @return [TestaAppiumDriver::Locator]
114
- def align_right(top: nil, bottom: nil, right: nil, left: nil)
115
- align(:right, top: top, bottom: bottom, right: right, left: left)
116
- end
117
-
118
- # Aligns element (by default) on top of the scrollable container, if the element does not exists it raise an exception
119
- # 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]
120
- # If the distance is greater than the threshold, it will attempt to realign it up to 2 more times.
121
- # The retry mechanism allows alignment even for dynamic layouts when elements are hidden/show when scrolling to certain direction
122
- # @return [TestaAppiumDriver::Locator]
123
- def align!(with = :top, top: nil, bottom: nil, right: nil, left: nil)
124
- align(with, top: top, bottom: bottom, right: right, left: left, scroll_to_find: true)
125
- end
126
-
127
- # Aligns element on top of the scrollable container, if the element does not exists it raise an exception
128
- # The element is aligned if the the distance from the top of the scrollable container is less than [TestaAppiumDriver::SCROLL_ALIGNMENT_THRESHOLD]
129
- # If the distance is greater than the threshold, it will attempt to realign it up to 2 more times.
130
- # The retry mechanism allows alignment even for dynamic layouts when elements are hidden/show when scrolling to certain direction
131
- # @return [TestaAppiumDriver::Locator]
132
- def align_top!(top: nil, bottom: nil, right: nil, left: nil)
133
- align(:top, top: top, bottom: bottom, right: right, left: left, scroll_to_find: true)
134
- end
135
-
136
- # Aligns element on bottom of the scrollable container, if the element does not exists it raise an exception
137
- # The element is aligned if the the distance from the bottom of the scrollable container is less than [TestaAppiumDriver::SCROLL_ALIGNMENT_THRESHOLD]
138
- # If the distance is greater than the threshold, it will attempt to realign it up to 2 more times.
139
- # The retry mechanism allows alignment even for dynamic layouts when elements are hidden/show when scrolling to certain direction
140
- # @return [TestaAppiumDriver::Locator]
141
- def align_bottom!(top: nil, bottom: nil, right: nil, left: nil)
142
- align(:bottom, top: top, bottom: bottom, right: right, left: left, scroll_to_find: true)
143
- end
144
-
145
- # Aligns element on left of the scrollable container, if the element does not exists it raise an exception
146
- # The element is aligned if the the distance from the left of the scrollable container is less than [TestaAppiumDriver::SCROLL_ALIGNMENT_THRESHOLD]
147
- # If the distance is greater than the threshold, it will attempt to realign it up to 2 more times.
148
- # The retry mechanism allows alignment even for dynamic layouts when elements are hidden/show when scrolling to certain direction
149
- # @return [TestaAppiumDriver::Locator]
150
- def align_left!(top: nil, bottom: nil, right: nil, left: nil)
151
- align(:left, top: top, bottom: bottom, right: right, left: left, scroll_to_find: true)
152
- end
153
-
154
- # Aligns element on right of the scrollable container, if the element does not exists it raise an exception
155
- # The element is aligned if the the distance from the right of the scrollable container is less than [TestaAppiumDriver::SCROLL_ALIGNMENT_THRESHOLD]
156
- # If the distance is greater than the threshold, it will attempt to realign it up to 2 more times.
157
- # The retry mechanism allows alignment even for dynamic layouts when elements are hidden/show when scrolling to certain direction
158
- # @return [TestaAppiumDriver::Locator]
159
- def align_right!(top: nil, bottom: nil, right: nil, left: nil)
160
- align(:right, top: top, bottom: bottom, right: right, left: left, scroll_to_find: true)
161
- end
162
-
163
-
164
- # First scrolls to the beginning of the scrollable container and then scrolls down until element is found or end is reached
165
- # @return [TestaAppiumDriver::Locator]
166
- def scroll_to(top: nil, bottom: nil, right: nil, left: nil, max_scrolls: nil, direction: nil)
167
- if direction
168
- _scroll_dir_to(_process_deadzone(top, bottom, right, left), max_scrolls, direction)
169
- else
170
- _scroll_to(_process_deadzone(top, bottom, right, left), max_scrolls)
171
- end
172
- end
173
-
174
-
175
- # Scrolls down until element is found or end is reached
176
- # @return [TestaAppiumDriver::Locator]
177
- def scroll_down_to(top: nil, bottom: nil, right: nil, left: nil, max_scrolls: nil)
178
- _scroll_dir_to(_process_deadzone(top, bottom, right, left), max_scrolls, :down)
179
- end
180
-
181
- # Scrolls up until element is found or end is reached
182
- # @return [TestaAppiumDriver::Locator]
183
- def scroll_up_to(top: nil, bottom: nil, right: nil, left: nil, max_scrolls: nil)
184
- _scroll_dir_to(_process_deadzone(top, bottom, right, left), max_scrolls, :up)
185
- end
186
-
187
- # Scrolls right until element is found or end is reached
188
- # @return [TestaAppiumDriver::Locator]
189
- def scroll_right_to(top: nil, bottom: nil, right: nil, left: nil, max_scrolls: nil)
190
- _scroll_dir_to(_process_deadzone(top, bottom, right, left), max_scrolls, :right)
191
- end
192
-
193
-
194
- # Scrolls left until element is found or end is reached
195
- # @return [TestaAppiumDriver::Locator]
196
- def scroll_left_to(top: nil, bottom: nil, right: nil, left: nil, max_scrolls: nil)
197
- _scroll_dir_to(_process_deadzone(top, bottom, right, left), max_scrolls, :left)
198
- end
199
-
200
- # Scrolls to the start of the scrollable container (top on vertical container, left on horizontal)
201
- # @return [TestaAppiumDriver::Locator]
202
- def scroll_to_start(top: nil, bottom: nil, right: nil, left: nil)
203
- _scroll_to_start_or_end(:start, _process_deadzone(top, bottom, right, left))
204
- end
205
-
206
- # Scrolls to the end of the scrollable container (bottom on vertical container, right on horizontal)
207
- # @return [TestaAppiumDriver::Locator]
208
- def scroll_to_end(top: nil, bottom: nil, right: nil, left: nil)
209
- _scroll_to_start_or_end(:end, _process_deadzone(top, bottom, right, left))
210
- end
211
-
212
-
213
- # @return [TestaAppiumDriver::Locator]
214
- def page_down(top: nil, bottom: nil, right: nil, left: nil)
215
- _page(:down, _process_deadzone(top, bottom, right, left))
216
- end
217
-
218
- # @return [TestaAppiumDriver::Locator]
219
- def page_up(top: nil, bottom: nil, right: nil, left: nil)
220
- _page(:up, _process_deadzone(top, bottom, right, left))
221
- end
222
-
223
- # @return [TestaAppiumDriver::Locator]
224
- def page_left(top: nil, bottom: nil, right: nil, left: nil)
225
- _page(:left, _process_deadzone(top, bottom, right, left))
226
- end
227
-
228
- # @return [TestaAppiumDriver::Locator]
229
- def page_right(top: nil, bottom: nil, right: nil, left: nil)
230
- _page(:right, _process_deadzone(top, bottom, right, left))
231
- end
232
-
233
- # @return [TestaAppiumDriver::Locator]
234
- def fling_down(top: nil, bottom: nil, right: nil, left: nil)
235
- _fling(:down, _process_deadzone(top, bottom, right, left))
236
- end
237
-
238
- # @return [TestaAppiumDriver::Locator]
239
- def fling_up(top: nil, bottom: nil, right: nil, left: nil)
240
- _fling(:up, _process_deadzone(top, bottom, right, left))
241
- end
242
-
243
- # @return [TestaAppiumDriver::Locator]
244
- def fling_left(top: nil, bottom: nil, right: nil, left: nil)
245
- _fling(:left, _process_deadzone(top, bottom, right, left))
246
- end
247
-
248
- # @return [TestaAppiumDriver::Locator]
249
- def fling_right(top: nil, bottom: nil, right: nil, left: nil)
250
- _fling(:right, _process_deadzone(top, bottom, right, left))
251
- end
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
-
269
-
270
- # @param [TestaAppiumDriver::Locator, Hash, Selenium::WebDriver::Element, String] to
271
- #noinspection RubyYardParamTypeMatch,RubyScope
272
- def drag_to(to)
273
- if !to.kind_of?(Selenium::WebDriver::Element) && !to.kind_of?(TestaAppiumDriver::Locator) && !to.kind_of?(Hash)
274
- raise "Parameter not accepted, acceptable instances of [TestaAppiumDriver::Locator, Hash, Selenium::WebDriver::Element]"
275
- end
276
- if to.kind_of?(Selenium::WebDriver::Element)
277
- bounds = TestaAppiumDriver::Bounds.from_android(to.bounds, @driver)
278
- x = bounds.center.x
279
- y = bounds.center.y
280
- end
281
- if to.kind_of?(TestaAppiumDriver::Locator)
282
- bounds = to.bounds
283
- x = bounds.center.x
284
- y = bounds.center.y
285
- end
286
- if to.kind_of?(Hash)
287
- raise "Missing x coordinate" if to[:x].nil?
288
- raise "Missing y coordinate" if to[:y].nil?
289
- x = to[:x]
290
- y = to[:y]
291
- end
292
- _drag_to(bounds.center.x, bounds.center.y, x, y)
293
- end
294
-
295
- def drag_by(amount, direction: :top)
296
- b = bounds
297
- x = b.center.x
298
- y = b.center.y
299
- case direction
300
- when :top
301
- y -= amount.to_i
302
- when :bottom
303
- y += amount.to_i
304
- when :left
305
- x -= amount.to_i
306
- when :right
307
- x += amount.to_i
308
- else
309
- raise "Unknown direction #{direction}"
310
- end
311
- _drag_to(b.center.x, b.center.y, x, y)
312
- end
313
-
314
-
315
-
316
- private
317
- def _process_deadzone(top, bottom, right, left)
318
- deadzone = nil
319
- if !top.nil? || !bottom.nil? || !right.nil? || !left.nil?
320
- deadzone = {}
321
- deadzone[:top] = top unless top.nil?
322
- deadzone[:bottom] = bottom unless bottom.nil?
323
- deadzone[:right] = right unless right.nil?
324
- deadzone[:left] = left unless left.nil?
325
- end
326
- deadzone
327
- end
328
-
329
- def _drag_to(x0, y0, x1, y1)
330
- sa = ScrollActions.new(@scrollable_locator,
331
- locator: self,
332
- default_scroll_strategy: @default_scroll_strategy)
333
- sa.drag_to(x0, y0, x1, y1)
334
- self
335
- end
336
-
337
-
338
- def _page(direction, deadzone)
339
- deadzone = @scrollable_locator.scroll_deadzone if deadzone.nil? && !@scrollable_locator.nil?
340
- sa = ScrollActions.new(@scrollable_locator,
341
- locator: self,
342
- deadzone: deadzone,
343
- direction: direction.to_sym,
344
- default_scroll_strategy: @default_scroll_strategy)
345
- sa.send("page_#{direction}")
346
- self
347
- end
348
-
349
- def _fling(direction, deadzone)
350
- deadzone = @scrollable_locator.scroll_deadzone if deadzone.nil? && !@scrollable_locator.nil?
351
- sa = ScrollActions.new(@scrollable_locator,
352
- locator: self,
353
- deadzone: deadzone,
354
- direction: direction.to_sym,
355
- default_scroll_strategy: @default_scroll_strategy)
356
- sa.send("fling_#{direction}")
357
- self
358
- end
359
-
360
- def _scroll_to_start_or_end(type, deadzone)
361
- deadzone = @scrollable_locator.scroll_deadzone if deadzone.nil? && !@scrollable_locator.nil?
362
- sa = ScrollActions.new(@scrollable_locator,
363
- locator: self,
364
- deadzone: deadzone,
365
- default_scroll_strategy: @default_scroll_strategy)
366
- if type == :start
367
- sa.scroll_to_start
368
- else
369
- sa.scroll_to_end
370
- end
371
- self
372
- end
373
-
374
- def _scroll_to(deadzone, max_scrolls)
375
- deadzone = @scrollable_locator.scroll_deadzone if deadzone.nil? && !@scrollable_locator.nil?
376
- sa = ScrollActions.new(@scrollable_locator,
377
- locator: self,
378
- deadzone: deadzone,
379
- max_scrolls: max_scrolls,
380
- default_scroll_strategy: @default_scroll_strategy)
381
- sa.scroll_to
382
- self
383
- end
384
-
385
- def _scroll_dir_to(deadzone, max_scrolls, direction)
386
- deadzone = @scrollable_locator.scroll_deadzone if deadzone.nil? && !@scrollable_locator.nil?
387
- sa = ScrollActions.new(@scrollable_locator,
388
- locator: self,
389
- deadzone: deadzone,
390
- max_scrolls: max_scrolls,
391
- default_scroll_strategy: @default_scroll_strategy)
392
-
393
- sa.send("scroll_#{direction}_to")
394
- self
395
- end
396
- end
1
+ module TestaAppiumDriver
2
+ #noinspection RubyTooManyMethodsInspection
3
+ class Locator
4
+
5
+ # performs a long tap on the retrieved element
6
+ # @param [Float] duration in seconds
7
+ def long_tap(duration = LONG_TAP_DURATION)
8
+ action_builder = @driver.action
9
+ b = bounds
10
+ f1 = action_builder.add_pointer_input(:touch, "finger1")
11
+ f1.create_pointer_move(duration: 0, x: b.center.x, y: b.center.y, origin: ::Selenium::WebDriver::Interactions::PointerMove::VIEWPORT)
12
+ f1.create_pointer_down(:left)
13
+ f1.create_pause(duration)
14
+ f1.create_pointer_up(:left)
15
+ puts "long tap execute: {x: #{b.center.x}, y: #{b.center.y}}"
16
+ @driver.perform_actions [f1]
17
+ end
18
+
19
+
20
+ # scrolls to the start of the scrollable containers and scrolls to the end,
21
+ # everytime a locator element is found the given block is executed
22
+ # @return [Array<Selenium::WebDriver::Element>]
23
+ def each(top: nil, bottom: nil, right: nil, left: nil, direction: nil, &block)
24
+ deadzone = _process_deadzone(top, bottom, right, left)
25
+ raise "Each can only be performed on multiple elements locator" if @single
26
+ deadzone = @scrollable_locator.scroll_deadzone if deadzone.nil? && !@scrollable_locator.nil?
27
+ sa = ScrollActions.new(@scrollable_locator,
28
+ locator: self,
29
+ deadzone: deadzone,
30
+ default_scroll_strategy: @default_scroll_strategy)
31
+ if direction.nil?
32
+ sa.each(&block)
33
+ else
34
+ sa.send("each_#{direction}", &block)
35
+ end
36
+ end
37
+
38
+ # scrolls down from the current page view (without prior scrolling to the top) and
39
+ # everytime a locator element is found the given block is executed
40
+ # @return [Array<Selenium::WebDriver::Element>]
41
+ def each_down(top: nil, bottom: nil, right: nil, left: nil, &block)
42
+ each(top: top, bottom: bottom, right: right, left: left, direction: :down, &block)
43
+ end
44
+
45
+ # scrolls up from the current page view (without prior scrolling to the bottom) and
46
+ # everytime a locator element is found the given block is executed
47
+ # @return [Array<Selenium::WebDriver::Element>]
48
+ def each_up(top: nil, bottom: nil, right: nil, left: nil, &block)
49
+ each(top: top, bottom: bottom, right: right, left: left, direction: :up, &block)
50
+ end
51
+
52
+ # scrolls right from the current page view (without prior scrolling to the left) and
53
+ # everytime a locator element is found the given block is executed
54
+ # @return [Array<Selenium::WebDriver::Element>]
55
+ def each_right(top: nil, bottom: nil, right: nil, left: nil, &block)
56
+ each(top: top, bottom: bottom, right: right, left: left, direction: :right, &block)
57
+ end
58
+
59
+ # scrolls left from the current page view (without prior scrolling to the right) and
60
+ # everytime a locator element is found the given block is executed
61
+ # @return [Array<Selenium::WebDriver::Element>]
62
+ def each_left(top: nil, bottom: nil, right: nil, left: nil, &block)
63
+ each(top: top, bottom: bottom, right: right, left: left, direction: :left, &block)
64
+ end
65
+
66
+
67
+ # Aligns element (by default) on top of the scrollable container, if the element does not exists it will scroll to find it
68
+ # 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]
69
+ # If the distance is greater than the threshold, it will attempt to realign it up to 2 more times.
70
+ # The retry mechanism allows alignment even for dynamic layouts when elements are hidden/show when scrolling to certain direction
71
+ # @return [TestaAppiumDriver::Locator]
72
+ def align(with = :top, top: nil, bottom: nil, right: nil, left: nil, scroll_to_find: false)
73
+ deadzone = _process_deadzone(top, bottom, right, left)
74
+ deadzone = @scrollable_locator.scroll_deadzone if deadzone.nil? && !@scrollable_locator.nil?
75
+ sa = ScrollActions.new(@scrollable_locator,
76
+ locator: self,
77
+ deadzone: deadzone,
78
+ default_scroll_strategy: @default_scroll_strategy)
79
+ sa.align(with, scroll_to_find)
80
+ self
81
+ end
82
+
83
+ # Aligns element on top of the scrollable container, if the element does not exists it will scroll to find it
84
+ # The element is aligned if the the distance from the top of the scrollable container is less than [TestaAppiumDriver::SCROLL_ALIGNMENT_THRESHOLD]
85
+ # If the distance is greater than the threshold, it will attempt to realign it up to 2 more times.
86
+ # The retry mechanism allows alignment even for dynamic layouts when elements are hidden/show when scrolling to certain direction
87
+ # @return [TestaAppiumDriver::Locator]
88
+ def align_top(top: nil, bottom: nil, right: nil, left: nil)
89
+ align(:top, top: top, bottom: bottom, right: right, left: left)
90
+ end
91
+
92
+ # Aligns element on bottom of the scrollable container, if the element does not exists it will scroll to find it
93
+ # The element is aligned if the the distance from the bottom of the scrollable container is less than [TestaAppiumDriver::SCROLL_ALIGNMENT_THRESHOLD]
94
+ # If the distance is greater than the threshold, it will attempt to realign it up to 2 more times.
95
+ # The retry mechanism allows alignment even for dynamic layouts when elements are hidden/show when scrolling to certain direction
96
+ # @return [TestaAppiumDriver::Locator]
97
+ def align_bottom(top: nil, bottom: nil, right: nil, left: nil)
98
+ align(:bottom, top: top, bottom: bottom, right: right, left: left)
99
+ end
100
+
101
+ # Aligns element on left of the scrollable container, if the element does not exists it will scroll to find it
102
+ # The element is aligned if the the distance from the left of the scrollable container is less than [TestaAppiumDriver::SCROLL_ALIGNMENT_THRESHOLD]
103
+ # If the distance is greater than the threshold, it will attempt to realign it up to 2 more times.
104
+ # The retry mechanism allows alignment even for dynamic layouts when elements are hidden/show when scrolling to certain direction
105
+ # @return [TestaAppiumDriver::Locator]
106
+ def align_left(top: nil, bottom: nil, right: nil, left: nil)
107
+ align(:left, top: top, bottom: bottom, right: right, left: left)
108
+ end
109
+
110
+ # Aligns element on right of the scrollable container, if the element does not exists it will scroll to find it
111
+ # The element is aligned if the the distance from the right of the scrollable container is less than [TestaAppiumDriver::SCROLL_ALIGNMENT_THRESHOLD]
112
+ # If the distance is greater than the threshold, it will attempt to realign it up to 2 more times.
113
+ # The retry mechanism allows alignment even for dynamic layouts when elements are hidden/show when scrolling to certain direction
114
+ # @return [TestaAppiumDriver::Locator]
115
+ def align_right(top: nil, bottom: nil, right: nil, left: nil)
116
+ align(:right, top: top, bottom: bottom, right: right, left: left)
117
+ end
118
+
119
+ # Aligns element (by default) on top of the scrollable container, if the element does not exists it raise an exception
120
+ # 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]
121
+ # If the distance is greater than the threshold, it will attempt to realign it up to 2 more times.
122
+ # The retry mechanism allows alignment even for dynamic layouts when elements are hidden/show when scrolling to certain direction
123
+ # @return [TestaAppiumDriver::Locator]
124
+ def align!(with = :top, top: nil, bottom: nil, right: nil, left: nil)
125
+ align(with, top: top, bottom: bottom, right: right, left: left, scroll_to_find: true)
126
+ end
127
+
128
+ # Aligns element on top of the scrollable container, if the element does not exists it raise an exception
129
+ # The element is aligned if the the distance from the top of the scrollable container is less than [TestaAppiumDriver::SCROLL_ALIGNMENT_THRESHOLD]
130
+ # If the distance is greater than the threshold, it will attempt to realign it up to 2 more times.
131
+ # The retry mechanism allows alignment even for dynamic layouts when elements are hidden/show when scrolling to certain direction
132
+ # @return [TestaAppiumDriver::Locator]
133
+ def align_top!(top: nil, bottom: nil, right: nil, left: nil)
134
+ align(:top, top: top, bottom: bottom, right: right, left: left, scroll_to_find: true)
135
+ end
136
+
137
+ # Aligns element on bottom of the scrollable container, if the element does not exists it raise an exception
138
+ # The element is aligned if the the distance from the bottom of the scrollable container is less than [TestaAppiumDriver::SCROLL_ALIGNMENT_THRESHOLD]
139
+ # If the distance is greater than the threshold, it will attempt to realign it up to 2 more times.
140
+ # The retry mechanism allows alignment even for dynamic layouts when elements are hidden/show when scrolling to certain direction
141
+ # @return [TestaAppiumDriver::Locator]
142
+ def align_bottom!(top: nil, bottom: nil, right: nil, left: nil)
143
+ align(:bottom, top: top, bottom: bottom, right: right, left: left, scroll_to_find: true)
144
+ end
145
+
146
+ # Aligns element on left of the scrollable container, if the element does not exists it raise an exception
147
+ # The element is aligned if the the distance from the left of the scrollable container is less than [TestaAppiumDriver::SCROLL_ALIGNMENT_THRESHOLD]
148
+ # If the distance is greater than the threshold, it will attempt to realign it up to 2 more times.
149
+ # The retry mechanism allows alignment even for dynamic layouts when elements are hidden/show when scrolling to certain direction
150
+ # @return [TestaAppiumDriver::Locator]
151
+ def align_left!(top: nil, bottom: nil, right: nil, left: nil)
152
+ align(:left, top: top, bottom: bottom, right: right, left: left, scroll_to_find: true)
153
+ end
154
+
155
+ # Aligns element on right of the scrollable container, if the element does not exists it raise an exception
156
+ # The element is aligned if the the distance from the right of the scrollable container is less than [TestaAppiumDriver::SCROLL_ALIGNMENT_THRESHOLD]
157
+ # If the distance is greater than the threshold, it will attempt to realign it up to 2 more times.
158
+ # The retry mechanism allows alignment even for dynamic layouts when elements are hidden/show when scrolling to certain direction
159
+ # @return [TestaAppiumDriver::Locator]
160
+ def align_right!(top: nil, bottom: nil, right: nil, left: nil)
161
+ align(:right, top: top, bottom: bottom, right: right, left: left, scroll_to_find: true)
162
+ end
163
+
164
+
165
+ # First scrolls to the beginning of the scrollable container and then scrolls down until element is found or end is reached
166
+ # @return [TestaAppiumDriver::Locator]
167
+ def scroll_to(top: nil, bottom: nil, right: nil, left: nil, max_scrolls: nil, direction: nil)
168
+ if direction
169
+ _scroll_dir_to(_process_deadzone(top, bottom, right, left), max_scrolls, direction)
170
+ else
171
+ _scroll_to(_process_deadzone(top, bottom, right, left), max_scrolls)
172
+ end
173
+ end
174
+
175
+
176
+ # Scrolls down until element is found or end is reached
177
+ # @return [TestaAppiumDriver::Locator]
178
+ def scroll_down_to(top: nil, bottom: nil, right: nil, left: nil, max_scrolls: nil)
179
+ _scroll_dir_to(_process_deadzone(top, bottom, right, left), max_scrolls, :down)
180
+ end
181
+
182
+ # Scrolls up until element is found or end is reached
183
+ # @return [TestaAppiumDriver::Locator]
184
+ def scroll_up_to(top: nil, bottom: nil, right: nil, left: nil, max_scrolls: nil)
185
+ _scroll_dir_to(_process_deadzone(top, bottom, right, left), max_scrolls, :up)
186
+ end
187
+
188
+ # Scrolls right until element is found or end is reached
189
+ # @return [TestaAppiumDriver::Locator]
190
+ def scroll_right_to(top: nil, bottom: nil, right: nil, left: nil, max_scrolls: nil)
191
+ _scroll_dir_to(_process_deadzone(top, bottom, right, left), max_scrolls, :right)
192
+ end
193
+
194
+
195
+ # Scrolls left until element is found or end is reached
196
+ # @return [TestaAppiumDriver::Locator]
197
+ def scroll_left_to(top: nil, bottom: nil, right: nil, left: nil, max_scrolls: nil)
198
+ _scroll_dir_to(_process_deadzone(top, bottom, right, left), max_scrolls, :left)
199
+ end
200
+
201
+ # Scrolls to the start of the scrollable container (top on vertical container, left on horizontal)
202
+ # @return [TestaAppiumDriver::Locator]
203
+ def scroll_to_start(top: nil, bottom: nil, right: nil, left: nil)
204
+ _scroll_to_start_or_end(:start, _process_deadzone(top, bottom, right, left))
205
+ end
206
+
207
+ # Scrolls to the end of the scrollable container (bottom on vertical container, right on horizontal)
208
+ # @return [TestaAppiumDriver::Locator]
209
+ def scroll_to_end(top: nil, bottom: nil, right: nil, left: nil)
210
+ _scroll_to_start_or_end(:end, _process_deadzone(top, bottom, right, left))
211
+ end
212
+
213
+
214
+ # @return [TestaAppiumDriver::Locator]
215
+ def page_down(top: nil, bottom: nil, right: nil, left: nil)
216
+ _page(:down, _process_deadzone(top, bottom, right, left))
217
+ end
218
+
219
+ # @return [TestaAppiumDriver::Locator]
220
+ def page_up(top: nil, bottom: nil, right: nil, left: nil)
221
+ _page(:up, _process_deadzone(top, bottom, right, left))
222
+ end
223
+
224
+ # @return [TestaAppiumDriver::Locator]
225
+ def page_left(top: nil, bottom: nil, right: nil, left: nil)
226
+ _page(:left, _process_deadzone(top, bottom, right, left))
227
+ end
228
+
229
+ # @return [TestaAppiumDriver::Locator]
230
+ def page_right(top: nil, bottom: nil, right: nil, left: nil)
231
+ _page(:right, _process_deadzone(top, bottom, right, left))
232
+ end
233
+
234
+ # @return [TestaAppiumDriver::Locator]
235
+ def fling_down(top: nil, bottom: nil, right: nil, left: nil)
236
+ _fling(:down, _process_deadzone(top, bottom, right, left))
237
+ end
238
+
239
+ # @return [TestaAppiumDriver::Locator]
240
+ def fling_up(top: nil, bottom: nil, right: nil, left: nil)
241
+ _fling(:up, _process_deadzone(top, bottom, right, left))
242
+ end
243
+
244
+ # @return [TestaAppiumDriver::Locator]
245
+ def fling_left(top: nil, bottom: nil, right: nil, left: nil)
246
+ _fling(:left, _process_deadzone(top, bottom, right, left))
247
+ end
248
+
249
+ # @return [TestaAppiumDriver::Locator]
250
+ def fling_right(top: nil, bottom: nil, right: nil, left: nil)
251
+ _fling(:right, _process_deadzone(top, bottom, right, left))
252
+ end
253
+
254
+ def drag_up_by(amount)
255
+ drag_by(amount, direction: :top)
256
+ end
257
+
258
+ def drag_down_by(amount)
259
+ drag_by(amount, direction: :bottom)
260
+ end
261
+
262
+ def drag_left_by(amount)
263
+ drag_by(amount, direction: :left)
264
+ end
265
+
266
+ def drag_right_by(amount)
267
+ drag_by(amount, direction: :right)
268
+ end
269
+
270
+
271
+ # @param [TestaAppiumDriver::Locator, Hash, Selenium::WebDriver::Element, String] to
272
+ #noinspection RubyYardParamTypeMatch,RubyScope
273
+ def drag_to(to)
274
+ if !to.kind_of?(Selenium::WebDriver::Element) && !to.kind_of?(TestaAppiumDriver::Locator) && !to.kind_of?(Hash)
275
+ raise "Parameter not accepted, acceptable instances of [TestaAppiumDriver::Locator, Hash, Selenium::WebDriver::Element]"
276
+ end
277
+ if to.kind_of?(Selenium::WebDriver::Element)
278
+ bounds = TestaAppiumDriver::Bounds.from_android(to.bounds, @driver)
279
+ x = bounds.center.x
280
+ y = bounds.center.y
281
+ end
282
+ if to.kind_of?(TestaAppiumDriver::Locator)
283
+ bounds = to.bounds
284
+ x = bounds.center.x
285
+ y = bounds.center.y
286
+ end
287
+ if to.kind_of?(Hash)
288
+ raise "Missing x coordinate" if to[:x].nil?
289
+ raise "Missing y coordinate" if to[:y].nil?
290
+ x = to[:x]
291
+ y = to[:y]
292
+ end
293
+ _drag_to(bounds.center.x, bounds.center.y, x, y)
294
+ end
295
+
296
+ def drag_by(amount, direction: :top)
297
+ b = bounds
298
+ x = b.center.x
299
+ y = b.center.y
300
+ case direction
301
+ when :top
302
+ y -= amount.to_i
303
+ when :bottom
304
+ y += amount.to_i
305
+ when :left
306
+ x -= amount.to_i
307
+ when :right
308
+ x += amount.to_i
309
+ else
310
+ raise "Unknown direction #{direction}"
311
+ end
312
+ _drag_to(b.center.x, b.center.y, x, y)
313
+ end
314
+
315
+
316
+
317
+ private
318
+ def _process_deadzone(top, bottom, right, left)
319
+ deadzone = nil
320
+ if !top.nil? || !bottom.nil? || !right.nil? || !left.nil?
321
+ deadzone = {}
322
+ deadzone[:top] = top unless top.nil?
323
+ deadzone[:bottom] = bottom unless bottom.nil?
324
+ deadzone[:right] = right unless right.nil?
325
+ deadzone[:left] = left unless left.nil?
326
+ end
327
+ deadzone
328
+ end
329
+
330
+ def _drag_to(x0, y0, x1, y1)
331
+ sa = ScrollActions.new(@scrollable_locator,
332
+ locator: self,
333
+ default_scroll_strategy: @default_scroll_strategy)
334
+ sa.drag_to(x0, y0, x1, y1)
335
+ self
336
+ end
337
+
338
+
339
+ def _page(direction, deadzone)
340
+ deadzone = @scrollable_locator.scroll_deadzone if deadzone.nil? && !@scrollable_locator.nil?
341
+ sa = ScrollActions.new(@scrollable_locator,
342
+ locator: self,
343
+ deadzone: deadzone,
344
+ direction: direction.to_sym,
345
+ default_scroll_strategy: @default_scroll_strategy)
346
+ sa.send("page_#{direction}")
347
+ self
348
+ end
349
+
350
+ def _fling(direction, deadzone)
351
+ deadzone = @scrollable_locator.scroll_deadzone if deadzone.nil? && !@scrollable_locator.nil?
352
+ sa = ScrollActions.new(@scrollable_locator,
353
+ locator: self,
354
+ deadzone: deadzone,
355
+ direction: direction.to_sym,
356
+ default_scroll_strategy: @default_scroll_strategy)
357
+ sa.send("fling_#{direction}")
358
+ self
359
+ end
360
+
361
+ def _scroll_to_start_or_end(type, deadzone)
362
+ deadzone = @scrollable_locator.scroll_deadzone if deadzone.nil? && !@scrollable_locator.nil?
363
+ sa = ScrollActions.new(@scrollable_locator,
364
+ locator: self,
365
+ deadzone: deadzone,
366
+ default_scroll_strategy: @default_scroll_strategy)
367
+ if type == :start
368
+ sa.scroll_to_start
369
+ else
370
+ sa.scroll_to_end
371
+ end
372
+ self
373
+ end
374
+
375
+ def _scroll_to(deadzone, max_scrolls)
376
+ deadzone = @scrollable_locator.scroll_deadzone if deadzone.nil? && !@scrollable_locator.nil?
377
+ sa = ScrollActions.new(@scrollable_locator,
378
+ locator: self,
379
+ deadzone: deadzone,
380
+ max_scrolls: max_scrolls,
381
+ default_scroll_strategy: @default_scroll_strategy)
382
+ sa.scroll_to
383
+ self
384
+ end
385
+
386
+ def _scroll_dir_to(deadzone, max_scrolls, direction)
387
+ deadzone = @scrollable_locator.scroll_deadzone if deadzone.nil? && !@scrollable_locator.nil?
388
+ sa = ScrollActions.new(@scrollable_locator,
389
+ locator: self,
390
+ deadzone: deadzone,
391
+ max_scrolls: max_scrolls,
392
+ default_scroll_strategy: @default_scroll_strategy)
393
+
394
+ sa.send("scroll_#{direction}_to")
395
+ self
396
+ end
397
+ end
397
398
  end