testa_appium_driver 0.1.20 → 0.1.22

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/.gitattributes +23 -0
  3. data/.gitignore +17 -0
  4. data/.rspec +3 -0
  5. data/.rubocop.yml +6 -0
  6. data/Gemfile.lock +1 -1
  7. data/bin/console +17 -0
  8. data/bin/setup +8 -0
  9. data/lib/testa_appium_driver/android/class_selectors.rb +438 -0
  10. data/lib/testa_appium_driver/android/driver.rb +71 -0
  11. data/lib/testa_appium_driver/android/locator/attributes.rb +115 -0
  12. data/lib/testa_appium_driver/android/locator.rb +142 -0
  13. data/lib/testa_appium_driver/android/scroll_actions/uiautomator_scroll_actions.rb +62 -0
  14. data/lib/testa_appium_driver/android/selenium_element.rb +12 -0
  15. data/lib/testa_appium_driver/common/bounds.rb +150 -0
  16. data/lib/testa_appium_driver/common/constants.rb +38 -0
  17. data/lib/testa_appium_driver/common/exceptions/strategy_mix_exception.rb +12 -0
  18. data/lib/testa_appium_driver/common/helpers.rb +272 -0
  19. data/lib/testa_appium_driver/common/locator/scroll_actions.rb +390 -0
  20. data/lib/testa_appium_driver/common/locator.rb +640 -0
  21. data/lib/testa_appium_driver/common/scroll_actions/json_wire_scroll_actions.rb +4 -0
  22. data/lib/testa_appium_driver/common/scroll_actions/w3c_scroll_actions.rb +371 -0
  23. data/lib/testa_appium_driver/common/scroll_actions.rb +271 -0
  24. data/lib/testa_appium_driver/common/selenium_element.rb +19 -0
  25. data/lib/testa_appium_driver/driver.rb +338 -0
  26. data/lib/testa_appium_driver/ios/driver.rb +49 -0
  27. data/lib/testa_appium_driver/ios/locator/attributes.rb +89 -0
  28. data/lib/testa_appium_driver/ios/locator.rb +73 -0
  29. data/lib/testa_appium_driver/ios/selenium_element.rb +8 -0
  30. data/lib/testa_appium_driver/ios/type_selectors.rb +201 -0
  31. data/lib/testa_appium_driver.rb +4 -0
  32. data/testa_appium_driver.gemspec +6 -2
  33. metadata +39 -11
  34. data/appium-driver.iml +0 -79
@@ -0,0 +1,371 @@
1
+ module ::TestaAppiumDriver
2
+ module W3cScrollActions
3
+ # @return [Array]
4
+ def w3c_scroll_each(direction, &block)
5
+ default_deadzone!
6
+ if direction.nil?
7
+ scroll_to_start
8
+ if @scrollable.scroll_orientation == :vertical
9
+ direction = :down
10
+ else
11
+ direction = :right
12
+ end
13
+ end
14
+
15
+ case direction
16
+ when :up
17
+ align_with = :bottom
18
+ when :down
19
+ align_with = :top
20
+ when :right
21
+ align_with = :left
22
+ when :left
23
+ align_with = :right
24
+ else
25
+ align_with = :top
26
+ end
27
+
28
+ if @driver.ios?
29
+ w3c_scroll_each_ios(direction, align_with, &block)
30
+ else
31
+ w3c_scroll_each_android(direction, align_with, &block)
32
+ end
33
+ end
34
+
35
+ def w3c_scroll_each_android(direction, align_with, &block)
36
+ elements = []
37
+ begin
38
+
39
+ iterations = 0
40
+ ignore_element_ids = []
41
+ previous_element = nil
42
+
43
+ until is_end_of_scroll?
44
+ # # $__.puts "-- new iteration"
45
+ # # $__.puts "-------------"
46
+ aligned_items = 0
47
+ new_ignore_element_ids = []
48
+ matches = @locator.execute(skip_cache: true)
49
+ matches.each_with_index do |m, index|
50
+ # # $__.puts "Matches: #{matches.count}"
51
+ # # $__.puts "M: #{m.id}"
52
+ if ignore_element_ids.include?(m.id)
53
+ previous_element = m
54
+ next
55
+ end
56
+
57
+ sa = self.dup
58
+ sa.locator = m
59
+ sa.w3c_align(align_with, false, 1, speed_coef: 2.0)
60
+ is_aligned = sa.is_aligned?(align_with, m)
61
+
62
+ # add the previous to ignore if current is not aligned (probably means we cannot scroll any further)
63
+ new_ignore_element_ids << previous_element.id if !is_aligned && !previous_element.nil?
64
+
65
+ aligned_items += 1 if is_aligned
66
+
67
+ # add last element to ignore
68
+ new_ignore_element_ids << m.id if matches.count == index + 1
69
+
70
+ elements << m
71
+ if block_given? # block is given
72
+ @locator.driver.invalidate_cache
73
+ block.call(m) # use call to execute the block
74
+ else
75
+ # the value of block_argument becomes nil if you didn't give a block
76
+ # block was not given
77
+ end
78
+ previous_element = m
79
+ end
80
+
81
+ iterations += 1
82
+ break if !@max_scrolls.nil? && iterations == @max_scrolls
83
+
84
+ if aligned_items.zero?
85
+ self.send("page_#{direction}")
86
+ else
87
+ ignore_element_ids = new_ignore_element_ids.dup
88
+ end
89
+ end
90
+ rescue StandardError => e
91
+ raise e
92
+ end
93
+
94
+ elements
95
+ end
96
+
97
+ def w3c_scroll_each_ios(direction, align_with, &block)
98
+ elements = []
99
+ elements_in_current_iteration = []
100
+ begin
101
+ iterations = 0
102
+
103
+ loop do
104
+ elements_in_last_iteration = elements_in_current_iteration
105
+ elements_in_current_iteration = []
106
+ elements_count_before_iteration = elements.count
107
+
108
+ new_element_in_this_iteration_found = false
109
+ matches = @locator.execute(skip_cache: true)
110
+ matches.each do |m|
111
+ elements_in_current_iteration << m.id
112
+
113
+ element_found_in_last_iteration = elements_in_last_iteration.include?(m.id)
114
+
115
+ # ignore all elements from last iteration until first new element is found
116
+ if !new_element_in_this_iteration_found && element_found_in_last_iteration
117
+ next
118
+ end
119
+
120
+ # new element in this iteration is found,
121
+ # process all remaining elements regardless if it is found in last iteration or not
122
+ new_element_in_this_iteration_found = true
123
+
124
+ sa = self.dup
125
+ sa.locator = m
126
+ sa.w3c_align(align_with, false, 1, speed_coef: 2.0)
127
+
128
+ elements << m.id
129
+ if block_given? # block is given
130
+ @locator.driver.invalidate_cache
131
+ block.call(m) # use call to execute the block
132
+ else
133
+ # the value of block_argument becomes nil if you didn't give a block
134
+ # block was not given
135
+ end
136
+ end
137
+
138
+ iterations += 1
139
+ break if !@max_scrolls.nil? && iterations == @max_scrolls
140
+
141
+ if matches.count.positive?
142
+ # if there are elements on screen, but there are no new elements
143
+ # then we have reached the end of scrolling
144
+ if elements.count == elements_count_before_iteration
145
+ return elements
146
+ end
147
+ else
148
+ # there are no matching elements. to detect end of scroll,
149
+ # first and last leaf is compared before with first and last leaf of previous iteration
150
+ if is_end_of_scroll?
151
+ return elements
152
+ end
153
+ end
154
+
155
+ # if there are more than 1 match on screen,
156
+ # the page is scrolled by aligning elements 1 by one,
157
+ # but if there is only 1, or none elements.
158
+ # then scroll the page manually
159
+ self.send("page_#{direction}") if matches.count < 2
160
+ end
161
+ rescue Selenium::WebDriver::Error::StaleElementReferenceError
162
+ # if boundElementsByIndex is enabled, we can get stale element reference while doing scroll each
163
+ retry
164
+ rescue StandardError => e
165
+ raise e
166
+ end
167
+
168
+ elements
169
+ end
170
+
171
+ def w3c_align(with, scroll_to_find, max_attempts, speed_coef: 1.25)
172
+ default_deadzone!
173
+
174
+ @locator.scroll_to if scroll_to_find
175
+
176
+ if @locator.instance_of?(TestaAppiumDriver::Locator)
177
+ element = @locator.execute
178
+ else
179
+ element = @locator
180
+ end
181
+
182
+ max_attempts = 3 if max_attempts.nil? || max_attempts <= 0
183
+ # $ctx.puts("Is aligned: #{is_aligned?(with, element)}")
184
+ timeout = 0
185
+ until is_aligned?(with, element) || timeout == max_attempts
186
+ # $ctx.puts("align roudn: #{timeout}")
187
+ w3c_attempt_align(with, speed_coef)
188
+ timeout += 1
189
+ end
190
+ # $ctx.puts("end align")
191
+ end
192
+
193
+ def w3c_attempt_align(with, speed_coef)
194
+ case with
195
+ when :top
196
+ y0 = @bounds.bottom_right.y - @deadzone[:bottom]
197
+ y1 = y0 - @align_offset
198
+ x0 = @bounds.width / 2
199
+ x1 = x0
200
+ scroll_direction = :down
201
+ when :bottom
202
+ y0 = @bounds.top_left.y + @deadzone[:top]
203
+ y1 = y0 + @align_offset
204
+ x0 = @bounds.width / 2
205
+ x1 = x0
206
+ scroll_direction = :up
207
+ when :left
208
+ x0 = @bounds.bottom_right.x - @deadzone[:right]
209
+ x1 = x0 - @align_offset
210
+ y0 = @bounds.height / 2
211
+ y1 = y0
212
+ scroll_direction = :right
213
+ when :right
214
+ x0 = @bounds.top_left.x + @deadzone[:top]
215
+ x1 = x0 + @align_offset
216
+ y0 = @bounds.height / 2
217
+ y1 = y0
218
+ scroll_direction = :left
219
+ else
220
+ raise "Unsupported align with option: #{with}"
221
+ end
222
+
223
+ x1, y1 = apply_w3c_correction(x1, y1, scroll_direction) if @driver.device == :android
224
+ w3c_action(x0, y0, x1, y1, SCROLL_ACTION_TYPE_SCROLL, speed_coef: speed_coef)
225
+ end
226
+
227
+ def w3c_scroll_to(direction)
228
+ rounds = 0
229
+ max_scrolls_reached = false
230
+ end_of_scroll_reached = false
231
+ # $ctx.puts("starting scroll to")
232
+ until (@driver.android? && @locator.exists?) ||
233
+ (@driver.ios? && @locator.exists? && @locator.in_viewport?) || end_of_scroll_reached
234
+ # $ctx.puts("Scroll to round: #{rounds}")
235
+ end_of_scroll_reached = is_end_of_scroll?
236
+ case direction
237
+ when :down
238
+ page_down
239
+ when :right
240
+ page_right
241
+ when :left
242
+ page_left
243
+ when :up
244
+ page_up
245
+ else
246
+ scroll_to_start
247
+ @previous_elements = nil
248
+ if @scrollable.scroll_orientation == :vertical
249
+ direction = :down
250
+ else
251
+ direction = :right
252
+ end
253
+ end
254
+
255
+ rounds += 1
256
+
257
+ max_scrolls_reached = true if rounds == @max_scrolls
258
+ break if rounds == @max_scrolls
259
+ end
260
+ # $ctx.puts("end scroll to")
261
+ raise Selenium::WebDriver::Error::NoSuchElementError if max_scrolls_reached || end_of_scroll_reached
262
+ end
263
+
264
+ def w3c_scroll_to_start_or_end(type)
265
+ default_deadzone!
266
+
267
+ @previous_elements = nil
268
+
269
+ if type == :start
270
+ if @scrollable.scroll_orientation == :vertical
271
+ method = "fling_up"
272
+ else
273
+ method = "fling_left"
274
+ end
275
+ else
276
+ if @scrollable.scroll_orientation == :vertical
277
+ method = "fling_down"
278
+ else
279
+ method = "fling_right"
280
+ end
281
+ end
282
+
283
+ iterations = 0
284
+ until is_end_of_scroll? || iterations >= 3
285
+ self.send(method)
286
+ iterations += 1
287
+ end
288
+
289
+ # reset the flag for end of scroll elements
290
+ @previous_elements = nil
291
+ end
292
+
293
+ def w3c_page_or_fling(type, direction)
294
+ default_deadzone!
295
+
296
+ if direction == :down || direction == :up
297
+ if direction == :down
298
+ y0 = @bounds.bottom_right.y - @deadzone[:bottom].to_i
299
+ y1 = @bounds.top_left.y + @deadzone[:top].to_i
300
+ else
301
+ y0 = @bounds.top_left.y + @deadzone[:top].to_i
302
+ y1 = @bounds.bottom_right.y - @deadzone[:bottom].to_i
303
+ end
304
+ x0 = @bounds.top_left.x + (@bounds.width - @deadzone[:left].to_i - @deadzone[:right].to_i) / 2
305
+ x0 = @bounds.top_left.x if x0 < @bounds.top_left.x
306
+ x0 = @bounds.bottom_right.x if x0 > @bounds.bottom_right.x
307
+ x1 = x0
308
+ else
309
+ if direction == :right
310
+ x0 = @bounds.bottom_right.x - @deadzone[:right].to_i
311
+ x1 = @bounds.top_left.x + @deadzone[:left].to_i
312
+ else
313
+ x0 = @bounds.top_left.x + @deadzone[:left].to_i
314
+ x1 = @bounds.bottom_right.x - @deadzone[:right].to_i
315
+ end
316
+
317
+ y0 = @bounds.top_left.y + (@bounds.height - @deadzone[:top].to_i - @deadzone[:bottom].to_i) / 2
318
+ y0 = @bounds.top_left.y if y0 < @bounds.top_left.y
319
+ y0 = @bounds.bottom_right.y if y0 > @bounds.bottom_right.y
320
+ y1 = y0
321
+ end
322
+ x1, y1 = apply_w3c_correction(x1, y1, direction) if @driver.device == :android
323
+
324
+ speed_coef = 1
325
+ speed_coef = 1.5 if type == SCROLL_ACTION_TYPE_SCROLL
326
+
327
+ w3c_action(x0, y0, x1, y1, type, speed_coef: speed_coef)
328
+ end
329
+
330
+ def w3c_action(x0, y0, x1, y1, type, speed_coef: 1.0)
331
+ speed_coef = 1 / speed_coef
332
+ if type == SCROLL_ACTION_TYPE_SCROLL
333
+ duration = 1.8 * speed_coef
334
+ elsif type == SCROLL_ACTION_TYPE_FLING
335
+ duration = 0.1 * speed_coef
336
+ elsif type == SCROLL_ACTION_TYPE_DRAG
337
+ duration = 3.5 * speed_coef
338
+ else
339
+ raise "Unknown scroll action type #{type}"
340
+ end
341
+
342
+ action_builder = @driver.action
343
+ f1 = action_builder.add_pointer_input(:touch, "finger1")
344
+ f1.create_pointer_move(duration: 0, x: x0, y: y0, origin: ::Selenium::WebDriver::Interactions::PointerMove::VIEWPORT)
345
+ f1.create_pointer_down(:left)
346
+
347
+ f1.create_pointer_move(duration: duration, x: x1, y: y1, origin: ::Selenium::WebDriver::Interactions::PointerMove::VIEWPORT)
348
+ unless type == SCROLL_ACTION_TYPE_FLING
349
+ # with this move we prevent flinging/overscroll
350
+ overscroll_pause = @driver.ios? ? 1 : 0.5
351
+ f1.create_pointer_move(duration: overscroll_pause, x: x1, y: y1, origin: ::Selenium::WebDriver::Interactions::PointerMove::VIEWPORT)
352
+ end
353
+ f1.create_pointer_up(:left)
354
+ puts "Scroll execute[w3c_action]: #{type}: {x0: #{x0}, y0: #{y0}} => (duration: #{duration}) => {x1: #{x1}, y1: #{y1}}"
355
+ # $ctx.puts "Scroll execute[w3c_action]: #{type}: {x0: #{x0}, y0: #{y0}} => (duration: #{duration}) => {x1: #{x1}, y1: #{y1}}"
356
+ @driver.perform_actions [f1]
357
+ end
358
+
359
+ def apply_w3c_correction(x1, y1, direction)
360
+ y1 -= SCROLL_CORRECTION_W3C if direction == :down
361
+ y1 += SCROLL_CORRECTION_W3C if direction == :up
362
+ x1 -= SCROLL_CORRECTION_W3C if direction == :right
363
+ x1 += SCROLL_CORRECTION_W3C if direction == :left
364
+ [x1, y1]
365
+ end
366
+
367
+ def w3c_drag_to(x0, y0, x1, y1)
368
+ w3c_action(x0, y0, x1, y1, SCROLL_ACTION_TYPE_DRAG)
369
+ end
370
+ end
371
+ end
@@ -0,0 +1,271 @@
1
+ require_relative 'scroll_actions/json_wire_scroll_actions'
2
+ require_relative 'scroll_actions/w3c_scroll_actions'
3
+
4
+ module ::TestaAppiumDriver
5
+
6
+ # Class for handling scroll actions
7
+ class ScrollActions
8
+ include W3cScrollActions
9
+ include JsonWireScrollActions
10
+
11
+ attr_accessor :locator
12
+ # @param [TestaAppiumDriver::Locator, nil] scrollable container that will be used to determine the bounds for scrolling
13
+ # @param [Hash] params
14
+ # acceptable params
15
+ # - locator - element that should be found with scrolling actions
16
+ # - deadzone - [Hash] that stores top, bottom, left and right deadzone values. If deadzone[:top] is 200 then 200px from top of the scrollable container will not be used for scrolling
17
+ # - max_scrolls - [Integer] maximum number of scrolls before exception is thrown
18
+ # - default_scroll_strategy - defines which scroll strategy will be used if a scroll action is valid for multiple strategies
19
+ def initialize(scrollable, params = {})
20
+ @scrollable = scrollable
21
+ @locator = params[:locator]
22
+ # TODO: raise error if locator is for multiple, but not for scroll each, chekc other cases aswell
23
+ @deadzone = params[:deadzone]
24
+ @max_scrolls = params[:max_scrolls]
25
+ @default_scroll_strategy = params[:default_scroll_strategy]
26
+ @driver = @locator.driver
27
+
28
+ if @scrollable.nil?
29
+ # if we dont have a scrollable element or if we do have it, but it is not compatible with uiautomator
30
+ # then find first scrollable in document
31
+ @scrollable = @driver.scrollable
32
+ end
33
+
34
+ @strategy = nil
35
+ if @scrollable.strategy == FIND_STRATEGY_XPATH || # uiautomator cannot resolve scrollable from a xpath locator
36
+ !@deadzone.nil? ||
37
+ !@scrollable.from_element.instance_of?(TestaAppiumDriver::Driver) # uiautomator cannot resolve nested scrollable
38
+ @strategy = SCROLL_STRATEGY_W3C
39
+ end
40
+
41
+ @bounds = @scrollable.bounds
42
+ end
43
+
44
+ def align(with, scroll_to_find, max_attempts)
45
+ w3c_align(with, scroll_to_find, max_attempts)
46
+ @locator
47
+ end
48
+
49
+ # @return [Array]
50
+ def scroll_each(&block)
51
+ w3c_scroll_each(nil, &block)
52
+ end
53
+
54
+ def scroll_each_down(&block)
55
+ w3c_scroll_each(:down, &block)
56
+ end
57
+
58
+ def scroll_each_up(&block)
59
+ w3c_scroll_each(:up, &block)
60
+ end
61
+
62
+ def scroll_each_right(&block)
63
+ w3c_scroll_each(:right, &block)
64
+ end
65
+
66
+ def scroll_each_left(&block)
67
+ w3c_scroll_each(:left, &block)
68
+ end
69
+
70
+ def resolve_strategy
71
+ if @strategy.nil?
72
+ @default_scroll_strategy
73
+ else
74
+ @strategy
75
+ end
76
+ end
77
+
78
+ def scroll_to
79
+ if @locator.strategy != FIND_STRATEGY_XPATH && resolve_strategy == SCROLL_STRATEGY_UIAUTOMATOR
80
+ uiautomator_scroll_to
81
+ elsif resolve_strategy == SCROLL_STRATEGY_W3C
82
+ w3c_scroll_to(nil)
83
+ end
84
+ end
85
+
86
+ def scroll_down_to
87
+ w3c_scroll_to(:down)
88
+ end
89
+
90
+ def scroll_up_to
91
+ w3c_scroll_to(:up)
92
+ end
93
+
94
+ def scroll_right_to
95
+ w3c_scroll_to(:right)
96
+ end
97
+
98
+ def scroll_left_to
99
+ w3c_scroll_to(:left)
100
+ end
101
+
102
+ def page_next
103
+ if @scrollable.scroll_orientation == :vertical
104
+ page_down
105
+ else
106
+ page_left
107
+ end
108
+ end
109
+
110
+ def page_back
111
+ if @scrollable.scroll_orientation == :vertical
112
+ page_up
113
+ else
114
+ page_right
115
+ end
116
+ end
117
+
118
+ def page_down
119
+ if resolve_strategy == SCROLL_STRATEGY_UIAUTOMATOR
120
+ uiautomator_page_or_fling(SCROLL_ACTION_TYPE_SCROLL, :down)
121
+ elsif resolve_strategy == SCROLL_STRATEGY_W3C
122
+ w3c_page_or_fling(SCROLL_ACTION_TYPE_SCROLL, :down)
123
+ end
124
+ end
125
+
126
+ def page_right
127
+ if resolve_strategy == SCROLL_STRATEGY_UIAUTOMATOR
128
+ uiautomator_page_or_fling(SCROLL_ACTION_TYPE_SCROLL, :right)
129
+ elsif resolve_strategy == SCROLL_STRATEGY_W3C
130
+ w3c_page_or_fling(SCROLL_ACTION_TYPE_SCROLL, :right)
131
+ end
132
+ end
133
+
134
+ def page_up
135
+ if resolve_strategy == SCROLL_STRATEGY_UIAUTOMATOR
136
+ uiautomator_page_or_fling(SCROLL_ACTION_TYPE_SCROLL, :up)
137
+ elsif resolve_strategy == SCROLL_STRATEGY_W3C
138
+ w3c_page_or_fling(SCROLL_ACTION_TYPE_SCROLL, :up)
139
+ end
140
+ end
141
+
142
+ def page_left
143
+ if resolve_strategy == SCROLL_STRATEGY_UIAUTOMATOR
144
+ uiautomator_page_or_fling(SCROLL_ACTION_TYPE_SCROLL, :left)
145
+ elsif resolve_strategy == SCROLL_STRATEGY_W3C
146
+ w3c_page_or_fling(SCROLL_ACTION_TYPE_SCROLL, :left)
147
+ end
148
+ end
149
+
150
+ def scroll_to_start
151
+ if resolve_strategy == SCROLL_STRATEGY_UIAUTOMATOR
152
+ uiautomator_scroll_to_start_or_end(:start)
153
+
154
+ elsif resolve_strategy == SCROLL_STRATEGY_W3C
155
+ w3c_scroll_to_start_or_end(:start)
156
+ end
157
+ end
158
+
159
+ def scroll_to_end
160
+ if resolve_strategy == SCROLL_STRATEGY_UIAUTOMATOR
161
+ uiautomator_scroll_to_start_or_end(:end)
162
+ elsif resolve_strategy == SCROLL_STRATEGY_W3C
163
+ w3c_scroll_to_start_or_end(:end)
164
+ end
165
+ end
166
+
167
+ def fling_down
168
+ if resolve_strategy == SCROLL_STRATEGY_UIAUTOMATOR
169
+ uiautomator_page_or_fling(SCROLL_ACTION_TYPE_FLING, :down)
170
+ elsif resolve_strategy == SCROLL_STRATEGY_W3C
171
+ w3c_page_or_fling(SCROLL_ACTION_TYPE_FLING, :down)
172
+ end
173
+ end
174
+
175
+ def fling_right
176
+ if resolve_strategy == SCROLL_STRATEGY_UIAUTOMATOR
177
+ uiautomator_page_or_fling(SCROLL_ACTION_TYPE_FLING, :right)
178
+ elsif resolve_strategy == SCROLL_STRATEGY_W3C
179
+ w3c_page_or_fling(SCROLL_ACTION_TYPE_FLING, :right)
180
+ end
181
+ end
182
+
183
+ def fling_up
184
+ if resolve_strategy == SCROLL_STRATEGY_UIAUTOMATOR
185
+ uiautomator_page_or_fling(SCROLL_ACTION_TYPE_FLING, :up)
186
+ elsif resolve_strategy == SCROLL_STRATEGY_W3C
187
+ w3c_page_or_fling(SCROLL_ACTION_TYPE_FLING, :up)
188
+ end
189
+ end
190
+
191
+ def fling_left
192
+ if resolve_strategy == SCROLL_STRATEGY_UIAUTOMATOR
193
+ uiautomator_page_or_fling(SCROLL_ACTION_TYPE_FLING, :left)
194
+ elsif resolve_strategy == SCROLL_STRATEGY_W3C
195
+ w3c_page_or_fling(SCROLL_ACTION_TYPE_FLING, :left)
196
+ end
197
+ end
198
+
199
+ def drag_to(x0, y0, x1, y1)
200
+ w3c_drag_to(x0, y0, x1, y1)
201
+ end
202
+
203
+
204
+ def is_aligned?(with, element)
205
+ align_bounds = @locator.bounds(force_cache_element: element)
206
+ case with
207
+ when :top
208
+ @align_offset = align_bounds.top_left.y - @bounds.top_left.y - @deadzone[:top]
209
+ when :bottom
210
+ @align_offset = @bounds.bottom_right.y - @deadzone[:bottom] - align_bounds.bottom_right.y
211
+ when :right
212
+ @align_offset = @bounds.bottom_right.x - @deadzone[:right] - align_bounds.bottom_right.x
213
+ when :left
214
+ @align_offset = align_bounds.top_left.x - @bounds.top_left.x - @deadzone[:left]
215
+ else
216
+ raise "Unsupported align with option: #{with}"
217
+ end
218
+ @align_offset < SCROLL_ALIGNMENT_THRESHOLD
219
+ end
220
+
221
+
222
+
223
+ def is_end_of_scroll?
224
+ # if @driver.device == :android
225
+
226
+ old_elements = @previous_elements
227
+ @previous_elements = @scrollable.first_and_last_leaf
228
+
229
+
230
+ # $__.puts "old: #{old_elements}"
231
+ # $__.puts "new: #{@previous_elements}"
232
+ # $__.puts "end_of_scroll? #{ old_elements == @previous_elements}"
233
+ old_elements == @previous_elements
234
+ # else
235
+ # # for ios, check location of first and last elements
236
+ # old_elements = @previous_elements
237
+ # @previous_elements = @scrollable.first_and_last_child&.map(&:location)
238
+ # # $__.puts "old:"
239
+ # # $__.puts old_elements
240
+ # # $__.puts "prev:"
241
+ # # $__.puts @previous_elements
242
+ # old_elements == @previous_elements
243
+ # end
244
+ end
245
+
246
+ def default_deadzone!
247
+ @deadzone = {} if @deadzone.nil?
248
+ if @deadzone[:top].nil?
249
+ @deadzone[:top] = 1
250
+ else
251
+ @deadzone[:top] = @deadzone[:top].to_f
252
+ end
253
+ if @deadzone[:bottom].nil?
254
+ @deadzone[:bottom] = 1
255
+ else
256
+ @deadzone[:bottom] = @deadzone[:bottom].to_f
257
+ end
258
+ if @deadzone[:right].nil?
259
+ @deadzone[:right] = 1
260
+ else
261
+ @deadzone[:right] = @deadzone[:right].to_f
262
+ end
263
+ if @deadzone[:left].nil?
264
+ @deadzone[:left] = 1
265
+ else
266
+ @deadzone[:left] = @deadzone[:left].to_f
267
+ end
268
+ end
269
+
270
+ end
271
+ end
@@ -0,0 +1,19 @@
1
+ module ::Appium
2
+ module Core
3
+ class Element
4
+ # sets the testa appium driver instance for the current phone
5
+ def self.set_driver(driver, udid)
6
+ udid = "unknown" if udid.nil?
7
+ @@drivers ||= {}
8
+ @@drivers[udid] = driver
9
+ end
10
+
11
+ # @return [TestaAppiumDriver::Driver] testa appium driver instance for the current phone
12
+ def get_driver
13
+ udid = @bridge.capabilities.instance_variable_get(:@capabilities)["udid"]
14
+ udid = "unknown" if udid.nil?
15
+ @@drivers[udid]
16
+ end
17
+ end
18
+ end
19
+ end