testcentricity_apps 4.0.15 → 4.1.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 +4 -4
- data/CHANGELOG.md +15 -14
- data/LICENSE.md +1 -1
- data/README.md +374 -248
- data/lib/testcentricity_apps/app_core/appium_connect_helper.rb +58 -70
- data/lib/testcentricity_apps/app_core/screen_object.rb +58 -12
- data/lib/testcentricity_apps/app_core/screen_objects_helper.rb +29 -15
- data/lib/testcentricity_apps/app_core/screen_section.rb +63 -20
- data/lib/testcentricity_apps/app_elements/alert.rb +8 -8
- data/lib/testcentricity_apps/app_elements/app_element.rb +39 -9
- data/lib/testcentricity_apps/app_elements/list.rb +4 -4
- data/lib/testcentricity_apps/app_elements/menu.rb +2 -2
- data/lib/testcentricity_apps/app_elements/menubar.rb +0 -22
- data/lib/testcentricity_apps/app_elements/selectlist.rb +5 -5
- data/lib/testcentricity_apps/app_elements/switch.rb +1 -1
- data/lib/testcentricity_apps/app_elements/table.rb +397 -0
- data/lib/testcentricity_apps/data_objects/data_objects_helper.rb +3 -7
- data/lib/testcentricity_apps/data_objects/environment.rb +2 -54
- data/lib/testcentricity_apps/exception_queue_helper.rb +9 -10
- data/lib/testcentricity_apps/utility_helpers.rb +1 -0
- data/lib/testcentricity_apps/version.rb +1 -1
- data/lib/testcentricity_apps.rb +1 -0
- metadata +23 -22
|
@@ -7,11 +7,7 @@ require 'uri'
|
|
|
7
7
|
|
|
8
8
|
module TestCentricity
|
|
9
9
|
module AppiumConnect
|
|
10
|
-
attr_accessor :driver
|
|
11
|
-
attr_accessor :running
|
|
12
|
-
attr_accessor :endpoint
|
|
13
|
-
attr_accessor :capabilities
|
|
14
|
-
attr_accessor :global_scope
|
|
10
|
+
attr_accessor :driver, :running, :endpoint, :capabilities, :global_scope
|
|
15
11
|
|
|
16
12
|
# Create a new driver instance with capabilities specified in the options parameter, or via Environment Variables.
|
|
17
13
|
# Refer to the `Connecting to a Mobile Simulator or Device` section of the ruby docs for this gem.
|
|
@@ -50,6 +46,7 @@ module TestCentricity
|
|
|
50
46
|
appium_local_capabilities
|
|
51
47
|
when :custom
|
|
52
48
|
raise 'User-defined cloud driver requires that you define options' if options.nil?
|
|
49
|
+
|
|
53
50
|
custom_capabilities
|
|
54
51
|
when :browserstack
|
|
55
52
|
browserstack_capabilities
|
|
@@ -75,9 +72,7 @@ module TestCentricity
|
|
|
75
72
|
Appium.promote_appium_methods(TestCentricity::AppElements::AppUIElement, driver = @driver)
|
|
76
73
|
|
|
77
74
|
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
|
|
75
|
+
Environ.driver_name = "#{Environ.driver}_#{Environ.device_os}_#{Environ.device_type}".downcase.to_sym unless Environ.driver_name
|
|
81
76
|
Environ.session_state = :running
|
|
82
77
|
end
|
|
83
78
|
|
|
@@ -328,11 +323,9 @@ module TestCentricity
|
|
|
328
323
|
end
|
|
329
324
|
|
|
330
325
|
def self.biometric_match(type, match)
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
raise 'biometric_match is not supported for this platform'
|
|
335
|
-
end
|
|
326
|
+
raise 'biometric_match is not supported for this platform' unless Environ.is_ios?
|
|
327
|
+
|
|
328
|
+
@driver.execute_script('mobile: sendBiometricMatch', { type: type, match: match })
|
|
336
329
|
end
|
|
337
330
|
|
|
338
331
|
# :nocov:
|
|
@@ -365,7 +358,7 @@ module TestCentricity
|
|
|
365
358
|
end
|
|
366
359
|
|
|
367
360
|
request = Net::HTTP::Post.new(url)
|
|
368
|
-
boundary =
|
|
361
|
+
boundary = 'WebAppBoundary'
|
|
369
362
|
post_body = []
|
|
370
363
|
post_body << "--#{boundary}\r\n"
|
|
371
364
|
post_body << "Content-Disposition: form-data; name=\"file\"; filename=\"#{file_path}\"\r\n"
|
|
@@ -380,7 +373,7 @@ module TestCentricity
|
|
|
380
373
|
end
|
|
381
374
|
post_body << "\r\n--#{boundary}--\r\n"
|
|
382
375
|
request.body = post_body.join
|
|
383
|
-
request[
|
|
376
|
+
request['Content-Type'] = "multipart/form-data; boundary=#{boundary}"
|
|
384
377
|
request.basic_auth(user_id, auth_key)
|
|
385
378
|
# send the request to upload to cloud service provider
|
|
386
379
|
uri = URI.parse(url)
|
|
@@ -391,18 +384,17 @@ module TestCentricity
|
|
|
391
384
|
end
|
|
392
385
|
response = conn.request(request)
|
|
393
386
|
result = JSON.parse(response.body)
|
|
394
|
-
if response.code.to_i > 202
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
end
|
|
399
|
-
end
|
|
387
|
+
raise "An error has occurred while attempting to upload #{file_path} to the #{service} service\n#{result}" if response.code.to_i > 202
|
|
388
|
+
|
|
389
|
+
puts "Successfully uploaded #{file_path} to the #{service} service\n#{result}"
|
|
390
|
+
end
|
|
400
391
|
# :nocov:
|
|
401
392
|
|
|
402
393
|
private
|
|
403
394
|
|
|
404
395
|
def self.get_app_id(bundle_id = nil)
|
|
405
396
|
return bundle_id unless bundle_id.nil?
|
|
397
|
+
|
|
406
398
|
case
|
|
407
399
|
when Environ.is_ios?
|
|
408
400
|
Environ.current.ios_bundle_id
|
|
@@ -442,11 +434,11 @@ module TestCentricity
|
|
|
442
434
|
if ENV['LOCALE'] && ENV['LANGUAGE']
|
|
443
435
|
caps[:'appium:language'] = ENV['LANGUAGE']
|
|
444
436
|
caps[:'appium:locale'] = if Environ.is_android?
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
437
|
+
locale = ENV['LOCALE'].gsub('-', '_')
|
|
438
|
+
locale.split('_')[1]
|
|
439
|
+
else
|
|
440
|
+
ENV['LOCALE'].gsub('-', '_')
|
|
441
|
+
end
|
|
450
442
|
end
|
|
451
443
|
caps[:'appium:newCommandTimeout'] = ENV['NEW_COMMAND_TIMEOUT'] if ENV['NEW_COMMAND_TIMEOUT']
|
|
452
444
|
caps[:'appium:noReset'] = ENV['APP_NO_RESET'] if ENV['APP_NO_RESET']
|
|
@@ -480,16 +472,16 @@ module TestCentricity
|
|
|
480
472
|
end
|
|
481
473
|
|
|
482
474
|
caps[:'appium:app'] = if ENV['APP']
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
475
|
+
ENV['APP']
|
|
476
|
+
else
|
|
477
|
+
if Environ.is_android?
|
|
478
|
+
Environ.current.android_apk_path
|
|
479
|
+
elsif Environ.is_ios?
|
|
480
|
+
Environ.is_device? ?
|
|
481
|
+
Environ.current.ios_ipa_path :
|
|
482
|
+
Environ.current.ios_app_path
|
|
483
|
+
end
|
|
484
|
+
end
|
|
493
485
|
caps
|
|
494
486
|
else
|
|
495
487
|
Environ.device_os = @capabilities[:platformName]
|
|
@@ -543,7 +535,7 @@ module TestCentricity
|
|
|
543
535
|
bs_options[:gpsLocation] = ENV['GPS_LOCATION'] if ENV['GPS_LOCATION']
|
|
544
536
|
bs_options[:acceptInsecureCerts] = ENV['ACCEPT_INSECURE_CERTS'] if ENV['ACCEPT_INSECURE_CERTS']
|
|
545
537
|
bs_options[:disableAnimations] = ENV['DISABLE_ANIMATION'] if ENV['DISABLE_ANIMATION']
|
|
546
|
-
bs_options[:appiumVersion] = ENV['APPIUM_VERSION'] ? ENV['APPIUM_VERSION'] : '2.
|
|
538
|
+
bs_options[:appiumVersion] = ENV['APPIUM_VERSION'] ? ENV['APPIUM_VERSION'] : '2.19.0'
|
|
547
539
|
|
|
548
540
|
capabilities = {
|
|
549
541
|
platformName: ENV['BS_OS'],
|
|
@@ -568,7 +560,6 @@ module TestCentricity
|
|
|
568
560
|
options
|
|
569
561
|
end
|
|
570
562
|
|
|
571
|
-
# :nocov:
|
|
572
563
|
def self.testingbot_capabilities
|
|
573
564
|
Environ.device = :simulator
|
|
574
565
|
# specify endpoint url
|
|
@@ -587,7 +578,7 @@ module TestCentricity
|
|
|
587
578
|
tb_options['testingbot.geoCountryCode'] = ENV['IP_GEOLOCATION'] if ENV['IP_GEOLOCATION']
|
|
588
579
|
tb_options[:screenrecorder] = ENV['RECORD_VIDEO'] if ENV['RECORD_VIDEO']
|
|
589
580
|
tb_options[:screenshot] = ENV['SCREENSHOTS'] if ENV['SCREENSHOTS']
|
|
590
|
-
tb_options[:appiumVersion] = ENV['APPIUM_VERSION'] ? ENV['APPIUM_VERSION'] : '
|
|
581
|
+
tb_options[:appiumVersion] = ENV['APPIUM_VERSION'] ? ENV['APPIUM_VERSION'] : 'latest'
|
|
591
582
|
|
|
592
583
|
capabilities = {
|
|
593
584
|
platformName: ENV['TB_OS'],
|
|
@@ -613,40 +604,37 @@ module TestCentricity
|
|
|
613
604
|
options
|
|
614
605
|
end
|
|
615
606
|
|
|
607
|
+
# :nocov:
|
|
616
608
|
def self.sauce_capabilities
|
|
617
609
|
# specify endpoint url
|
|
618
|
-
if @endpoint.nil?
|
|
619
|
-
@endpoint = "https://#{ENV['SL_USERNAME']}:#{ENV['SL_AUTHKEY']}@ondemand.#{ENV['SL_DATA_CENTER']}.saucelabs.com:443/wd/hub"
|
|
620
|
-
end
|
|
610
|
+
@endpoint = "https://#{ENV['SL_USERNAME']}:#{ENV['SL_AUTHKEY']}@ondemand.#{ENV['SL_DATA_CENTER']}.saucelabs.com:443/wd/hub" if @endpoint.nil?
|
|
621
611
|
# define SauceLabs options
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
end
|
|
649
|
-
options
|
|
612
|
+
if @capabilities.nil?
|
|
613
|
+
Environ.device_name = ENV['SL_DEVICE']
|
|
614
|
+
Environ.device_os = ENV['SL_OS']
|
|
615
|
+
Environ.device_os_version = ENV['SL_OS_VERSION']
|
|
616
|
+
# define the required set of SauceLabs options
|
|
617
|
+
sl_options = { build: test_context_message }
|
|
618
|
+
# define the optional SauceLabs options
|
|
619
|
+
sl_options[:name] = ENV['AUTOMATE_PROJECT'] if ENV['AUTOMATE_PROJECT']
|
|
620
|
+
sl_options[:deviceOrientation] = ENV['ORIENTATION'].upcase if ENV['ORIENTATION']
|
|
621
|
+
sl_options[:recordVideo] = ENV['RECORD_VIDEO'] if ENV['RECORD_VIDEO']
|
|
622
|
+
sl_options[:recordScreenshots] = ENV['SCREENSHOTS'] if ENV['SCREENSHOTS']
|
|
623
|
+
sl_options[:appiumVersion] = ENV['APPIUM_VERSION'] ? ENV['APPIUM_VERSION'] : '2.1.3'
|
|
624
|
+
{
|
|
625
|
+
platformName: ENV['SL_OS'],
|
|
626
|
+
'appium:platformVersion': ENV['SL_OS_VERSION'],
|
|
627
|
+
'appium:deviceName': ENV['SL_DEVICE'],
|
|
628
|
+
'appium:automationName': ENV['AUTOMATION_ENGINE'],
|
|
629
|
+
'appium:app': ENV['APP'],
|
|
630
|
+
'sauce:options': sl_options
|
|
631
|
+
}
|
|
632
|
+
else
|
|
633
|
+
Environ.device_os = @capabilities[:platformName]
|
|
634
|
+
Environ.device_name = @capabilities[:'appium:deviceName']
|
|
635
|
+
Environ.device_os_version = @capabilities[:'appium:platformVersion']
|
|
636
|
+
@capabilities
|
|
637
|
+
end
|
|
650
638
|
end
|
|
651
639
|
|
|
652
640
|
def self.test_context_message
|
|
@@ -8,6 +8,7 @@ module TestCentricity
|
|
|
8
8
|
|
|
9
9
|
def initialize
|
|
10
10
|
raise "Screen object #{self.class.name} does not have a screen_name trait defined" unless defined?(screen_name)
|
|
11
|
+
|
|
11
12
|
@locator = screen_locator if defined?(screen_locator)
|
|
12
13
|
end
|
|
13
14
|
|
|
@@ -236,6 +237,30 @@ module TestCentricity
|
|
|
236
237
|
end
|
|
237
238
|
end
|
|
238
239
|
|
|
240
|
+
# Declare and instantiate a single table UI Element for this screen object.
|
|
241
|
+
#
|
|
242
|
+
# @param element_name [Symbol] name of table object (as a symbol)
|
|
243
|
+
# @param locator [Hash] { locator_strategy: locator_identifier }
|
|
244
|
+
# @example
|
|
245
|
+
# table :sidebar_table, { predicate: 'identifier == "library.sidebar"' }
|
|
246
|
+
#
|
|
247
|
+
def self.table(element_name, locator)
|
|
248
|
+
define_screen_element(element_name, TestCentricity::AppElements::AppTable, locator)
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
# Declare and instantiate a collection of tables for this screen object.
|
|
252
|
+
#
|
|
253
|
+
# @param element_hash [Hash] names of tables (as symbol) and locator Hash
|
|
254
|
+
# @example
|
|
255
|
+
# tables sidebar_table: { predicate: 'identifier == "library.sidebar"' },
|
|
256
|
+
# view_table: { predicate: 'identifier == "view.library.table"' }
|
|
257
|
+
#
|
|
258
|
+
def self.tables(element_hash)
|
|
259
|
+
element_hash.each do |element_name, locator|
|
|
260
|
+
table(element_name, locator)
|
|
261
|
+
end
|
|
262
|
+
end
|
|
263
|
+
|
|
239
264
|
# Declare and instantiate a single image UI Element for this screen object.
|
|
240
265
|
#
|
|
241
266
|
# @param element_name [Symbol] name of image object (as a symbol)
|
|
@@ -285,6 +310,30 @@ module TestCentricity
|
|
|
285
310
|
end
|
|
286
311
|
end
|
|
287
312
|
|
|
313
|
+
# Declare and instantiate a single menu UI Element for this screen object.
|
|
314
|
+
#
|
|
315
|
+
# @param element_name [Symbol] name of menu object (as a symbol)
|
|
316
|
+
# @param locator [Hash] { locator_strategy: locator_identifier }
|
|
317
|
+
# @example
|
|
318
|
+
# menu :convert_menu, { xpath: '//XCUIElementTypeMenuBarItem[6]' }
|
|
319
|
+
#
|
|
320
|
+
def self.menu(element_name, locator)
|
|
321
|
+
define_screen_element(element_name, TestCentricity::AppElements::AppMenu, locator)
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
# Declare and instantiate a collection of menus for this screen object.
|
|
325
|
+
#
|
|
326
|
+
# @param element_hash [Hash] names of menus (as symbol) and locator Hash
|
|
327
|
+
# @example
|
|
328
|
+
# menus convert_menu: { xpath: '//XCUIElementTypeMenuBarItem[6]' },
|
|
329
|
+
# view_menu: { xpath: '//XCUIElementTypeMenuBarItem[5]' }
|
|
330
|
+
#
|
|
331
|
+
def self.menus(element_hash)
|
|
332
|
+
element_hash.each do |element_name, locator|
|
|
333
|
+
menu(element_name, locator)
|
|
334
|
+
end
|
|
335
|
+
end
|
|
336
|
+
|
|
288
337
|
# Declare and instantiate a single MenuBar object for this screen object.
|
|
289
338
|
#
|
|
290
339
|
# @param element_name [Symbol] name of MenuBar object (as a symbol)
|
|
@@ -327,7 +376,7 @@ module TestCentricity
|
|
|
327
376
|
# home_screen.exists?
|
|
328
377
|
#
|
|
329
378
|
def exists?
|
|
330
|
-
@locator.is_a?(Array) ?
|
|
379
|
+
tries ||= @locator.is_a?(Array) ? 2 : 1
|
|
331
380
|
if @locator.is_a?(Array)
|
|
332
381
|
loc = @locator[tries - 1]
|
|
333
382
|
find_element(loc.keys[0], loc.values[0])
|
|
@@ -336,7 +385,7 @@ module TestCentricity
|
|
|
336
385
|
end
|
|
337
386
|
true
|
|
338
387
|
rescue
|
|
339
|
-
retry if (tries -= 1)
|
|
388
|
+
retry if (tries -= 1).positive?
|
|
340
389
|
false
|
|
341
390
|
end
|
|
342
391
|
|
|
@@ -347,19 +396,15 @@ module TestCentricity
|
|
|
347
396
|
# calculator_screen.title
|
|
348
397
|
#
|
|
349
398
|
def title
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
raise 'title is not a supported attribute'
|
|
354
|
-
end
|
|
399
|
+
raise 'title is not a supported attribute' unless Environ.is_macos?
|
|
400
|
+
|
|
401
|
+
find_element(@locator.keys[0], @locator.values[0]).title
|
|
355
402
|
end
|
|
356
403
|
|
|
357
404
|
def identifier
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
raise 'identifier is not a supported attribute'
|
|
362
|
-
end
|
|
405
|
+
raise 'identifier is not a supported attribute' unless Environ.is_macos?
|
|
406
|
+
|
|
407
|
+
find_element(@locator.keys[0], @locator.values[0]).identifier
|
|
363
408
|
end
|
|
364
409
|
|
|
365
410
|
# Wait until the Screen object exists, or until the specified wait time has expired. If the wait time is nil, then
|
|
@@ -477,6 +522,7 @@ module TestCentricity
|
|
|
477
522
|
ivar_name = "@#{element_name}"
|
|
478
523
|
ivar = instance_variable_get(ivar_name)
|
|
479
524
|
return ivar if ivar
|
|
525
|
+
|
|
480
526
|
instance_variable_set(ivar_name, obj.new(element_name, self, locator, :screen))
|
|
481
527
|
end
|
|
482
528
|
end
|
|
@@ -47,24 +47,25 @@ module TestCentricity
|
|
|
47
47
|
# security_code_field => UserData.current.cvv
|
|
48
48
|
# }
|
|
49
49
|
# populate_data_fields(fields)
|
|
50
|
+
#
|
|
50
51
|
def populate_data_fields(data, wait_time = nil)
|
|
51
52
|
timeout = wait_time.nil? ? 2 : wait_time
|
|
52
53
|
data.each do |data_field, data_param|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
54
|
+
next if data_param.blank?
|
|
55
|
+
|
|
56
|
+
# make sure the intended UI target element is visible before trying to set its value
|
|
57
|
+
data_field.scroll_into_view unless data_field.wait_until_visible(timeout, post_exception = false)
|
|
58
|
+
if data_param == '!DELETE'
|
|
59
|
+
data_field.clear
|
|
60
|
+
else
|
|
61
|
+
case data_field.get_object_type
|
|
62
|
+
when :checkbox
|
|
63
|
+
data_field.set_checkbox_state(data_param.to_bool)
|
|
64
|
+
when :radio
|
|
65
|
+
data_field.set_selected_state(data_param.to_bool)
|
|
66
|
+
when :textfield
|
|
57
67
|
data_field.clear
|
|
58
|
-
|
|
59
|
-
case data_field.get_object_type
|
|
60
|
-
when :checkbox
|
|
61
|
-
data_field.set_checkbox_state(data_param.to_bool)
|
|
62
|
-
when :radio
|
|
63
|
-
data_field.set_selected_state(data_param.to_bool)
|
|
64
|
-
when :textfield
|
|
65
|
-
data_field.clear
|
|
66
|
-
data_field.set(data_param)
|
|
67
|
-
end
|
|
68
|
+
data_field.set(data_param)
|
|
68
69
|
end
|
|
69
70
|
end
|
|
70
71
|
end
|
|
@@ -111,6 +112,12 @@ module TestCentricity
|
|
|
111
112
|
ui_object.read_only?
|
|
112
113
|
when :maxlength
|
|
113
114
|
ui_object.get_max_length
|
|
115
|
+
when :rowcount
|
|
116
|
+
ui_object.get_row_count
|
|
117
|
+
when :columncount
|
|
118
|
+
ui_object.get_column_count
|
|
119
|
+
when :column_headers
|
|
120
|
+
ui_object.get_header_columns
|
|
114
121
|
when :items
|
|
115
122
|
ui_object.get_list_items
|
|
116
123
|
when :itemcount
|
|
@@ -143,6 +150,12 @@ module TestCentricity
|
|
|
143
150
|
ui_object.get_item_enabled(value.to_i)
|
|
144
151
|
when :item_data
|
|
145
152
|
ui_object.get_item_data(value.to_i)
|
|
153
|
+
when :row
|
|
154
|
+
ui_object.get_table_row(value.to_i)
|
|
155
|
+
when :column
|
|
156
|
+
ui_object.get_table_column(value.to_i)
|
|
157
|
+
when :cell
|
|
158
|
+
ui_object.get_table_cell(value[0].to_i, value[1].to_i)
|
|
146
159
|
else
|
|
147
160
|
raise "#{key} is not a valid property key"
|
|
148
161
|
end
|
|
@@ -176,7 +189,8 @@ module TestCentricity
|
|
|
176
189
|
# swipe_gesture(direction = :down, distance = 1)
|
|
177
190
|
#
|
|
178
191
|
def swipe_gesture(direction, distance = 0.5)
|
|
179
|
-
raise 'Scroll distance must be between 0 and 1' if
|
|
192
|
+
raise 'Scroll distance must be between 0 and 1' if distance.negative? || distance > 1
|
|
193
|
+
|
|
180
194
|
size = window_size
|
|
181
195
|
mid_pt = [(size.width * 0.5).to_i, (size.height * 0.5).to_i]
|
|
182
196
|
top = (mid_pt[1] - ((size.height * distance) * 0.5)).to_i
|
|
@@ -5,10 +5,7 @@ module TestCentricity
|
|
|
5
5
|
include Test::Unit::Assertions
|
|
6
6
|
|
|
7
7
|
attr_reader :context, :name
|
|
8
|
-
attr_accessor :locator
|
|
9
|
-
attr_accessor :parent
|
|
10
|
-
attr_accessor :parent_list
|
|
11
|
-
attr_accessor :list_index
|
|
8
|
+
attr_accessor :locator, :parent, :parent_list, :list_index
|
|
12
9
|
|
|
13
10
|
def initialize(name, parent, locator, context)
|
|
14
11
|
@name = name
|
|
@@ -58,6 +55,7 @@ module TestCentricity
|
|
|
58
55
|
|
|
59
56
|
def get_item_count
|
|
60
57
|
raise 'No parent list defined' if @parent_list.nil?
|
|
58
|
+
|
|
61
59
|
@parent_list.get_item_count
|
|
62
60
|
end
|
|
63
61
|
|
|
@@ -294,6 +292,28 @@ module TestCentricity
|
|
|
294
292
|
element_hash.each_pair { |element_name, locator| selectlist(element_name, locator) }
|
|
295
293
|
end
|
|
296
294
|
|
|
295
|
+
# Declare and instantiate a single table UI Element for this screen section object.
|
|
296
|
+
#
|
|
297
|
+
# @param element_name [Symbol] name of table object (as a symbol)
|
|
298
|
+
# @param locator [Hash] { locator_strategy: locator_identifier }
|
|
299
|
+
# @example
|
|
300
|
+
# table :sidebar_table, { predicate: 'identifier == "library.sidebar"' }
|
|
301
|
+
#
|
|
302
|
+
def self.table(element_name, locator)
|
|
303
|
+
define_section_element(element_name, TestCentricity::AppElements::AppTable, locator)
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
# Declare and instantiate a collection of tables for this screen section object.
|
|
307
|
+
#
|
|
308
|
+
# @param element_hash [Hash] names of tables (as symbol) and locator Hash
|
|
309
|
+
# @example
|
|
310
|
+
# tables sidebar_table: { predicate: 'identifier == "library.sidebar"' },
|
|
311
|
+
# view_table: { predicate: 'identifier == "view.library.table"' }
|
|
312
|
+
#
|
|
313
|
+
def self.tables(element_hash)
|
|
314
|
+
element_hash.each_pair { |element_name, locator| table(element_name, locator) }
|
|
315
|
+
end
|
|
316
|
+
|
|
297
317
|
# Declare and instantiate a single image UI Element for this screen section object.
|
|
298
318
|
#
|
|
299
319
|
# @param element_name [Symbol] name of image object (as a symbol)
|
|
@@ -316,6 +336,28 @@ module TestCentricity
|
|
|
316
336
|
element_hash.each_pair { |element_name, locator| image(element_name, locator) }
|
|
317
337
|
end
|
|
318
338
|
|
|
339
|
+
# Declare and instantiate a single menu UI Element for this ScreenSection object.
|
|
340
|
+
#
|
|
341
|
+
# @param element_name [Symbol] name of menu object (as a symbol)
|
|
342
|
+
# @param locator [Hash] { locator_strategy: locator_identifier }
|
|
343
|
+
# @example
|
|
344
|
+
# menu :convert_menu, { xpath: '//XCUIElementTypeMenuBarItem[6]' }
|
|
345
|
+
#
|
|
346
|
+
def self.menu(element_name, locator)
|
|
347
|
+
define_section_element(element_name, TestCentricity::AppElements::AppMenu, locator)
|
|
348
|
+
end
|
|
349
|
+
|
|
350
|
+
# Declare and instantiate a collection of menus for this ScreenSection object.
|
|
351
|
+
#
|
|
352
|
+
# @param element_hash [Hash] names of menus (as symbol) and locator Hash
|
|
353
|
+
# @example
|
|
354
|
+
# menus convert_menu: { xpath: '//XCUIElementTypeMenuBarItem[6]' },
|
|
355
|
+
# view_menu: { xpath: '//XCUIElementTypeMenuBarItem[5]' }
|
|
356
|
+
#
|
|
357
|
+
def self.menus(element_hash)
|
|
358
|
+
element_hash.each_pair { |element_name, locator| menu(element_name, locator) }
|
|
359
|
+
end
|
|
360
|
+
|
|
319
361
|
# Instantiate a single ScreenSection object within this ScreenSection object.
|
|
320
362
|
#
|
|
321
363
|
# @param section_name [Symbol] name of ScreenSection object (as a symbol)
|
|
@@ -405,6 +447,7 @@ module TestCentricity
|
|
|
405
447
|
#
|
|
406
448
|
def scroll_into_view(scroll_mode = :vertical)
|
|
407
449
|
return if visible?
|
|
450
|
+
|
|
408
451
|
obj = element
|
|
409
452
|
object_not_found_exception(obj)
|
|
410
453
|
driver.action.move_to(obj).perform
|
|
@@ -424,12 +467,12 @@ module TestCentricity
|
|
|
424
467
|
swipe_gesture(direction, distance = 0.2)
|
|
425
468
|
try_count -= 1
|
|
426
469
|
if try_count.zero?
|
|
427
|
-
if direction == end_direction
|
|
428
|
-
|
|
429
|
-
|
|
470
|
+
break if direction == end_direction
|
|
471
|
+
|
|
472
|
+
|
|
430
473
|
direction = end_direction
|
|
431
474
|
try_count = 8
|
|
432
|
-
|
|
475
|
+
|
|
433
476
|
end
|
|
434
477
|
end
|
|
435
478
|
end
|
|
@@ -476,6 +519,7 @@ module TestCentricity
|
|
|
476
519
|
def visible?
|
|
477
520
|
section = find_section
|
|
478
521
|
return false if section.nil?
|
|
522
|
+
|
|
479
523
|
section.displayed?
|
|
480
524
|
end
|
|
481
525
|
|
|
@@ -490,13 +534,11 @@ module TestCentricity
|
|
|
490
534
|
end
|
|
491
535
|
|
|
492
536
|
def identifier
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
raise 'identifier is not a supported attribute'
|
|
499
|
-
end
|
|
537
|
+
raise 'identifier is not a supported attribute' unless Environ.is_macos?
|
|
538
|
+
|
|
539
|
+
section = find_section
|
|
540
|
+
section_not_found_exception(section)
|
|
541
|
+
section.identifier
|
|
500
542
|
end
|
|
501
543
|
|
|
502
544
|
# Send keystrokes to this section object.
|
|
@@ -641,11 +683,11 @@ module TestCentricity
|
|
|
641
683
|
obj = nil
|
|
642
684
|
locators = get_locator
|
|
643
685
|
locators.each do |loc|
|
|
644
|
-
if obj.nil?
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
686
|
+
obj = if obj.nil?
|
|
687
|
+
find_element(loc.keys[0], loc.values[0])
|
|
688
|
+
else
|
|
689
|
+
obj.find_element(loc.keys[0], loc.values[0])
|
|
690
|
+
end
|
|
649
691
|
puts "Found section object #{loc}" if ENV['DEBUG']
|
|
650
692
|
end
|
|
651
693
|
obj
|
|
@@ -662,6 +704,7 @@ module TestCentricity
|
|
|
662
704
|
ivar_name = "@#{element_name}"
|
|
663
705
|
ivar = instance_variable_get(ivar_name)
|
|
664
706
|
return ivar if ivar
|
|
707
|
+
|
|
665
708
|
instance_variable_set(ivar_name, obj.new(element_name, self, locator, :section))
|
|
666
709
|
end
|
|
667
710
|
end
|
|
@@ -38,10 +38,10 @@ module TestCentricity
|
|
|
38
38
|
reset_mru_cache
|
|
39
39
|
alert_accept
|
|
40
40
|
wait_until_gone(seconds = 5, post_exception = false)
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
41
|
+
return unless visible?
|
|
42
|
+
|
|
43
|
+
alert_accept
|
|
44
|
+
wait_until_gone(5)
|
|
45
45
|
end
|
|
46
46
|
|
|
47
47
|
# Performs the action required dismiss the currently visible alert modal. If the alert modal is still visible after
|
|
@@ -54,10 +54,10 @@ module TestCentricity
|
|
|
54
54
|
reset_mru_cache
|
|
55
55
|
alert_dismiss
|
|
56
56
|
wait_until_gone(seconds = 5, post_exception = false)
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
57
|
+
return unless visible?
|
|
58
|
+
|
|
59
|
+
alert_dismiss
|
|
60
|
+
wait_until_gone(5)
|
|
61
61
|
end
|
|
62
62
|
|
|
63
63
|
#
|