testa_appium_driver 0.1.7 → 0.1.11

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2dadb5244c71161bcdf995e9b057951ee4a5e979be496e65e828f7188baa85dc
4
- data.tar.gz: bd5d23887285a260d5231525ad09d42f33219ac655432a74ba044b9b57805647
3
+ metadata.gz: 1c55e4e3d29193b3bc89ea292de2c36d093897208050494204da865ea4902d6c
4
+ data.tar.gz: 35014def9a47f5fcfb1242cd1c897a4c13add7f1e9359b66170c2057aa450e3c
5
5
  SHA512:
6
- metadata.gz: 463e52be3a9a6764bbcbc068a46cb0cdc5f6ff41e0651cd95b9bc26da6b2210ba8c90f6651e8f6a153b76b0d173905a8d4a3a3d8b68055ea1e07653af3f4ecf1
7
- data.tar.gz: 7b6ba6de823bbfcc993e712fe11f846cabd3e263b63a23ebfab5bc08c980eeee2c27c9ed0b85690505ed1441e137b3495661a65ecec81db1c6bd8d3755de6638
6
+ metadata.gz: 3562a893791f45303d3cf4cbb3d2b1d1510122ae296e9fb257ce25bd83a9388efacd69ebc9e149219fc5a02fc42f80a9c05f0be72241909b6cd142abfec48e8b
7
+ data.tar.gz: 741a8b9d2b1683484e0100d01c53966d63f9eeacb19ca188589e32b62990ee1cc822d8306e6e23baf34f93ac0a34b929ce5342fdbe1d4a80f3be0e87acf7d28c
data/.idea/deployment.xml CHANGED
@@ -12,7 +12,7 @@
12
12
  <paths name="testa.fun">
13
13
  <serverdata>
14
14
  <mappings>
15
- <mapping deploy="/testa_docker/path_data/testa_appium_driver" local="$PROJECT_DIR$" web="/" />
15
+ <mapping local="$PROJECT_DIR$" web="/" />
16
16
  </mappings>
17
17
  </serverdata>
18
18
  </paths>
@@ -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
@@ -106,7 +106,7 @@ module TestaAppiumDriver
106
106
  end
107
107
 
108
108
  if is_scrollable_selector?(selectors, single)
109
- locator.scrollable_locator = self
109
+ locator.scrollable_locator = locator
110
110
  if selectors[:class] == "android.widget.HorizontalScrollView"
111
111
  locator.scrollable_locator.scroll_orientation = :horizontal
112
112
  else
@@ -38,7 +38,6 @@ module TestaAppiumDriver
38
38
 
39
39
 
40
40
  def uiautomator_page_or_fling(type, direction)
41
-
42
41
  scrollable_selector = @scrollable.ui_selector(false)
43
42
  orientation = direction == :up || direction == :down ? ".setAsVerticalList()" : ".setAsHorizontalList()"
44
43
  if type == SCROLL_ACTION_TYPE_SCROLL
@@ -7,6 +7,7 @@ module TestaAppiumDriver
7
7
  FIND_STRATEGY_ID = :id
8
8
  FIND_STRATEGY_NAME = :name
9
9
  FIND_STRATEGY_IMAGE = :image
10
+ FIND_STRATEGY_CLASS_CHAIN = :class_chain
10
11
 
11
12
  SCROLL_STRATEGY_UIAUTOMATOR = :uiautomator
12
13
  SCROLL_STRATEGY_W3C = :w3c
@@ -157,6 +157,33 @@ module TestaAppiumDriver
157
157
  command
158
158
  end
159
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
+
160
187
  # check if selectors are for a scrollable element
161
188
  # @param [Boolean] single should the command return first instance or all of matched elements
162
189
  # @param [Hash] selectors for fetching elements
@@ -70,6 +70,7 @@ module TestaAppiumDriver
70
70
  # The retry mechanism allows alignment even for dynamic layouts when elements are hidden/show when scrolling to certain direction
71
71
  # @return [TestaAppiumDriver::Locator]
72
72
  def align(with = :top, top: nil, bottom: nil, right: nil, left: nil, scroll_to_find: false)
73
+ deadzone = _process_deadzone(top, bottom, right, left)
73
74
  deadzone = @scrollable_locator.scroll_deadzone if deadzone.nil? && !@scrollable_locator.nil?
74
75
  sa = ScrollActions.new(@scrollable_locator,
75
76
  locator: self,
@@ -289,7 +290,7 @@ module TestaAppiumDriver
289
290
  x = to[:x]
290
291
  y = to[:y]
291
292
  end
292
- _drag_to(x, y)
293
+ _drag_to(bounds.center.x, bounds.center.y, x, y)
293
294
  end
294
295
 
295
296
  def drag_by(amount, direction: :top)
@@ -308,7 +309,7 @@ module TestaAppiumDriver
308
309
  else
309
310
  raise "Unknown direction #{direction}"
310
311
  end
311
- _drag_to(x, y)
312
+ _drag_to(b.center.x, b.center.y, x, y)
312
313
  end
313
314
 
314
315
 
@@ -326,11 +327,11 @@ module TestaAppiumDriver
326
327
  deadzone
327
328
  end
328
329
 
329
- def _drag_to(x, y)
330
+ def _drag_to(x0, y0, x1, y1)
330
331
  sa = ScrollActions.new(@scrollable_locator,
331
332
  locator: self,
332
333
  default_scroll_strategy: @default_scroll_strategy)
333
- sa.drag_to(x, y)
334
+ sa.drag_to(x0, y0, x1, y1)
334
335
  self
335
336
  end
336
337
 
@@ -133,13 +133,12 @@ module TestaAppiumDriver
133
133
 
134
134
 
135
135
 
136
- r = @driver.execute(@from_element, @single, strategies_and_selectors, skip_cache, ignore_implicit_wait)
136
+ r = @driver.execute(@from_element, @single, strategies_and_selectors, skip_cache: skip_cache, ignore_implicit_wait: ignore_implicit_wait)
137
137
  r = r[@index_for_multiple] if !@index_for_multiple.nil? && !@single
138
138
  r
139
139
  end
140
140
 
141
141
  def when_exists(timeout = nil, &block)
142
- timeout = @driver.get_timeouts["implicit"] / 1000 if timeout.nil?
143
142
  found = false
144
143
  begin
145
144
  wait_until_exists(timeout)
@@ -161,7 +160,6 @@ module TestaAppiumDriver
161
160
  # @param [Integer] timeout in seconds
162
161
  # @return [TestaAppiumDriver::Locator]
163
162
  def wait_until_exists(timeout = nil)
164
- timeout = @driver.get_timeouts["implicit"] / 1000 if timeout.nil?
165
163
  args = {timeout: timeout}
166
164
  _wait(:until, args)
167
165
  end
@@ -170,7 +168,6 @@ module TestaAppiumDriver
170
168
  # @param [Integer] timeout in seconds
171
169
  # @return [TestaAppiumDriver::Locator]
172
170
  def wait_while_exists(timeout = nil)
173
- timeout = @driver.get_timeouts["implicit"] / 1000 if timeout.nil?
174
171
  args = {timeout: timeout}
175
172
  _wait(:while, args)
176
173
  end
@@ -221,13 +218,20 @@ module TestaAppiumDriver
221
218
 
222
219
  def [](instance)
223
220
  raise "Cannot add index selector to non-Array" if @single
224
- if ((@strategy.nil? && !@last_selector_adjacent) || @strategy == FIND_STRATEGY_UIAUTOMATOR) && instance >= 0
221
+ if ((@strategy.nil? && !@last_selector_adjacent && @driver.device == :android) || @strategy == FIND_STRATEGY_UIAUTOMATOR) && instance >= 0
225
222
  locator = self.dup
226
223
  locator.strategy = FIND_STRATEGY_UIAUTOMATOR
227
224
  locator.ui_selector = "#{@ui_selector}.instance(#{instance})"
228
225
  locator.single = true
229
226
  locator.can_use_id_strategy = false
230
227
  locator
228
+ elsif (@driver.device == :ios && !@last_selector_adjacent && @strategy.nil?) || @strategy == FIND_STRATEGY_CLASS_CHAIN
229
+ locator = self.dup
230
+ locator.strategy = FIND_STRATEGY_CLASS_CHAIN
231
+ locator.class_chain_selector += "[#{instance + 1}]"
232
+ locator.single = true
233
+ locator.can_use_id_strategy = false
234
+ locator
231
235
  else
232
236
  from_element = self.dup
233
237
  from_element.index_for_multiple = instance
@@ -262,10 +266,8 @@ module TestaAppiumDriver
262
266
  strategy: @strategy,
263
267
  default_strategy: @default_find_strategy,
264
268
  single: @single,
265
- context: @from_element.nil? ? nil : @from_element.to_s,
266
269
  uiautomator: defined?(self.ui_selector) ? ui_selector : nil,
267
270
  xpath: @xpath_selector,
268
- scrollable: @scrollable_locator.nil? ? nil : @scrollable_locator.to_s,
269
271
  scroll_orientation: @scroll_orientation,
270
272
  resolved: strategies_and_selectors,
271
273
  index_for_multiple: @index_for_multiple
@@ -301,12 +303,56 @@ module TestaAppiumDriver
301
303
  end
302
304
 
303
305
 
304
- def tap
305
- click
306
+ def tap(x = nil, y = nil)
307
+ click(x, y)
306
308
  end
307
309
 
308
- def click
309
- perform_driver_method(:click)
310
+ # if both x or y, or both are not given, will click in the center of the element
311
+ # @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
+ # @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?
315
+
316
+ b = self.bounds
317
+ if x.kind_of? Integer
318
+ if x >= 0
319
+ x = b.top_left.x + x
320
+ else
321
+ x = b.bottom_right.x + x
322
+ end
323
+ elsif x.kind_of? Float
324
+ x = b.top_left.x + b.width*x
325
+ else
326
+ raise "x value #{x} not supported"
327
+ end
328
+
329
+ if y.kind_of? Integer
330
+ if y >= 0
331
+ y = b.bottom_right.y + y
332
+ else
333
+ y = b.top_left + y
334
+ end
335
+ elsif y.kind_of? Float
336
+ y = b.bottom_right.y + b.height*y
337
+ end
338
+
339
+ action_builder = @driver.action
340
+ f1 = action_builder.add_pointer_input(:touch, "finger1")
341
+ f1.create_pointer_move(duration: 0, x: x, y: y, origin: ::Selenium::WebDriver::Interactions::PointerMove::VIEWPORT)
342
+ f1.create_pointer_down(:left)
343
+ f1.create_pointer_up(:left)
344
+ @driver.perform_actions [f1]
345
+ else
346
+ if @driver.device == :android
347
+ perform_driver_method(:click)
348
+ else
349
+ # on ios, if element is not visible, first click will scroll to it
350
+ # then on second click actually perform the click
351
+ visible = visible?
352
+ perform_driver_method(:click)
353
+ perform_driver_method(:click) unless visible rescue nil
354
+ end
355
+ end
310
356
  end
311
357
 
312
358
  def send_key(*args)
@@ -336,15 +382,20 @@ module TestaAppiumDriver
336
382
  # @return [TestaAppiumDriver::Locator]
337
383
  def children
338
384
  raise "Cannot add children selector to array" unless @single
339
- raise StrategyMixException.new(@strategy, @strategy_reason, FIND_STRATEGY_XPATH, "children") if @strategy != FIND_STRATEGY_XPATH && !@strategy.nil?
385
+ raise StrategyMixException.new(@strategy, @strategy_reason, FIND_STRATEGY_XPATH, "children") if @strategy != FIND_STRATEGY_XPATH && @strategy != FIND_STRATEGY_CLASS_CHAIN && !@strategy.nil?
340
386
 
341
387
  locator = self.dup
342
- locator.strategy = FIND_STRATEGY_XPATH
343
388
  locator.strategy_reason = "children"
344
389
  locator.xpath_selector += "/*"
345
390
  locator.single = false
346
391
  locator.last_selector_adjacent = true
347
392
  locator.can_use_id_strategy = false
393
+
394
+ if @driver.device == :android
395
+ locator.strategy = FIND_STRATEGY_XPATH
396
+ else
397
+ locator.class_chain_selector += "/*"
398
+ end
348
399
  locator
349
400
  end
350
401
 
@@ -353,14 +404,20 @@ module TestaAppiumDriver
353
404
  # @return [TestaAppiumDriver::Locator]
354
405
  def child
355
406
  raise "Cannot add children selector to array" unless @single
356
- raise StrategyMixException.new(@strategy, @strategy_reason, FIND_STRATEGY_XPATH, "child") if @strategy != FIND_STRATEGY_XPATH && !@strategy.nil?
407
+ raise StrategyMixException.new(@strategy, @strategy_reason, FIND_STRATEGY_XPATH, "child") if @strategy != FIND_STRATEGY_XPATH && @strategy != FIND_STRATEGY_CLASS_CHAIN && !@strategy.nil?
357
408
 
358
409
  locator = self.dup
359
- locator.strategy = FIND_STRATEGY_XPATH
410
+
360
411
  locator.strategy_reason = "child"
361
412
  locator.xpath_selector += "/*[1]"
362
413
  locator.single = true
363
414
  locator.can_use_id_strategy = false
415
+
416
+ if @driver.device == :android
417
+ locator.strategy = FIND_STRATEGY_XPATH
418
+ else
419
+ locator.class_chain_selector += "/*[1]"
420
+ end
364
421
  locator
365
422
  end
366
423
 
@@ -461,7 +518,8 @@ module TestaAppiumDriver
461
518
  message = args[:message] unless args[:message].nil?
462
519
 
463
520
  if args[:timeout].nil?
464
- timeout = @driver.get_timeouts["implicit"] / 1000
521
+ #timeout = @driver.get_timeouts["implicit"] / 1000
522
+ timeout = 10
465
523
  else
466
524
  timeout = args[:timeout]
467
525
  end
@@ -23,6 +23,7 @@ module TestaAppiumDriver
23
23
  until is_end_of_scroll?
24
24
  matches = @locator.execute(skip_cache: true)
25
25
  matches.each_with_index do |m|
26
+ next if elements.include?(m)
26
27
  elements << m
27
28
  if block_given? # block is given
28
29
  block.call(m) # use call to execute the block
@@ -228,10 +229,8 @@ module TestaAppiumDriver
228
229
 
229
230
 
230
231
 
231
- def w3c_drag_to(x, y)
232
- x0 = @bounds.center.x
233
- y0 = @bounds.center.y
234
- w3c_action(x0, y0, x, y, SCROLL_ACTION_TYPE_DRAG)
232
+ def w3c_drag_to(x0, y0, x1, y1)
233
+ w3c_action(x0, y0, x1, y1, SCROLL_ACTION_TYPE_DRAG)
235
234
  end
236
235
 
237
236
  end
@@ -1,7 +1,6 @@
1
1
  require_relative 'scroll_actions/json_wire_scroll_actions'
2
2
  require_relative 'scroll_actions/w3c_scroll_actions'
3
3
 
4
-
5
4
  module TestaAppiumDriver
6
5
 
7
6
  # Class for handling scroll actions
@@ -21,7 +20,6 @@ module TestaAppiumDriver
21
20
  @default_scroll_strategy = params[:default_scroll_strategy]
22
21
  @driver = @locator.driver
23
22
 
24
-
25
23
  if @scrollable.nil?
26
24
  # if we dont have a scrollable element or if we do have it, but it is not compatible with uiautomator
27
25
  # then find first scrollable in document
@@ -30,16 +28,14 @@ module TestaAppiumDriver
30
28
 
31
29
  @strategy = nil
32
30
  if @scrollable.strategy == FIND_STRATEGY_XPATH || # uiautomator cannot resolve scrollable from a xpath locator
33
- !@deadzone.nil? ||
34
- !@scrollable.from_element.instance_of?(TestaAppiumDriver::Driver) # uiautomator cannot resolve nested scrollable
31
+ !@deadzone.nil? ||
32
+ !@scrollable.from_element.instance_of?(TestaAppiumDriver::Driver) # uiautomator cannot resolve nested scrollable
35
33
  @strategy = SCROLL_STRATEGY_W3C
36
34
  end
37
35
 
38
-
39
36
  @bounds = @scrollable.bounds
40
37
  end
41
38
 
42
-
43
39
  def align(with, scroll_to_find)
44
40
  w3c_align(with, scroll_to_find)
45
41
  @locator
@@ -66,7 +62,6 @@ module TestaAppiumDriver
66
62
  w3c_each(:left, &block)
67
63
  end
68
64
 
69
-
70
65
  def resolve_strategy
71
66
  if @strategy.nil?
72
67
  @default_scroll_strategy
@@ -75,7 +70,6 @@ module TestaAppiumDriver
75
70
  end
76
71
  end
77
72
 
78
-
79
73
  def scroll_to
80
74
  if @locator.strategy != FIND_STRATEGY_XPATH && resolve_strategy == SCROLL_STRATEGY_UIAUTOMATOR
81
75
  uiautomator_scroll_to
@@ -116,7 +110,6 @@ module TestaAppiumDriver
116
110
  end
117
111
  end
118
112
 
119
-
120
113
  def page_down
121
114
  if resolve_strategy == SCROLL_STRATEGY_UIAUTOMATOR
122
115
  uiautomator_page_or_fling(SCROLL_ACTION_TYPE_SCROLL, :down)
@@ -149,10 +142,10 @@ module TestaAppiumDriver
149
142
  end
150
143
  end
151
144
 
152
-
153
145
  def scroll_to_start
154
146
  if resolve_strategy == SCROLL_STRATEGY_UIAUTOMATOR
155
147
  uiautomator_scroll_to_start_or_end(:start)
148
+
156
149
  elsif resolve_strategy == SCROLL_STRATEGY_W3C
157
150
  w3c_scroll_to_start_or_end(:start)
158
151
  end
@@ -198,11 +191,10 @@ module TestaAppiumDriver
198
191
  end
199
192
  end
200
193
 
201
- def drag_to(x, y)
202
- w3c_drag_to(x, y)
194
+ def drag_to(x0, y0, x1, y1)
195
+ w3c_drag_to(x0, y0, x1, y1)
203
196
  end
204
197
 
205
-
206
198
  private
207
199
 
208
200
  def is_end_of_scroll?
@@ -211,7 +203,6 @@ module TestaAppiumDriver
211
203
  old_elements == @previous_elements
212
204
  end
213
205
 
214
-
215
206
  def default_deadzone!
216
207
  @deadzone = {} if @deadzone.nil?
217
208
  if @deadzone[:top].nil?
@@ -29,9 +29,6 @@ module TestaAppiumDriver
29
29
  def initialize(opts = {})
30
30
  @testa_opts = opts[:testa_appium_driver] || {}
31
31
 
32
- @wait_for_idle_disabled = false
33
- @implicit_wait_disabled = false
34
-
35
32
  core = Appium::Core.for(opts)
36
33
  extend_for(core.device, core.automation_name)
37
34
  @device = core.device
@@ -43,6 +40,9 @@ module TestaAppiumDriver
43
40
  invalidate_cache
44
41
 
45
42
 
43
+ disable_wait_for_idle
44
+ disable_implicit_wait
45
+
46
46
  Selenium::WebDriver::Element.set_driver(self, opts[:caps][:udid])
47
47
  end
48
48
 
@@ -69,11 +69,9 @@ module TestaAppiumDriver
69
69
  # @param [Array<Hash>] strategies_and_selectors array of usable strategies and selectors
70
70
  # @param [Boolean] skip_cache to skip checking and storing cache
71
71
  # @return [Selenium::WebDriver::Element, Array] element is returned if single is true, array otherwise
72
- def execute(from_element, single, strategies_and_selectors, skip_cache = false, ignore_implicit_wait = false)
72
+ def execute(from_element, single, strategies_and_selectors, skip_cache: false, ignore_implicit_wait: false)
73
73
 
74
74
  # if user wants to wait for element to exist, he can use wait_until_present
75
- disable_wait_for_idle
76
- disable_implicit_wait
77
75
  start_time = Time.now.to_f
78
76
  ss_index = 0
79
77
 
@@ -126,15 +124,13 @@ module TestaAppiumDriver
126
124
  puts "Using cache from #{@cache[:time].strftime("%H:%M:%S.%L")}, strategy: #{@cache[:strategy]}"
127
125
  end
128
126
  rescue => e
129
- if (start_time + @implicit_wait_ms/1000 < Time.now.to_f && !ignore_implicit_wait) || ss_index < strategies_and_selectors.count
127
+ #if (start_time + @implicit_wait_ms/1000 < Time.now.to_f && !ignore_implicit_wait) || ss_index < strategies_and_selectors.count
128
+ if ss_index < strategies_and_selectors.count
130
129
  sleep EXISTS_WAIT if ss_index >= strategies_and_selectors.count
131
130
  retry
132
131
  else
133
132
  raise e
134
133
  end
135
- ensure
136
- enable_implicit_wait
137
- enable_wait_for_idle
138
134
  end
139
135
 
140
136
  execute_result
@@ -151,43 +147,23 @@ module TestaAppiumDriver
151
147
 
152
148
  # disables implicit wait
153
149
  def disable_implicit_wait
154
- unless @implicit_wait_disabled
155
- @implicit_wait_ms = @driver.get_timeouts["implicit"]
150
+ @implicit_wait_ms = @driver.get_timeouts["implicit"].to_i
151
+ @implicit_wait_ms = @implicit_wait_ms/1000 if @implicit_wait_ms > 100000
156
152
  @implicit_wait_uiautomator_ms = @driver.get_settings["waitForSelectorTimeout"]
157
153
  @driver.manage.timeouts.implicit_wait = 0
158
- @driver.update_settings({waitForSelectorTimeout: 0})
159
- @implicit_wait_disabled = true
160
- end
154
+ @driver.update_settings({waitForSelectorTimeout: 1})
161
155
  end
162
156
 
163
- # enables implicit wait, can be called only after disabling implicit wait
164
- def enable_implicit_wait
165
- raise "Implicit wait is not disabled" unless @implicit_wait_disabled
166
- # get_timeouts always returns in milliseconds, but we should set in seconds
167
- @driver.manage.timeouts.implicit_wait = @implicit_wait_ms / 1000
168
- @driver.update_settings({waitForSelectorTimeout: @implicit_wait_uiautomator_ms})
169
- @implicit_wait_disabled = false
170
- end
171
157
 
172
158
  # disables wait for idle, only executed for android devices
173
159
  def disable_wait_for_idle
174
- unless @wait_for_idle_disabled
175
- if @device == :android
176
- @wait_for_idle_timeout = @driver.settings.get["waitForIdleTimeout"]
177
- @driver.update_settings({waitForIdleTimeout: 0})
178
- end
179
- @wait_for_idle_disabled = true
180
- end
181
- end
182
-
183
- # enables wait for idle, only executed for android devices
184
- def enable_wait_for_idle
185
160
  if @device == :android
186
- raise "Wait for idle is not disabled" unless @wait_for_idle_disabled
187
- @driver.update_settings({waitForIdleTimeout: @wait_for_idle_timeout})
161
+ @wait_for_idle_timeout = @driver.settings.get["waitForIdleTimeout"]
162
+ @driver.update_settings({waitForIdleTimeout: 1})
188
163
  end
189
164
  end
190
165
 
166
+
191
167
  def set_find_by_image_settings(settings)
192
168
  settings.delete(:image)
193
169
  @default_find_image_settings = {}
@@ -233,6 +209,33 @@ module TestaAppiumDriver
233
209
  @driver.hide_keyboard
234
210
  end
235
211
 
212
+ def home_key
213
+ @driver.press_keycode(3)
214
+ end
215
+ def tab_key
216
+ @driver.press_keycode(61)
217
+ end
218
+
219
+ def dpad_up_key
220
+ @driver.press_keycode(19)
221
+ end
222
+
223
+ def dpad_down_key
224
+ @driver.press_keycode(20)
225
+ end
226
+
227
+ def dpad_right_key
228
+ @driver.press_keycode(22)
229
+ end
230
+
231
+ def dpad_left_key
232
+ @driver.press_keycode(23)
233
+ end
234
+
235
+ def enter_key
236
+ @driver.press_keycode(66)
237
+ end
238
+
236
239
  def press_keycode(code)
237
240
  @driver.press_keycode(code)
238
241
  end
@@ -241,16 +244,42 @@ module TestaAppiumDriver
241
244
  @driver.long_press_keycode(code)
242
245
  end
243
246
 
247
+ def click(x, y)
248
+ ws = driver.window_size
249
+ window_width = ws.width.to_i
250
+ window_height = ws.height.to_i
251
+ if x.kind_of? Integer
252
+ if x < 0
253
+ x = window_width + x
254
+ end
255
+ elsif x.kind_of? Float
256
+ x = window_width*x
257
+ else
258
+ raise "x value #{x} not supported"
259
+ end
260
+
261
+ if y.kind_of? Integer
262
+ if y < 0
263
+ y = window_height + y
264
+ end
265
+ elsif y.kind_of? Float
266
+ y = window_height*y
267
+ end
268
+
269
+
270
+ action_builder = @driver.action
271
+ f1 = action_builder.add_pointer_input(:touch, "finger1")
272
+ f1.create_pointer_move(duration: 0, x: x, y: y, origin: ::Selenium::WebDriver::Interactions::PointerMove::VIEWPORT)
273
+ f1.create_pointer_down(:left)
274
+ f1.create_pointer_up(:left)
275
+ @driver.perform_actions [f1]
276
+ end
244
277
 
245
278
 
246
279
 
247
280
  # @return [Array<Selenium::WebDriver::Element] array of 2 elements, the first element without children and the last element without children in the current page
248
281
  def first_and_last_leaf(from_element = @driver)
249
- disable_wait_for_idle
250
- disable_implicit_wait
251
282
  elements = from_element.find_elements(xpath: "//*[not(*)]")
252
- enable_implicit_wait
253
- enable_wait_for_idle
254
283
  return nil if elements.count == 0
255
284
  [elements[0], elements[-1]]
256
285
  end
@@ -3,6 +3,7 @@ require_relative 'locator/attributes'
3
3
  module TestaAppiumDriver
4
4
  class Locator
5
5
  include TypeSelectors
6
+ attr_accessor :class_chain_selector
6
7
 
7
8
  def init(params, selectors, single)
8
9
  if is_scrollable_selector?(selectors, single)
@@ -19,6 +20,9 @@ module TestaAppiumDriver
19
20
  params[:scrollable_locator] = self.dup
20
21
  end
21
22
 
23
+ @class_chain_selector = hash_to_class_chain(selectors, single)
24
+
25
+
22
26
  @scrollable_locator = params[:scrollable_locator] if params[:scrollable_locator]
23
27
  end
24
28
 
@@ -29,7 +33,7 @@ module TestaAppiumDriver
29
33
  if @can_use_id_strategy
30
34
  ss.push({"#{FIND_STRATEGY_NAME}": @can_use_id_strategy})
31
35
  end
32
-
36
+ ss.push({"#{FIND_STRATEGY_CLASS_CHAIN}": @class_chain_selector}) if @strategy.nil? || @strategy == FIND_STRATEGY_CLASS_CHAIN
33
37
  ss.push({"#{FIND_STRATEGY_XPATH}": @xpath_selector}) if @strategy.nil? || @strategy == FIND_STRATEGY_XPATH
34
38
  ss.push({"#{FIND_STRATEGY_IMAGE}": @image_selector}) if @strategy == FIND_STRATEGY_IMAGE
35
39
  ss
@@ -45,13 +49,23 @@ module TestaAppiumDriver
45
49
 
46
50
  locator = self.dup
47
51
  add_xpath_child_selectors(locator, selectors, single)
52
+ if @strategy.nil? || @strategy == FIND_STRATEGY_CLASS_CHAIN
53
+ add_class_chain_child_selectors(locator, selectors, single)
54
+ end
55
+
48
56
  if is_scrollable_selector?(selectors, single)
49
57
  locator.scrollable_locator.scroll_orientation = :vertical
50
- locator.scrollable_locator = self.dup
58
+ locator.scrollable_locator = locator
51
59
  end
52
60
 
53
61
  locator.last_selector_adjacent = false
54
62
  locator
55
63
  end
64
+
65
+
66
+ def add_class_chain_child_selectors(locator, selectors, single)
67
+ locator.single = false unless single # switching from single result to multiple
68
+ locator.class_chain_selector += "/" + hash_to_class_chain(selectors, single)
69
+ end
56
70
  end
57
71
  end
@@ -5,10 +5,15 @@ module TestaAppiumDriver
5
5
  # @return [TestaAppiumDriver::Locator]
6
6
  def add_selector(*args, &block)
7
7
  # if class selector is executed from driver, create new locator instance
8
- if self.kind_of?(TestaAppiumDriver::Driver) || self.kind_of(Selenium::WebDriver::Element)
8
+ if self.kind_of?(TestaAppiumDriver::Driver) || self.instance_of?(Selenium::WebDriver::Element)
9
9
  args.last[:default_find_strategy] = @default_find_strategy
10
10
  args.last[:default_scroll_strategy] = @default_scroll_strategy
11
- Locator.new(self, self, *args)
11
+ if self.instance_of?(Selenium::WebDriver::Element)
12
+ driver = self.get_driver
13
+ else
14
+ driver = self
15
+ end
16
+ Locator.new(driver, self, *args)
12
17
  else
13
18
  # class selector is executed from locator, just add child selector criteria
14
19
  self.add_child_selector(*args)
@@ -150,5 +155,34 @@ module TestaAppiumDriver
150
155
  params[:single] = false
151
156
  add_selector(params)
152
157
  end
158
+
159
+
160
+
161
+ # @return [TestaAppiumDriver::Locator]
162
+ def text_field(params = {})
163
+ params[:type] = "XCUIElementTypeTextField"
164
+ add_selector(params)
165
+ end
166
+
167
+ # @return [TestaAppiumDriver::Locator]
168
+ def text_fields(params = {})
169
+ params[:type] = "XCUIElementTypeTextField"
170
+ params[:single] = false
171
+ add_selector(params)
172
+ end
173
+
174
+
175
+ # @return [TestaAppiumDriver::Locator]
176
+ def secure_text_field(params = {})
177
+ params[:type] = "XCUIElementTypeSecureTextField"
178
+ add_selector(params)
179
+ end
180
+
181
+ # @return [TestaAppiumDriver::Locator]
182
+ def secure_text_fields(params = {})
183
+ params[:type] = "XCUIElementTypeSecureTextField"
184
+ params[:single] = false
185
+ add_selector(params)
186
+ end
153
187
  end
154
188
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module TestaAppiumDriver
4
- VERSION = "0.1.7"
4
+ VERSION = "0.1.11"
5
5
  end
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.7
4
+ version: 0.1.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - karlo.razumovic
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-09-22 00:00:00.000000000 Z
11
+ date: 2022-01-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: appium_lib_core