testa_appium_driver 0.1.4 → 0.1.8

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/.gitignore +2 -2
  3. data/.idea/deployment.xml +9 -1
  4. data/.idea/inspectionProfiles/Project_Default.xml +8 -8
  5. data/.idea/runConfigurations/Android_Test.xml +41 -41
  6. data/.idea/runConfigurations.xml +10 -0
  7. data/.idea/sshConfigs.xml +3 -0
  8. data/.idea/webServers.xml +7 -0
  9. data/.rspec +3 -3
  10. data/.rubocop.yml +13 -13
  11. data/CHANGELOG.md +5 -5
  12. data/CODE_OF_CONDUCT.md +102 -102
  13. data/Gemfile +12 -12
  14. data/LICENSE.txt +21 -21
  15. data/README.md +18 -5
  16. data/Rakefile +12 -12
  17. data/bin/console +17 -17
  18. data/bin/setup +8 -8
  19. data/lib/testa_appium_driver/android/class_selectors.rb +53 -18
  20. data/lib/testa_appium_driver/android/driver.rb +17 -0
  21. data/lib/testa_appium_driver/android/locator/attributes.rb +1 -3
  22. data/lib/testa_appium_driver/android/locator.rb +22 -7
  23. data/lib/testa_appium_driver/android/scroll_actions/uiautomator_scroll_actions.rb +1 -14
  24. data/lib/testa_appium_driver/common/constants.rb +2 -0
  25. data/lib/testa_appium_driver/common/helpers.rb +32 -1
  26. data/lib/testa_appium_driver/common/locator/scroll_actions.rb +20 -4
  27. data/lib/testa_appium_driver/common/locator.rb +191 -31
  28. data/lib/testa_appium_driver/common/scroll_actions/w3c_scroll_actions.rb +4 -35
  29. data/lib/testa_appium_driver/common/scroll_actions.rb +5 -14
  30. data/lib/testa_appium_driver/driver.rb +92 -40
  31. data/lib/testa_appium_driver/ios/driver.rb +13 -0
  32. data/lib/testa_appium_driver/ios/locator.rb +22 -4
  33. data/lib/testa_appium_driver/ios/type_selectors.rb +36 -15
  34. data/lib/testa_appium_driver/version.rb +5 -5
  35. data/testa_appium_driver.iml +36 -2
  36. metadata +3 -2
@@ -24,6 +24,9 @@ module TestaAppiumDriver
24
24
  # @param selectors [Hash]
25
25
  # @return [TestaAppiumDriver::Locator] first element
26
26
  def element(selectors = {})
27
+ unless selectors[:image].nil?
28
+ selectors[:strategy] = FIND_STRATEGY_IMAGE
29
+ end
27
30
  add_selector(selectors)
28
31
  end
29
32
 
@@ -31,24 +34,9 @@ module TestaAppiumDriver
31
34
  # @param params [Hash]
32
35
  # @return [TestaAppiumDriver::Locator] all elements that match given selectors
33
36
  def elements(params = {})
34
- params[:single] = false
35
- add_selector(params)
36
- end
37
-
38
-
39
- # first element that has scrollable: true
40
- # @param selectors [Hash]
41
- # @return [TestaAppiumDriver::Locator] first scrollable element
42
- def scrollable(selectors = {})
43
- selectors[:scrollable] = true
44
- add_selector(selectors)
45
- end
46
-
47
- # all elements that have scrollable: true
48
- # @param params [Hash]
49
- # @return [TestaAppiumDriver::Locator] first scrollable element
50
- def scrollables(params = {})
51
- params[:scrollable] = true
37
+ unless params[:image].nil?
38
+ params[:strategy] = FIND_STRATEGY_IMAGE
39
+ end
52
40
  params[:single] = false
53
41
  add_selector(params)
54
42
  end
@@ -399,5 +387,52 @@ module TestaAppiumDriver
399
387
  add_selector(params)
400
388
  end
401
389
 
390
+
391
+ # first androidx.cardview.widget.CardView element that match given selectors
392
+ # @return [TestaAppiumDriver::Locator]
393
+ def card_view(params = {})
394
+ params[:class] = "androidx.cardview.widget.CardView"
395
+ add_selector(params)
396
+ end
397
+
398
+ # all androidx.cardview.widget.CardView elements that match given selectors
399
+ # @return [TestaAppiumDriver::Locator]
400
+ def card_views(params = {})
401
+ params[:class] = "androidx.cardview.widget.CardView"
402
+ params[:single] = false
403
+ add_selector(params)
404
+ end
405
+
406
+ # first android.widget.Switch element that match given selectors
407
+ # @return [TestaAppiumDriver::Locator]
408
+ def switch(params = {})
409
+ params[:class] = "android.widget.Switch"
410
+ add_selector(params)
411
+ end
412
+
413
+ # all android.widget.Switch elements that match given selectors
414
+ # @return [TestaAppiumDriver::Locator]
415
+ def switches(params = {})
416
+ params[:class] = "android.widget.Switch"
417
+ params[:single] = false
418
+ add_selector(params)
419
+ end
420
+
421
+
422
+ # first android.webkit.WebView element that match given selectors
423
+ # @return [TestaAppiumDriver::Locator]
424
+ def web_view(params = {})
425
+ params[:class] = "android.webkit.WebView"
426
+ add_selector(params)
427
+ end
428
+
429
+ # all android.webkit.WebView elements that match given selectors
430
+ # @return [TestaAppiumDriver::Locator]
431
+ def web_views(params = {})
432
+ params[:class] = "android.webkit.WebView"
433
+ params[:single] = false
434
+ add_selector(params)
435
+ end
436
+
402
437
  end
403
438
  end
@@ -24,6 +24,23 @@ module TestaAppiumDriver
24
24
  end
25
25
 
26
26
 
27
+ def scrollable
28
+ locator = Locator.new(self, self, {single: true})
29
+ locator.xpath_selector = "//androidx.recyclerview.widget.RecyclerView|//android.widget.ScrollView|//android.widget.ListView|//android.widget.HorizontalScrollView"
30
+ locator.ui_selector = "new UiSelector().scrollable(true).instance(0)"
31
+ locator
32
+ end
33
+
34
+
35
+ def scrollables
36
+ locator = Locator.new(self, self, {single: false})
37
+ locator.xpath_selector = "//androidx.recyclerview.widget.RecyclerView|//android.widget.ScrollView|//android.widget.ListView|//android.widget.HorizontalScrollView"
38
+ locator.ui_selector = "new UiSelector().scrollable(true)"
39
+ locator
40
+ end
41
+
42
+
43
+
27
44
  private
28
45
  def handle_testa_opts
29
46
  if @testa_opts[:default_find_strategy].nil?
@@ -7,7 +7,6 @@ module TestaAppiumDriver
7
7
 
8
8
  @driver = get_driver if self.instance_of?(Selenium::WebDriver::Element)
9
9
 
10
- @driver.disable_wait_for_idle
11
10
  if elements.kind_of?(Selenium::WebDriver::Element)
12
11
  r = elements.send(:attribute, name.to_s)
13
12
  r = TestaAppiumDriver::Bounds.from_android(r, @driver) if name.to_s == "bounds"
@@ -15,7 +14,6 @@ module TestaAppiumDriver
15
14
  r = elements.map { |e| e.send(:attribute, name.to_s) }
16
15
  r.map! { |b| TestaAppiumDriver::Bounds.from_android(b, @driver) } if name.to_s == "bounds"
17
16
  end
18
- @driver.enable_wait_for_idle
19
17
  r
20
18
  end
21
19
 
@@ -110,7 +108,7 @@ module TestaAppiumDriver
110
108
  children = self.dup.parent.children.execute
111
109
  index = children.index(this)
112
110
  raise "Index not found" if index.nil?
113
- index
111
+ index.to_i
114
112
  end
115
113
  end
116
114
  end
@@ -36,15 +36,23 @@ module TestaAppiumDriver
36
36
 
37
37
 
38
38
  # resolve selector which will be used for finding element
39
- def strategy_and_selector
39
+ def strategies_and_selectors
40
+ ss = []
40
41
  if @can_use_id_strategy
41
- return FIND_STRATEGY_ID, @can_use_id_strategy
42
+ ss.push({"#{FIND_STRATEGY_ID}": @can_use_id_strategy})
42
43
  end
43
- if (@strategy.nil? && @default_find_strategy == FIND_STRATEGY_UIAUTOMATOR) || @strategy == FIND_STRATEGY_UIAUTOMATOR
44
- [FIND_STRATEGY_UIAUTOMATOR, ui_selector]
45
- elsif (@strategy.nil? && @default_find_strategy == FIND_STRATEGY_XPATH) || @strategy == FIND_STRATEGY_XPATH
46
- [FIND_STRATEGY_XPATH, @xpath_selector]
44
+ if @strategy.nil? || @strategy == FIND_STRATEGY_UIAUTOMATOR
45
+ ss.push({"#{FIND_STRATEGY_UIAUTOMATOR}": ui_selector})
47
46
  end
47
+
48
+ if @strategy.nil? || @strategy == FIND_STRATEGY_XPATH
49
+ ss.push({"#{FIND_STRATEGY_XPATH}": @xpath_selector})
50
+ end
51
+
52
+ if @strategy == FIND_STRATEGY_IMAGE
53
+ ss.push({"#{FIND_STRATEGY_IMAGE}": @image_selector})
54
+ end
55
+ ss
48
56
  end
49
57
 
50
58
 
@@ -89,6 +97,8 @@ module TestaAppiumDriver
89
97
  add_xpath_child_selectors(locator, selectors, single)
90
98
  elsif @strategy == FIND_STRATEGY_UIAUTOMATOR
91
99
  locator = add_uiautomator_child_selector(locator, selectors, single)
100
+ elsif @strategy == FIND_STRATEGY_IMAGE
101
+ locator = add_image_child_selector(locator, selectors, single)
92
102
  else
93
103
  # both paths are valid
94
104
  add_xpath_child_selectors(locator, selectors, single)
@@ -96,7 +106,7 @@ module TestaAppiumDriver
96
106
  end
97
107
 
98
108
  if is_scrollable_selector?(selectors, single)
99
- locator.scrollable_locator = self
109
+ locator.scrollable_locator = locator
100
110
  if selectors[:class] == "android.widget.HorizontalScrollView"
101
111
  locator.scrollable_locator.scroll_orientation = :horizontal
102
112
  else
@@ -123,5 +133,10 @@ module TestaAppiumDriver
123
133
  locator
124
134
  end
125
135
  end
136
+
137
+ def add_image_child_selector(locator, selectors, single)
138
+ params = selectors.merge({single: single, scrollable_locator: locator.scrollable_locator})
139
+ Locator.new(@driver, self, params)
140
+ end
126
141
  end
127
142
  end
@@ -4,10 +4,9 @@ module TestaAppiumDriver
4
4
  private
5
5
 
6
6
  def uiautomator_scroll_to_start_or_end(type)
7
- @driver.disable_wait_for_idle
8
- @driver.disable_implicit_wait
9
7
 
10
8
  scrollable_selector = @scrollable.ui_selector(false)
9
+ puts @scrollable.bounds
11
10
  orientation = @scrollable.scroll_orientation == :vertical ? ".setAsVerticalList()" : ".setAsHorizontalList()"
12
11
  scroll_command = type == :start ? ".scrollToBeginning(#{DEFAULT_UIAUTOMATOR_MAX_SWIPES})" : ".scrollToEnd(#{DEFAULT_UIAUTOMATOR_MAX_SWIPES})"
13
12
  cmd = "new UiScrollable(#{scrollable_selector})#{orientation}#{scroll_command};"
@@ -19,18 +18,12 @@ module TestaAppiumDriver
19
18
  end
20
19
 
21
20
 
22
- @driver.enable_implicit_wait
23
- @driver.enable_wait_for_idle
24
21
  end
25
22
 
26
23
 
27
24
  def uiautomator_scroll_to
28
25
  raise "UiAutomator scroll cannot work with specified direction" unless @direction.nil?
29
26
 
30
-
31
- @driver.disable_wait_for_idle
32
- @driver.disable_implicit_wait
33
-
34
27
  scrollable_selector = @scrollable.ui_selector(false)
35
28
  element_selector = @locator.ui_selector(false)
36
29
  orientation_command = @scrollable.scroll_orientation == :vertical ? ".setAsVerticalList()" : ".setAsHorizontalList()"
@@ -41,15 +34,11 @@ module TestaAppiumDriver
41
34
  rescue
42
35
  # Ignored
43
36
  ensure
44
- @driver.enable_implicit_wait
45
- @driver.enable_wait_for_idle
46
37
  end
47
38
  end
48
39
 
49
40
 
50
41
  def uiautomator_page_or_fling(type, direction)
51
- @driver.disable_wait_for_idle
52
- @driver.disable_implicit_wait
53
42
 
54
43
  scrollable_selector = @scrollable.ui_selector(false)
55
44
  orientation = direction == :up || direction == :down ? ".setAsVerticalList()" : ".setAsHorizontalList()"
@@ -67,8 +56,6 @@ module TestaAppiumDriver
67
56
  rescue
68
57
  # Ignored
69
58
  end
70
- @driver.enable_implicit_wait
71
- @driver.enable_wait_for_idle
72
59
  end
73
60
 
74
61
 
@@ -6,6 +6,8 @@ module TestaAppiumDriver
6
6
  FIND_STRATEGY_XPATH = :xpath
7
7
  FIND_STRATEGY_ID = :id
8
8
  FIND_STRATEGY_NAME = :name
9
+ FIND_STRATEGY_IMAGE = :image
10
+ FIND_STRATEGY_CLASS_CHAIN = :class_chain
9
11
 
10
12
  SCROLL_STRATEGY_UIAUTOMATOR = :uiautomator
11
13
  SCROLL_STRATEGY_W3C = :w3c
@@ -120,7 +120,9 @@ module TestaAppiumDriver
120
120
  command = "#{ command }[@focused=\"#{ hash[:focused] }\"]" unless hash[:focused].nil?
121
121
  command = "#{ command }[@index=\"#{ hash[:index] }\"]" unless hash[:index].nil?
122
122
  command = "#{ command }[@selected=\"#{ hash[:selected] }\"]" unless hash[:selected].nil?
123
- command = "#{ command }[@scrollable=\"#{ hash[:scrollable] }\"]" unless hash[:scrollable].nil?
123
+
124
+ # it seems like you cannot query by scrollable
125
+ # command = "#{ command }[@scrollable=\"#{ hash[:scrollable] }\"]" unless hash[:scrollable].nil?
124
126
  else
125
127
 
126
128
  hash[:type] = hash[:class] unless hash[:class].nil?
@@ -155,6 +157,33 @@ module TestaAppiumDriver
155
157
  command
156
158
  end
157
159
 
160
+
161
+ def hash_to_class_chain(hash, single = true)
162
+ command = "**/"
163
+
164
+ hash[:type] = hash[:class] unless hash[:class].nil?
165
+ hash[:label] = hash[:text] unless hash[:text].nil?
166
+ hash[:name] = hash[:id] unless hash[:id].nil?
167
+ if hash[:type] && hash[:type].kind_of?(String)
168
+ command = "#{ command }#{hash[:type] }"
169
+ else
170
+ command = "#{command}*"
171
+ end
172
+
173
+ command = "#{ command }[`enabled == #{ hash[:enabled] }`]" unless hash[:enabled].nil?
174
+ command = "#{ command }[`label == \"#{ %(#{hash[:label] }) }\"`]" if hash[:label] && hash[:label].kind_of?(String)
175
+ command = "#{ command }[`label CONTAINS \"#{ %(#{hash[:label].source }) }\"`]" if hash[:label] && hash[:label].kind_of?(Regexp)
176
+ command = "#{ command }[`name == \"#{ %(#{hash[:name] }) }\"`]" if hash[:name] && hash[:name].kind_of?(String)
177
+ command = "#{ command }[`name CONTAINS \"#{ %(#{hash[:name].source }) }\"`]" if hash[:name] && hash[:name].kind_of?(Regexp)
178
+ command = "#{ command }[`value == \"#{ %(#{hash[:value] }) }\"`]" if hash[:value] && hash[:value].kind_of?(String)
179
+ command = "#{ command }[`value CONTAINS \"#{ %(#{hash[:value].source }) }\"`]" if hash[:value] && hash[:value].kind_of?(Regexp)
180
+ command = "#{ command }[`visible == #{ hash[:visible] }`]" unless hash[:visible].nil?
181
+
182
+ command += "[1]" if single
183
+
184
+ command
185
+ end
186
+
158
187
  # check if selectors are for a scrollable element
159
188
  # @param [Boolean] single should the command return first instance or all of matched elements
160
189
  # @param [Hash] selectors for fetching elements
@@ -205,6 +234,8 @@ module TestaAppiumDriver
205
234
  :visible,
206
235
  :name,
207
236
  :value,
237
+
238
+ :image
208
239
  ].include?(key) }
209
240
  params = Hash[params.to_a - selectors.to_a]
210
241
 
@@ -250,6 +250,22 @@ module TestaAppiumDriver
250
250
  _fling(:right, _process_deadzone(top, bottom, right, left))
251
251
  end
252
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
+
253
269
 
254
270
  # @param [TestaAppiumDriver::Locator, Hash, Selenium::WebDriver::Element, String] to
255
271
  #noinspection RubyYardParamTypeMatch,RubyScope
@@ -273,7 +289,7 @@ module TestaAppiumDriver
273
289
  x = to[:x]
274
290
  y = to[:y]
275
291
  end
276
- _drag_to(x, y)
292
+ _drag_to(bounds.center.x, bounds.center.y, x, y)
277
293
  end
278
294
 
279
295
  def drag_by(amount, direction: :top)
@@ -292,7 +308,7 @@ module TestaAppiumDriver
292
308
  else
293
309
  raise "Unknown direction #{direction}"
294
310
  end
295
- _drag_to(x, y)
311
+ _drag_to(b.center.x, b.center.y, x, y)
296
312
  end
297
313
 
298
314
 
@@ -310,11 +326,11 @@ module TestaAppiumDriver
310
326
  deadzone
311
327
  end
312
328
 
313
- def _drag_to(x, y)
329
+ def _drag_to(x0, y0, x1, y1)
314
330
  sa = ScrollActions.new(@scrollable_locator,
315
331
  locator: self,
316
332
  default_scroll_strategy: @default_scroll_strategy)
317
- sa.drag_to(x, y)
333
+ sa.drag_to(x0, y0, x1, y1)
318
334
  self
319
335
  end
320
336