testcentricity_mobile 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.yardopts +3 -0
- data/CHANGELOG.md +105 -0
- data/LICENSE.md +27 -0
- data/README.md +1795 -0
- data/lib/testcentricity_mobile/app_core/appium_connect_helper.rb +634 -0
- data/lib/testcentricity_mobile/app_core/screen_object.rb +413 -0
- data/lib/testcentricity_mobile/app_core/screen_objects_helper.rb +183 -0
- data/lib/testcentricity_mobile/app_core/screen_section.rb +607 -0
- data/lib/testcentricity_mobile/app_elements/alert.rb +152 -0
- data/lib/testcentricity_mobile/app_elements/app_element.rb +692 -0
- data/lib/testcentricity_mobile/app_elements/button.rb +10 -0
- data/lib/testcentricity_mobile/app_elements/checkbox.rb +56 -0
- data/lib/testcentricity_mobile/app_elements/image.rb +10 -0
- data/lib/testcentricity_mobile/app_elements/label.rb +10 -0
- data/lib/testcentricity_mobile/app_elements/list.rb +175 -0
- data/lib/testcentricity_mobile/app_elements/switch.rb +66 -0
- data/lib/testcentricity_mobile/app_elements/textfield.rb +51 -0
- data/lib/testcentricity_mobile/appium_server.rb +71 -0
- data/lib/testcentricity_mobile/data_objects/data_objects_helper.rb +100 -0
- data/lib/testcentricity_mobile/data_objects/environment.rb +416 -0
- data/lib/testcentricity_mobile/exception_queue_helper.rb +160 -0
- data/lib/testcentricity_mobile/utility_helpers.rb +48 -0
- data/lib/testcentricity_mobile/version.rb +3 -0
- data/lib/testcentricity_mobile/world_extensions.rb +61 -0
- data/lib/testcentricity_mobile.rb +99 -0
- metadata +317 -0
@@ -0,0 +1,634 @@
|
|
1
|
+
require 'appium_lib'
|
2
|
+
require 'json'
|
3
|
+
require 'net/http'
|
4
|
+
require 'net/https'
|
5
|
+
require 'uri'
|
6
|
+
|
7
|
+
|
8
|
+
module TestCentricity
|
9
|
+
module AppiumConnect
|
10
|
+
attr_accessor :driver
|
11
|
+
attr_accessor :running
|
12
|
+
attr_accessor :endpoint
|
13
|
+
attr_accessor :capabilities
|
14
|
+
attr_accessor :global_scope
|
15
|
+
|
16
|
+
# Create a new driver instance with capabilities specified in the options parameter, or via Environment Variables.
|
17
|
+
# Refer to the `Connecting to a Mobile Simulator or Device` section of the ruby docs for this gem.
|
18
|
+
#
|
19
|
+
def self.initialize_appium(options = nil)
|
20
|
+
@endpoint = nil
|
21
|
+
@capabilities = nil
|
22
|
+
@running = false
|
23
|
+
@global_scope = false
|
24
|
+
Environ.driver_name = nil
|
25
|
+
Environ.device_orientation = nil
|
26
|
+
Environ.platform = :mobile
|
27
|
+
Environ.device = :simulator
|
28
|
+
|
29
|
+
if options.is_a?(Hash)
|
30
|
+
@endpoint = options[:endpoint] if options.key?(:endpoint)
|
31
|
+
@capabilities = options[:capabilities] if options.key?(:capabilities)
|
32
|
+
@global_scope = options[:global_driver] if options.key?(:global_driver)
|
33
|
+
Environ.driver = options[:driver] if options.key?(:driver)
|
34
|
+
Environ.driver_name = options[:driver_name] if options.key?(:driver_name)
|
35
|
+
Environ.device_type = options[:device_type] if options.key?(:device_type)
|
36
|
+
end
|
37
|
+
if @capabilities.nil?
|
38
|
+
Environ.driver = ENV['DRIVER'].downcase.to_sym if ENV['DRIVER']
|
39
|
+
Environ.device_type = ENV['DEVICE_TYPE'] if ENV['DEVICE_TYPE']
|
40
|
+
Environ.device_orientation = ENV['ORIENTATION'] if ENV['ORIENTATION']
|
41
|
+
else
|
42
|
+
raise ':browserName is specified in capabilities' if @capabilities[:browserName]
|
43
|
+
end
|
44
|
+
|
45
|
+
raise 'You must specify a driver' if Environ.driver.nil?
|
46
|
+
raise 'You must specify a device type - :phone or :tablet' if Environ.device_type.nil?
|
47
|
+
|
48
|
+
driver_caps = case Environ.driver
|
49
|
+
when :appium
|
50
|
+
appium_local_capabilities
|
51
|
+
when :custom
|
52
|
+
raise 'User-defined cloud driver requires that you define options' if options.nil?
|
53
|
+
custom_capabilities
|
54
|
+
when :browserstack
|
55
|
+
browserstack_capabilities
|
56
|
+
when :testingbot
|
57
|
+
testingbot_capabilities
|
58
|
+
# :nocov:
|
59
|
+
when :saucelabs
|
60
|
+
sauce_capabilities
|
61
|
+
else
|
62
|
+
raise "#{Environ.driver} is not a supported driver"
|
63
|
+
# :nocov:
|
64
|
+
end
|
65
|
+
driver_opts = {
|
66
|
+
caps: driver_caps,
|
67
|
+
appium_lib: { server_url: @endpoint }
|
68
|
+
}
|
69
|
+
@driver = Appium::Driver.new(driver_opts, global_driver = @global_scope)
|
70
|
+
@driver.start_driver
|
71
|
+
Environ.appium_driver = @driver
|
72
|
+
@running = true
|
73
|
+
Appium.promote_appium_methods(TestCentricity::ScreenObject, driver = @driver)
|
74
|
+
Appium.promote_appium_methods(TestCentricity::ScreenSection, driver = @driver)
|
75
|
+
Appium.promote_appium_methods(TestCentricity::AppElements::AppUIElement, driver = @driver)
|
76
|
+
|
77
|
+
Environ.screen_size = window_size
|
78
|
+
unless Environ.driver_name
|
79
|
+
Environ.driver_name = "#{Environ.driver}_#{Environ.device_os}_#{Environ.device_type}".downcase.to_sym
|
80
|
+
end
|
81
|
+
Environ.session_state = :running
|
82
|
+
end
|
83
|
+
|
84
|
+
# Quit the running driver instance. Sets Environ.session_state to :quit.
|
85
|
+
#
|
86
|
+
def self.quit_driver
|
87
|
+
if @running
|
88
|
+
driver.driver_quit
|
89
|
+
@running = false
|
90
|
+
end
|
91
|
+
Environ.session_state = :quit
|
92
|
+
end
|
93
|
+
|
94
|
+
# Return a reference to last created Appium driver
|
95
|
+
#
|
96
|
+
def self.driver
|
97
|
+
@driver
|
98
|
+
end
|
99
|
+
|
100
|
+
# Save a screenshot in .png format to the specified file path.
|
101
|
+
#
|
102
|
+
# @param png_save_path [String] path to save the screenshot
|
103
|
+
# @example
|
104
|
+
# AppiumConnect.take_screenshot('reports/screenshots/login_screen.png')
|
105
|
+
#
|
106
|
+
def self.take_screenshot(png_save_path)
|
107
|
+
FileUtils.mkdir_p(File.dirname(png_save_path))
|
108
|
+
driver.driver.save_screenshot(png_save_path)
|
109
|
+
end
|
110
|
+
|
111
|
+
# Install app on device. If bundle_id is not specified, then bundle id will be retrieved from Environ.current.ios_bundle_id
|
112
|
+
# or Environ.current.android_app_id dependent on which platform is being tested.
|
113
|
+
#
|
114
|
+
# @param bundle_id [String] OPTIONAL bundle id of app
|
115
|
+
# @example
|
116
|
+
# AppiumConnect.install_app('com.saucelabs.mydemoapp.rn')
|
117
|
+
#
|
118
|
+
def self.install_app(app_path)
|
119
|
+
driver.install_app(app_path)
|
120
|
+
end
|
121
|
+
|
122
|
+
# Remove app from device. If bundle_id is not specified, then bundle id will be retrieved from Environ.current.ios_bundle_id
|
123
|
+
# or Environ.current.android_app_id dependent on which platform is being tested.
|
124
|
+
#
|
125
|
+
# @param bundle_id [String] OPTIONAL bundle id of app
|
126
|
+
# @example
|
127
|
+
# AppiumConnect.remove_app('com.saucelabs.mydemoapp.rn')
|
128
|
+
#
|
129
|
+
def self.remove_app(bundle_id = nil)
|
130
|
+
driver.remove_app(get_app_id(bundle_id))
|
131
|
+
end
|
132
|
+
|
133
|
+
# Is the app installed? If bundle_id is not specified, then bundle id will be retrieved from Environ.current.ios_bundle_id
|
134
|
+
# or Environ.current.android_app_id dependent on which platform is being tested.
|
135
|
+
#
|
136
|
+
# @param bundle_id [String] OPTIONAL bundle id of app
|
137
|
+
# @return [Boolean] TRUE if app is installed
|
138
|
+
# @example
|
139
|
+
# AppiumConnect.app_installed?('com.saucelabs.mydemoapp.rn')
|
140
|
+
#
|
141
|
+
def self.app_installed?(bundle_id = nil)
|
142
|
+
driver.app_installed?(get_app_id(bundle_id))
|
143
|
+
end
|
144
|
+
|
145
|
+
# Backgrounds the app for a specified number of seconds.
|
146
|
+
#
|
147
|
+
# @param duration [Integer] number of seconds to background the app for
|
148
|
+
# @example
|
149
|
+
# AppiumConnect.background_app(20)
|
150
|
+
#
|
151
|
+
def self.background_app(duration = 0)
|
152
|
+
driver.background_app(duration)
|
153
|
+
end
|
154
|
+
|
155
|
+
# Launch the app. If bundle_id is not specified, then bundle id will be retrieved from Environ.current.ios_bundle_id
|
156
|
+
# or Environ.current.android_app_id dependent on which platform is being tested.
|
157
|
+
#
|
158
|
+
# @param bundle_id [String] OPTIONAL bundle id of app
|
159
|
+
# @example
|
160
|
+
# AppiumConnect.activate_app('com.saucelabs.mydemoapp.rn')
|
161
|
+
#
|
162
|
+
def self.activate_app(bundle_id = nil)
|
163
|
+
driver.activate_app(get_app_id(bundle_id))
|
164
|
+
if Environ.is_android?
|
165
|
+
sleep(1.5) if app_state == :running_in_foreground
|
166
|
+
end
|
167
|
+
Environ.new_app_session
|
168
|
+
end
|
169
|
+
|
170
|
+
# Get status of app. If bundle_id is not specified, then bundle id will be retrieved from Environ.current.ios_bundle_id
|
171
|
+
# or Environ.current.android_app_id dependent on which platform is being tested. Returns the following statuses:
|
172
|
+
# :not_installed - The current application state cannot be determined/is unknown
|
173
|
+
# :not_running - The application is not running
|
174
|
+
# :running_in_background_suspended - The application is running in the background and is suspended
|
175
|
+
# :running_in_background - The application is running in the background and is not suspended
|
176
|
+
# :running_in_foreground - The application is running in the foreground
|
177
|
+
#
|
178
|
+
# @param bundle_id [String] OPTIONAL bundle id of app
|
179
|
+
# @return [Symbol] status of app
|
180
|
+
# @example
|
181
|
+
# AppiumConnect.app_state('com.saucelabs.mydemoapp.rn')
|
182
|
+
#
|
183
|
+
def self.app_state(bundle_id = nil)
|
184
|
+
driver.app_state(get_app_id(bundle_id))
|
185
|
+
end
|
186
|
+
|
187
|
+
# Terminate the app. If bundle_id is not specified, then bundle id will be retrieved from Environ.current.ios_bundle_id
|
188
|
+
# or Environ.current.android_app_id dependent on which platform is being tested.
|
189
|
+
#
|
190
|
+
# @param bundle_id [String] OPTIONAL bundle id of app
|
191
|
+
# @example
|
192
|
+
# AppiumConnect.terminate_app('com.saucelabs.mydemoapp.rn')
|
193
|
+
#
|
194
|
+
def self.terminate_app(bundle_id = nil)
|
195
|
+
driver.terminate_app(get_app_id(bundle_id))
|
196
|
+
end
|
197
|
+
|
198
|
+
# Set the amount of time the driver should wait when searching for elements.
|
199
|
+
#
|
200
|
+
# @param timeout [Integer] number of seconds to wait
|
201
|
+
#
|
202
|
+
def self.implicit_wait(timeout)
|
203
|
+
driver.manage.timeouts.implicit_wait = timeout
|
204
|
+
end
|
205
|
+
|
206
|
+
# Hide the onscreen keyboard
|
207
|
+
#
|
208
|
+
def self.hide_keyboard
|
209
|
+
driver.hide_keyboard
|
210
|
+
end
|
211
|
+
|
212
|
+
# Is onscreen keyboard displayed?
|
213
|
+
#
|
214
|
+
# @return [Boolean] TRUE if keyboard is shown. Return false if keyboard is hidden.
|
215
|
+
#
|
216
|
+
def self.keyboard_shown?
|
217
|
+
driver.driver.keyboard_shown?
|
218
|
+
end
|
219
|
+
|
220
|
+
# Get the current screen orientation
|
221
|
+
#
|
222
|
+
# @return [Symbol] :landscape or :portrait
|
223
|
+
#
|
224
|
+
def self.orientation
|
225
|
+
driver.driver.orientation
|
226
|
+
end
|
227
|
+
|
228
|
+
# Change the screen orientation
|
229
|
+
#
|
230
|
+
# @param orientation [Symbol or String] :landscape or :portrait
|
231
|
+
#
|
232
|
+
def self.rotation(orientation)
|
233
|
+
orientation.downcase.to_sym if orientation.is_a?(String)
|
234
|
+
driver.driver.rotation = orientation
|
235
|
+
end
|
236
|
+
|
237
|
+
# Get the device's window size.
|
238
|
+
#
|
239
|
+
# @return [Array] window size as [width, height]
|
240
|
+
#
|
241
|
+
def self.window_size
|
242
|
+
size = driver.window_size
|
243
|
+
[size.width, size.height]
|
244
|
+
end
|
245
|
+
|
246
|
+
# Get the device's window rectangle.
|
247
|
+
#
|
248
|
+
# @return (Selenium::WebDriver::Rectangle)
|
249
|
+
#
|
250
|
+
def self.window_rect
|
251
|
+
driver.window_rect
|
252
|
+
end
|
253
|
+
|
254
|
+
def self.geolocation
|
255
|
+
driver.driver.location
|
256
|
+
end
|
257
|
+
|
258
|
+
def self.set_geolocation(location_data)
|
259
|
+
driver.set_location(location_data)
|
260
|
+
end
|
261
|
+
|
262
|
+
def self.current_context
|
263
|
+
driver.current_context
|
264
|
+
end
|
265
|
+
|
266
|
+
def self.set_context(context)
|
267
|
+
driver.set_context(context)
|
268
|
+
end
|
269
|
+
|
270
|
+
def self.available_contexts
|
271
|
+
driver.available_contexts
|
272
|
+
end
|
273
|
+
|
274
|
+
def self.is_webview?
|
275
|
+
driver.current_context.start_with?('WEBVIEW')
|
276
|
+
end
|
277
|
+
|
278
|
+
def self.is_native_app?
|
279
|
+
driver.current_context.start_with?('NATIVE_APP')
|
280
|
+
end
|
281
|
+
|
282
|
+
def self.webview_context
|
283
|
+
contexts = driver.available_contexts
|
284
|
+
puts "Contexts = #{contexts}" if ENV['DEBUG']
|
285
|
+
set_context(contexts.last)
|
286
|
+
puts "Current context = #{driver.current_context}" if ENV['DEBUG']
|
287
|
+
end
|
288
|
+
|
289
|
+
def self.is_biometric_enrolled?
|
290
|
+
if Environ.is_ios?
|
291
|
+
@driver.execute_script('mobile: isBiometricEnrolled')
|
292
|
+
else
|
293
|
+
puts 'biometric_enrollment is not supported for Android'
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
297
|
+
def self.set_biometric_enrollment(state)
|
298
|
+
if Environ.is_ios?
|
299
|
+
@driver.execute_script('mobile: enrollBiometric', { isEnabled: state })
|
300
|
+
else
|
301
|
+
puts 'biometric_enrollment is not supported for Android'
|
302
|
+
end
|
303
|
+
end
|
304
|
+
|
305
|
+
def self.biometric_match(type, match)
|
306
|
+
if Environ.is_ios?
|
307
|
+
@driver.execute_script('mobile: sendBiometricMatch', { type: type, match: match })
|
308
|
+
else
|
309
|
+
raise 'biometric_match is not supported for Android'
|
310
|
+
end
|
311
|
+
end
|
312
|
+
|
313
|
+
# :nocov:
|
314
|
+
def self.upload_app(service)
|
315
|
+
# determine app custom test id (if specified)
|
316
|
+
custom_id = if ENV['APP_ID']
|
317
|
+
ENV['APP_ID']
|
318
|
+
else
|
319
|
+
Environ.is_android? ? Environ.current.android_test_id : Environ.current.ios_test_id
|
320
|
+
end
|
321
|
+
# determine endpoint url, user id, and auth key for specified cloud service provider
|
322
|
+
case service
|
323
|
+
when :browserstack
|
324
|
+
url = 'https://api-cloud.browserstack.com/app-automate/upload'
|
325
|
+
user_id = ENV['BS_USERNAME']
|
326
|
+
auth_key = ENV['BS_AUTHKEY']
|
327
|
+
when :testingbot
|
328
|
+
url = 'https://api.testingbot.com/v1/storage'
|
329
|
+
url = "#{url}/#{custom_id}" unless custom_id.nil?
|
330
|
+
user_id = ENV['TB_USERNAME']
|
331
|
+
auth_key = ENV['TB_AUTHKEY']
|
332
|
+
else
|
333
|
+
raise "#{service} is not supported"
|
334
|
+
end
|
335
|
+
# determine file path of app to be uploaded to cloud service
|
336
|
+
file_path = if Environ.is_android?
|
337
|
+
Environ.current.android_apk_path
|
338
|
+
elsif Environ.is_ios?
|
339
|
+
Environ.is_device? ? Environ.current.ios_ipa_path : Environ.current.ios_app_path
|
340
|
+
end
|
341
|
+
|
342
|
+
request = Net::HTTP::Post.new(url)
|
343
|
+
boundary = "WebAppBoundary"
|
344
|
+
post_body = []
|
345
|
+
post_body << "--#{boundary}\r\n"
|
346
|
+
post_body << "Content-Disposition: form-data; name=\"file\"; filename=\"#{file_path}\"\r\n"
|
347
|
+
post_body << "\r\n"
|
348
|
+
post_body << File.open(file_path) {|io| io.read}
|
349
|
+
# add custom id form data to post body if a custom test id has been provided
|
350
|
+
if !custom_id.nil? && service == :browserstack
|
351
|
+
post_body << "\r\n--#{boundary}\r\n"
|
352
|
+
post_body << "Content-Disposition: form-data; name=\"custom_id\"\r\n"
|
353
|
+
post_body << "\r\n"
|
354
|
+
post_body << "#{custom_id}"
|
355
|
+
end
|
356
|
+
post_body << "\r\n--#{boundary}--\r\n"
|
357
|
+
request.body = post_body.join
|
358
|
+
request["Content-Type"] = "multipart/form-data; boundary=#{boundary}"
|
359
|
+
request.basic_auth(user_id, auth_key)
|
360
|
+
# send the request to upload to cloud service provider
|
361
|
+
uri = URI.parse(url)
|
362
|
+
conn = Net::HTTP.new(uri.host, uri.port)
|
363
|
+
if uri.scheme == 'https'
|
364
|
+
conn.use_ssl = true
|
365
|
+
conn.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
366
|
+
end
|
367
|
+
response = conn.request(request)
|
368
|
+
result = JSON.parse(response.body)
|
369
|
+
if response.code.to_i > 202
|
370
|
+
raise "An error has occurred while attempting to upload #{file_path} to the #{service} service\n#{result}"
|
371
|
+
else
|
372
|
+
puts "Successfully uploaded #{file_path} to the #{service} service\n#{result}"
|
373
|
+
end
|
374
|
+
end
|
375
|
+
# :nocov:
|
376
|
+
|
377
|
+
private
|
378
|
+
|
379
|
+
def self.get_app_id(bundle_id = nil)
|
380
|
+
return bundle_id unless bundle_id.nil?
|
381
|
+
|
382
|
+
if Environ.is_ios?
|
383
|
+
Environ.current.ios_bundle_id
|
384
|
+
elsif Environ.is_android?
|
385
|
+
Environ.current.android_app_id
|
386
|
+
else
|
387
|
+
nil
|
388
|
+
end
|
389
|
+
end
|
390
|
+
|
391
|
+
def self.appium_local_capabilities
|
392
|
+
# specify endpoint url
|
393
|
+
@endpoint = 'http://127.0.0.1:4723/wd/hub' if @endpoint.nil?
|
394
|
+
# define local Appium capabilities
|
395
|
+
if @capabilities.nil?
|
396
|
+
Environ.device_name = ENV['APP_DEVICE']
|
397
|
+
Environ.device_os = ENV['APP_PLATFORM_NAME']
|
398
|
+
Environ.device_os_version = ENV['APP_VERSION']
|
399
|
+
Environ.device = ENV['UDID'] ? :device : :simulator
|
400
|
+
|
401
|
+
caps = {
|
402
|
+
platformName: ENV['APP_PLATFORM_NAME'],
|
403
|
+
'appium:platformVersion': ENV['APP_VERSION'],
|
404
|
+
'appium:deviceName': ENV['APP_DEVICE'],
|
405
|
+
'appium:automationName': ENV['AUTOMATION_ENGINE']
|
406
|
+
}
|
407
|
+
caps[:'appium:avd'] = ENV['APP_DEVICE'] if ENV['APP_PLATFORM_NAME'].downcase.to_sym == :android
|
408
|
+
caps[:'appium:orientation'] = ENV['ORIENTATION'].upcase if ENV['ORIENTATION']
|
409
|
+
if ENV['LOCALE'] && ENV['LANGUAGE']
|
410
|
+
caps[:'appium:language'] = ENV['LANGUAGE']
|
411
|
+
caps[:'appium:locale'] = if Environ.is_android?
|
412
|
+
locale = ENV['LOCALE'].gsub('-', '_')
|
413
|
+
locale.split('_')[1]
|
414
|
+
else
|
415
|
+
ENV['LOCALE'].gsub('-', '_')
|
416
|
+
end
|
417
|
+
end
|
418
|
+
caps[:'appium:newCommandTimeout'] = ENV['NEW_COMMAND_TIMEOUT'] if ENV['NEW_COMMAND_TIMEOUT']
|
419
|
+
caps[:'appium:noReset'] = ENV['APP_NO_RESET'] if ENV['APP_NO_RESET']
|
420
|
+
caps[:'appium:fullReset'] = ENV['APP_FULL_RESET'] if ENV['APP_FULL_RESET']
|
421
|
+
caps[:'appium:autoLaunch'] = ENV['AUTO_LAUNCH'] if ENV['AUTO_LAUNCH']
|
422
|
+
caps[:'appium:webkitDebugProxyPort'] = ENV['WEBKIT_DEBUG_PROXY_PORT'] if ENV['WEBKIT_DEBUG_PROXY_PORT']
|
423
|
+
caps[:'appium:webDriverAgentUrl'] = ENV['WEBDRIVER_AGENT_URL'] if ENV['WEBDRIVER_AGENT_URL']
|
424
|
+
caps[:'appium:wdaLocalPort'] = ENV['WDA_LOCAL_PORT'] if ENV['WDA_LOCAL_PORT']
|
425
|
+
caps[:'appium:usePrebuiltWDA'] = ENV['USE_PREBUILT_WDA'] if ENV['USE_PREBUILT_WDA']
|
426
|
+
caps[:'appium:useNewWDA'] = ENV['USE_NEW_WDA'] if ENV['USE_NEW_WDA']
|
427
|
+
caps[:'appium:autoWebview'] = ENV['AUTO_WEBVIEW'] if ENV['AUTO_WEBVIEW']
|
428
|
+
caps[:'appium:chromedriverExecutable'] = ENV['CHROMEDRIVER_EXECUTABLE'] if ENV['CHROMEDRIVER_EXECUTABLE']
|
429
|
+
caps[:'appium:autoWebviewTimeout'] = ENV['AUTO_WEBVIEW_TIMEOUT'] if ENV['AUTO_WEBVIEW_TIMEOUT']
|
430
|
+
caps[:'appium:udid'] = ENV['UDID'] if ENV['UDID']
|
431
|
+
caps[:'appium:xcodeOrgId'] = ENV['TEAM_ID'] if ENV['TEAM_ID']
|
432
|
+
caps[:'appium:xcodeSigningId'] = ENV['TEAM_NAME'] if ENV['TEAM_NAME']
|
433
|
+
caps[:'appium:appActivity'] = ENV['APP_ACTIVITY'] if ENV['APP_ACTIVITY']
|
434
|
+
caps[:'appium:appPackage'] = ENV['APP_PACKAGE'] if ENV['APP_PACKAGE']
|
435
|
+
caps[:'appium:forceSimulatorSoftwareKeyboardPresence'] = ENV['SHOW_SIM_KEYBOARD'] if ENV['SHOW_SIM_KEYBOARD']
|
436
|
+
caps[:'appium:webviewConnectTimeout'] = '90000'
|
437
|
+
|
438
|
+
if ENV['BUNDLE_ID']
|
439
|
+
caps[:'appium:bundleId'] = ENV['BUNDLE_ID']
|
440
|
+
else
|
441
|
+
app_id = get_app_id
|
442
|
+
caps[:'appium:bundleId'] = app_id unless app_id.nil?
|
443
|
+
end
|
444
|
+
|
445
|
+
caps[:'appium:app'] = if ENV['APP']
|
446
|
+
ENV['APP']
|
447
|
+
else
|
448
|
+
if Environ.is_android?
|
449
|
+
Environ.current.android_apk_path
|
450
|
+
elsif Environ.is_ios?
|
451
|
+
Environ.is_device? ?
|
452
|
+
Environ.current.ios_ipa_path :
|
453
|
+
Environ.current.ios_app_path
|
454
|
+
end
|
455
|
+
end
|
456
|
+
caps
|
457
|
+
else
|
458
|
+
Environ.device_os = @capabilities[:platformName]
|
459
|
+
Environ.device_name = @capabilities[:'appium:deviceName']
|
460
|
+
Environ.device_os_version = @capabilities[:'appium:platformVersion']
|
461
|
+
Environ.device_orientation = @capabilities[:'appium:orientation']
|
462
|
+
Environ.device = if @capabilities[:'appium:udid']
|
463
|
+
:device
|
464
|
+
else
|
465
|
+
:simulator
|
466
|
+
end
|
467
|
+
@capabilities
|
468
|
+
end
|
469
|
+
end
|
470
|
+
|
471
|
+
def self.custom_capabilities
|
472
|
+
raise 'User-defined cloud driver requires that you provide capabilities' if @capabilities.nil?
|
473
|
+
raise 'User-defined cloud driver requires that you provide an endpoint' if @endpoint.nil?
|
474
|
+
|
475
|
+
Environ.device_os = @capabilities[:platformName]
|
476
|
+
Environ.device_name = @capabilities[:'appium:deviceName']
|
477
|
+
Environ.device_os_version = @capabilities[:'appium:platformVersion']
|
478
|
+
@capabilities
|
479
|
+
end
|
480
|
+
|
481
|
+
def self.browserstack_capabilities
|
482
|
+
# specify endpoint url
|
483
|
+
@endpoint = "https://#{ENV['BS_USERNAME']}:#{ENV['BS_AUTHKEY']}@hub-cloud.browserstack.com/wd/hub" if @endpoint.nil?
|
484
|
+
# define BrowserStack options
|
485
|
+
options = if @capabilities.nil?
|
486
|
+
Environ.device_name = ENV['BS_DEVICE']
|
487
|
+
Environ.device_os = ENV['BS_OS']
|
488
|
+
Environ.device_os_version = ENV['BS_OS_VERSION']
|
489
|
+
# define the required set of BrowserStack options
|
490
|
+
bs_options = {
|
491
|
+
userName: ENV['BS_USERNAME'],
|
492
|
+
accessKey: ENV['BS_AUTHKEY'],
|
493
|
+
sessionName: test_context_message
|
494
|
+
}
|
495
|
+
# define the optional BrowserStack options
|
496
|
+
bs_options[:projectName] = ENV['AUTOMATE_PROJECT'] if ENV['AUTOMATE_PROJECT']
|
497
|
+
bs_options[:buildName] = ENV['AUTOMATE_BUILD'] if ENV['AUTOMATE_BUILD']
|
498
|
+
bs_options[:geoLocation] = ENV['IP_GEOLOCATION'] if ENV['IP_GEOLOCATION']
|
499
|
+
bs_options[:timezone] = ENV['TIME_ZONE'] if ENV['TIME_ZONE']
|
500
|
+
bs_options[:video] = ENV['RECORD_VIDEO'] if ENV['RECORD_VIDEO']
|
501
|
+
bs_options[:debug] = ENV['SCREENSHOTS'] if ENV['SCREENSHOTS']
|
502
|
+
bs_options[:local] = ENV['TUNNELING'] if ENV['TUNNELING']
|
503
|
+
bs_options[:deviceOrientation] = ENV['ORIENTATION'] if ENV['ORIENTATION']
|
504
|
+
bs_options[:appiumLogs] = ENV['APPIUM_LOGS'] if ENV['APPIUM_LOGS']
|
505
|
+
bs_options[:networkLogs] = ENV['NETWORK_LOGS'] if ENV['NETWORK_LOGS']
|
506
|
+
bs_options[:deviceLogs] = ENV['DEVICE_LOGS'] if ENV['DEVICE_LOGS']
|
507
|
+
bs_options[:networkProfile] = ENV['NETWORK_PROFILE'] if ENV['NETWORK_PROFILE']
|
508
|
+
bs_options[:idleTimeout] = ENV['IDLE_TIMEOUT'] if ENV['IDLE_TIMEOUT']
|
509
|
+
bs_options[:resignApp] = ENV['RESIGN_APP'] if ENV['RESIGN_APP']
|
510
|
+
bs_options[:gpsLocation] = ENV['GPS_LOCATION'] if ENV['GPS_LOCATION']
|
511
|
+
bs_options[:acceptInsecureCerts] = ENV['ACCEPT_INSECURE_CERTS'] if ENV['ACCEPT_INSECURE_CERTS']
|
512
|
+
bs_options[:disableAnimations] = ENV['DISABLE_ANIMATION'] if ENV['DISABLE_ANIMATION']
|
513
|
+
bs_options[:appiumVersion] = ENV['APPIUM_VERSION'] ? ENV['APPIUM_VERSION'] : '2.4.1'
|
514
|
+
|
515
|
+
capabilities = {
|
516
|
+
platformName: ENV['BS_OS'],
|
517
|
+
'appium:platformVersion': ENV['BS_OS_VERSION'],
|
518
|
+
'appium:deviceName': ENV['BS_DEVICE'],
|
519
|
+
'appium:automationName': ENV['AUTOMATION_ENGINE'],
|
520
|
+
'appium:app': ENV['APP'],
|
521
|
+
'bstack:options': bs_options
|
522
|
+
}
|
523
|
+
capabilities[:language] = ENV['LANGUAGE'] if ENV['LANGUAGE']
|
524
|
+
capabilities[:locale] = ENV['LOCALE'] if ENV['LOCALE']
|
525
|
+
capabilities
|
526
|
+
else
|
527
|
+
Environ.device_os = @capabilities[:platformName]
|
528
|
+
Environ.device_name = @capabilities[:'appium:deviceName']
|
529
|
+
Environ.device_os_version = @capabilities[:'appium:platformVersion']
|
530
|
+
@capabilities
|
531
|
+
end
|
532
|
+
# BrowserStack uses only real devices
|
533
|
+
Environ.device = :device
|
534
|
+
upload_app(:browserstack) if ENV['UPLOAD_APP']
|
535
|
+
options
|
536
|
+
end
|
537
|
+
|
538
|
+
# :nocov:
|
539
|
+
def self.testingbot_capabilities
|
540
|
+
Environ.device = :simulator
|
541
|
+
# specify endpoint url
|
542
|
+
@endpoint = "http://#{ENV['TB_USERNAME']}:#{ENV['TB_AUTHKEY']}@hub.testingbot.com/wd/hub" if @endpoint.nil?
|
543
|
+
# define TestingBot options
|
544
|
+
options = if @capabilities.nil?
|
545
|
+
Environ.device_name = ENV['TB_DEVICE']
|
546
|
+
Environ.device_os = ENV['TB_OS']
|
547
|
+
Environ.device_os_version = ENV['TB_OS_VERSION']
|
548
|
+
Environ.device = :device if ENV['REAL_DEVICE'] == 'true'
|
549
|
+
# define the required set of TestingBot options
|
550
|
+
tb_options = { build: test_context_message }
|
551
|
+
# define the optional TestingBot options
|
552
|
+
tb_options[:name] = ENV['AUTOMATE_PROJECT'] if ENV['AUTOMATE_PROJECT']
|
553
|
+
tb_options[:timeZone] = ENV['TIME_ZONE'] if ENV['TIME_ZONE']
|
554
|
+
tb_options['testingbot.geoCountryCode'] = ENV['IP_GEOLOCATION'] if ENV['IP_GEOLOCATION']
|
555
|
+
tb_options[:screenrecorder] = ENV['RECORD_VIDEO'] if ENV['RECORD_VIDEO']
|
556
|
+
tb_options[:screenshot] = ENV['SCREENSHOTS'] if ENV['SCREENSHOTS']
|
557
|
+
tb_options[:appiumVersion] = ENV['APPIUM_VERSION'] ? ENV['APPIUM_VERSION'] : '2.4.1'
|
558
|
+
|
559
|
+
capabilities = {
|
560
|
+
platformName: ENV['TB_OS'],
|
561
|
+
'appium:platformVersion': ENV['TB_OS_VERSION'],
|
562
|
+
'appium:deviceName': ENV['TB_DEVICE'],
|
563
|
+
'appium:automationName': ENV['AUTOMATION_ENGINE'],
|
564
|
+
'appium:app': ENV['APP'],
|
565
|
+
'tb:options': tb_options
|
566
|
+
}
|
567
|
+
capabilities[:'appium:realDevice'] = ENV['REAL_DEVICE'] if ENV['REAL_DEVICE']
|
568
|
+
capabilities
|
569
|
+
else
|
570
|
+
Environ.device_os = @capabilities[:platformName]
|
571
|
+
Environ.device_name = @capabilities[:'appium:deviceName']
|
572
|
+
Environ.device_os_version = @capabilities[:'appium:platformVersion']
|
573
|
+
if @capabilities.key?(:'appium:realDevice') && @capabilities[:'appium:realDevice'] == true
|
574
|
+
Environ.device = :device
|
575
|
+
end
|
576
|
+
@capabilities
|
577
|
+
end
|
578
|
+
|
579
|
+
upload_app(:testingbot) if ENV['UPLOAD_APP']
|
580
|
+
options
|
581
|
+
end
|
582
|
+
|
583
|
+
def self.sauce_capabilities
|
584
|
+
# specify endpoint url
|
585
|
+
if @endpoint.nil?
|
586
|
+
@endpoint = "https://#{ENV['SL_USERNAME']}:#{ENV['SL_AUTHKEY']}@ondemand.#{ENV['SL_DATA_CENTER']}.saucelabs.com:443/wd/hub"
|
587
|
+
end
|
588
|
+
# define SauceLabs options
|
589
|
+
options = if @capabilities.nil?
|
590
|
+
Environ.device_name = ENV['SL_DEVICE']
|
591
|
+
Environ.device_os = ENV['SL_OS']
|
592
|
+
Environ.device_os_version = ENV['SL_OS_VERSION']
|
593
|
+
# define the required set of SauceLabs options
|
594
|
+
sl_options = { build: test_context_message }
|
595
|
+
# define the optional SauceLabs options
|
596
|
+
sl_options[:name] = ENV['AUTOMATE_PROJECT'] if ENV['AUTOMATE_PROJECT']
|
597
|
+
sl_options[:deviceOrientation] = ENV['ORIENTATION'].upcase if ENV['ORIENTATION']
|
598
|
+
sl_options[:recordVideo] = ENV['RECORD_VIDEO'] if ENV['RECORD_VIDEO']
|
599
|
+
sl_options[:recordScreenshots] = ENV['SCREENSHOTS'] if ENV['SCREENSHOTS']
|
600
|
+
sl_options[:appiumVersion] = ENV['APPIUM_VERSION'] ? ENV['APPIUM_VERSION'] : '2.1.3'
|
601
|
+
capabilities = {
|
602
|
+
platformName: ENV['SL_OS'],
|
603
|
+
'appium:platformVersion': ENV['SL_OS_VERSION'],
|
604
|
+
'appium:deviceName': ENV['SL_DEVICE'],
|
605
|
+
'appium:automationName': ENV['AUTOMATION_ENGINE'],
|
606
|
+
'appium:app': ENV['APP'],
|
607
|
+
'sauce:options': sl_options
|
608
|
+
}
|
609
|
+
capabilities
|
610
|
+
else
|
611
|
+
Environ.device_os = @capabilities[:platformName]
|
612
|
+
Environ.device_name = @capabilities[:'appium:deviceName']
|
613
|
+
Environ.device_os_version = @capabilities[:'appium:platformVersion']
|
614
|
+
@capabilities
|
615
|
+
end
|
616
|
+
options
|
617
|
+
end
|
618
|
+
|
619
|
+
def self.test_context_message
|
620
|
+
context_message = if ENV['TEST_CONTEXT']
|
621
|
+
"#{Environ.test_environment.to_s.upcase} - #{ENV['TEST_CONTEXT']}"
|
622
|
+
else
|
623
|
+
Environ.test_environment.to_s.upcase
|
624
|
+
end
|
625
|
+
if ENV['PARALLEL']
|
626
|
+
thread_num = ENV['TEST_ENV_NUMBER']
|
627
|
+
thread_num = 1 if thread_num.blank?
|
628
|
+
context_message = "#{context_message} - Thread ##{thread_num}"
|
629
|
+
end
|
630
|
+
context_message
|
631
|
+
end
|
632
|
+
# :nocov:
|
633
|
+
end
|
634
|
+
end
|