testa_appium_driver 0.1.4 → 0.1.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -2
- data/.idea/deployment.xml +9 -1
- data/.idea/inspectionProfiles/Project_Default.xml +8 -8
- data/.idea/runConfigurations/Android_Test.xml +41 -41
- data/.idea/runConfigurations.xml +10 -0
- data/.idea/sshConfigs.xml +3 -0
- data/.idea/webServers.xml +7 -0
- data/.rspec +3 -3
- data/.rubocop.yml +13 -13
- data/CHANGELOG.md +5 -5
- data/CODE_OF_CONDUCT.md +102 -102
- data/Gemfile +12 -12
- data/LICENSE.txt +21 -21
- data/README.md +18 -5
- data/Rakefile +12 -12
- data/bin/console +17 -17
- data/bin/setup +8 -8
- data/lib/testa_appium_driver/android/class_selectors.rb +53 -18
- data/lib/testa_appium_driver/android/driver.rb +17 -0
- data/lib/testa_appium_driver/android/locator/attributes.rb +1 -3
- data/lib/testa_appium_driver/android/locator.rb +22 -7
- data/lib/testa_appium_driver/android/scroll_actions/uiautomator_scroll_actions.rb +1 -14
- data/lib/testa_appium_driver/common/constants.rb +2 -0
- data/lib/testa_appium_driver/common/helpers.rb +32 -1
- data/lib/testa_appium_driver/common/locator/scroll_actions.rb +20 -4
- data/lib/testa_appium_driver/common/locator.rb +191 -31
- data/lib/testa_appium_driver/common/scroll_actions/w3c_scroll_actions.rb +4 -35
- data/lib/testa_appium_driver/common/scroll_actions.rb +5 -14
- data/lib/testa_appium_driver/driver.rb +92 -40
- data/lib/testa_appium_driver/ios/driver.rb +13 -0
- data/lib/testa_appium_driver/ios/locator.rb +22 -4
- data/lib/testa_appium_driver/ios/type_selectors.rb +36 -15
- data/lib/testa_appium_driver/version.rb +5 -5
- data/testa_appium_driver.iml +36 -2
- 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[:
|
35
|
-
|
36
|
-
|
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
|
39
|
+
def strategies_and_selectors
|
40
|
+
ss = []
|
40
41
|
if @can_use_id_strategy
|
41
|
-
|
42
|
+
ss.push({"#{FIND_STRATEGY_ID}": @can_use_id_strategy})
|
42
43
|
end
|
43
|
-
if
|
44
|
-
|
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 =
|
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
|
|
@@ -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
|
-
|
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(
|
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(
|
333
|
+
sa.drag_to(x0, y0, x1, y1)
|
318
334
|
self
|
319
335
|
end
|
320
336
|
|