testa_appium_driver 0.1.8 → 0.1.12

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +15 -15
  3. data/.idea/deployment.xml +21 -21
  4. data/.idea/inspectionProfiles/Project_Default.xml +8 -8
  5. data/.idea/misc.xml +5 -5
  6. data/.idea/modules.xml +7 -7
  7. data/.idea/runConfigurations/Android_Test.xml +41 -41
  8. data/.idea/runConfigurations.xml +9 -9
  9. data/.idea/sshConfigs.xml +12 -12
  10. data/.idea/vcs.xml +5 -5
  11. data/.idea/webServers.xml +20 -20
  12. data/.rspec +3 -3
  13. data/.rubocop.yml +13 -13
  14. data/CHANGELOG.md +5 -5
  15. data/CODE_OF_CONDUCT.md +102 -102
  16. data/Gemfile +12 -12
  17. data/LICENSE.txt +21 -21
  18. data/README.md +378 -378
  19. data/Rakefile +12 -12
  20. data/bin/console +17 -17
  21. data/bin/setup +8 -8
  22. data/lib/testa_appium_driver/android/class_selectors.rb +437 -437
  23. data/lib/testa_appium_driver/android/driver.rb +69 -69
  24. data/lib/testa_appium_driver/android/locator/attributes.rb +113 -113
  25. data/lib/testa_appium_driver/android/locator.rb +141 -141
  26. data/lib/testa_appium_driver/android/scroll_actions/uiautomator_scroll_actions.rb +61 -63
  27. data/lib/testa_appium_driver/android/selenium_element.rb +7 -7
  28. data/lib/testa_appium_driver/common/bounds.rb +149 -149
  29. data/lib/testa_appium_driver/common/constants.rb +36 -36
  30. data/lib/testa_appium_driver/common/exceptions/strategy_mix_exception.rb +11 -11
  31. data/lib/testa_appium_driver/common/helpers.rb +270 -270
  32. data/lib/testa_appium_driver/common/locator/scroll_actions.rb +397 -396
  33. data/lib/testa_appium_driver/common/locator.rb +610 -578
  34. data/lib/testa_appium_driver/common/scroll_actions/json_wire_scroll_actions.rb +3 -3
  35. data/lib/testa_appium_driver/common/scroll_actions/w3c_scroll_actions.rb +237 -237
  36. data/lib/testa_appium_driver/common/scroll_actions.rb +246 -246
  37. data/lib/testa_appium_driver/common/selenium_element.rb +19 -19
  38. data/lib/testa_appium_driver/driver.rb +312 -278
  39. data/lib/testa_appium_driver/ios/driver.rb +48 -48
  40. data/lib/testa_appium_driver/ios/locator/attributes.rb +80 -80
  41. data/lib/testa_appium_driver/ios/locator.rb +70 -70
  42. data/lib/testa_appium_driver/ios/selenium_element.rb +6 -6
  43. data/lib/testa_appium_driver/ios/type_selectors.rb +187 -187
  44. data/lib/testa_appium_driver/version.rb +5 -5
  45. data/lib/testa_appium_driver.rb +6 -6
  46. data/testa_appium_driver.gemspec +41 -41
  47. data/testa_appium_driver.iml +27 -78
  48. metadata +3 -3
@@ -1,579 +1,611 @@
1
- require_relative 'locator/scroll_actions'
2
-
3
-
4
- module TestaAppiumDriver
5
- #noinspection RubyTooManyInstanceVariablesInspection,RubyTooManyMethodsInspection
6
- class Locator
7
- include Helpers
8
-
9
- attr_accessor :xpath_selector
10
- attr_accessor :single
11
-
12
- attr_accessor :driver
13
- attr_accessor :strategy
14
- attr_accessor :strategy_reason
15
-
16
- # @type [Boolean] used to determine if last selector was one of siblings or children. Only in those selectors we can reliably use xpath array [instance] selector
17
- attr_accessor :last_selector_adjacent
18
- attr_accessor :can_use_id_strategy
19
-
20
- attr_accessor :image_selector
21
-
22
- attr_accessor :from_element
23
- attr_accessor :scroll_orientation
24
- attr_accessor :scroll_deadzone
25
- attr_accessor :scrollable_locator
26
-
27
- attr_accessor :default_find_strategy
28
- attr_accessor :default_scroll_strategy
29
-
30
- attr_accessor :index_for_multiple
31
-
32
-
33
- # locator parameters are:
34
- # single: true or false
35
- # scrollable_locator: [TestaAppiumDriver::Locator, nil] for scrolling if needed later
36
- # default_find_strategy: default strategy if find element strategy is not enforced
37
- # default_scroll_strategy: default strategy for scrolling if not enforced
38
- #
39
- # @param [TestaAppiumDriver::Driver] driver
40
- # @param [TestaAppiumDriver::Driver, TestaAppiumDriver::Locator, Selenium::WebDriver::Element] from_element from which element to execute the find_element
41
- # @param [Hash] params selectors and params for locator
42
- def initialize(driver, from_element, params = {})
43
- # @type [TestaAppiumDriver::Driver]
44
- @driver = driver
45
- @index_for_multiple = nil
46
- @image_selector = nil
47
-
48
- params, selectors = extract_selectors_from_params(params)
49
- single = params[:single]
50
-
51
- @single = single
52
-
53
- if selectors[:image].nil?
54
- if from_element.instance_of?(TestaAppiumDriver::Locator) && !from_element.image_selector.nil?
55
- raise "Cannot chain non-image selectors to image selectors"
56
- end
57
- else
58
- handle_image_selector(selectors, params)
59
- end
60
-
61
- selectors[:id] = selectors[:name] unless selectors[:name].nil?
62
- if from_element.instance_of?(Selenium::WebDriver::Element)
63
- @xpath_selector = "//*" # to select current element
64
- @xpath_selector += hash_to_xpath(@driver.device, selectors, single)[1..-1]
65
- else
66
- @xpath_selector = hash_to_xpath(@driver.device, selectors, single)
67
- end
68
-
69
-
70
- @from_element = from_element
71
- @default_find_strategy = params[:default_find_strategy]
72
- @default_scroll_strategy = params[:default_scroll_strategy]
73
-
74
-
75
- @can_use_id_strategy = is_only_id_selector?(selectors)
76
- if @can_use_id_strategy
77
- if @driver.device == :android
78
- @can_use_id_strategy = resolve_id(selectors[:id])
79
- else
80
- @can_use_id_strategy = selectors[:id]
81
- end
82
- end
83
-
84
-
85
- @strategy = params[:strategy]
86
- @strategy_reason = params[:strategy_reason]
87
-
88
- @last_selector_adjacent = false
89
-
90
- init(params, selectors, single)
91
- end
92
-
93
-
94
-
95
-
96
- def is_only_id_selector?(selectors)
97
- # since, name and id is the same thing for iOS,
98
- if @driver.device == :android
99
- selectors.keys.count == 1 && !selectors[:id].nil?
100
- else
101
- # if it iOS we assign the name to id
102
- selectors.keys.count == 2 && !selectors[:id].nil? && selectors[:id] == selectors[:name]
103
- end
104
- end
105
-
106
-
107
- # method missing is used to fetch the element before executing additional commands like click, send_key, count
108
- def method_missing(method, *args, &block)
109
- r = execute.send(method, *args, &block)
110
- @driver.invalidate_cache
111
- r
112
- end
113
-
114
-
115
- # @param [Boolean] skip_cache if true it will skip cache check and store
116
- # @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
- # @return [Selenium::WebDriver::Element, Array]
118
- def execute(skip_cache: false, force_cache_element: nil, ignore_implicit_wait: false)
119
- return force_cache_element unless force_cache_element.nil?
120
- # if we are looking for current element, then return from_element
121
- # for example when we have driver.element.elements[1].click
122
- # elements[2] will be resolved with xpath because we are looking for multiple elements from element
123
- # and since we are looking for instance 2, [](instance) method will return new "empty locator"
124
- # 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 == "//*[1]" && !@from_element.nil? && @image_selector.nil?
126
- return @from_element if @from_element.instance_of?(Selenium::WebDriver::Element)
127
- 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
- return @from_element
129
- end
130
-
131
-
132
-
133
-
134
-
135
-
136
- r = @driver.execute(@from_element, @single, strategies_and_selectors, skip_cache: skip_cache, ignore_implicit_wait: ignore_implicit_wait)
137
- r = r[@index_for_multiple] if !@index_for_multiple.nil? && !@single
138
- r
139
- end
140
-
141
- def when_exists(timeout = nil, &block)
142
- timeout = @driver.get_timeouts["implicit"] / 1000 if timeout.nil?
143
- found = false
144
- begin
145
- wait_until_exists(timeout)
146
- found = true
147
- rescue
148
- #ignored
149
- end
150
- if found
151
- if block_given? # block is given
152
- block.call(self) # use call to execute the block
153
- else # the value of block_argument becomes nil if you didn't give a block
154
- # block was not given
155
- end
156
- end
157
- self
158
- end
159
-
160
-
161
- # @param [Integer] timeout in seconds
162
- # @return [TestaAppiumDriver::Locator]
163
- def wait_until_exists(timeout = nil)
164
- timeout = @driver.get_timeouts["implicit"] / 1000 if timeout.nil?
165
- args = {timeout: timeout}
166
- _wait(:until, args)
167
- end
168
-
169
-
170
- # @param [Integer] timeout in seconds
171
- # @return [TestaAppiumDriver::Locator]
172
- def wait_while_exists(timeout = nil)
173
- timeout = @driver.get_timeouts["implicit"] / 1000 if timeout.nil?
174
- args = {timeout: timeout}
175
- _wait(:while, args)
176
- end
177
-
178
-
179
- def wait_while(timeout = nil, args = {})
180
- args[:timeout] = timeout
181
- _wait(:while, args)
182
- end
183
-
184
- def wait_until(timeout = nil, args = {})
185
- args[:timeout] = timeout
186
- _wait(:until, args)
187
- end
188
-
189
-
190
- # all timeouts are disabled before check, and enabled after check
191
- # @return [boolean] true if it exists in the page regardless if visible or not
192
- def exists?
193
- found = true
194
- begin
195
- execute(skip_cache: true, ignore_implicit_wait: true)
196
- rescue StandardError
197
- found = false
198
- end
199
- found
200
- end
201
-
202
- # @return [TestaAppiumDriver::Locator]
203
- def first
204
- self[0]
205
- end
206
-
207
- # @return [TestaAppiumDriver::Locator]
208
- def second
209
- self[1]
210
- end
211
-
212
- # @return [TestaAppiumDriver::Locator]
213
- def third
214
- self[2]
215
- end
216
-
217
- # @return [TestaAppiumDriver::Locator]
218
- def last
219
- self[-1]
220
- end
221
-
222
- def [](instance)
223
- raise "Cannot add index selector to non-Array" if @single
224
- if ((@strategy.nil? && !@last_selector_adjacent && @driver.device == :android) || @strategy == FIND_STRATEGY_UIAUTOMATOR) && instance >= 0
225
- locator = self.dup
226
- locator.strategy = FIND_STRATEGY_UIAUTOMATOR
227
- locator.ui_selector = "#{@ui_selector}.instance(#{instance})"
228
- locator.single = true
229
- locator.can_use_id_strategy = false
230
- locator
231
- elsif (@driver.device == :ios && !@last_selector_adjacent && @strategy.nil?) || @strategy == FIND_STRATEGY_CLASS_CHAIN
232
- locator = self.dup
233
- locator.strategy = FIND_STRATEGY_CLASS_CHAIN
234
- locator.class_chain_selector += "[#{instance + 1}]"
235
- locator.single = true
236
- locator.can_use_id_strategy = false
237
- locator
238
- else
239
- from_element = self.dup
240
- from_element.index_for_multiple = instance
241
- params = {}.merge({single: true, scrollable_locator: @scrollable_locator})
242
- #params[:strategy] = FIND_STRATEGY_XPATH
243
- #params[:strategy_reason] = "retrieved instance of a array"
244
- params[:default_find_strategy] = @default_find_strategy
245
- params[:default_scroll_strategy] = @default_scroll_strategy
246
- Locator.new(@driver, from_element, params)
247
- end
248
- end
249
-
250
-
251
- # @param [TestaAppiumDriver::Locator, Selenium::WebDriver::Element, Array] other
252
- #noinspection RubyNilAnalysis,RubyUnnecessaryReturnStatement
253
- def ==(other)
254
- elements = execute
255
- other = other.execute if other.kind_of?(TestaAppiumDriver::Locator)
256
-
257
- if elements.kind_of?(Array)
258
- return false unless other.kind_of?(Array)
259
- return false if other.count != elements.count
260
- return (elements - other).empty?
261
- else
262
- return false if other.kind_of?(Array)
263
- return elements == other
264
- end
265
- end
266
-
267
- def as_json
268
- {
269
- strategy: @strategy,
270
- default_strategy: @default_find_strategy,
271
- single: @single,
272
- context: @from_element.nil? ? nil : @from_element.to_s,
273
- uiautomator: defined?(self.ui_selector) ? ui_selector : nil,
274
- xpath: @xpath_selector,
275
- scrollable: @scrollable_locator.nil? ? nil : @scrollable_locator.to_s,
276
- scroll_orientation: @scroll_orientation,
277
- resolved: strategies_and_selectors,
278
- index_for_multiple: @index_for_multiple
279
- }
280
- end
281
-
282
- def to_s
283
- JSON.dump(as_json)
284
- end
285
-
286
- def to_ary
287
- [self.to_s]
288
- end
289
-
290
-
291
- # @return [TestaAppiumDriver::Locator]
292
- def as_scrollable(orientation: :vertical, top: nil, bottom: nil, right: nil, left: nil)
293
- @scroll_orientation = orientation
294
- if !top.nil? || !bottom.nil? || !right.nil? || !left.nil?
295
- @scroll_deadzone = {}
296
- @scroll_deadzone[:top] = top.to_f unless top.nil?
297
- @scroll_deadzone[:bottom] = bottom.to_f unless bottom.nil?
298
- @scroll_deadzone[:right] = right.to_f unless right.nil?
299
- @scroll_deadzone[:left] = left.to_f unless left.nil?
300
- end
301
- @scrollable_locator = self.dup
302
- self
303
- end
304
-
305
-
306
- def first_and_last_leaf
307
- @driver.first_and_last_leaf(execute)
308
- end
309
-
310
-
311
- def tap
312
- click
313
- end
314
-
315
- def click
316
- if @driver.device == :android
317
- perform_driver_method(:click)
318
- else
319
- # on ios, if element is not visible, first click will scroll to it
320
- # then on second click actually perform the click
321
- visible = visible?
322
- perform_driver_method(:click)
323
- perform_driver_method(:click) unless visible rescue nil
324
- end
325
- end
326
-
327
- def send_key(*args)
328
- perform_driver_method(:send_keys, *args)
329
- end
330
-
331
- def clear
332
- perform_driver_method(:clear)
333
- end
334
-
335
-
336
- # Return parent element
337
- # @return [TestaAppiumDriver::Locator]
338
- def parent
339
- raise StrategyMixException.new(@strategy, @strategy_reason, FIND_STRATEGY_XPATH, "parent") if @strategy != FIND_STRATEGY_XPATH && !@strategy.nil?
340
- raise "Cannot add parent selector to a retrieved instance of a class array" if (@xpath_selector == "//*" || @xpath_selector == "//*[1]") && !@from_element.nil?
341
-
342
- locator = self.dup
343
- locator.strategy = FIND_STRATEGY_XPATH
344
- locator.strategy_reason = "parent"
345
- locator.xpath_selector += "/.."
346
- locator.can_use_id_strategy = false
347
- locator
348
- end
349
-
350
- # Return all children elements
351
- # @return [TestaAppiumDriver::Locator]
352
- def children
353
- raise "Cannot add children selector to array" unless @single
354
- raise StrategyMixException.new(@strategy, @strategy_reason, FIND_STRATEGY_XPATH, "children") if @strategy != FIND_STRATEGY_XPATH && @strategy != FIND_STRATEGY_CLASS_CHAIN && !@strategy.nil?
355
-
356
- locator = self.dup
357
- locator.strategy_reason = "children"
358
- locator.xpath_selector += "/*"
359
- locator.single = false
360
- locator.last_selector_adjacent = true
361
- locator.can_use_id_strategy = false
362
-
363
- if @driver.device == :android
364
- locator.strategy = FIND_STRATEGY_XPATH
365
- else
366
- locator.class_chain_selector += "/*"
367
- end
368
- locator
369
- end
370
-
371
-
372
- # Return first child element
373
- # @return [TestaAppiumDriver::Locator]
374
- def child
375
- raise "Cannot add children selector to array" unless @single
376
- raise StrategyMixException.new(@strategy, @strategy_reason, FIND_STRATEGY_XPATH, "child") if @strategy != FIND_STRATEGY_XPATH && @strategy != FIND_STRATEGY_CLASS_CHAIN && !@strategy.nil?
377
-
378
- locator = self.dup
379
-
380
- locator.strategy_reason = "child"
381
- locator.xpath_selector += "/*[1]"
382
- locator.single = true
383
- locator.can_use_id_strategy = false
384
-
385
- if @driver.device == :android
386
- locator.strategy = FIND_STRATEGY_XPATH
387
- else
388
- locator.class_chain_selector += "/*[1]"
389
- end
390
- locator
391
- end
392
-
393
-
394
- # @return [TestaAppiumDriver::Locator]
395
- def siblings
396
- raise "Cannot add siblings selector to array" unless @single
397
- raise StrategyMixException.new(@strategy, @strategy_reason, FIND_STRATEGY_XPATH, "siblings") if @strategy != FIND_STRATEGY_XPATH && !@strategy.nil?
398
- raise "Cannot add siblings selector to a retrieved instance of a class array" if (@xpath_selector == "//*" || @xpath_selector == "//*[1]") && !@from_element.nil?
399
-
400
- locator = self.dup
401
- locator.strategy = FIND_STRATEGY_XPATH
402
- locator.strategy_reason = "siblings"
403
- locator.xpath_selector += "/../*[not(@index=\"#{index}\")]"
404
- locator.single = false
405
- locator.last_selector_adjacent = true
406
- locator.can_use_id_strategy = false
407
- locator
408
- end
409
-
410
- # @return [TestaAppiumDriver::Locator]
411
- def preceding_siblings
412
- raise "Cannot add preceding_siblings selector to array" unless @single
413
- raise StrategyMixException.new(@strategy, @strategy_reason, FIND_STRATEGY_XPATH, "preceding_siblings") if @strategy != FIND_STRATEGY_XPATH && !@strategy.nil?
414
- raise "Cannot add preceding_siblings selector to a retrieved instance of a class array" if (@xpath_selector == "//*" || @xpath_selector == "//*[1]") && !@from_element.nil?
415
-
416
- locator = self.dup
417
- locator.strategy = FIND_STRATEGY_XPATH
418
- locator.strategy_reason = "preceding_siblings"
419
- locator.xpath_selector += "/../*[position() < #{index + 1}]" # position() starts from 1
420
- locator.single = false
421
- locator.last_selector_adjacent = true
422
- locator.can_use_id_strategy = false
423
- locator
424
- end
425
-
426
- # @return [TestaAppiumDriver::Locator]
427
- def preceding_sibling
428
- raise "Cannot add preceding_sibling selector to array" unless @single
429
- raise StrategyMixException.new(@strategy, @strategy_reason, FIND_STRATEGY_XPATH, "preceding_sibling") if @strategy != FIND_STRATEGY_XPATH && !@strategy.nil?
430
- raise "Cannot add preceding siblings selector to a retrieved instance of a class array" if (@xpath_selector == "//*" || @xpath_selector == "//*[1]") && !@from_element.nil?
431
-
432
- locator = self.dup
433
- locator.strategy = FIND_STRATEGY_XPATH
434
- locator.strategy_reason = "preceding_sibling"
435
- i = index
436
- locator.single = true
437
- return nil if i == 0
438
- locator.xpath_selector += "/../*[@index=\"#{i - 1}\"]"
439
- locator.last_selector_adjacent = true
440
- locator.can_use_id_strategy = false
441
- locator
442
- end
443
-
444
-
445
- # @return [TestaAppiumDriver::Locator]
446
- def following_siblings
447
- raise "Cannot add following_siblings selector to array" unless @single
448
- raise StrategyMixException.new(@strategy, @strategy_reason, FIND_STRATEGY_XPATH, "following_siblings") if @strategy != FIND_STRATEGY_XPATH && !@strategy.nil?
449
- raise "Cannot add following_siblings selector to a retrieved instance of a class array" if (@xpath_selector == "//*" || @xpath_selector == "//*[1]") && !@from_element.nil?
450
-
451
- locator = self.dup
452
- locator.strategy = FIND_STRATEGY_XPATH
453
- locator.strategy_reason = "following_siblings"
454
- locator.xpath_selector += "/../*[position() > #{index + 1}]" # position() starts from 1
455
- locator.single = false
456
- locator.last_selector_adjacent = true
457
- locator.can_use_id_strategy = false
458
- locator
459
- end
460
-
461
- # @return [TestaAppiumDriver::Locator]
462
- def following_sibling
463
- raise "Cannot add following_sibling selector to array" unless @single
464
- raise StrategyMixException.new(@strategy, @strategy_reason, FIND_STRATEGY_XPATH, "following_sibling") if @strategy != FIND_STRATEGY_XPATH && !@strategy.nil?
465
- raise "Cannot add following_sibling selector to a retrieved instance of a class array" if (@xpath_selector == "//*" || @xpath_selector == "//*[1]") && !@from_element.nil?
466
-
467
- locator = self.dup
468
- locator.strategy = FIND_STRATEGY_XPATH
469
- locator.strategy_reason = "following_sibling"
470
- i = index
471
- locator.single = true
472
- return nil if i == 0
473
- locator.xpath_selector += "/../*[@index=\"#{i + 1}\"]"
474
- locator.last_selector_adjacent = true
475
- locator.can_use_id_strategy = false
476
- locator
477
- end
478
-
479
-
480
- private
481
-
482
- def _wait(type, args)
483
- interval = EXISTS_WAIT
484
- interval = args[:interval] unless args[:interval].nil?
485
-
486
- message = "wait #{type} exists timeout exceeded"
487
- message = args[:message] unless args[:message].nil?
488
-
489
- if args[:timeout].nil?
490
- timeout = @driver.get_timeouts["implicit"] / 1000
491
- else
492
- timeout = args[:timeout]
493
- end
494
-
495
- args.delete(:message)
496
- args.delete(:interval)
497
- args.delete(:timeout)
498
-
499
-
500
-
501
- start_time = Time.now.to_f
502
- if type == :while
503
- while exists? && _attributes_match(args)
504
- raise message if start_time + timeout < Time.now.to_f
505
- sleep interval
506
- end
507
- else
508
- until exists? && _attributes_match(args)
509
- raise message if start_time + timeout < Time.now.to_f
510
- sleep interval
511
- end
512
- end
513
- self
514
- end
515
-
516
- def _attributes_match(attributes)
517
- all_match = true
518
- attributes.each do |key, value|
519
- unless attribute(key) == value
520
- all_match = false
521
- break
522
- end
523
- end
524
- all_match
525
- end
526
-
527
- #noinspection RubyNilAnalysis
528
- def perform_driver_method(name, *args)
529
- elements = execute
530
- if elements.kind_of?(Array)
531
- elements.map { |e| e.send(name, *args) }
532
- else
533
- elements.send(name, *args)
534
- end
535
- end
536
-
537
- def add_xpath_child_selectors(locator, selectors, single)
538
- locator.single = false unless single # switching from single result to multiple
539
- locator.xpath_selector += hash_to_xpath(@driver.device, selectors, single)
540
- end
541
-
542
-
543
- def handle_image_selector(selectors, params)
544
- image_match_threshold = 0.4
545
- image_match_threshold = params[:imageMatchThreshold] unless params[:imageMatchThreshold].nil?
546
- image_match_threshold = params[:threshold] unless params[:threshold].nil?
547
- fix_image_find_screenshot_dims = true
548
- fix_image_find_screenshot_dims = params[:fixImageFindScreenshotDims] unless params[:fixImageFindScreenshotDims].nil?
549
- fix_image_template_size = false
550
- fix_image_template_size = params[:fixImageTemplateSize] unless params[:fixImageTemplateSize].nil?
551
- fix_image_template_scale = false
552
- fix_image_template_scale = params[:fixImageTemplateScale] unless params[:fixImageTemplateScale].nil?
553
- default_image_template_scale = 1.0
554
- default_image_template_scale = params[:defaultImageTemplateScale] unless params[:defaultImageTemplateScale].nil?
555
- check_for_image_element_staleness = true
556
- check_for_image_element_staleness = params[:checkForImageElementStaleness] unless params[:checkForImageElementStaleness].nil?
557
- auto_update_image_element_position = false
558
- auto_update_image_element_position = params[:autoUpdateImageElementPosition] unless params[:autoUpdateImageElementPosition].nil?
559
- image_element_tap_strategy = "w3cActions"
560
- image_element_tap_strategy = params[:imageElementTapStrategy] unless params[:imageElementTapStrategy].nil?
561
- get_matched_image_result = false
562
- get_matched_image_result = params[:getMatchedImageResult] unless params[:getMatchedImageResult].nil?
563
-
564
- @image_selector = {
565
- image: selectors[:image],
566
- imageMatchThreshold: image_match_threshold,
567
- fixImageFindScreenshotDims: fix_image_find_screenshot_dims,
568
- fixImageTemplateSize: fix_image_template_size,
569
- fixImageTemplateScale: fix_image_template_scale,
570
- defaultImageTemplateScale: default_image_template_scale,
571
- checkForImageElementStaleness: check_for_image_element_staleness,
572
- autoUpdateImageElementPosition: auto_update_image_element_position,
573
- imageElementTapStrategy: image_element_tap_strategy,
574
- getMatchedImageResult: get_matched_image_result,
575
- }
576
- end
577
- end
578
-
1
+ require_relative 'locator/scroll_actions'
2
+
3
+
4
+ module TestaAppiumDriver
5
+ #noinspection RubyTooManyInstanceVariablesInspection,RubyTooManyMethodsInspection
6
+ class Locator
7
+ include Helpers
8
+
9
+ attr_accessor :xpath_selector
10
+ attr_accessor :single
11
+
12
+ attr_accessor :driver
13
+ attr_accessor :strategy
14
+ attr_accessor :strategy_reason
15
+
16
+ # @type [Boolean] used to determine if last selector was one of siblings or children. Only in those selectors we can reliably use xpath array [instance] selector
17
+ attr_accessor :last_selector_adjacent
18
+ attr_accessor :can_use_id_strategy
19
+
20
+ attr_accessor :image_selector
21
+
22
+ attr_accessor :from_element
23
+ attr_accessor :scroll_orientation
24
+ attr_accessor :scroll_deadzone
25
+ attr_accessor :scrollable_locator
26
+
27
+ attr_accessor :default_find_strategy
28
+ attr_accessor :default_scroll_strategy
29
+
30
+ attr_accessor :index_for_multiple
31
+
32
+
33
+ # locator parameters are:
34
+ # single: true or false
35
+ # scrollable_locator: [TestaAppiumDriver::Locator, nil] for scrolling if needed later
36
+ # default_find_strategy: default strategy if find element strategy is not enforced
37
+ # default_scroll_strategy: default strategy for scrolling if not enforced
38
+ #
39
+ # @param [TestaAppiumDriver::Driver] driver
40
+ # @param [TestaAppiumDriver::Driver, TestaAppiumDriver::Locator, Selenium::WebDriver::Element] from_element from which element to execute the find_element
41
+ # @param [Hash] params selectors and params for locator
42
+ def initialize(driver, from_element, params = {})
43
+ # @type [TestaAppiumDriver::Driver]
44
+ @driver = driver
45
+ @index_for_multiple = nil
46
+ @image_selector = nil
47
+
48
+ params, selectors = extract_selectors_from_params(params)
49
+ single = params[:single]
50
+
51
+ @single = single
52
+
53
+ if selectors[:image].nil?
54
+ if from_element.instance_of?(TestaAppiumDriver::Locator) && !from_element.image_selector.nil?
55
+ raise "Cannot chain non-image selectors to image selectors"
56
+ end
57
+ else
58
+ handle_image_selector(selectors, params)
59
+ end
60
+
61
+ selectors[:id] = selectors[:name] unless selectors[:name].nil?
62
+ if from_element.instance_of?(Selenium::WebDriver::Element)
63
+ @xpath_selector = "//*" # to select current element
64
+ @xpath_selector += hash_to_xpath(@driver.device, selectors, single)[1..-1]
65
+ else
66
+ @xpath_selector = hash_to_xpath(@driver.device, selectors, single)
67
+ end
68
+
69
+
70
+ @from_element = from_element
71
+ @default_find_strategy = params[:default_find_strategy]
72
+ @default_scroll_strategy = params[:default_scroll_strategy]
73
+
74
+
75
+ @can_use_id_strategy = is_only_id_selector?(selectors)
76
+ if @can_use_id_strategy
77
+ if @driver.device == :android
78
+ @can_use_id_strategy = resolve_id(selectors[:id])
79
+ else
80
+ @can_use_id_strategy = selectors[:id]
81
+ end
82
+ end
83
+
84
+
85
+ @strategy = params[:strategy]
86
+ @strategy_reason = params[:strategy_reason]
87
+
88
+ @last_selector_adjacent = false
89
+
90
+ init(params, selectors, single)
91
+ end
92
+
93
+
94
+
95
+
96
+ def is_only_id_selector?(selectors)
97
+ # since, name and id is the same thing for iOS,
98
+ if @driver.device == :android
99
+ selectors.keys.count == 1 && !selectors[:id].nil?
100
+ else
101
+ # if it iOS we assign the name to id
102
+ selectors.keys.count == 2 && !selectors[:id].nil? && selectors[:id] == selectors[:name]
103
+ end
104
+ end
105
+
106
+
107
+ # method missing is used to fetch the element before executing additional commands like click, send_key, count
108
+ def method_missing(method, *args, &block)
109
+ r = execute.send(method, *args, &block)
110
+ @driver.invalidate_cache
111
+ r
112
+ end
113
+
114
+
115
+ # @param [Boolean] skip_cache if true it will skip cache check and store
116
+ # @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
+ # @return [Selenium::WebDriver::Element, Array]
118
+ def execute(skip_cache: false, force_cache_element: nil, ignore_implicit_wait: false)
119
+ return force_cache_element unless force_cache_element.nil?
120
+ # if we are looking for current element, then return from_element
121
+ # for example when we have driver.element.elements[1].click
122
+ # elements[2] will be resolved with xpath because we are looking for multiple elements from element
123
+ # and since we are looking for instance 2, [](instance) method will return new "empty locator"
124
+ # 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 == "//*[1]" && !@from_element.nil? && @image_selector.nil?
126
+ return @from_element if @from_element.instance_of?(Selenium::WebDriver::Element)
127
+ 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
+ return @from_element
129
+ end
130
+
131
+
132
+
133
+
134
+
135
+
136
+ r = @driver.execute(@from_element, @single, strategies_and_selectors, skip_cache: skip_cache, ignore_implicit_wait: ignore_implicit_wait)
137
+ r = r[@index_for_multiple] if !@index_for_multiple.nil? && !@single
138
+ r
139
+ end
140
+
141
+ def when_exists(timeout = nil, &block)
142
+ found = false
143
+ begin
144
+ wait_until_exists(timeout)
145
+ found = true
146
+ rescue
147
+ #ignored
148
+ end
149
+ if found
150
+ if block_given? # block is given
151
+ block.call(self) # use call to execute the block
152
+ else # the value of block_argument becomes nil if you didn't give a block
153
+ # block was not given
154
+ end
155
+ end
156
+ self
157
+ end
158
+
159
+
160
+ # @param [Integer] timeout in seconds
161
+ # @return [TestaAppiumDriver::Locator]
162
+ def wait_until_exists(timeout = nil)
163
+ args = {timeout: timeout}
164
+ _wait(:until, args)
165
+ end
166
+
167
+
168
+ # @param [Integer] timeout in seconds
169
+ # @return [TestaAppiumDriver::Locator]
170
+ def wait_while_exists(timeout = nil)
171
+ args = {timeout: timeout}
172
+ _wait(:while, args)
173
+ end
174
+
175
+
176
+ def wait_while(timeout = nil, args = {})
177
+ args[:timeout] = timeout
178
+ _wait(:while, args)
179
+ end
180
+
181
+ def wait_until(timeout = nil, args = {})
182
+ args[:timeout] = timeout
183
+ _wait(:until, args)
184
+ end
185
+
186
+
187
+ # all timeouts are disabled before check, and enabled after check
188
+ # @return [boolean] true if it exists in the page regardless if visible or not
189
+ def exists?
190
+ found = true
191
+ begin
192
+ execute(skip_cache: true, ignore_implicit_wait: true)
193
+ rescue StandardError
194
+ found = false
195
+ end
196
+ found
197
+ end
198
+
199
+ # @return [TestaAppiumDriver::Locator]
200
+ def first
201
+ self[0]
202
+ end
203
+
204
+ # @return [TestaAppiumDriver::Locator]
205
+ def second
206
+ self[1]
207
+ end
208
+
209
+ # @return [TestaAppiumDriver::Locator]
210
+ def third
211
+ self[2]
212
+ end
213
+
214
+ # @return [TestaAppiumDriver::Locator]
215
+ def last
216
+ self[-1]
217
+ end
218
+
219
+ def [](instance)
220
+ raise "Cannot add index selector to non-Array" if @single
221
+ if ((@strategy.nil? && !@last_selector_adjacent && @driver.device == :android) || @strategy == FIND_STRATEGY_UIAUTOMATOR) && instance >= 0
222
+ locator = self.dup
223
+ locator.strategy = FIND_STRATEGY_UIAUTOMATOR
224
+ locator.ui_selector = "#{@ui_selector}.instance(#{instance})"
225
+ locator.single = true
226
+ locator.can_use_id_strategy = false
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
235
+ else
236
+ from_element = self.dup
237
+ from_element.index_for_multiple = instance
238
+ params = {}.merge({single: true, scrollable_locator: @scrollable_locator})
239
+ #params[:strategy] = FIND_STRATEGY_XPATH
240
+ #params[:strategy_reason] = "retrieved instance of a array"
241
+ params[:default_find_strategy] = @default_find_strategy
242
+ params[:default_scroll_strategy] = @default_scroll_strategy
243
+ Locator.new(@driver, from_element, params)
244
+ end
245
+ end
246
+
247
+
248
+ # @param [TestaAppiumDriver::Locator, Selenium::WebDriver::Element, Array] other
249
+ #noinspection RubyNilAnalysis,RubyUnnecessaryReturnStatement
250
+ def ==(other)
251
+ elements = execute
252
+ other = other.execute if other.kind_of?(TestaAppiumDriver::Locator)
253
+
254
+ if elements.kind_of?(Array)
255
+ return false unless other.kind_of?(Array)
256
+ return false if other.count != elements.count
257
+ return (elements - other).empty?
258
+ else
259
+ return false if other.kind_of?(Array)
260
+ return elements == other
261
+ end
262
+ end
263
+
264
+ def as_json
265
+ {
266
+ strategy: @strategy,
267
+ default_strategy: @default_find_strategy,
268
+ single: @single,
269
+ uiautomator: defined?(self.ui_selector) ? ui_selector : nil,
270
+ xpath: @xpath_selector,
271
+ scroll_orientation: @scroll_orientation,
272
+ resolved: strategies_and_selectors,
273
+ index_for_multiple: @index_for_multiple
274
+ }
275
+ end
276
+
277
+ def to_s
278
+ JSON.dump(as_json)
279
+ end
280
+
281
+ def to_ary
282
+ [self.to_s]
283
+ end
284
+
285
+
286
+ # @return [TestaAppiumDriver::Locator]
287
+ def as_scrollable(orientation: :vertical, top: nil, bottom: nil, right: nil, left: nil)
288
+ @scroll_orientation = orientation
289
+ if !top.nil? || !bottom.nil? || !right.nil? || !left.nil?
290
+ @scroll_deadzone = {}
291
+ @scroll_deadzone[:top] = top.to_f unless top.nil?
292
+ @scroll_deadzone[:bottom] = bottom.to_f unless bottom.nil?
293
+ @scroll_deadzone[:right] = right.to_f unless right.nil?
294
+ @scroll_deadzone[:left] = left.to_f unless left.nil?
295
+ end
296
+ @scrollable_locator = self.dup
297
+ self
298
+ end
299
+
300
+
301
+ def first_and_last_leaf
302
+ @driver.first_and_last_leaf(execute)
303
+ end
304
+
305
+
306
+ def tap(x = nil, y = nil)
307
+ click(x, y)
308
+ end
309
+
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
356
+ end
357
+
358
+ def send_key(*args)
359
+ perform_driver_method(:send_keys, *args)
360
+ end
361
+
362
+ def clear
363
+ perform_driver_method(:clear)
364
+ end
365
+
366
+
367
+ # Return parent element
368
+ # @return [TestaAppiumDriver::Locator]
369
+ def parent
370
+ 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 == "//*" || @xpath_selector == "//*[1]") && !@from_element.nil?
372
+
373
+ locator = self.dup
374
+ locator.strategy = FIND_STRATEGY_XPATH
375
+ locator.strategy_reason = "parent"
376
+ locator.xpath_selector += "/.."
377
+ locator.can_use_id_strategy = false
378
+ locator
379
+ end
380
+
381
+ # Return all children elements
382
+ # @return [TestaAppiumDriver::Locator]
383
+ def children
384
+ 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 && @strategy != FIND_STRATEGY_CLASS_CHAIN && !@strategy.nil?
386
+
387
+ locator = self.dup
388
+ locator.strategy_reason = "children"
389
+ locator.xpath_selector += "/*"
390
+ locator.single = false
391
+ locator.last_selector_adjacent = true
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
399
+ locator
400
+ end
401
+
402
+
403
+ # Return first child element
404
+ # @return [TestaAppiumDriver::Locator]
405
+ def child
406
+ raise "Cannot add children selector to array" unless @single
407
+ raise StrategyMixException.new(@strategy, @strategy_reason, FIND_STRATEGY_XPATH, "child") if @strategy != FIND_STRATEGY_XPATH && @strategy != FIND_STRATEGY_CLASS_CHAIN && !@strategy.nil?
408
+
409
+ locator = self.dup
410
+
411
+ locator.strategy_reason = "child"
412
+ locator.xpath_selector += "/*[1]"
413
+ locator.single = true
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
421
+ locator
422
+ end
423
+
424
+
425
+ # @return [TestaAppiumDriver::Locator]
426
+ def siblings
427
+ raise "Cannot add siblings selector to array" unless @single
428
+ 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 == "//*" || @xpath_selector == "//*[1]") && !@from_element.nil?
430
+
431
+ locator = self.dup
432
+ locator.strategy = FIND_STRATEGY_XPATH
433
+ locator.strategy_reason = "siblings"
434
+ locator.xpath_selector += "/../*[not(@index=\"#{index}\")]"
435
+ locator.single = false
436
+ locator.last_selector_adjacent = true
437
+ locator.can_use_id_strategy = false
438
+ locator
439
+ end
440
+
441
+ # @return [TestaAppiumDriver::Locator]
442
+ def preceding_siblings
443
+ raise "Cannot add preceding_siblings selector to array" unless @single
444
+ 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 == "//*" || @xpath_selector == "//*[1]") && !@from_element.nil?
446
+
447
+ locator = self.dup
448
+ locator.strategy = FIND_STRATEGY_XPATH
449
+ locator.strategy_reason = "preceding_siblings"
450
+ locator.xpath_selector += "/../*[position() < #{index + 1}]" # position() starts from 1
451
+ locator.single = false
452
+ locator.last_selector_adjacent = true
453
+ locator.can_use_id_strategy = false
454
+ locator
455
+ end
456
+
457
+ # @return [TestaAppiumDriver::Locator]
458
+ def preceding_sibling
459
+ raise "Cannot add preceding_sibling selector to array" unless @single
460
+ 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 == "//*" || @xpath_selector == "//*[1]") && !@from_element.nil?
462
+
463
+ locator = self.dup
464
+ locator.strategy = FIND_STRATEGY_XPATH
465
+ locator.strategy_reason = "preceding_sibling"
466
+ i = index
467
+ locator.single = true
468
+ return nil if i == 0
469
+ locator.xpath_selector += "/../*[@index=\"#{i - 1}\"]"
470
+ locator.last_selector_adjacent = true
471
+ locator.can_use_id_strategy = false
472
+ locator
473
+ end
474
+
475
+
476
+ # @return [TestaAppiumDriver::Locator]
477
+ def following_siblings
478
+ raise "Cannot add following_siblings selector to array" unless @single
479
+ 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 == "//*" || @xpath_selector == "//*[1]") && !@from_element.nil?
481
+
482
+ locator = self.dup
483
+ locator.strategy = FIND_STRATEGY_XPATH
484
+ locator.strategy_reason = "following_siblings"
485
+ locator.xpath_selector += "/../*[position() > #{index + 1}]" # position() starts from 1
486
+ locator.single = false
487
+ locator.last_selector_adjacent = true
488
+ locator.can_use_id_strategy = false
489
+ locator
490
+ end
491
+
492
+ # @return [TestaAppiumDriver::Locator]
493
+ def following_sibling
494
+ raise "Cannot add following_sibling selector to array" unless @single
495
+ 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 == "//*" || @xpath_selector == "//*[1]") && !@from_element.nil?
497
+
498
+ locator = self.dup
499
+ locator.strategy = FIND_STRATEGY_XPATH
500
+ locator.strategy_reason = "following_sibling"
501
+ i = index
502
+ locator.single = true
503
+ return nil if i == 0
504
+ locator.xpath_selector += "/../*[@index=\"#{i + 1}\"]"
505
+ locator.last_selector_adjacent = true
506
+ locator.can_use_id_strategy = false
507
+ locator
508
+ end
509
+
510
+
511
+ private
512
+
513
+ def _wait(type, args)
514
+ interval = EXISTS_WAIT
515
+ interval = args[:interval] unless args[:interval].nil?
516
+
517
+ message = "wait #{type} exists timeout exceeded"
518
+ message = args[:message] unless args[:message].nil?
519
+
520
+ if args[:timeout].nil?
521
+ #timeout = @driver.get_timeouts["implicit"] / 1000
522
+ timeout = 10
523
+ else
524
+ timeout = args[:timeout]
525
+ end
526
+
527
+ args.delete(:message)
528
+ args.delete(:interval)
529
+ args.delete(:timeout)
530
+
531
+
532
+
533
+ start_time = Time.now.to_f
534
+ if type == :while
535
+ while exists? && _attributes_match(args)
536
+ raise message if start_time + timeout < Time.now.to_f
537
+ sleep interval
538
+ end
539
+ else
540
+ until exists? && _attributes_match(args)
541
+ raise message if start_time + timeout < Time.now.to_f
542
+ sleep interval
543
+ end
544
+ end
545
+ self
546
+ end
547
+
548
+ def _attributes_match(attributes)
549
+ all_match = true
550
+ attributes.each do |key, value|
551
+ unless attribute(key) == value
552
+ all_match = false
553
+ break
554
+ end
555
+ end
556
+ all_match
557
+ end
558
+
559
+ #noinspection RubyNilAnalysis
560
+ def perform_driver_method(name, *args)
561
+ elements = execute
562
+ if elements.kind_of?(Array)
563
+ elements.map { |e| e.send(name, *args) }
564
+ else
565
+ elements.send(name, *args)
566
+ end
567
+ end
568
+
569
+ def add_xpath_child_selectors(locator, selectors, single)
570
+ locator.single = false unless single # switching from single result to multiple
571
+ locator.xpath_selector += hash_to_xpath(@driver.device, selectors, single)
572
+ end
573
+
574
+
575
+ def handle_image_selector(selectors, params)
576
+ image_match_threshold = 0.4
577
+ image_match_threshold = params[:imageMatchThreshold] unless params[:imageMatchThreshold].nil?
578
+ image_match_threshold = params[:threshold] unless params[:threshold].nil?
579
+ fix_image_find_screenshot_dims = true
580
+ fix_image_find_screenshot_dims = params[:fixImageFindScreenshotDims] unless params[:fixImageFindScreenshotDims].nil?
581
+ fix_image_template_size = false
582
+ fix_image_template_size = params[:fixImageTemplateSize] unless params[:fixImageTemplateSize].nil?
583
+ fix_image_template_scale = false
584
+ fix_image_template_scale = params[:fixImageTemplateScale] unless params[:fixImageTemplateScale].nil?
585
+ default_image_template_scale = 1.0
586
+ default_image_template_scale = params[:defaultImageTemplateScale] unless params[:defaultImageTemplateScale].nil?
587
+ check_for_image_element_staleness = true
588
+ check_for_image_element_staleness = params[:checkForImageElementStaleness] unless params[:checkForImageElementStaleness].nil?
589
+ auto_update_image_element_position = false
590
+ auto_update_image_element_position = params[:autoUpdateImageElementPosition] unless params[:autoUpdateImageElementPosition].nil?
591
+ image_element_tap_strategy = "w3cActions"
592
+ image_element_tap_strategy = params[:imageElementTapStrategy] unless params[:imageElementTapStrategy].nil?
593
+ get_matched_image_result = false
594
+ get_matched_image_result = params[:getMatchedImageResult] unless params[:getMatchedImageResult].nil?
595
+
596
+ @image_selector = {
597
+ image: selectors[:image],
598
+ imageMatchThreshold: image_match_threshold,
599
+ fixImageFindScreenshotDims: fix_image_find_screenshot_dims,
600
+ fixImageTemplateSize: fix_image_template_size,
601
+ fixImageTemplateScale: fix_image_template_scale,
602
+ defaultImageTemplateScale: default_image_template_scale,
603
+ checkForImageElementStaleness: check_for_image_element_staleness,
604
+ autoUpdateImageElementPosition: auto_update_image_element_position,
605
+ imageElementTapStrategy: image_element_tap_strategy,
606
+ getMatchedImageResult: get_matched_image_result,
607
+ }
608
+ end
609
+ end
610
+
579
611
  end