testa_appium_driver 0.1.31 → 0.1.32
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/testa_appium_driver/common/locator/scroll_actions.rb +20 -21
- data/lib/testa_appium_driver/common/locator.rb +38 -42
- data/lib/testa_appium_driver/common/scroll_actions/w3c_scroll_actions.rb +8 -8
- data/lib/testa_appium_driver/common/scroll_actions.rb +1 -18
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: add83f6c9df4e695d9c8869c37d15611e0b87a065c6f844828264784e6d333a5
|
4
|
+
data.tar.gz: fa96bc1504a4863534aa9557041ce611594e6267c75f8b6a2d300a42605652d3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b2fac94a46daef9a2782cc854f959434cc811ea3d853021c626c2b3eb12f9b80b8ce98e666472e916f0f2968524828c6635b9f52f5b0473a9a2f5ab92b230aef
|
7
|
+
data.tar.gz: 23f90e32e4c4bb11893a5140202b11a6c7d81681833cd3525539ae470144bce5f92611e57b6c0ac75c90cf6f357183e7c38791d123991d21728d2bdc86a0b4b3
|
@@ -67,14 +67,13 @@ module TestaAppiumDriver
|
|
67
67
|
# If the distance is greater than the threshold, it will attempt to realign it up to 2 more times.
|
68
68
|
# The retry mechanism allows alignment even for dynamic layouts when elements are hidden/show when scrolling to certain direction
|
69
69
|
# @return [TestaAppiumDriver::Locator]
|
70
|
-
def align(with = :top, top: nil, bottom: nil, right: nil, left: nil, scroll_to_find: false, max_attempts: 3
|
70
|
+
def align(with = :top, top: nil, bottom: nil, right: nil, left: nil, scroll_to_find: false, max_attempts: 3)
|
71
71
|
deadzone = _process_deadzone(top, bottom, right, left)
|
72
72
|
deadzone = @scrollable_locator.scroll_deadzone if deadzone.nil? && !@scrollable_locator.nil?
|
73
73
|
sa = ScrollActions.new(@scrollable_locator,
|
74
74
|
locator: self,
|
75
75
|
deadzone: deadzone,
|
76
|
-
default_scroll_strategy: @default_scroll_strategy
|
77
|
-
bounds_from_cache_element: bounds_from_cache_element)
|
76
|
+
default_scroll_strategy: @default_scroll_strategy)
|
78
77
|
sa.align(with, scroll_to_find, max_attempts)
|
79
78
|
self
|
80
79
|
end
|
@@ -84,8 +83,8 @@ module TestaAppiumDriver
|
|
84
83
|
# If the distance is greater than the threshold, it will attempt to realign it up to 2 more times.
|
85
84
|
# The retry mechanism allows alignment even for dynamic layouts when elements are hidden/show when scrolling to certain direction
|
86
85
|
# @return [TestaAppiumDriver::Locator]
|
87
|
-
def align_top(top: nil, bottom: nil, right: nil, left: nil, max_attempts: 3
|
88
|
-
align(:top, top: top, bottom: bottom, right: right, left: left, max_attempts: max_attempts
|
86
|
+
def align_top(top: nil, bottom: nil, right: nil, left: nil, max_attempts: 3)
|
87
|
+
align(:top, top: top, bottom: bottom, right: right, left: left, max_attempts: max_attempts)
|
89
88
|
end
|
90
89
|
|
91
90
|
# Aligns element on bottom of the scrollable container, if the element does not exists it will scroll to find it
|
@@ -93,8 +92,8 @@ module TestaAppiumDriver
|
|
93
92
|
# If the distance is greater than the threshold, it will attempt to realign it up to 2 more times.
|
94
93
|
# The retry mechanism allows alignment even for dynamic layouts when elements are hidden/show when scrolling to certain direction
|
95
94
|
# @return [TestaAppiumDriver::Locator]
|
96
|
-
def align_bottom(top: nil, bottom: nil, right: nil, left: nil, max_attempts: 3
|
97
|
-
align(:bottom, top: top, bottom: bottom, right: right, left: left, max_attempts: max_attempts
|
95
|
+
def align_bottom(top: nil, bottom: nil, right: nil, left: nil, max_attempts: 3)
|
96
|
+
align(:bottom, top: top, bottom: bottom, right: right, left: left, max_attempts: max_attempts)
|
98
97
|
end
|
99
98
|
|
100
99
|
# Aligns element on left of the scrollable container, if the element does not exists it will scroll to find it
|
@@ -102,8 +101,8 @@ module TestaAppiumDriver
|
|
102
101
|
# If the distance is greater than the threshold, it will attempt to realign it up to 2 more times.
|
103
102
|
# The retry mechanism allows alignment even for dynamic layouts when elements are hidden/show when scrolling to certain direction
|
104
103
|
# @return [TestaAppiumDriver::Locator]
|
105
|
-
def align_left(top: nil, bottom: nil, right: nil, left: nil, max_attempts: 3
|
106
|
-
align(:left, top: top, bottom: bottom, right: right, left: left, max_attempts: max_attempts
|
104
|
+
def align_left(top: nil, bottom: nil, right: nil, left: nil, max_attempts: 3)
|
105
|
+
align(:left, top: top, bottom: bottom, right: right, left: left, max_attempts: max_attempts)
|
107
106
|
end
|
108
107
|
|
109
108
|
# Aligns element on right of the scrollable container, if the element does not exists it will scroll to find it
|
@@ -111,8 +110,8 @@ module TestaAppiumDriver
|
|
111
110
|
# If the distance is greater than the threshold, it will attempt to realign it up to 2 more times.
|
112
111
|
# The retry mechanism allows alignment even for dynamic layouts when elements are hidden/show when scrolling to certain direction
|
113
112
|
# @return [TestaAppiumDriver::Locator]
|
114
|
-
def align_right(top: nil, bottom: nil, right: nil, left: nil, max_attempts: 3
|
115
|
-
align(:right, top: top, bottom: bottom, right: right, left: left, max_attempts: max_attempts
|
113
|
+
def align_right(top: nil, bottom: nil, right: nil, left: nil, max_attempts: 3)
|
114
|
+
align(:right, top: top, bottom: bottom, right: right, left: left, max_attempts: max_attempts)
|
116
115
|
end
|
117
116
|
|
118
117
|
# Aligns element (by default) on top of the scrollable container, if the element does not exists it raise an exception
|
@@ -120,8 +119,8 @@ module TestaAppiumDriver
|
|
120
119
|
# If the distance is greater than the threshold, it will attempt to realign it up to 2 more times.
|
121
120
|
# The retry mechanism allows alignment even for dynamic layouts when elements are hidden/show when scrolling to certain direction
|
122
121
|
# @return [TestaAppiumDriver::Locator]
|
123
|
-
def align!(with = :top, top: nil, bottom: nil, right: nil, left: nil, max_attempts: 3
|
124
|
-
align(with, top: top, bottom: bottom, right: right, left: left, scroll_to_find: true, max_attempts: max_attempts
|
122
|
+
def align!(with = :top, top: nil, bottom: nil, right: nil, left: nil, max_attempts: 3)
|
123
|
+
align(with, top: top, bottom: bottom, right: right, left: left, scroll_to_find: true, max_attempts: max_attempts)
|
125
124
|
end
|
126
125
|
|
127
126
|
# Aligns element on top of the scrollable container, if the element does not exists it raise an exception
|
@@ -129,8 +128,8 @@ module TestaAppiumDriver
|
|
129
128
|
# If the distance is greater than the threshold, it will attempt to realign it up to 2 more times.
|
130
129
|
# The retry mechanism allows alignment even for dynamic layouts when elements are hidden/show when scrolling to certain direction
|
131
130
|
# @return [TestaAppiumDriver::Locator]
|
132
|
-
def align_top!(top: nil, bottom: nil, right: nil, left: nil, max_attempts: 3
|
133
|
-
align(:top, top: top, bottom: bottom, right: right, left: left, scroll_to_find: true, max_attempts: max_attempts
|
131
|
+
def align_top!(top: nil, bottom: nil, right: nil, left: nil, max_attempts: 3)
|
132
|
+
align(:top, top: top, bottom: bottom, right: right, left: left, scroll_to_find: true, max_attempts: max_attempts)
|
134
133
|
end
|
135
134
|
|
136
135
|
# Aligns element on bottom of the scrollable container, if the element does not exists it raise an exception
|
@@ -138,8 +137,8 @@ module TestaAppiumDriver
|
|
138
137
|
# If the distance is greater than the threshold, it will attempt to realign it up to 2 more times.
|
139
138
|
# The retry mechanism allows alignment even for dynamic layouts when elements are hidden/show when scrolling to certain direction
|
140
139
|
# @return [TestaAppiumDriver::Locator]
|
141
|
-
def align_bottom!(top: nil, bottom: nil, right: nil, left: nil, max_attempts: 3
|
142
|
-
align(:bottom, top: top, bottom: bottom, right: right, left: left, scroll_to_find: true, max_attempts: max_attempts
|
140
|
+
def align_bottom!(top: nil, bottom: nil, right: nil, left: nil, max_attempts: 3)
|
141
|
+
align(:bottom, top: top, bottom: bottom, right: right, left: left, scroll_to_find: true, max_attempts: max_attempts)
|
143
142
|
end
|
144
143
|
|
145
144
|
# Aligns element on left of the scrollable container, if the element does not exists it raise an exception
|
@@ -147,8 +146,8 @@ module TestaAppiumDriver
|
|
147
146
|
# If the distance is greater than the threshold, it will attempt to realign it up to 2 more times.
|
148
147
|
# The retry mechanism allows alignment even for dynamic layouts when elements are hidden/show when scrolling to certain direction
|
149
148
|
# @return [TestaAppiumDriver::Locator]
|
150
|
-
def align_left!(top: nil, bottom: nil, right: nil, left: nil, max_attempts: 3
|
151
|
-
align(:left, top: top, bottom: bottom, right: right, left: left, scroll_to_find: true, max_attempts: max_attempts
|
149
|
+
def align_left!(top: nil, bottom: nil, right: nil, left: nil, max_attempts: 3)
|
150
|
+
align(:left, top: top, bottom: bottom, right: right, left: left, scroll_to_find: true, max_attempts: max_attempts)
|
152
151
|
end
|
153
152
|
|
154
153
|
# Aligns element on right of the scrollable container, if the element does not exists it raise an exception
|
@@ -156,8 +155,8 @@ module TestaAppiumDriver
|
|
156
155
|
# If the distance is greater than the threshold, it will attempt to realign it up to 2 more times.
|
157
156
|
# The retry mechanism allows alignment even for dynamic layouts when elements are hidden/show when scrolling to certain direction
|
158
157
|
# @return [TestaAppiumDriver::Locator]
|
159
|
-
def align_right!(top: nil, bottom: nil, right: nil, left: nil, max_attempts: 3
|
160
|
-
align(:right, top: top, bottom: bottom, right: right, left: left, scroll_to_find: true, max_attempts: max_attempts
|
158
|
+
def align_right!(top: nil, bottom: nil, right: nil, left: nil, max_attempts: 3)
|
159
|
+
align(:right, top: top, bottom: bottom, right: right, left: left, scroll_to_find: true, max_attempts: max_attempts)
|
161
160
|
end
|
162
161
|
|
163
162
|
# First scrolls to the beginning of the scrollable container and then scrolls down until element is found or end is reached
|
@@ -187,7 +187,8 @@ module ::TestaAppiumDriver
|
|
187
187
|
begin
|
188
188
|
r = execute(skip_cache: true, ignore_implicit_wait: true)
|
189
189
|
return r.count.positive? if r.is_a?(Array)
|
190
|
-
|
190
|
+
# ios17 has phantom child elements that overlap parent so this returns false positive
|
191
|
+
# return r.displayed? if @driver.ios?
|
191
192
|
rescue StandardError
|
192
193
|
found = false
|
193
194
|
end
|
@@ -332,56 +333,51 @@ module ::TestaAppiumDriver
|
|
332
333
|
# if both x or y, or both are not given, will click in the center of the element
|
333
334
|
# @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
|
334
335
|
# @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
|
335
|
-
def click(x = nil, y = nil, double: false
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
if x >= 0
|
344
|
-
x = b.top_left.x + x
|
345
|
-
else
|
346
|
-
x = b.bottom_right.x + x
|
347
|
-
end
|
348
|
-
elsif x.is_a?(Float) && x <= 1.0 && x >= 0
|
349
|
-
x = b.top_left.x + b.width * x
|
336
|
+
def click(x = nil, y = nil, double: false)
|
337
|
+
x = 0.5 if x.nil?
|
338
|
+
y = 0.5 if y.nil?
|
339
|
+
|
340
|
+
b = self.bounds
|
341
|
+
if x.is_a?(Integer)
|
342
|
+
if x >= 0
|
343
|
+
x = b.top_left.x + x
|
350
344
|
else
|
351
|
-
|
345
|
+
x = b.bottom_right.x + x
|
352
346
|
end
|
347
|
+
elsif x.is_a?(Float) && x <= 1.0 && x >= 0
|
348
|
+
x = b.top_left.x + b.width * x
|
349
|
+
else
|
350
|
+
raise "x value #{x} not supported. Use integer as pixel or float (0..1) as percentage of element width"
|
351
|
+
end
|
353
352
|
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
else
|
358
|
-
y = b.bottom_right + y
|
359
|
-
end
|
360
|
-
elsif y.is_a?(Float) && y <= 1.0 && y >= 0
|
361
|
-
y = b.top_left.y + b.height * y
|
353
|
+
if y.is_a?(Integer)
|
354
|
+
if y >= 0
|
355
|
+
y = b.top_left.y + y
|
362
356
|
else
|
363
|
-
|
357
|
+
y = b.bottom_right + y
|
364
358
|
end
|
359
|
+
elsif y.is_a?(Float) && y <= 1.0 && y >= 0
|
360
|
+
y = b.top_left.y + b.height * y
|
361
|
+
else
|
362
|
+
raise "y value #{x} not supported. Use integer as pixel or float (0..1) as percentage of element height"
|
363
|
+
end
|
365
364
|
|
366
|
-
|
367
|
-
|
368
|
-
|
365
|
+
action_builder = @driver.action
|
366
|
+
f1 = action_builder.add_pointer_input(:touch, "finger1")
|
367
|
+
f1.create_pointer_move(duration: 0.1, x: x, y: y, origin: ::Selenium::WebDriver::Interactions::PointerMove::VIEWPORT)
|
368
|
+
f1.create_pointer_down(:left)
|
369
|
+
f1.create_pointer_up(:left)
|
370
|
+
if double
|
371
|
+
if @driver.ios?
|
372
|
+
# NOTE: ios is stupid, we have to do another move
|
373
|
+
# NOTE: ios is stupid, works very wierd if duration is 0
|
374
|
+
f1.create_pointer_move(duration: 0.1, x: x, y: y, origin: ::Selenium::WebDriver::Interactions::PointerMove::VIEWPORT)
|
375
|
+
end
|
376
|
+
f1.create_pause(0.1)
|
369
377
|
f1.create_pointer_down(:left)
|
370
378
|
f1.create_pointer_up(:left)
|
371
|
-
if double
|
372
|
-
if @driver.ios?
|
373
|
-
# NOTE: ios is stupid, we have to do another move
|
374
|
-
# NOTE: ios is stupid, works very wierd if duration is 0
|
375
|
-
f1.create_pointer_move(duration: 0.1, x: x, y: y, origin: ::Selenium::WebDriver::Interactions::PointerMove::VIEWPORT)
|
376
|
-
end
|
377
|
-
f1.create_pause(0.1)
|
378
|
-
f1.create_pointer_down(:left)
|
379
|
-
f1.create_pointer_up(:left)
|
380
|
-
end
|
381
|
-
@driver.perform_actions [f1]
|
382
|
-
else
|
383
|
-
perform_driver_method(:click)
|
384
379
|
end
|
380
|
+
@driver.perform_actions [f1]
|
385
381
|
end
|
386
382
|
|
387
383
|
alias_method :tap, :click
|
@@ -186,7 +186,7 @@ module ::TestaAppiumDriver
|
|
186
186
|
stale_retries = 0
|
187
187
|
begin
|
188
188
|
until is_aligned?(with, element) || timeout == max_attempts
|
189
|
-
#
|
189
|
+
# $ctx.puts("align roudn: #{timeout}")
|
190
190
|
w3c_attempt_align(with, speed_coef)
|
191
191
|
timeout += 1
|
192
192
|
end
|
@@ -194,12 +194,12 @@ module ::TestaAppiumDriver
|
|
194
194
|
# if boundElementsByIndex is enabled, we can get stale element reference while doing scroll each
|
195
195
|
stale_retries += 1
|
196
196
|
sleep 0.2
|
197
|
-
#
|
197
|
+
# $ctx.puts "Looking for #{@locator.xpath_selector}"
|
198
198
|
element = @locator.execute if @locator.instance_of?(TestaAppiumDriver::Locator)
|
199
199
|
retry if stale_retries < 4
|
200
200
|
raise
|
201
201
|
end
|
202
|
-
#
|
202
|
+
# $ctx.puts("end align")
|
203
203
|
end
|
204
204
|
|
205
205
|
def w3c_attempt_align(with, speed_coef)
|
@@ -240,9 +240,9 @@ module ::TestaAppiumDriver
|
|
240
240
|
rounds = 0
|
241
241
|
max_scrolls_reached = false
|
242
242
|
end_of_scroll_reached = false
|
243
|
-
#
|
243
|
+
# $ctx.puts("starting scroll to")
|
244
244
|
until (element_found = ((@driver.android? && @locator.exists?) || (@driver.ios? && @locator.exists? && @locator.in_viewport?))) || end_of_scroll_reached
|
245
|
-
#
|
245
|
+
# $ctx.puts("Scroll to round: #{rounds}")
|
246
246
|
end_of_scroll_reached = is_end_of_scroll?
|
247
247
|
case direction
|
248
248
|
when :down
|
@@ -268,7 +268,7 @@ module ::TestaAppiumDriver
|
|
268
268
|
max_scrolls_reached = true if rounds == @max_scrolls
|
269
269
|
break if rounds == @max_scrolls
|
270
270
|
end
|
271
|
-
#
|
271
|
+
# $ctx.puts("end scroll to")
|
272
272
|
raise Selenium::WebDriver::Error::NoSuchElementError if (max_scrolls_reached || end_of_scroll_reached) && !element_found
|
273
273
|
end
|
274
274
|
|
@@ -362,8 +362,8 @@ module ::TestaAppiumDriver
|
|
362
362
|
f1.create_pointer_move(duration: overscroll_pause, x: x1, y: y1, origin: ::Selenium::WebDriver::Interactions::PointerMove::VIEWPORT)
|
363
363
|
end
|
364
364
|
f1.create_pointer_up(:left)
|
365
|
-
|
366
|
-
#
|
365
|
+
puts "Scroll execute[w3c_action]: #{type}: {x0: #{x0}, y0: #{y0}} => (duration: #{duration}) => {x1: #{x1}, y1: #{y1}}"
|
366
|
+
# $ctx.puts "Scroll execute[w3c_action]: #{type}: {x0: #{x0}, y0: #{y0}} => (duration: #{duration}) => {x1: #{x1}, y1: #{y1}}"
|
367
367
|
@driver.perform_actions [f1]
|
368
368
|
end
|
369
369
|
|
@@ -16,7 +16,6 @@ module ::TestaAppiumDriver
|
|
16
16
|
# - deadzone - [Hash] that stores top, bottom, left and right deadzone values. If deadzone[:top] is 200 then 200px from top of the scrollable container will not be used for scrolling
|
17
17
|
# - max_scrolls - [Integer] maximum number of scrolls before exception is thrown
|
18
18
|
# - default_scroll_strategy - defines which scroll strategy will be used if a scroll action is valid for multiple strategies
|
19
|
-
# - bounds_from_cache_element - true by default, use the cached element to get element bounds
|
20
19
|
def initialize(scrollable, params = {})
|
21
20
|
@scrollable = scrollable
|
22
21
|
@locator = params[:locator]
|
@@ -24,9 +23,6 @@ module ::TestaAppiumDriver
|
|
24
23
|
@deadzone = params[:deadzone]
|
25
24
|
@max_scrolls = params[:max_scrolls]
|
26
25
|
@default_scroll_strategy = params[:default_scroll_strategy]
|
27
|
-
@bounds_from_cache_element = params[:bounds_from_cache_element]
|
28
|
-
@bounds_from_cache_element = true if @bounds_from_cache_element.nil?
|
29
|
-
|
30
26
|
@driver = @locator.driver
|
31
27
|
|
32
28
|
if @scrollable.nil?
|
@@ -205,20 +201,7 @@ module ::TestaAppiumDriver
|
|
205
201
|
end
|
206
202
|
|
207
203
|
def is_aligned?(with, element)
|
208
|
-
|
209
|
-
# in some cases, the cached element returns the same bounds, even though it was scrolled a split second ago
|
210
|
-
align_bounds = @locator.bounds(force_cache_element: element)
|
211
|
-
else
|
212
|
-
align_bounds = @locator.bounds
|
213
|
-
end
|
214
|
-
|
215
|
-
# $ctx.puts("Align bounds: ")
|
216
|
-
# $ctx.puts(align_bounds)
|
217
|
-
# $ctx.puts("Scrollable bounds: ")
|
218
|
-
# $ctx.puts(@bounds)
|
219
|
-
|
220
|
-
# $ctx.puts("Deadzone: ")
|
221
|
-
# $ctx.puts(@deadzone)
|
204
|
+
align_bounds = @locator.bounds(force_cache_element: element)
|
222
205
|
case with
|
223
206
|
when :top
|
224
207
|
@align_offset = align_bounds.top_left.y - @bounds.top_left.y - @deadzone[:top]
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: testa_appium_driver
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.32
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- karlo.razumovic
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-11-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: appium_lib_core
|
@@ -90,7 +90,7 @@ metadata:
|
|
90
90
|
homepage_uri: https://github.com/Karazum/testa_appium_driver
|
91
91
|
source_code_uri: https://github.com/Karazum/testa_appium_driver
|
92
92
|
changelog_uri: https://github.com/Karazum/testa_appium_driver
|
93
|
-
post_install_message:
|
93
|
+
post_install_message:
|
94
94
|
rdoc_options: []
|
95
95
|
require_paths:
|
96
96
|
- lib
|
@@ -106,7 +106,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
106
106
|
version: '0'
|
107
107
|
requirements: []
|
108
108
|
rubygems_version: 3.1.6
|
109
|
-
signing_key:
|
109
|
+
signing_key:
|
110
110
|
specification_version: 4
|
111
111
|
summary: Appium made easy
|
112
112
|
test_files: []
|