testa_appium_driver 0.1.11 → 0.1.14

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 (50) hide show
  1. checksums.yaml +4 -4
  2. data/.gitattributes +23 -0
  3. data/.gitignore +16 -16
  4. data/.rspec +3 -3
  5. data/.rubocop.yml +13 -13
  6. data/CHANGELOG.md +5 -5
  7. data/CODE_OF_CONDUCT.md +102 -102
  8. data/Gemfile +12 -12
  9. data/Gemfile.lock +74 -0
  10. data/LICENSE.txt +21 -21
  11. data/README.md +402 -378
  12. data/Rakefile +12 -12
  13. data/{testa_appium_driver.iml → appium-driver.iml} +71 -78
  14. data/bin/console +17 -17
  15. data/bin/setup +8 -8
  16. data/lib/testa_appium_driver/android/class_selectors.rb +437 -437
  17. data/lib/testa_appium_driver/android/driver.rb +70 -69
  18. data/lib/testa_appium_driver/android/locator/attributes.rb +117 -113
  19. data/lib/testa_appium_driver/android/locator.rb +141 -141
  20. data/lib/testa_appium_driver/android/scroll_actions/uiautomator_scroll_actions.rb +61 -61
  21. data/lib/testa_appium_driver/android/selenium_element.rb +11 -7
  22. data/lib/testa_appium_driver/common/bounds.rb +149 -149
  23. data/lib/testa_appium_driver/common/constants.rb +37 -36
  24. data/lib/testa_appium_driver/common/exceptions/strategy_mix_exception.rb +11 -11
  25. data/lib/testa_appium_driver/common/helpers.rb +270 -270
  26. data/lib/testa_appium_driver/common/locator/scroll_actions.rb +397 -397
  27. data/lib/testa_appium_driver/common/locator.rb +627 -610
  28. data/lib/testa_appium_driver/common/scroll_actions/json_wire_scroll_actions.rb +3 -3
  29. data/lib/testa_appium_driver/common/scroll_actions/w3c_scroll_actions.rb +304 -237
  30. data/lib/testa_appium_driver/common/scroll_actions.rb +253 -246
  31. data/lib/testa_appium_driver/common/selenium_element.rb +19 -19
  32. data/lib/testa_appium_driver/driver.rb +328 -312
  33. data/lib/testa_appium_driver/ios/driver.rb +48 -48
  34. data/lib/testa_appium_driver/ios/locator/attributes.rb +84 -80
  35. data/lib/testa_appium_driver/ios/locator.rb +71 -70
  36. data/lib/testa_appium_driver/ios/selenium_element.rb +6 -6
  37. data/lib/testa_appium_driver/ios/type_selectors.rb +187 -187
  38. data/lib/testa_appium_driver/version.rb +5 -5
  39. data/lib/testa_appium_driver.rb +6 -6
  40. data/testa_appium_driver.gemspec +41 -41
  41. metadata +9 -16
  42. data/.idea/deployment.xml +0 -22
  43. data/.idea/inspectionProfiles/Project_Default.xml +0 -9
  44. data/.idea/misc.xml +0 -6
  45. data/.idea/modules.xml +0 -8
  46. data/.idea/runConfigurations/Android_Test.xml +0 -42
  47. data/.idea/runConfigurations.xml +0 -10
  48. data/.idea/sshConfigs.xml +0 -13
  49. data/.idea/vcs.xml +0 -6
  50. data/.idea/webServers.xml +0 -21
@@ -1,4 +1,4 @@
1
- module TestaAppiumDriver
2
- class ScrollActions
3
- end
1
+ module TestaAppiumDriver
2
+ module JsonWireScrollActions
3
+ end
4
4
  end
@@ -1,238 +1,305 @@
1
- module TestaAppiumDriver
2
- class ScrollActions
3
-
4
- private
5
- # @return [Array]
6
- def w3c_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
-
23
- until is_end_of_scroll?
24
- matches = @locator.execute(skip_cache: true)
25
- matches.each_with_index do |m|
26
- next if elements.include?(m)
27
- elements << m
28
- if block_given? # block is given
29
- block.call(m) # use call to execute the block
30
- else # the value of block_argument becomes nil if you didn't give a block
31
- # block was not given
32
- end
33
- end
34
- iterations += 1
35
- break if !@max_scrolls.nil? && iterations == @max_scrolls
36
- self.send("page_#{direction}")
37
- end
38
- rescue => e
39
- raise e
40
-
41
- end
42
- elements
43
- end
44
-
45
- def w3c_align(with, scroll_to_find)
46
- default_deadzone!
47
-
48
-
49
-
50
- @locator.scroll_to if scroll_to_find
51
-
52
- element = @locator.execute
53
-
54
- timeout = 0
55
- until is_aligned?(with, element) || timeout == 3
56
- w3c_attempt_align(with)
57
- timeout += 1
58
- end
59
-
60
- end
61
-
62
-
63
- def w3c_attempt_align(with)
64
- case with
65
- when :top
66
- y0 = @bounds.bottom_right.y - @deadzone[:bottom]
67
- y1 = y0 - @align_offset
68
- x0 = @bounds.width / 2
69
- x1 = x0
70
- scroll_direction = :down
71
- when :bottom
72
- y0 = @bounds.top_left.y + @deadzone[:top]
73
- y1 = y0 + @align_offset
74
- x0 = @bounds.width / 2
75
- x1 = x0
76
- scroll_direction = :up
77
- when :left
78
- x0 = @bounds.bottom_right.x - @deadzone[:right]
79
- x1 = x0 - @align_offset
80
- y0 = @bounds.height / 2
81
- y1 = y0
82
- scroll_direction = :right
83
- when :right
84
- x0 = @bounds.top_left.x + @deadzone[:top]
85
- x1 = x0 + @align_offset
86
- y0 = @bounds.height / 2
87
- y1 = y0
88
- scroll_direction = :left
89
- else
90
- raise "Unsupported align with option: #{with}"
91
- end
92
-
93
- x1, y1 = apply_w3c_correction(x1, y1, scroll_direction) if @driver.device == :android
94
- w3c_action(x0, y0, x1, y1, SCROLL_ACTION_TYPE_SCROLL)
95
- end
96
-
97
-
98
- def w3c_scroll_to(direction)
99
-
100
- rounds = 0
101
- max_scrolls_reached = false
102
- end_of_scroll_reached = false
103
- until @locator.exists? || end_of_scroll_reached
104
- end_of_scroll_reached = is_end_of_scroll?
105
- case direction
106
- when :down
107
- page_down
108
- when :right
109
- page_right
110
- when :left
111
- page_left
112
- when :up
113
- page_up
114
- else
115
- scroll_to_start
116
- @previous_elements = nil
117
- if @scrollable.scroll_orientation == :vertical
118
- direction = :down
119
- else
120
- direction = :right
121
- end
122
- end
123
-
124
- rounds += 1
125
-
126
- max_scrolls_reached = true if rounds == @max_scrolls
127
- break if rounds == @max_scrolls
128
- end
129
- raise Selenium::WebDriver::Error::NoSuchElementError if max_scrolls_reached || end_of_scroll_reached
130
- end
131
-
132
- def w3c_scroll_to_start_or_end(type)
133
- default_deadzone!
134
-
135
- @previous_elements = nil
136
-
137
-
138
- if type == :start
139
- if @scrollable.scroll_orientation == :vertical
140
- method = "fling_up"
141
- else
142
- method = "fling_left"
143
- end
144
- else
145
- if @scrollable.scroll_orientation == :vertical
146
- method = "fling_down"
147
- else
148
- method = "fling_right"
149
- end
150
- end
151
-
152
- iterations = 0
153
- until is_end_of_scroll? || iterations >= 3
154
- self.send(method)
155
- iterations += 1
156
- end
157
-
158
- # reset the flag for end of scroll elements
159
- @previous_elements = nil
160
- end
161
-
162
-
163
- def w3c_page_or_fling(type, direction)
164
- default_deadzone!
165
-
166
- if direction == :down || direction == :up
167
- if direction == :down
168
- y0 = @bounds.bottom_right.y - @deadzone[:bottom].to_i
169
- y1 = @bounds.top_left.y + @deadzone[:top].to_i
170
- else
171
- y0 = @bounds.top_left.y + @deadzone[:top].to_i
172
- y1 = @bounds.bottom_right.y - @deadzone[:bottom].to_i
173
- end
174
- x0 = @bounds.width / 2
175
- x1 = x0
176
- else
177
- if direction == :right
178
- x0 = @bounds.bottom_right.x - @deadzone[:right].to_i
179
- x1 = @bounds.top_left.x + @deadzone[:left].to_i
180
- else
181
- x0 = @bounds.top_left.x + @deadzone[:left].to_i
182
- x1 = @bounds.bottom_right.x - @deadzone[:right].to_i
183
- end
184
- y0 = @bounds.height / 2
185
- y1 = y0
186
- end
187
- x1, y1 = apply_w3c_correction(x1, y1, direction) if @driver.device == :android
188
-
189
-
190
- w3c_action(x0, y0, x1, y1, type)
191
-
192
- end
193
-
194
-
195
- def w3c_action(x0, y0, x1, y1, type)
196
- if type == SCROLL_ACTION_TYPE_SCROLL
197
- duration = 1.8
198
- elsif type == SCROLL_ACTION_TYPE_FLING
199
- duration = 0.1
200
- elsif type == SCROLL_ACTION_TYPE_DRAG
201
- duration = 3.5
202
- else
203
- raise "Unknown scroll action type #{type}"
204
- end
205
-
206
- action_builder = @driver.action
207
- f1 = action_builder.add_pointer_input(:touch, "finger1")
208
- f1.create_pointer_move(duration: 0, x: x0, y: y0, origin: ::Selenium::WebDriver::Interactions::PointerMove::VIEWPORT)
209
- f1.create_pointer_down(:left)
210
-
211
- f1.create_pointer_move(duration: duration, x: x1, y: y1, origin: ::Selenium::WebDriver::Interactions::PointerMove::VIEWPORT)
212
- unless type == SCROLL_ACTION_TYPE_FLING
213
- # with this move we prevent flinging/overscroll
214
- f1.create_pointer_move(duration: 0.5, x: x1, y: y1, origin: ::Selenium::WebDriver::Interactions::PointerMove::VIEWPORT)
215
- end
216
- f1.create_pointer_up(:left)
217
- puts "Scroll execute[w3c_action]: #{type}: {x0: #{x0}, y0: #{y0}} => {x1: #{x1}, y1: #{y1}}"
218
- @driver.perform_actions [f1]
219
- end
220
-
221
-
222
- def apply_w3c_correction(x1, y1, direction)
223
- y1 -= SCROLL_CORRECTION_W3C if direction == :down
224
- y1 += SCROLL_CORRECTION_W3C if direction == :up
225
- x1 -= SCROLL_CORRECTION_W3C if direction == :right
226
- x1 += SCROLL_CORRECTION_W3C if direction == :left
227
- [x1, y1]
228
- end
229
-
230
-
231
-
232
- def w3c_drag_to(x0, y0, x1, y1)
233
- w3c_action(x0, y0, x1, y1, SCROLL_ACTION_TYPE_DRAG)
234
- end
235
-
236
- end
237
-
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
+
88
+ end
89
+ rescue => e
90
+ raise e
91
+ end
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
+
238
305
  end