testa_appium_driver 0.1.11 → 0.1.14

Sign up to get free protection for your applications and to get access to all the features.
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