testa_appium_driver 0.1.18 → 0.1.20

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 (36) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -0
  3. data/Gemfile.lock +5 -1
  4. data/appium-driver.iml +79 -0
  5. data/testa_appium_driver.gemspec +4 -8
  6. metadata +11 -40
  7. data/.gitattributes +0 -23
  8. data/.gitignore +0 -17
  9. data/.rspec +0 -3
  10. data/.rubocop.yml +0 -5
  11. data/bin/console +0 -17
  12. data/bin/setup +0 -8
  13. data/lib/testa_appium_driver/android/class_selectors.rb +0 -438
  14. data/lib/testa_appium_driver/android/driver.rb +0 -71
  15. data/lib/testa_appium_driver/android/locator/attributes.rb +0 -118
  16. data/lib/testa_appium_driver/android/locator.rb +0 -142
  17. data/lib/testa_appium_driver/android/scroll_actions/uiautomator_scroll_actions.rb +0 -62
  18. data/lib/testa_appium_driver/android/selenium_element.rb +0 -12
  19. data/lib/testa_appium_driver/common/bounds.rb +0 -150
  20. data/lib/testa_appium_driver/common/constants.rb +0 -38
  21. data/lib/testa_appium_driver/common/exceptions/strategy_mix_exception.rb +0 -12
  22. data/lib/testa_appium_driver/common/helpers.rb +0 -271
  23. data/lib/testa_appium_driver/common/locator/scroll_actions.rb +0 -398
  24. data/lib/testa_appium_driver/common/locator.rb +0 -599
  25. data/lib/testa_appium_driver/common/scroll_actions/json_wire_scroll_actions.rb +0 -4
  26. data/lib/testa_appium_driver/common/scroll_actions/w3c_scroll_actions.rb +0 -305
  27. data/lib/testa_appium_driver/common/scroll_actions.rb +0 -267
  28. data/lib/testa_appium_driver/common/selenium_element.rb +0 -19
  29. data/lib/testa_appium_driver/driver.rb +0 -335
  30. data/lib/testa_appium_driver/ios/driver.rb +0 -49
  31. data/lib/testa_appium_driver/ios/locator/attributes.rb +0 -85
  32. data/lib/testa_appium_driver/ios/locator.rb +0 -72
  33. data/lib/testa_appium_driver/ios/selenium_element.rb +0 -8
  34. data/lib/testa_appium_driver/ios/type_selectors.rb +0 -188
  35. data/lib/testa_appium_driver/version.rb +0 -5
  36. data/lib/testa_appium_driver.rb +0 -6
@@ -1,305 +0,0 @@
1
- module ::TestaAppiumDriver
2
- module W3cScrollActions
3
-
4
-
5
- # @return [Array]
6
- def w3c_scroll_each(direction, &block)
7
- elements = []
8
- begin
9
- default_deadzone!
10
-
11
- iterations = 0
12
-
13
-
14
- if direction.nil?
15
- scroll_to_start
16
- if @scrollable.scroll_orientation == :vertical
17
- direction = :down
18
- else
19
- direction = :right
20
- end
21
- end
22
- case direction
23
- when :up
24
- align_with = :bottom
25
- when :down
26
- align_with = :top
27
- when :right
28
- align_with = :left
29
- when :left
30
- align_with = :right
31
- else
32
- align_with = :top
33
- end
34
-
35
-
36
-
37
- ignore_element_ids = []
38
- previous_element = nil
39
-
40
- until is_end_of_scroll?
41
- aligned_items = 0
42
- new_ignore_element_ids = []
43
- matches = @locator.execute(skip_cache: true)
44
- matches.each_with_index do |m, index|
45
- if ignore_element_ids.include?(m.id)
46
- previous_element = m
47
- next
48
- end
49
-
50
- sa = self.dup
51
- sa.locator = m
52
- sa.w3c_align(align_with, false, 1, speed_coef: 2.0)
53
- is_aligned = sa.is_aligned?(align_with, m)
54
- if !is_aligned && !previous_element.nil?
55
- new_ignore_element_ids << previous_element.id
56
- end
57
-
58
- if is_aligned
59
- aligned_items += 1
60
- end
61
-
62
- if matches.count == index + 1
63
- new_ignore_element_ids << m.id
64
- end
65
-
66
- elements << m
67
- if block_given? # block is given
68
- @locator.driver.invalidate_cache
69
- block.call(m) # use call to execute the block
70
- else # the value of block_argument becomes nil if you didn't give a block
71
- # block was not given
72
- end
73
- previous_element = m
74
- end
75
-
76
- iterations += 1
77
- break if !@max_scrolls.nil? && iterations == @max_scrolls
78
-
79
- if aligned_items == 0
80
- self.send("page_#{direction}")
81
- else
82
- ignore_element_ids = new_ignore_element_ids.dup
83
- end
84
-
85
-
86
-
87
- end
88
- rescue => e
89
- raise e
90
- end
91
-
92
- elements
93
- end
94
-
95
- def w3c_align(with, scroll_to_find, max_attempts, speed_coef: 1.25)
96
- default_deadzone!
97
-
98
-
99
-
100
- @locator.scroll_to if scroll_to_find
101
-
102
- if @locator.instance_of?(TestaAppiumDriver::Locator)
103
- element = @locator.execute
104
- else
105
- element = @locator
106
- end
107
-
108
-
109
- max_attempts = 3 if max_attempts.nil? || max_attempts <= 0
110
-
111
- timeout = 0
112
- until is_aligned?(with, element) || timeout == max_attempts
113
- w3c_attempt_align(with, speed_coef)
114
- timeout += 1
115
- end
116
-
117
- end
118
-
119
-
120
- def w3c_attempt_align(with, speed_coef)
121
- case with
122
- when :top
123
- y0 = @bounds.bottom_right.y - @deadzone[:bottom]
124
- y1 = y0 - @align_offset
125
- x0 = @bounds.width / 2
126
- x1 = x0
127
- scroll_direction = :down
128
- when :bottom
129
- y0 = @bounds.top_left.y + @deadzone[:top]
130
- y1 = y0 + @align_offset
131
- x0 = @bounds.width / 2
132
- x1 = x0
133
- scroll_direction = :up
134
- when :left
135
- x0 = @bounds.bottom_right.x - @deadzone[:right]
136
- x1 = x0 - @align_offset
137
- y0 = @bounds.height / 2
138
- y1 = y0
139
- scroll_direction = :right
140
- when :right
141
- x0 = @bounds.top_left.x + @deadzone[:top]
142
- x1 = x0 + @align_offset
143
- y0 = @bounds.height / 2
144
- y1 = y0
145
- scroll_direction = :left
146
- else
147
- raise "Unsupported align with option: #{with}"
148
- end
149
-
150
- x1, y1 = apply_w3c_correction(x1, y1, scroll_direction) if @driver.device == :android
151
- w3c_action(x0, y0, x1, y1, SCROLL_ACTION_TYPE_SCROLL, speed_coef: speed_coef)
152
- end
153
-
154
-
155
- def w3c_scroll_to(direction)
156
-
157
- rounds = 0
158
- max_scrolls_reached = false
159
- end_of_scroll_reached = false
160
- until @locator.exists? || end_of_scroll_reached
161
- end_of_scroll_reached = is_end_of_scroll?
162
- case direction
163
- when :down
164
- page_down
165
- when :right
166
- page_right
167
- when :left
168
- page_left
169
- when :up
170
- page_up
171
- else
172
- scroll_to_start
173
- @previous_elements = nil
174
- if @scrollable.scroll_orientation == :vertical
175
- direction = :down
176
- else
177
- direction = :right
178
- end
179
- end
180
-
181
- rounds += 1
182
-
183
- max_scrolls_reached = true if rounds == @max_scrolls
184
- break if rounds == @max_scrolls
185
- end
186
- raise Selenium::WebDriver::Error::NoSuchElementError if max_scrolls_reached || end_of_scroll_reached
187
- end
188
-
189
- def w3c_scroll_to_start_or_end(type)
190
- default_deadzone!
191
-
192
- @previous_elements = nil
193
-
194
-
195
- if type == :start
196
- if @scrollable.scroll_orientation == :vertical
197
- method = "fling_up"
198
- else
199
- method = "fling_left"
200
- end
201
- else
202
- if @scrollable.scroll_orientation == :vertical
203
- method = "fling_down"
204
- else
205
- method = "fling_right"
206
- end
207
- end
208
-
209
- iterations = 0
210
- until is_end_of_scroll? || iterations >= 3
211
- self.send(method)
212
- iterations += 1
213
- end
214
-
215
- # reset the flag for end of scroll elements
216
- @previous_elements = nil
217
- end
218
-
219
-
220
- def w3c_page_or_fling(type, direction)
221
- default_deadzone!
222
-
223
- if direction == :down || direction == :up
224
- if direction == :down
225
- y0 = @bounds.bottom_right.y - @deadzone[:bottom].to_i
226
- y1 = @bounds.top_left.y + @deadzone[:top].to_i
227
- else
228
- y0 = @bounds.top_left.y + @deadzone[:top].to_i
229
- y1 = @bounds.bottom_right.y - @deadzone[:bottom].to_i
230
- end
231
- x0 = @bounds.top_left.x + (@bounds.width - @deadzone[:left].to_i - @deadzone[:right].to_i)/ 2
232
- x0 = @bounds.top_left.x if x0 < @bounds.top_left.x
233
- x0 = @bounds.bottom_right.x if x0 > @bounds.bottom_right.x
234
- x1 = x0
235
- else
236
- if direction == :right
237
- x0 = @bounds.bottom_right.x - @deadzone[:right].to_i
238
- x1 = @bounds.top_left.x + @deadzone[:left].to_i
239
- else
240
- x0 = @bounds.top_left.x + @deadzone[:left].to_i
241
- x1 = @bounds.bottom_right.x - @deadzone[:right].to_i
242
- end
243
-
244
- y0 = @bounds.top_left.y + (@bounds.height - @deadzone[:top].to_i - @deadzone[:bottom].to_i)/ 2
245
- y0 = @bounds.top_left.y if y0 < @bounds.top_left.y
246
- y0 = @bounds.bottom_right.y if y0 > @bounds.bottom_right.y
247
- y1 = y0
248
- end
249
- x1, y1 = apply_w3c_correction(x1, y1, direction) if @driver.device == :android
250
-
251
- speed_coef = 1
252
- if type == SCROLL_ACTION_TYPE_SCROLL
253
- speed_coef = 1.5
254
- end
255
-
256
- w3c_action(x0, y0, x1, y1, type, speed_coef: speed_coef)
257
-
258
- end
259
-
260
-
261
- def w3c_action(x0, y0, x1, y1, type, speed_coef: 1.0)
262
- speed_coef = 1/speed_coef
263
- if type == SCROLL_ACTION_TYPE_SCROLL
264
- duration = 1.8*speed_coef
265
- elsif type == SCROLL_ACTION_TYPE_FLING
266
- duration = 0.1*speed_coef
267
- elsif type == SCROLL_ACTION_TYPE_DRAG
268
- duration = 3.5*speed_coef
269
- else
270
- raise "Unknown scroll action type #{type}"
271
- end
272
-
273
- action_builder = @driver.action
274
- f1 = action_builder.add_pointer_input(:touch, "finger1")
275
- f1.create_pointer_move(duration: 0, x: x0, y: y0, origin: ::Selenium::WebDriver::Interactions::PointerMove::VIEWPORT)
276
- f1.create_pointer_down(:left)
277
-
278
- f1.create_pointer_move(duration: duration, x: x1, y: y1, origin: ::Selenium::WebDriver::Interactions::PointerMove::VIEWPORT)
279
- unless type == SCROLL_ACTION_TYPE_FLING
280
- # with this move we prevent flinging/overscroll
281
- f1.create_pointer_move(duration: 0.5, x: x1, y: y1, origin: ::Selenium::WebDriver::Interactions::PointerMove::VIEWPORT)
282
- end
283
- f1.create_pointer_up(:left)
284
- puts "Scroll execute[w3c_action]: #{type}: {x0: #{x0}, y0: #{y0}} => {x1: #{x1}, y1: #{y1}}"
285
- @driver.perform_actions [f1]
286
- end
287
-
288
-
289
- def apply_w3c_correction(x1, y1, direction)
290
- y1 -= SCROLL_CORRECTION_W3C if direction == :down
291
- y1 += SCROLL_CORRECTION_W3C if direction == :up
292
- x1 -= SCROLL_CORRECTION_W3C if direction == :right
293
- x1 += SCROLL_CORRECTION_W3C if direction == :left
294
- [x1, y1]
295
- end
296
-
297
-
298
-
299
- def w3c_drag_to(x0, y0, x1, y1)
300
- w3c_action(x0, y0, x1, y1, SCROLL_ACTION_TYPE_DRAG)
301
- end
302
-
303
- end
304
-
305
- end
@@ -1,267 +0,0 @@
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
- # $__ctx.puts "end_of_scroll?"
226
- # $__ctx.puts "old: #{@previous_elements}"
227
- # $__ctx.puts "device: #{@driver.device}"
228
-
229
- old_elements = @previous_elements
230
- @previous_elements = @scrollable.first_and_last_leaf
231
- # $__ctx.puts "new: #{@previous_elements}"
232
-
233
- old_elements == @previous_elements
234
- else
235
- # for is, check location of first and last elements
236
- old_elements = @previous_elements
237
- @previous_elements = @scrollable.first_and_last_child&.map(&:location)
238
- old_elements == @previous_elements
239
- end
240
- end
241
-
242
- def default_deadzone!
243
- @deadzone = {} if @deadzone.nil?
244
- if @deadzone[:top].nil?
245
- @deadzone[:top] = 1
246
- else
247
- @deadzone[:top] = @deadzone[:top].to_f
248
- end
249
- if @deadzone[:bottom].nil?
250
- @deadzone[:bottom] = 1
251
- else
252
- @deadzone[:bottom] = @deadzone[:bottom].to_f
253
- end
254
- if @deadzone[:right].nil?
255
- @deadzone[:right] = 1
256
- else
257
- @deadzone[:right] = @deadzone[:right].to_f
258
- end
259
- if @deadzone[:left].nil?
260
- @deadzone[:left] = 1
261
- else
262
- @deadzone[:left] = @deadzone[:left].to_f
263
- end
264
- end
265
-
266
- end
267
- end
@@ -1,19 +0,0 @@
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