Class: TestaAppiumDriver::Driver
- Inherits:
-
Object
- Object
- TestaAppiumDriver::Driver
show all
- Includes:
- ClassSelectors, Helpers, TypeSelectors
- Defined in:
- lib/testa_appium_driver/driver.rb,
lib/testa_appium_driver/ios/driver.rb,
lib/testa_appium_driver/android/driver.rb
Instance Attribute Summary collapse
Instance Method Summary
collapse
-
#android? ⇒ Boolean
-
#back ⇒ Object
-
#click(x, y, double: false) ⇒ Object
-
#current_package ⇒ Object
@@return [String] current package under test.
-
#disable_implicit_wait ⇒ Object
-
#disable_wait_for_idle ⇒ Object
disables wait for idle, only executed for android devices.
-
#double_click(x, y) ⇒ Object
-
#dpad_down_key ⇒ Object
-
#dpad_left_key ⇒ Object
-
#dpad_right_key ⇒ Object
-
#dpad_up_key ⇒ Object
-
#enter_key ⇒ Object
-
#execute(from_element, single, strategies_and_selectors, skip_cache: false, ignore_implicit_wait: false) ⇒ Selenium::WebDriver::Element, Array
Executes the find_element with the resolved locator strategy and selector.
-
#first_and_last_child(from_element = @driver) ⇒ Object
-
#first_and_last_leaf(from_element = @driver) ⇒ Array<Selenium::WebDriver::Element] array of 2 elements, the first element without children and the last element without children in the current page
Array<Selenium::WebDriver::Element] array of 2 elements, the first element without children and the last element without children in the current page.
-
#hide_keyboard ⇒ Object
-
#home_key ⇒ Object
-
#initialize(opts = {}) ⇒ Driver
constructor
custom options - default_find_strategy: default strategy to be used for finding elements.
-
#invalidate_cache ⇒ Object
invalidates current find_element cache.
-
#ios? ⇒ Boolean
-
#is_keyboard_shown? ⇒ Boolean
-
#long_press_keycode(code) ⇒ Object
-
#method_missing(method, *args, &block) ⇒ Object
method missing is used to forward methods to the actual appium driver after the method is executed, find element cache is invalidated.
-
#press_keycode(code) ⇒ Object
-
#restore_set_by_image_settings ⇒ Object
-
#scrollable ⇒ TestaAppiumDriver::Locator
First scrollable element.
-
#scrollables ⇒ TestaAppiumDriver::Locator
First scrollable element.
-
#set_find_by_image_settings(settings) ⇒ Object
-
#shell(command, args: nil, timeout: nil, includeStderr: true) ⇒ Object
-
#tab_key ⇒ Object
-
#window_size ⇒ Object
#add_selector, #button, #buttons, #card_view, #card_views, #check_box, #check_boxes, #edit_text, #edit_texts, #element, #elements, #frame_layout, #frame_layouts, #horizontal_scroll_view, #horizontal_scroll_views, #image_button, #image_buttons, #image_view, #image_views, #linear_layout, #linear_layouts, #list_view, #list_views, #progress_bar, #progress_bars, #radio_button, #radio_buttons, #radio_group, #radio_groups, #recycler_view, #recycler_views, #relative_layout, #relative_layouts, #scroll_view, #scroll_views, #search_view, #search_views, #spinner, #spinners, #switch, #switches, #text_view, #text_views, #toast, #toasts, #toolbar, #toolbars, #view, #view_group, #view_groups, #view_pager, #view_pagers, #views, #web_view, #web_views
#add_selector, #button, #buttons, #cell, #cells, #collection_view, #collection_views, #element, #elements, #image, #images, #navigation_bar, #navigation_bars, #other, #others, #scroll_view, #scroll_views, #secure_text_field, #secure_text_fields, #static_text, #static_texts, #table, #tables, #text_field, #text_fields, #window, #windows
Methods included from Helpers
#extract_selectors_from_params, #hash_to_class_chain, #hash_to_uiautomator, #hash_to_xpath, #is_scrollable_selector?, #resolve_id
Constructor Details
#initialize(opts = {}) ⇒ Driver
custom options
- default_find_strategy: default strategy to be used for finding elements. Available strategies :uiautomator or :xpath
- default_scroll_strategy: default strategy to be used for scrolling. Available strategies: :uiautomator(android only), :w3c
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
# File 'lib/testa_appium_driver/driver.rb', line 29
def initialize(opts = {})
@testa_opts = opts[:testa_appium_driver] || {}
core = Appium::Core.for(opts)
@driver = core.start_driver
@automation_name = @driver.capabilities["automationName"].downcase.to_sym
@device = @driver.capabilities.platform_name.downcase.to_sym
extend_for(@device, @automation_name)
handle_testa_opts
invalidate_cache
::Appium::Core::Element.set_driver(self, @driver.capabilities["udid"])
end
|
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method, *args, &block) ⇒ Object
method missing is used to forward methods to the actual appium driver
after the method is executed, find element cache is invalidated
145
146
147
148
149
|
# File 'lib/testa_appium_driver/driver.rb', line 145
def method_missing(method, *args, &block)
r = @driver.send(method, *args, &block)
invalidate_cache
r
end
|
Instance Attribute Details
#automation_name ⇒ String
Returns driver automation name (uiautomator2 or xcuitest).
24
25
26
|
# File 'lib/testa_appium_driver/driver.rb', line 24
def automation_name
@automation_name
end
|
#device ⇒ String
21
22
23
|
# File 'lib/testa_appium_driver/driver.rb', line 21
def device
@device
end
|
#driver ⇒ ::Appium::Core::Base::Driver
Returns the ruby_lib_core appium driver.
18
19
20
|
# File 'lib/testa_appium_driver/driver.rb', line 18
def driver
@driver
end
|
Instance Method Details
#android? ⇒ Boolean
308
309
310
|
# File 'lib/testa_appium_driver/driver.rb', line 308
def android?
device == :android
end
|
#back ⇒ Object
201
202
203
|
# File 'lib/testa_appium_driver/driver.rb', line 201
def back
@driver.back
end
|
#click(x, y, double: false) ⇒ Object
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
|
# File 'lib/testa_appium_driver/driver.rb', line 250
def click(x, y, double: false)
ws = driver.window_size
window_width = ws.width.to_i
window_height = ws.height.to_i
if x.kind_of?(Integer)
if x < 0
x = window_width + x
end
elsif x.kind_of?(Float) && x <= 1.0 && x >= 0
x = window_width*x
else
raise "x value #{x} not supported. Use integer as pixel or float (0..1) as percentage of screen"
end
if y.kind_of?(Integer)
if y < 0
y = window_height + y
end
elsif y.kind_of?(Float) && y <= 1.0 && y >= 0
y = window_height*y
else
raise "y value #{x} not supported. Use integer as pixel or float (0..1) as percentage of screen"
end
action_builder = @driver.action
f1 = action_builder.add_pointer_input(:touch, "finger1")
f1.create_pointer_move(duration: 0, x: x, y: y, origin: ::Selenium::WebDriver::Interactions::PointerMove::VIEWPORT)
f1.create_pointer_down(:left)
f1.create_pointer_up(:left)
if double
f1.create_pause(0.1)
f1.create_pointer_down(:left)
f1.create_pointer_up(:left)
end
@driver.perform_actions [f1]
end
|
#current_package ⇒ Object
@@return [String] current package under test
192
193
194
|
# File 'lib/testa_appium_driver/driver.rb', line 192
def current_package
@driver.current_package
end
|
#disable_implicit_wait ⇒ Object
152
153
154
155
156
157
158
|
# File 'lib/testa_appium_driver/driver.rb', line 152
def disable_implicit_wait
@implicit_wait_ms = @driver.get_timeouts["implicit"].to_i
@implicit_wait_ms = @implicit_wait_ms/1000 if @implicit_wait_ms > 100000
@implicit_wait_uiautomator_ms = @driver.get_settings["waitForSelectorTimeout"]
@driver.manage.timeouts.implicit_wait = 0
@driver.update_settings({waitForSelectorTimeout: 0})
end
|
#disable_wait_for_idle ⇒ Object
disables wait for idle, only executed for android devices
161
162
163
164
165
166
|
# File 'lib/testa_appium_driver/driver.rb', line 161
def disable_wait_for_idle
if @device == :android
@wait_for_idle_timeout = @driver.settings.get["waitForIdleTimeout"]
@driver.update_settings({waitForIdleTimeout: 0})
end
end
|
#double_click(x, y) ⇒ Object
288
289
290
|
# File 'lib/testa_appium_driver/driver.rb', line 288
def double_click(x,y)
click(x,y, double: true)
end
|
#dpad_down_key ⇒ Object
226
227
228
|
# File 'lib/testa_appium_driver/driver.rb', line 226
def dpad_down_key
@driver.press_keycode(20)
end
|
#dpad_left_key ⇒ Object
234
235
236
|
# File 'lib/testa_appium_driver/driver.rb', line 234
def dpad_left_key
@driver.press_keycode(23)
end
|
#dpad_right_key ⇒ Object
230
231
232
|
# File 'lib/testa_appium_driver/driver.rb', line 230
def dpad_right_key
@driver.press_keycode(22)
end
|
#dpad_up_key ⇒ Object
222
223
224
|
# File 'lib/testa_appium_driver/driver.rb', line 222
def dpad_up_key
@driver.press_keycode(19)
end
|
#enter_key ⇒ Object
238
239
240
|
# File 'lib/testa_appium_driver/driver.rb', line 238
def enter_key
@driver.press_keycode(66)
end
|
#execute(from_element, single, strategies_and_selectors, skip_cache: false, ignore_implicit_wait: false) ⇒ Selenium::WebDriver::Element, Array
Executes the find_element with the resolved locator strategy and selector. Find_element might be skipped if cache is hit.
Cache stores last executed find_element with given selector, strategy and from_element. If given values are the same within
last 5 seconds element is retrieved from cache.
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
|
# File 'lib/testa_appium_driver/driver.rb', line 72
def execute(from_element, single, strategies_and_selectors, skip_cache: false, ignore_implicit_wait: false)
start_time = Time.now.to_f
ss_index = 0
from_element_id = from_element.instance_of?(TestaAppiumDriver::Locator) ? from_element.strategies_and_selectors : nil
begin
begin
ss = strategies_and_selectors[ss_index % strategies_and_selectors.count]
rescue ZeroDivisionError
puts "aa"
end
ss_index +=1
puts "Executing #{from_element_id ? "from #{from_element.strategy}: #{from_element.strategies_and_selectors} => " : ""}#{ss.keys[0]}: #{ss.values[0]}"
if @cache[:selector] != ss.values[0] || @cache[:time] + 5 <= Time.now || @cache[:strategy] != ss.keys[0] || @cache[:from_element_id] != from_element_id || skip_cache
if ss.keys[0] == FIND_STRATEGY_IMAGE
set_find_by_image_settings(ss.values[0].dup)
if single
execute_result = from_element.find_element_by_image(ss.values[0][:image])
else
execute_result = from_element.find_elements_by_image(ss.values[0][:image])
end
restore_set_by_image_settings
else
if single
execute_result = from_element.find_element(ss)
else
execute_result = from_element.find_elements(ss)
end
end
unless skip_cache
@cache[:selector] = ss.values[0]
@cache[:strategy] = ss.keys[0]
@cache[:time] = Time.now
@cache[:from_element_id] = from_element_id
@cache[:element] = execute_result
end
else
execute_result = @cache[:element]
puts "Using cache from #{@cache[:time].strftime("%H:%M:%S.%L")}, strategy: #{@cache[:strategy]}"
end
rescue => e
if ss_index < strategies_and_selectors.count
sleep EXISTS_WAIT if ss_index >= strategies_and_selectors.count
retry
else
raise e
end
end
execute_result
end
|
#first_and_last_child(from_element = @driver) ⇒ Object
301
302
303
304
305
306
|
# File 'lib/testa_appium_driver/driver.rb', line 301
def first_and_last_child(from_element = @driver)
elements = from_element.find_elements(xpath: "./*")
return nil if elements.count == 0
[elements[0], elements[-1]]
end
|
#first_and_last_leaf(from_element = @driver) ⇒ Array<Selenium::WebDriver::Element] array of 2 elements, the first element without children and the last element without children in the current page
Returns Array<Selenium::WebDriver::Element] array of 2 elements, the first element without children and the last element without children in the current page.
295
296
297
298
299
|
# File 'lib/testa_appium_driver/driver.rb', line 295
def first_and_last_leaf(from_element = @driver)
elements = from_element.find_elements(xpath: ".//*[not(*)]")
return nil if elements.count == 0
[elements[0], elements[-1]]
end
|
#hide_keyboard ⇒ Object
210
211
212
|
# File 'lib/testa_appium_driver/driver.rb', line 210
def hide_keyboard
@driver.hide_keyboard
end
|
#home_key ⇒ Object
214
215
216
|
# File 'lib/testa_appium_driver/driver.rb', line 214
def home_key
@driver.press_keycode(3)
end
|
#invalidate_cache ⇒ Object
invalidates current find_element cache
51
52
53
54
55
56
57
58
59
|
# File 'lib/testa_appium_driver/driver.rb', line 51
def invalidate_cache
@cache = {
strategy: nil,
selector: nil,
element: nil,
from_element: nil,
time: Time.at(0)
}
end
|
#ios? ⇒ Boolean
312
313
314
|
# File 'lib/testa_appium_driver/driver.rb', line 312
def ios?
device == :ios
end
|
#is_keyboard_shown? ⇒ Boolean
206
207
208
|
# File 'lib/testa_appium_driver/driver.rb', line 206
def is_keyboard_shown?
@driver.is_keyboard_shown
end
|
#long_press_keycode(code) ⇒ Object
246
247
248
|
# File 'lib/testa_appium_driver/driver.rb', line 246
def long_press_keycode(code)
@driver.long_press_keycode(code)
end
|
#press_keycode(code) ⇒ Object
242
243
244
|
# File 'lib/testa_appium_driver/driver.rb', line 242
def press_keycode(code)
@driver.press_keycode(code)
end
|
#restore_set_by_image_settings ⇒ Object
186
187
188
|
# File 'lib/testa_appium_driver/driver.rb', line 186
def restore_set_by_image_settings
@driver.update_settings(@default_find_image_settings) if @default_find_image_settings
end
|
Returns first scrollable element.
13
14
15
|
# File 'lib/testa_appium_driver/ios/driver.rb', line 13
def scrollable(params = {})
scroll_view(params)
end
|
Returns first scrollable element.
19
20
21
|
# File 'lib/testa_appium_driver/ios/driver.rb', line 19
def scrollables(params = {})
scroll_views(params)
end
|
#set_find_by_image_settings(settings) ⇒ Object
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
|
# File 'lib/testa_appium_driver/driver.rb', line 169
def set_find_by_image_settings(settings)
settings.delete(:image)
@default_find_image_settings = {}
old_settings = @driver.get_settings
@default_find_image_settings[:imageMatchThreshold] = old_settings["imageMatchThreshold"]
@default_find_image_settings[:fixImageFindScreenshotDims] = old_settings["fixImageFindScreenshotDims"]
@default_find_image_settings[:fixImageTemplateSize] = old_settings["fixImageTemplateSize"]
@default_find_image_settings[:fixImageTemplateScale] = old_settings["fixImageTemplateScale"]
@default_find_image_settings[:defaultImageTemplateScale] = old_settings["defaultImageTemplateScale"]
@default_find_image_settings[:checkForImageElementStaleness] = old_settings["checkForImageElementStaleness"]
@default_find_image_settings[:autoUpdateImageElementPosition] = old_settings["autoUpdateImageElementPosition"]
@default_find_image_settings[:imageElementTapStrategy] = old_settings["imageElementTapStrategy"]
@default_find_image_settings[:getMatchedImageResult] = old_settings["getMatchedImageResult"]
@driver.update_settings(settings)
end
|
#shell(command, args: nil, timeout: nil, includeStderr: true) ⇒ Object
15
16
17
18
19
20
21
22
23
|
# File 'lib/testa_appium_driver/android/driver.rb', line 15
def shell(command, args: nil, timeout: nil, includeStderr: true)
params = {
command: command,
includeStderr: includeStderr,
}
params[:args] = args unless args.nil?
params[:timeout] = timeout unless timeout.nil?
@driver.execute_script("mobile: shell", params)
end
|
#tab_key ⇒ Object
218
219
220
|
# File 'lib/testa_appium_driver/driver.rb', line 218
def tab_key
@driver.press_keycode(61)
end
|
#window_size ⇒ Object
197
198
199
|
# File 'lib/testa_appium_driver/driver.rb', line 197
def window_size
@driver.window_size
end
|