testa_appium_driver 0.1.13 → 0.1.16
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitattributes +23 -0
- data/.gitignore +2 -3
- data/.rubocop.yml +5 -13
- data/Gemfile +1 -1
- data/Gemfile.lock +76 -0
- data/appium-driver.iml +74 -0
- data/lib/testa_appium_driver/android/class_selectors.rb +7 -7
- data/lib/testa_appium_driver/android/driver.rb +1 -0
- data/lib/testa_appium_driver/android/locator/attributes.rb +29 -25
- data/lib/testa_appium_driver/android/locator.rb +1 -1
- data/lib/testa_appium_driver/android/selenium_element.rb +6 -2
- data/lib/testa_appium_driver/common/constants.rb +2 -1
- data/lib/testa_appium_driver/common/locator/scroll_actions.rb +33 -33
- data/lib/testa_appium_driver/common/locator.rb +66 -78
- data/lib/testa_appium_driver/common/scroll_actions/json_wire_scroll_actions.rb +1 -1
- data/lib/testa_appium_driver/common/scroll_actions/w3c_scroll_actions.rb +87 -20
- data/lib/testa_appium_driver/common/scroll_actions.rb +43 -23
- data/lib/testa_appium_driver/common/selenium_element.rb +2 -2
- data/lib/testa_appium_driver/driver.rb +41 -20
- data/lib/testa_appium_driver/ios/locator/attributes.rb +24 -20
- data/lib/testa_appium_driver/ios/locator.rb +1 -0
- data/lib/testa_appium_driver/ios/selenium_element.rb +3 -2
- data/lib/testa_appium_driver/ios/type_selectors.rb +2 -2
- data/lib/testa_appium_driver/version.rb +1 -1
- data/testa_appium_driver.gemspec +2 -2
- metadata +11 -18
- data/.idea/deployment.xml +0 -22
- data/.idea/inspectionProfiles/Project_Default.xml +0 -9
- data/.idea/misc.xml +0 -6
- data/.idea/modules.xml +0 -8
- data/.idea/runConfigurations/Android_Test.xml +0 -42
- data/.idea/runConfigurations.xml +0 -10
- data/.idea/sshConfigs.xml +0 -13
- data/.idea/vcs.xml +0 -6
- data/.idea/webServers.xml +0 -21
- data/testa_appium_driver.iml +0 -41
@@ -1,7 +1,6 @@
|
|
1
1
|
require_relative 'locator/scroll_actions'
|
2
2
|
|
3
|
-
|
4
|
-
module TestaAppiumDriver
|
3
|
+
module ::TestaAppiumDriver
|
5
4
|
#noinspection RubyTooManyInstanceVariablesInspection,RubyTooManyMethodsInspection
|
6
5
|
class Locator
|
7
6
|
include Helpers
|
@@ -29,7 +28,6 @@ module TestaAppiumDriver
|
|
29
28
|
|
30
29
|
attr_accessor :index_for_multiple
|
31
30
|
|
32
|
-
|
33
31
|
# locator parameters are:
|
34
32
|
# single: true or false
|
35
33
|
# scrollable_locator: [TestaAppiumDriver::Locator, nil] for scrolling if needed later
|
@@ -59,19 +57,17 @@ module TestaAppiumDriver
|
|
59
57
|
end
|
60
58
|
|
61
59
|
selectors[:id] = selectors[:name] unless selectors[:name].nil?
|
62
|
-
if from_element.instance_of?(Selenium::WebDriver::Element)
|
63
|
-
@xpath_selector = "
|
64
|
-
@xpath_selector += hash_to_xpath(@driver.device, selectors, single)
|
60
|
+
if from_element.instance_of?(::Selenium::WebDriver::Element) || from_element.instance_of?(::Appium::Core::Element) || from_element.instance_of?(::TestaAppiumDriver::Locator)
|
61
|
+
@xpath_selector = "."
|
62
|
+
@xpath_selector += hash_to_xpath(@driver.device, selectors, single)
|
65
63
|
else
|
66
64
|
@xpath_selector = hash_to_xpath(@driver.device, selectors, single)
|
67
65
|
end
|
68
66
|
|
69
|
-
|
70
67
|
@from_element = from_element
|
71
68
|
@default_find_strategy = params[:default_find_strategy]
|
72
69
|
@default_scroll_strategy = params[:default_scroll_strategy]
|
73
70
|
|
74
|
-
|
75
71
|
@can_use_id_strategy = is_only_id_selector?(selectors)
|
76
72
|
if @can_use_id_strategy
|
77
73
|
if @driver.device == :android
|
@@ -81,7 +77,6 @@ module TestaAppiumDriver
|
|
81
77
|
end
|
82
78
|
end
|
83
79
|
|
84
|
-
|
85
80
|
@strategy = params[:strategy]
|
86
81
|
@strategy_reason = params[:strategy_reason]
|
87
82
|
|
@@ -90,9 +85,6 @@ module TestaAppiumDriver
|
|
90
85
|
init(params, selectors, single)
|
91
86
|
end
|
92
87
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
88
|
def is_only_id_selector?(selectors)
|
97
89
|
# since, name and id is the same thing for iOS,
|
98
90
|
if @driver.device == :android
|
@@ -103,7 +95,6 @@ module TestaAppiumDriver
|
|
103
95
|
end
|
104
96
|
end
|
105
97
|
|
106
|
-
|
107
98
|
# method missing is used to fetch the element before executing additional commands like click, send_key, count
|
108
99
|
def method_missing(method, *args, &block)
|
109
100
|
r = execute.send(method, *args, &block)
|
@@ -111,7 +102,6 @@ module TestaAppiumDriver
|
|
111
102
|
r
|
112
103
|
end
|
113
104
|
|
114
|
-
|
115
105
|
# @param [Boolean] skip_cache if true it will skip cache check and store
|
116
106
|
# @param [Selenium::WebDriver::Element] force_cache_element, for internal use where we have already the element, and want to execute custom locator methods on it
|
117
107
|
# @return [Selenium::WebDriver::Element, Array]
|
@@ -122,17 +112,12 @@ module TestaAppiumDriver
|
|
122
112
|
# elements[2] will be resolved with xpath because we are looking for multiple elements from element
|
123
113
|
# and since we are looking for instance 2, [](instance) method will return new "empty locator"
|
124
114
|
# we are executing click on that "empty locator" so we have to return the instance 2 of elements for the click
|
125
|
-
if @xpath_selector == "
|
126
|
-
return @from_element if @from_element.instance_of?(Selenium::WebDriver::Element)
|
115
|
+
if @xpath_selector == ".//*[1]" && !@from_element.nil? && @image_selector.nil?
|
116
|
+
return @from_element if @from_element.instance_of?(::Selenium::WebDriver::Element) || @from_element.instance_of?(::Appium::Core::Element)
|
127
117
|
return @from_element.execute(skip_cache: skip_cache, force_cache_element: force_cache_element, ignore_implicit_wait: ignore_implicit_wait) if @from_element.instance_of?(TestaAppiumDriver::Locator)
|
128
118
|
return @from_element
|
129
119
|
end
|
130
120
|
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
121
|
r = @driver.execute(@from_element, @single, strategies_and_selectors, skip_cache: skip_cache, ignore_implicit_wait: ignore_implicit_wait)
|
137
122
|
r = r[@index_for_multiple] if !@index_for_multiple.nil? && !@single
|
138
123
|
r
|
@@ -149,30 +134,28 @@ module TestaAppiumDriver
|
|
149
134
|
if found
|
150
135
|
if block_given? # block is given
|
151
136
|
block.call(self) # use call to execute the block
|
152
|
-
else
|
137
|
+
else
|
138
|
+
# the value of block_argument becomes nil if you didn't give a block
|
153
139
|
# block was not given
|
154
140
|
end
|
155
141
|
end
|
156
142
|
self
|
157
143
|
end
|
158
144
|
|
159
|
-
|
160
145
|
# @param [Integer] timeout in seconds
|
161
146
|
# @return [TestaAppiumDriver::Locator]
|
162
147
|
def wait_until_exists(timeout = nil)
|
163
|
-
args = {timeout: timeout}
|
148
|
+
args = { timeout: timeout }
|
164
149
|
_wait(:until, args)
|
165
150
|
end
|
166
151
|
|
167
|
-
|
168
152
|
# @param [Integer] timeout in seconds
|
169
153
|
# @return [TestaAppiumDriver::Locator]
|
170
154
|
def wait_while_exists(timeout = nil)
|
171
|
-
args = {timeout: timeout}
|
155
|
+
args = { timeout: timeout }
|
172
156
|
_wait(:while, args)
|
173
157
|
end
|
174
158
|
|
175
|
-
|
176
159
|
def wait_while(timeout = nil, args = {})
|
177
160
|
args[:timeout] = timeout
|
178
161
|
_wait(:while, args)
|
@@ -183,13 +166,13 @@ module TestaAppiumDriver
|
|
183
166
|
_wait(:until, args)
|
184
167
|
end
|
185
168
|
|
186
|
-
|
187
169
|
# all timeouts are disabled before check, and enabled after check
|
188
170
|
# @return [boolean] true if it exists in the page regardless if visible or not
|
189
171
|
def exists?
|
190
172
|
found = true
|
191
173
|
begin
|
192
|
-
execute(skip_cache: true, ignore_implicit_wait: true)
|
174
|
+
r = execute(skip_cache: true, ignore_implicit_wait: true)
|
175
|
+
return r.count.positive? if r.is_a?(Array)
|
193
176
|
rescue StandardError
|
194
177
|
found = false
|
195
178
|
end
|
@@ -235,7 +218,7 @@ module TestaAppiumDriver
|
|
235
218
|
else
|
236
219
|
from_element = self.dup
|
237
220
|
from_element.index_for_multiple = instance
|
238
|
-
params = {}.merge({single: true, scrollable_locator: @scrollable_locator})
|
221
|
+
params = {}.merge({ single: true, scrollable_locator: @scrollable_locator })
|
239
222
|
#params[:strategy] = FIND_STRATEGY_XPATH
|
240
223
|
#params[:strategy_reason] = "retrieved instance of a array"
|
241
224
|
params[:default_find_strategy] = @default_find_strategy
|
@@ -244,33 +227,32 @@ module TestaAppiumDriver
|
|
244
227
|
end
|
245
228
|
end
|
246
229
|
|
247
|
-
|
248
230
|
# @param [TestaAppiumDriver::Locator, Selenium::WebDriver::Element, Array] other
|
249
231
|
#noinspection RubyNilAnalysis,RubyUnnecessaryReturnStatement
|
250
232
|
def ==(other)
|
251
233
|
elements = execute
|
252
|
-
other = other.execute if other.
|
234
|
+
other = other.execute if other.is_a?(TestaAppiumDriver::Locator)
|
253
235
|
|
254
|
-
if elements.
|
255
|
-
return false unless other.
|
236
|
+
if elements.is_a?(Array)
|
237
|
+
return false unless other.is_a?(Array)
|
256
238
|
return false if other.count != elements.count
|
257
239
|
return (elements - other).empty?
|
258
240
|
else
|
259
|
-
return false if other.
|
241
|
+
return false if other.is_a?(Array)
|
260
242
|
return elements == other
|
261
243
|
end
|
262
244
|
end
|
263
245
|
|
264
246
|
def as_json
|
265
247
|
{
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
248
|
+
strategy: @strategy,
|
249
|
+
default_strategy: @default_find_strategy,
|
250
|
+
single: @single,
|
251
|
+
uiautomator: defined?(self.ui_selector) ? ui_selector : nil,
|
252
|
+
xpath: @xpath_selector,
|
253
|
+
scroll_orientation: @scroll_orientation,
|
254
|
+
resolved: strategies_and_selectors,
|
255
|
+
index_for_multiple: @index_for_multiple
|
274
256
|
}
|
275
257
|
end
|
276
258
|
|
@@ -282,7 +264,6 @@ module TestaAppiumDriver
|
|
282
264
|
[self.to_s]
|
283
265
|
end
|
284
266
|
|
285
|
-
|
286
267
|
# @return [TestaAppiumDriver::Locator]
|
287
268
|
def as_scrollable(orientation: :vertical, top: nil, bottom: nil, right: nil, left: nil)
|
288
269
|
@scroll_orientation = orientation
|
@@ -297,43 +278,50 @@ module TestaAppiumDriver
|
|
297
278
|
self
|
298
279
|
end
|
299
280
|
|
300
|
-
|
301
281
|
def first_and_last_leaf
|
302
282
|
@driver.first_and_last_leaf(execute)
|
303
283
|
end
|
304
284
|
|
285
|
+
def first_and_last_child
|
286
|
+
@driver.first_and_last_child(execute)
|
287
|
+
end
|
305
288
|
|
306
|
-
def
|
307
|
-
click(x, y)
|
289
|
+
def double_click(x = nil, y = nil)
|
290
|
+
click(x, y, double: true)
|
308
291
|
end
|
309
292
|
|
310
293
|
# if both x or y, or both are not given, will click in the center of the element
|
311
294
|
# @param x If positive integer, will offset the click from the left side, if negative integer, will offset the click from the right. If float value is given, it will threat it as percentage offset, giving it 0.5 will click in the middle
|
312
295
|
# @param y If positive integer, will offset the click from the bottom side, if negative integer, will offset the click from the top. If float value is given, it will threat it as percentage offset, giving it 0.5 will click in the middle
|
313
|
-
def click(x = nil, y = nil)
|
314
|
-
if !x.nil? && !y.nil?
|
296
|
+
def click(x = nil, y = nil, double: false, by_coords: false)
|
297
|
+
if !x.nil? && !y.nil? || double || by_coords
|
298
|
+
|
299
|
+
x = 0.5 if x.nil?
|
300
|
+
y = 0.5 if y.nil?
|
315
301
|
|
316
302
|
b = self.bounds
|
317
|
-
if x.
|
303
|
+
if x.is_a?(Integer)
|
318
304
|
if x >= 0
|
319
305
|
x = b.top_left.x + x
|
320
306
|
else
|
321
307
|
x = b.bottom_right.x + x
|
322
308
|
end
|
323
|
-
elsif x.
|
324
|
-
x = b.top_left.x + b.width*x
|
309
|
+
elsif x.is_a?(Float) && x <= 1.0 && x >= 0
|
310
|
+
x = b.top_left.x + b.width * x
|
325
311
|
else
|
326
|
-
raise "x value #{x} not supported"
|
312
|
+
raise "x value #{x} not supported. Use integer as pixel or float (0..1) as percentage of element width"
|
327
313
|
end
|
328
314
|
|
329
|
-
if y.
|
315
|
+
if y.is_a?(Integer)
|
330
316
|
if y >= 0
|
331
|
-
y = b.
|
317
|
+
y = b.top_left.y + y
|
332
318
|
else
|
333
|
-
y = b.
|
319
|
+
y = b.bottom_right + y
|
334
320
|
end
|
335
|
-
elsif y.
|
336
|
-
y = b.
|
321
|
+
elsif y.is_a?(Float) && y <= 1.0 && y >= 0
|
322
|
+
y = b.top_left.y + b.height * y
|
323
|
+
else
|
324
|
+
raise "y value #{x} not supported. Use integer as pixel or float (0..1) as percentage of element height"
|
337
325
|
end
|
338
326
|
|
339
327
|
action_builder = @driver.action
|
@@ -341,6 +329,11 @@ module TestaAppiumDriver
|
|
341
329
|
f1.create_pointer_move(duration: 0, x: x, y: y, origin: ::Selenium::WebDriver::Interactions::PointerMove::VIEWPORT)
|
342
330
|
f1.create_pointer_down(:left)
|
343
331
|
f1.create_pointer_up(:left)
|
332
|
+
if double
|
333
|
+
f1.create_pause(0.1)
|
334
|
+
f1.create_pointer_down(:left)
|
335
|
+
f1.create_pointer_up(:left)
|
336
|
+
end
|
344
337
|
@driver.perform_actions [f1]
|
345
338
|
else
|
346
339
|
if @driver.device == :android
|
@@ -348,13 +341,16 @@ module TestaAppiumDriver
|
|
348
341
|
else
|
349
342
|
# on ios, if element is not visible, first click will scroll to it
|
350
343
|
# then on second click actually perform the click
|
351
|
-
visible = visible?
|
344
|
+
#visible = visible?
|
352
345
|
perform_driver_method(:click)
|
353
|
-
perform_driver_method(:click) unless visible rescue nil
|
346
|
+
#perform_driver_method(:click) unless visible rescue nil
|
354
347
|
end
|
355
348
|
end
|
356
349
|
end
|
357
350
|
|
351
|
+
alias_method :tap, :click
|
352
|
+
alias_method :double_tap, :double_click
|
353
|
+
|
358
354
|
def send_key(*args)
|
359
355
|
perform_driver_method(:send_keys, *args)
|
360
356
|
end
|
@@ -363,12 +359,11 @@ module TestaAppiumDriver
|
|
363
359
|
perform_driver_method(:clear)
|
364
360
|
end
|
365
361
|
|
366
|
-
|
367
362
|
# Return parent element
|
368
363
|
# @return [TestaAppiumDriver::Locator]
|
369
364
|
def parent
|
370
365
|
raise StrategyMixException.new(@strategy, @strategy_reason, FIND_STRATEGY_XPATH, "parent") if @strategy != FIND_STRATEGY_XPATH && !@strategy.nil?
|
371
|
-
raise "Cannot add parent selector to a retrieved instance of a class array" if (@xpath_selector == "
|
366
|
+
raise "Cannot add parent selector to a retrieved instance of a class array" if (@xpath_selector == ".//*" || @xpath_selector == ".//*[1]") && !@from_element.nil?
|
372
367
|
|
373
368
|
locator = self.dup
|
374
369
|
locator.strategy = FIND_STRATEGY_XPATH
|
@@ -382,7 +377,7 @@ module TestaAppiumDriver
|
|
382
377
|
# @return [TestaAppiumDriver::Locator]
|
383
378
|
def children
|
384
379
|
raise "Cannot add children selector to array" unless @single
|
385
|
-
raise StrategyMixException.new(@strategy, @strategy_reason, FIND_STRATEGY_XPATH, "children") if @strategy != FIND_STRATEGY_XPATH &&
|
380
|
+
raise StrategyMixException.new(@strategy, @strategy_reason, FIND_STRATEGY_XPATH, "children") if @strategy != FIND_STRATEGY_XPATH && @strategy != FIND_STRATEGY_CLASS_CHAIN && !@strategy.nil?
|
386
381
|
|
387
382
|
locator = self.dup
|
388
383
|
locator.strategy_reason = "children"
|
@@ -399,7 +394,6 @@ module TestaAppiumDriver
|
|
399
394
|
locator
|
400
395
|
end
|
401
396
|
|
402
|
-
|
403
397
|
# Return first child element
|
404
398
|
# @return [TestaAppiumDriver::Locator]
|
405
399
|
def child
|
@@ -421,12 +415,11 @@ module TestaAppiumDriver
|
|
421
415
|
locator
|
422
416
|
end
|
423
417
|
|
424
|
-
|
425
418
|
# @return [TestaAppiumDriver::Locator]
|
426
419
|
def siblings
|
427
420
|
raise "Cannot add siblings selector to array" unless @single
|
428
421
|
raise StrategyMixException.new(@strategy, @strategy_reason, FIND_STRATEGY_XPATH, "siblings") if @strategy != FIND_STRATEGY_XPATH && !@strategy.nil?
|
429
|
-
raise "Cannot add siblings selector to a retrieved instance of a class array" if (@xpath_selector == "
|
422
|
+
raise "Cannot add siblings selector to a retrieved instance of a class array" if (@xpath_selector == ".//*" || @xpath_selector == ".//*[1]") && !@from_element.nil?
|
430
423
|
|
431
424
|
locator = self.dup
|
432
425
|
locator.strategy = FIND_STRATEGY_XPATH
|
@@ -442,7 +435,7 @@ module TestaAppiumDriver
|
|
442
435
|
def preceding_siblings
|
443
436
|
raise "Cannot add preceding_siblings selector to array" unless @single
|
444
437
|
raise StrategyMixException.new(@strategy, @strategy_reason, FIND_STRATEGY_XPATH, "preceding_siblings") if @strategy != FIND_STRATEGY_XPATH && !@strategy.nil?
|
445
|
-
raise "Cannot add preceding_siblings selector to a retrieved instance of a class array" if (@xpath_selector == "
|
438
|
+
raise "Cannot add preceding_siblings selector to a retrieved instance of a class array" if (@xpath_selector == ".//*" || @xpath_selector == ".//*[1]") && !@from_element.nil?
|
446
439
|
|
447
440
|
locator = self.dup
|
448
441
|
locator.strategy = FIND_STRATEGY_XPATH
|
@@ -458,7 +451,7 @@ module TestaAppiumDriver
|
|
458
451
|
def preceding_sibling
|
459
452
|
raise "Cannot add preceding_sibling selector to array" unless @single
|
460
453
|
raise StrategyMixException.new(@strategy, @strategy_reason, FIND_STRATEGY_XPATH, "preceding_sibling") if @strategy != FIND_STRATEGY_XPATH && !@strategy.nil?
|
461
|
-
raise "Cannot add preceding siblings selector to a retrieved instance of a class array" if (@xpath_selector == "
|
454
|
+
raise "Cannot add preceding siblings selector to a retrieved instance of a class array" if (@xpath_selector == ".//*" || @xpath_selector == ".//*[1]") && !@from_element.nil?
|
462
455
|
|
463
456
|
locator = self.dup
|
464
457
|
locator.strategy = FIND_STRATEGY_XPATH
|
@@ -472,12 +465,11 @@ module TestaAppiumDriver
|
|
472
465
|
locator
|
473
466
|
end
|
474
467
|
|
475
|
-
|
476
468
|
# @return [TestaAppiumDriver::Locator]
|
477
469
|
def following_siblings
|
478
470
|
raise "Cannot add following_siblings selector to array" unless @single
|
479
471
|
raise StrategyMixException.new(@strategy, @strategy_reason, FIND_STRATEGY_XPATH, "following_siblings") if @strategy != FIND_STRATEGY_XPATH && !@strategy.nil?
|
480
|
-
raise "Cannot add following_siblings selector to a retrieved instance of a class array" if (@xpath_selector == "
|
472
|
+
raise "Cannot add following_siblings selector to a retrieved instance of a class array" if (@xpath_selector == ".//*" || @xpath_selector == ".//*[1]") && !@from_element.nil?
|
481
473
|
|
482
474
|
locator = self.dup
|
483
475
|
locator.strategy = FIND_STRATEGY_XPATH
|
@@ -493,7 +485,7 @@ module TestaAppiumDriver
|
|
493
485
|
def following_sibling
|
494
486
|
raise "Cannot add following_sibling selector to array" unless @single
|
495
487
|
raise StrategyMixException.new(@strategy, @strategy_reason, FIND_STRATEGY_XPATH, "following_sibling") if @strategy != FIND_STRATEGY_XPATH && !@strategy.nil?
|
496
|
-
raise "Cannot add following_sibling selector to a retrieved instance of a class array" if (@xpath_selector == "
|
488
|
+
raise "Cannot add following_sibling selector to a retrieved instance of a class array" if (@xpath_selector == ".//*" || @xpath_selector == ".//*[1]") && !@from_element.nil?
|
497
489
|
|
498
490
|
locator = self.dup
|
499
491
|
locator.strategy = FIND_STRATEGY_XPATH
|
@@ -507,7 +499,6 @@ module TestaAppiumDriver
|
|
507
499
|
locator
|
508
500
|
end
|
509
501
|
|
510
|
-
|
511
502
|
private
|
512
503
|
|
513
504
|
def _wait(type, args)
|
@@ -528,10 +519,8 @@ module TestaAppiumDriver
|
|
528
519
|
args.delete(:interval)
|
529
520
|
args.delete(:timeout)
|
530
521
|
|
531
|
-
|
532
|
-
|
533
522
|
start_time = Time.now.to_f
|
534
|
-
if type ==
|
523
|
+
if type == :while
|
535
524
|
while exists? && _attributes_match(args)
|
536
525
|
raise message if start_time + timeout < Time.now.to_f
|
537
526
|
sleep interval
|
@@ -548,7 +537,7 @@ module TestaAppiumDriver
|
|
548
537
|
def _attributes_match(attributes)
|
549
538
|
all_match = true
|
550
539
|
attributes.each do |key, value|
|
551
|
-
unless
|
540
|
+
unless testa_attribute(key) == value
|
552
541
|
all_match = false
|
553
542
|
break
|
554
543
|
end
|
@@ -559,7 +548,7 @@ module TestaAppiumDriver
|
|
559
548
|
#noinspection RubyNilAnalysis
|
560
549
|
def perform_driver_method(name, *args)
|
561
550
|
elements = execute
|
562
|
-
if elements.
|
551
|
+
if elements.is_a?(Array)
|
563
552
|
elements.map { |e| e.send(name, *args) }
|
564
553
|
else
|
565
554
|
elements.send(name, *args)
|
@@ -571,7 +560,6 @@ module TestaAppiumDriver
|
|
571
560
|
locator.xpath_selector += hash_to_xpath(@driver.device, selectors, single)
|
572
561
|
end
|
573
562
|
|
574
|
-
|
575
563
|
def handle_image_selector(selectors, params)
|
576
564
|
image_match_threshold = 0.4
|
577
565
|
image_match_threshold = params[:imageMatchThreshold] unless params[:imageMatchThreshold].nil?
|
@@ -1,7 +1,7 @@
|
|
1
|
-
module TestaAppiumDriver
|
2
|
-
|
1
|
+
module ::TestaAppiumDriver
|
2
|
+
module W3cScrollActions
|
3
|
+
|
3
4
|
|
4
|
-
private
|
5
5
|
# @return [Array]
|
6
6
|
def w3c_scroll_each(direction, &block)
|
7
7
|
elements = []
|
@@ -19,48 +19,105 @@ module TestaAppiumDriver
|
|
19
19
|
direction = :right
|
20
20
|
end
|
21
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
|
22
39
|
|
23
40
|
until is_end_of_scroll?
|
41
|
+
aligned_items = 0
|
42
|
+
new_ignore_element_ids = []
|
24
43
|
matches = @locator.execute(skip_cache: true)
|
25
|
-
matches.each_with_index do |m|
|
26
|
-
|
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
|
+
|
27
66
|
elements << m
|
28
67
|
if block_given? # block is given
|
68
|
+
@locator.driver.invalidate_cache
|
29
69
|
block.call(m) # use call to execute the block
|
30
70
|
else # the value of block_argument becomes nil if you didn't give a block
|
31
71
|
# block was not given
|
32
72
|
end
|
73
|
+
previous_element = m
|
33
74
|
end
|
75
|
+
|
34
76
|
iterations += 1
|
35
77
|
break if !@max_scrolls.nil? && iterations == @max_scrolls
|
36
|
-
|
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
|
+
|
37
87
|
end
|
38
88
|
rescue => e
|
39
89
|
raise e
|
40
|
-
|
41
90
|
end
|
91
|
+
|
42
92
|
elements
|
43
93
|
end
|
44
94
|
|
45
|
-
def w3c_align(with, scroll_to_find)
|
95
|
+
def w3c_align(with, scroll_to_find, max_attempts, speed_coef: 1.25)
|
46
96
|
default_deadzone!
|
47
97
|
|
48
98
|
|
49
99
|
|
50
100
|
@locator.scroll_to if scroll_to_find
|
51
101
|
|
52
|
-
|
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
|
53
110
|
|
54
111
|
timeout = 0
|
55
|
-
until is_aligned?(with, element) || timeout ==
|
56
|
-
w3c_attempt_align(with)
|
112
|
+
until is_aligned?(with, element) || timeout == max_attempts
|
113
|
+
w3c_attempt_align(with, speed_coef)
|
57
114
|
timeout += 1
|
58
115
|
end
|
59
116
|
|
60
117
|
end
|
61
118
|
|
62
119
|
|
63
|
-
def w3c_attempt_align(with)
|
120
|
+
def w3c_attempt_align(with, speed_coef)
|
64
121
|
case with
|
65
122
|
when :top
|
66
123
|
y0 = @bounds.bottom_right.y - @deadzone[:bottom]
|
@@ -91,7 +148,7 @@ module TestaAppiumDriver
|
|
91
148
|
end
|
92
149
|
|
93
150
|
x1, y1 = apply_w3c_correction(x1, y1, scroll_direction) if @driver.device == :android
|
94
|
-
w3c_action(x0, y0, x1, y1, SCROLL_ACTION_TYPE_SCROLL)
|
151
|
+
w3c_action(x0, y0, x1, y1, SCROLL_ACTION_TYPE_SCROLL, speed_coef: speed_coef)
|
95
152
|
end
|
96
153
|
|
97
154
|
|
@@ -171,7 +228,9 @@ module TestaAppiumDriver
|
|
171
228
|
y0 = @bounds.top_left.y + @deadzone[:top].to_i
|
172
229
|
y1 = @bounds.bottom_right.y - @deadzone[:bottom].to_i
|
173
230
|
end
|
174
|
-
x0 = @bounds.width / 2
|
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
|
175
234
|
x1 = x0
|
176
235
|
else
|
177
236
|
if direction == :right
|
@@ -181,24 +240,32 @@ module TestaAppiumDriver
|
|
181
240
|
x0 = @bounds.top_left.x + @deadzone[:left].to_i
|
182
241
|
x1 = @bounds.bottom_right.x - @deadzone[:right].to_i
|
183
242
|
end
|
184
|
-
|
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
|
185
247
|
y1 = y0
|
186
248
|
end
|
187
249
|
x1, y1 = apply_w3c_correction(x1, y1, direction) if @driver.device == :android
|
188
250
|
|
251
|
+
speed_coef = 1
|
252
|
+
if type == SCROLL_ACTION_TYPE_SCROLL
|
253
|
+
speed_coef = 1.5
|
254
|
+
end
|
189
255
|
|
190
|
-
w3c_action(x0, y0, x1, y1, type)
|
256
|
+
w3c_action(x0, y0, x1, y1, type, speed_coef: speed_coef)
|
191
257
|
|
192
258
|
end
|
193
259
|
|
194
260
|
|
195
|
-
def w3c_action(x0, y0, x1, y1, type)
|
261
|
+
def w3c_action(x0, y0, x1, y1, type, speed_coef: 1.0)
|
262
|
+
speed_coef = 1/speed_coef
|
196
263
|
if type == SCROLL_ACTION_TYPE_SCROLL
|
197
|
-
duration = 1.8
|
264
|
+
duration = 1.8*speed_coef
|
198
265
|
elsif type == SCROLL_ACTION_TYPE_FLING
|
199
|
-
duration = 0.1
|
266
|
+
duration = 0.1*speed_coef
|
200
267
|
elsif type == SCROLL_ACTION_TYPE_DRAG
|
201
|
-
duration = 3.5
|
268
|
+
duration = 3.5*speed_coef
|
202
269
|
else
|
203
270
|
raise "Unknown scroll action type #{type}"
|
204
271
|
end
|