testcentricity 3.0.4 → 3.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.
Files changed (87) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +29 -0
  3. data/README.md +48 -46
  4. data/lib/testcentricity/app_core/appium_connect_helper.rb +6 -8
  5. data/lib/testcentricity/app_core/screen_section.rb +0 -1
  6. data/lib/testcentricity/app_elements/app_element_helper.rb +14 -4
  7. data/lib/testcentricity/version.rb +1 -1
  8. metadata +13 -158
  9. data/.gitignore +0 -40
  10. data/.rspec +0 -4
  11. data/.rubocop.yml +0 -38
  12. data/.ruby-version +0 -1
  13. data/.simplecov +0 -9
  14. data/CODE_OF_CONDUCT.md +0 -13
  15. data/Gemfile +0 -6
  16. data/Rakefile +0 -63
  17. data/config/cucumber.yml +0 -146
  18. data/config/locales/en-US.yml +0 -56
  19. data/config/test_data/data.yml +0 -76
  20. data/features/deep_links.feature +0 -38
  21. data/features/login.feature +0 -30
  22. data/features/navigation.feature +0 -43
  23. data/features/step_definitions/generic_steps.rb +0 -67
  24. data/features/support/android/screens/about_screen.rb +0 -11
  25. data/features/support/android/screens/base_app_screen.rb +0 -31
  26. data/features/support/android/screens/biometrics_screen.rb +0 -17
  27. data/features/support/android/screens/checkout_address_screen.rb +0 -17
  28. data/features/support/android/screens/checkout_payment_screen.rb +0 -22
  29. data/features/support/android/screens/geo_location_screen.rb +0 -28
  30. data/features/support/android/screens/login_screen.rb +0 -18
  31. data/features/support/android/screens/product_item_screen.rb +0 -39
  32. data/features/support/android/screens/products_screen.rb +0 -27
  33. data/features/support/android/screens/qr_code_scanner_screen.rb +0 -15
  34. data/features/support/android/screens/saucebot_screen.rb +0 -16
  35. data/features/support/android/screens/webview_screen.rb +0 -13
  36. data/features/support/android/sections/list_items/product_list_item.rb +0 -13
  37. data/features/support/android/sections/nav_widgets/nav_menu.rb +0 -39
  38. data/features/support/data/product_data.rb +0 -27
  39. data/features/support/data/user_data.rb +0 -17
  40. data/features/support/env.rb +0 -62
  41. data/features/support/hooks.rb +0 -135
  42. data/features/support/ios/screens/about_screen.rb +0 -11
  43. data/features/support/ios/screens/base_app_screen.rb +0 -20
  44. data/features/support/ios/screens/biometrics_screen.rb +0 -17
  45. data/features/support/ios/screens/checkout_address_screen.rb +0 -17
  46. data/features/support/ios/screens/checkout_payment_screen.rb +0 -22
  47. data/features/support/ios/screens/geo_location_screen.rb +0 -32
  48. data/features/support/ios/screens/login_screen.rb +0 -18
  49. data/features/support/ios/screens/product_item_screen.rb +0 -39
  50. data/features/support/ios/screens/products_screen.rb +0 -27
  51. data/features/support/ios/screens/qr_code_scanner_screen.rb +0 -11
  52. data/features/support/ios/screens/saucebot_screen.rb +0 -16
  53. data/features/support/ios/screens/webview_screen.rb +0 -13
  54. data/features/support/ios/sections/list_items/product_list_item.rb +0 -13
  55. data/features/support/ios/sections/nav_widgets/nav_bar.rb +0 -31
  56. data/features/support/ios/sections/nav_widgets/nav_menu.rb +0 -41
  57. data/features/support/shared_components/screens/base_app_screen.rb +0 -35
  58. data/features/support/shared_components/screens/checkout_address_screen.rb +0 -17
  59. data/features/support/shared_components/screens/checkout_payment_screen.rb +0 -22
  60. data/features/support/shared_components/screens/login_screen.rb +0 -39
  61. data/features/support/shared_components/screens/saucebot_screen.rb +0 -17
  62. data/features/support/shared_components/screens/webview_screen.rb +0 -12
  63. data/features/support/shared_components/sections/nav_menu.rb +0 -58
  64. data/features/support/world_data.rb +0 -15
  65. data/features/support/world_pages.rb +0 -30
  66. data/reports/.keep +0 -1
  67. data/spec/fixtures/page_object.rb +0 -22
  68. data/spec/fixtures/page_section_object.rb +0 -21
  69. data/spec/fixtures/screen_object.rb +0 -16
  70. data/spec/fixtures/screen_section_object.rb +0 -16
  71. data/spec/spec_helper.rb +0 -33
  72. data/spec/testcentricity/elements/button_spec.rb +0 -18
  73. data/spec/testcentricity/elements/checkbox_spec.rb +0 -28
  74. data/spec/testcentricity/elements/image_spec.rb +0 -13
  75. data/spec/testcentricity/elements/label_spec.rb +0 -18
  76. data/spec/testcentricity/elements/list_spec.rb +0 -13
  77. data/spec/testcentricity/elements/ui_element_spec.rb +0 -72
  78. data/spec/testcentricity/mobile/appium_connect_spec.rb +0 -117
  79. data/spec/testcentricity/mobile/screen_object_spec.rb +0 -63
  80. data/spec/testcentricity/mobile/screen_section_object_spec.rb +0 -56
  81. data/spec/testcentricity/version_spec.rb +0 -7
  82. data/spec/testcentricity/web/browser_spec.rb +0 -41
  83. data/spec/testcentricity/web/local_webdriver_spec.rb +0 -86
  84. data/spec/testcentricity/web/mobile_webdriver_spec.rb +0 -123
  85. data/spec/testcentricity/web/page_object_spec.rb +0 -85
  86. data/spec/testcentricity/web/page_section_object_spec.rb +0 -72
  87. data/testcentricity.gemspec +0 -48
@@ -1,22 +0,0 @@
1
- class CheckoutPaymentScreen < BaseAppScreen
2
- include SharedCheckoutPaymentScreen
3
-
4
- trait(:page_name) { 'Checkout - Payment' }
5
- trait(:page_locator) { { accessibility_id: 'checkout payment screen' } }
6
- trait(:page_url) { 'checkout-payment' }
7
-
8
- # Checkout Payment screen UI elements
9
- textfields payee_name_field: { xpath: '(//android.widget.EditText[@content-desc="Full Name* input field"])[1]' },
10
- card_number_field: { accessibility_id: 'Card Number* input field' },
11
- expiration_field: { accessibility_id: 'Expiration Date* input field' },
12
- security_code_field: { accessibility_id: 'Security Code* input field' },
13
- recipient_name_field: { xpath: '(//android.widget.EditText[@content-desc="Full Name* input field"])[2]' },
14
- address1_field: { accessibility_id: 'Address Line 1* input field' },
15
- address2_field: { accessibility_id: 'Address Line 2 input field' },
16
- city_field: { accessibility_id: 'City* input field' },
17
- state_region_field: { accessibility_id: 'State/Region input field' },
18
- zip_code_field: { accessibility_id: 'Zip Code* input field' },
19
- country_field: { accessibility_id: 'Country* input field' }
20
- checkbox :bill_address_check, { xpath: '//android.view.ViewGroup[contains(@content-desc, "checkbox")]/android.view.ViewGroup'}
21
- button :review_order_button, { accessibility_id: 'Review Order button' }
22
- end
@@ -1,28 +0,0 @@
1
- class GeoLocationScreen < BaseAppScreen
2
- trait(:page_name) { 'Geo Location' }
3
- trait(:page_locator) { { accessibility_id: 'geo location screen' } }
4
- trait(:page_url) { 'geo-locations' }
5
- trait(:navigator) { nav_menu.open_geo_location }
6
-
7
- # Geo Location screen UI elements
8
- buttons start_observing_button: { accessibility_id: 'Start Observing button'},
9
- stop_observing_button: { accessibility_id: 'Stop Observing button'}
10
- labels latitude_data: { accessibility_id: 'latitude data' },
11
- longitude_data: { accessibility_id: 'longitude data' }
12
-
13
- def verify_page_ui
14
- super
15
- ui = {
16
- header_label => { visible: true, caption: 'Geo Location' },
17
- start_observing_button => { visible: true, enabled: false, caption: 'Start Observing' },
18
- stop_observing_button => { visible: true, enabled: true, caption: 'Stop Observing' },
19
- latitude_data => { visible: true, caption: { not_equal: '0' } },
20
- longitude_data => { visible: true, caption: { not_equal: '0' } }
21
- }
22
- verify_ui_states(ui)
23
- end
24
-
25
- def modal_action(action)
26
- grant_modal.await_and_respond(action.downcase.to_sym, timeout = 1, button_name = 'Only this time')
27
- end
28
- end
@@ -1,18 +0,0 @@
1
- class LoginScreen < BaseAppScreen
2
- include SharedLoginScreen
3
-
4
- trait(:page_name) { 'Login' }
5
- trait(:page_locator) { { accessibility_id: 'login screen' } }
6
- trait(:page_url) { 'login' }
7
- trait(:navigator) { nav_menu.open_log_in }
8
-
9
- # Login screen UI elements
10
- labels username_label: { xpath: '//android.view.ViewGroup[@content-desc="login screen"]/android.widget.ScrollView/android.view.ViewGroup/android.widget.TextView[2]'},
11
- password_label: { xpath: '//android.view.ViewGroup[@content-desc="login screen"]/android.widget.ScrollView/android.view.ViewGroup/android.widget.TextView[3]'},
12
- username_error: { accessibility_id: 'Username-error-message' },
13
- password_error: { accessibility_id: 'Password-error-message' },
14
- generic_error: { accessibility_id: 'generic-error-message' }
15
- textfields username_field: { accessibility_id: 'Username input field' },
16
- password_field: { accessibility_id: 'Password input field' }
17
- button :login_button, { accessibility_id: 'Login button' }
18
- end
@@ -1,39 +0,0 @@
1
- class ProductItemScreen < BaseAppScreen
2
- trait(:page_name) { 'Product Item' }
3
- trait(:page_locator) { { accessibility_id: 'product screen' } }
4
- trait(:page_url) { "product-details/#{ProductData.current.id.to_s}" }
5
-
6
- # Product Item screen UI elements
7
- labels price_value: { accessibility_id: 'product price' },
8
- description_value: { accessibility_id: 'product description' },
9
- quantity_value: { accessibility_id: 'counter amount' },
10
- highlights_label: { xpath: '//android.view.ViewGroup/android.widget.TextView[2]' }
11
- image :product_image, { xpath: '//android.view.ViewGroup/android.widget.ImageView' }
12
- buttons add_to_cart_button: { accessibility_id: 'Add To Cart button' },
13
- minus_qty_button: { accessibility_id: 'counter minus button' },
14
- plus_qty_button: { accessibility_id: 'counter plus button' },
15
- black_color_button: { accessibility_id: 'black circle' },
16
- blue_color_button: { accessibility_id: 'blue circle' },
17
- gray_color_button: { accessibility_id: 'gray circle' },
18
- red_color_button: { accessibility_id: 'red circle' }
19
-
20
- def verify_page_ui
21
- super
22
- ui = {
23
- header_label => { visible: true, caption: ProductData.current.name },
24
- price_value => { visible: true, caption: ProductData.current.price },
25
- highlights_label => { visible: true, caption: 'Product Highlights' },
26
- description_value => { visible: true, caption: ProductData.current.description },
27
- product_image => { visible: true, enabled: true },
28
- black_color_button => { visible: ProductData.current.colors.include?('BLACK') },
29
- blue_color_button => { visible: ProductData.current.colors.include?('BLUE') },
30
- gray_color_button => { visible: ProductData.current.colors.include?('GRAY') },
31
- red_color_button => { visible: ProductData.current.colors.include?('RED') },
32
- minus_qty_button => { visible: true, enabled: true },
33
- quantity_value => { visible: true, enabled: true, caption: '1' },
34
- plus_qty_button => { visible: true, enabled: true },
35
- add_to_cart_button => { visible: true, enabled: true, caption: 'Add To Cart' }
36
- }
37
- verify_ui_states(ui)
38
- end
39
- end
@@ -1,27 +0,0 @@
1
- class ProductsScreen < BaseAppScreen
2
- trait(:page_name) { 'Products' }
3
- trait(:page_locator) { { accessibility_id: 'products screen' } }
4
- trait(:page_url) { 'store-overview' }
5
-
6
- # Products screen UI elements
7
- list :product_list, { xpath: '//android.widget.ScrollView' }
8
- section :product_list_item, ProductListItem
9
-
10
- def initialize
11
- super
12
- # define the list item element for the Product list object
13
- list_elements = { list_item: { xpath: '//android.view.ViewGroup[@content-desc="store item"]' } }
14
- product_list.define_list_elements(list_elements)
15
- # associate the Product List Item indexed section object with the Product list object
16
- product_list_item.set_list_index(product_list)
17
- end
18
-
19
- def verify_page_ui
20
- super
21
- ui = {
22
- header_label => { visible: true, caption: 'Products' },
23
- product_list => { visible: true, itemcount: 6 }
24
- }
25
- verify_ui_states(ui)
26
- end
27
- end
@@ -1,15 +0,0 @@
1
- class QRCodeScannerScreen < BaseAppScreen
2
- trait(:page_name) { 'QR Code Scanner' }
3
- trait(:page_locator) { { accessibility_id: 'qr code screen' } }
4
- trait(:page_url) { 'qr-code-scanner' }
5
- trait(:navigator) { nav_menu.open_qr_code_scanner }
6
-
7
- def verify_page_ui
8
- super
9
- verify_ui_states(header_label => { visible: true, caption: 'QR Code Scanner' })
10
- end
11
-
12
- def modal_action(action)
13
- grant_modal.await_and_respond(action.downcase.to_sym, timeout = 1, button_name = 'Only this time')
14
- end
15
- end
@@ -1,16 +0,0 @@
1
- class SauceBotScreen < BaseAppScreen
2
- include SharedSauceBotScreen
3
-
4
- trait(:page_name) { 'SauceBot Video' }
5
- trait(:page_locator) { { accessibility_id: 'SauceBot screen' } }
6
- trait(:navigator) { nav_menu.open_saucebot_video }
7
-
8
- # SauceBot Video screen UI elements
9
- element :video_player, { xpath: '//android.view.View[@resource-id="movie_player"]' }
10
- buttons video_back: { accessibility_id: 'video icon backward' },
11
- video_play: { accessibility_id: 'video icon play' },
12
- video_pause: { accessibility_id: 'video icon stop' },
13
- video_forward: { accessibility_id: 'video icon forward' },
14
- video_volume: { accessibility_id: 'video icon volume-up' },
15
- video_mute: { accessibility_id: 'video icon volume-mute' }
16
- end
@@ -1,13 +0,0 @@
1
- class WebViewScreen < BaseAppScreen
2
- include SharedWebViewScreen
3
-
4
- trait(:page_name) { 'Webview' }
5
- trait(:page_locator) { { accessibility_id: 'webview selection screen' } }
6
- trait(:page_url) { 'webview' }
7
- trait(:navigator) { nav_menu.open_webview }
8
-
9
- # Webview screen UI elements
10
- label :url_label, { xpath: '//android.view.ViewGroup[@content-desc="webview selection screen"]/android.widget.ScrollView/android.view.ViewGroup/android.widget.TextView[1]' }
11
- textfield :url_field, { accessibility_id: 'URL input field' }
12
- button :go_to_site_button, { accessibility_id: 'Go To Site button' }
13
- end
@@ -1,13 +0,0 @@
1
- class ProductListItem < TestCentricity::ScreenSection
2
- trait(:section_name) { 'Product List Item' }
3
- trait(:section_locator) { { xpath: '//android.view.ViewGroup[@content-desc="store item"]' } }
4
-
5
- # Product Cell Item UI elements
6
- labels product_name: { xpath: '//android.widget.TextView[@content-desc="store item text"]' },
7
- product_price: { xpath: '//android.widget.TextView[@content-desc="store item price"]' }
8
- buttons review_star_1: { xpath: '//android.view.ViewGroup[@content-desc="review star 1"]' },
9
- review_star_2: { xpath: '//android.view.ViewGroup[@content-desc="review star 2"]' },
10
- review_star_3: { xpath: '//android.view.ViewGroup[@content-desc="review star 3"]' },
11
- review_star_4: { xpath: '//android.view.ViewGroup[@content-desc="review star 4"]' },
12
- review_star_5: { xpath: '//android.view.ViewGroup[@content-desc="review star 5"]' }
13
- end
@@ -1,39 +0,0 @@
1
- class NavMenu < TestCentricity::ScreenSection
2
- include SharedNavMenu
3
-
4
- trait(:section_name) { 'Nav Menu' }
5
- trait(:section_locator) { { xpath: '//android.widget.ScrollView/android.view.ViewGroup' } }
6
-
7
- # Nav Menu UI elements
8
- buttons close_button: { accessibility_id: 'menu item catalog' },
9
- webview_button: { accessibility_id: 'menu item webview' },
10
- qr_code_button: { accessibility_id: 'menu item qr code scanner' },
11
- geo_location_button: { accessibility_id: 'menu item geo location' },
12
- drawing_button: { accessibility_id: 'menu item drawing' },
13
- about_button: { accessibility_id: 'menu item about' },
14
- reset_app_button: { accessibility_id: 'menu item reset app' },
15
- biometrics_button: { accessibility_id: 'menu item biometrics' },
16
- log_in_button: { accessibility_id: 'menu item log in' },
17
- log_out_button: { accessibility_id: 'menu item log out' },
18
- api_calls_button: { accessibility_id: 'menu item api calls' },
19
- sauce_video_button: { accessibility_id: 'menu item sauce bot video' }
20
-
21
- def verify_ui
22
- ui = {
23
- self => { visible: true },
24
- close_button => { visible: true, enabled: true },
25
- webview_button => { visible: true, enabled: true, caption: 'Webview' },
26
- qr_code_button => { visible: true, enabled: true, caption: 'QR Code Scanner' },
27
- geo_location_button => { visible: true, enabled: true, caption: 'Geo Location' },
28
- drawing_button => { visible: true, enabled: true, caption: 'Drawing' },
29
- about_button => { visible: true, enabled: true, caption: 'About' },
30
- reset_app_button => { visible: true, enabled: true, caption: 'Reset App State' },
31
- biometrics_button => { visible: true, enabled: true, caption: 'FingerPrint' },
32
- log_in_button => { visible: true, enabled: true, caption: 'Log In' },
33
- log_out_button => { visible: true, enabled: true, caption: 'Log Out' },
34
- api_calls_button => { visible: true, enabled: true, caption: 'Api Calls' },
35
- sauce_video_button => { visible: true, enabled: true, caption: 'Sauce Bot Video' }
36
- }
37
- verify_ui_states(ui)
38
- end
39
- end
@@ -1,27 +0,0 @@
1
- class ProductDataSource < TestCentricity::DataSource
2
- def find_product(product_id)
3
- ProductData.current = ProductData.new(environs.read('Products', product_id.to_i))
4
- end
5
- end
6
-
7
-
8
- class ProductData < TestCentricity::DataPresenter
9
- attribute :id, Integer
10
- attribute :name, String
11
- attribute :description, String
12
- attribute :price, String
13
- attribute :review, Integer
14
- attribute :colors, Array
15
- attribute :default_color, String
16
-
17
- def initialize(data)
18
- @id = data[:id]
19
- @name = data[:name]
20
- @description = data[:description]
21
- @price = data[:price]
22
- @review = data[:review]
23
- @colors = data[:colors]
24
- @default_color = data[:defaultColor]
25
- super
26
- end
27
- end
@@ -1,17 +0,0 @@
1
- class UserDataSource < TestCentricity::DataSource
2
- def find_user_creds(node_name)
3
- UserData.current = UserData.new(environs.read('User_creds', node_name))
4
- end
5
- end
6
-
7
-
8
- class UserData < TestCentricity::DataPresenter
9
- attribute :username, String
10
- attribute :password, String
11
-
12
- def initialize(data)
13
- @username = data[:username]
14
- @password = data[:password]
15
- super
16
- end
17
- end
@@ -1,62 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'capybara/cucumber'
4
- require 'parallel_tests'
5
- require 'require_all'
6
- require 'simplecov'
7
- require 'testcentricity_web'
8
- require 'testcentricity'
9
-
10
- include TestCentricity
11
-
12
- SimpleCov.command_name("Features-#{ENV['PLATFORM']}-#{Time.now.strftime('%Y%m%d%H%M%S%L')}")
13
-
14
- require_relative 'world_data'
15
- require_relative 'world_pages'
16
-
17
- require_rel 'data'
18
- require_rel 'shared_components'
19
-
20
- # conditionally require page and section objects based on target platform
21
- case ENV['PLATFORM'].downcase.to_sym
22
- when :ios
23
- require_rel 'ios'
24
- when :android
25
- require_rel 'android'
26
- when :web
27
- require_rel 'web'
28
- else
29
- raise "Platform unknown. Please specify the target test platform using '-p ios', '-p android', or '-p web' in the command line"
30
- end
31
-
32
- $LOAD_PATH << './lib'
33
-
34
- # set the default locale and auto load all translations from config/locales/*.rb,yml.
35
- ENV['LOCALE'] = 'en-US' unless ENV['LOCALE']
36
- ENV['LANGUAGE'] = 'en' unless ENV['LANGUAGE']
37
- I18n.load_path += Dir['config/locales/*.{rb,yml}']
38
- I18n.default_locale = ENV['LOCALE']
39
- I18n.locale = ENV['LOCALE']
40
- Faker::Config.locale = ENV['LOCALE']
41
-
42
- # instantiate all data objects and target test environment
43
- include WorldData
44
- environs.find_environ(ENV['TEST_ENVIRONMENT'], :yaml)
45
- WorldData.instantiate_data_objects
46
-
47
- # instantiate all page objects
48
- include WorldPages
49
- WorldPages.instantiate_page_objects
50
-
51
- # connect to appropriate driver (WebDriver or Appium) based on target platform
52
- case ENV['PLATFORM'].downcase.to_sym
53
- when :web
54
- # establish connection to WebDriver and target web browser
55
- Webdrivers.cache_time = 86_400
56
- WebDriverConnect.initialize_web_driver
57
- when :ios, :android
58
- AppiumConnect.initialize_appium
59
- end
60
-
61
- # set TestCentricity's default max wait time to 20 seconds
62
- Environ.default_max_wait_time = 20
@@ -1,135 +0,0 @@
1
-
2
- BeforeAll do
3
- # start Appium Server if command line option was specified and target browser is mobile simulator or device
4
- if ENV['APPIUM_SERVER'] == 'run' && Environ.driver == :appium
5
- $server = TestCentricity::AppiumServer.new
6
- $server.start
7
- end
8
- # connect to sim/device and install app
9
- AppiumConnect.start_driver
10
- end
11
-
12
-
13
- AfterAll do
14
- # quit Appium driver
15
- TestCentricity::AppiumConnect.quit_driver
16
- # terminate Appium Server if command line option was specified and target browser is mobile simulator or device
17
- if ENV['APPIUM_SERVER'] == 'run' && Environ.driver == :appium && $server.running?
18
- $server.stop
19
- end
20
- end
21
-
22
-
23
- Before do |scenario|
24
- # if executing tests in parallel concurrent threads, print thread number with scenario name
25
- message = Environ.parallel ? "Thread ##{Environ.process_num} | Scenario: #{scenario.name}" : "Scenario: #{scenario.name}"
26
- log message
27
- $initialized ||= false
28
- unless $initialized
29
- $initialized = true
30
- $test_start_time = Time.now
31
- # HTML report header information if reporting is enabled
32
- log Environ.report_header if ENV['REPORTING']
33
- end
34
- end
35
-
36
-
37
- After do |scenario|
38
- # process and embed any screenshots recorded during execution of scenario
39
- process_embed_screenshots(scenario)
40
- # clear out any queued screenshots
41
- Environ.reset_contexts
42
- # close app
43
- TestCentricity::AppiumConnect.close_app
44
- end
45
-
46
-
47
- # exclusionary Around hooks to prevent running feature/scenario on unsupported browsers, devices, or
48
- # cloud remote browser hosting platforms. Use the following tags to block test execution:
49
- # mobile devices: @!ipad, @!iphone
50
-
51
-
52
- # block feature/scenario execution if running against iPad mobile browser
53
- Around('@!ipad') do |scenario, block|
54
- qualify_device('ipad', scenario, block)
55
- end
56
-
57
-
58
- # block feature/scenario execution if running against iPhone mobile browser
59
- Around('@!iphone') do |scenario, block|
60
- qualify_device('iphone', scenario, block)
61
- end
62
-
63
-
64
- # block feature/scenario execution if running against a physical or emulated mobile device
65
- Around('@!device') do |scenario, block|
66
- if Environ.is_device?
67
- log "Scenario '#{scenario.name}' cannot be executed on physical or emulated devices."
68
- skip_this_scenario
69
- else
70
- block.call
71
- end
72
- end
73
-
74
-
75
- Around('@!ios') do |scenario, block|
76
- if Environ.device_os == :android
77
- block.call
78
- else
79
- log "Scenario '#{scenario.name}' can not be executed on iOS devices."
80
- skip_this_scenario
81
- end
82
- end
83
-
84
-
85
- Around('@!android') do |scenario, block|
86
- if Environ.device_os == :ios
87
- block.call
88
- else
89
- log "Scenario '#{scenario.name}' can not be executed on Android devices."
90
- skip_this_scenario
91
- end
92
- end
93
-
94
-
95
- # supporting methods
96
-
97
- def qualify_device(device, scenario, block)
98
- if Environ.is_device?
99
- if Environ.device_type.include? device
100
- log "Scenario '#{scenario.name}' cannot be executed on #{device} devices."
101
- skip_this_scenario
102
- else
103
- block.call
104
- end
105
- else
106
- block.call
107
- end
108
- end
109
-
110
- def screen_shot_and_save_page(scenario)
111
- timestamp = Time.now.strftime('%Y%m%d%H%M%S%L')
112
- filename = scenario.nil? ? "Screenshot-#{timestamp}.png" : "Screenshot-#{scenario.__id__}-#{timestamp}.png"
113
- path = File.join Dir.pwd, 'reports/screenshots/', filename
114
- if Environ.driver == :appium
115
- TestCentricity::AppiumConnect.take_screenshot(path)
116
- else
117
- save_screenshot path
118
- end
119
- log "Screenshot saved at #{path}"
120
- screen_shot = { path: path, filename: filename }
121
- Environ.save_screen_shot(screen_shot)
122
- attach(path, 'image/png') unless scenario.nil?
123
- end
124
-
125
- def process_embed_screenshots(scenario)
126
- screen_shots = Environ.get_screen_shots
127
- if screen_shots.count > 0
128
- screen_shots.each do |row|
129
- path = row[:path]
130
- attach(path, 'image/png')
131
- end
132
- else
133
- screen_shot_and_save_page(scenario) if scenario.failed?
134
- end
135
- end
@@ -1,11 +0,0 @@
1
- class AboutScreen < BaseAppScreen
2
- trait(:page_name) { 'About' }
3
- trait(:page_locator) { { accessibility_id: 'about screen' } }
4
- trait(:page_url) { 'about' }
5
- trait(:navigator) { nav_menu.open_about }
6
-
7
- def verify_page_ui
8
- super
9
- verify_ui_states(header_label => { visible: true, caption: 'About' })
10
- end
11
- end
@@ -1,20 +0,0 @@
1
- class BaseAppScreen < TestCentricity::ScreenObject
2
- include SharedBaseAppScreen
3
-
4
- trait(:page_name) { 'Base App Screen' }
5
-
6
- # Base App screen UI elements
7
- label :header_label, { accessibility_id: 'container header' }
8
- alert :alert_modal, { class: 'XCUIElementTypeAlert' }
9
- sections nav_bar: NavBar,
10
- nav_menu: NavMenu
11
-
12
- def verify_page_ui
13
- nav_bar.verify_ui
14
- end
15
-
16
- def invoke_nav_menu
17
- nav_bar.open_menu
18
- nav_menu.wait_until_visible(3)
19
- end
20
- end
@@ -1,17 +0,0 @@
1
- class BiometricsScreen < BaseAppScreen
2
- trait(:page_name) { 'Biometrics' }
3
- trait(:page_locator) { { accessibility_id: 'biometrics screen' } }
4
- trait(:navigator) { nav_menu.open_biometrics }
5
-
6
- # Biometrics screen UI elements
7
- switch :face_id_switch, { accessibility_id: 'biometrics switch'}
8
-
9
- def verify_page_ui
10
- super
11
- ui = {
12
- header_label => { visible: true, caption: 'FaceID' },
13
- face_id_switch => { visible: true, enabled: false, value: '0' }
14
- }
15
- verify_ui_states(ui)
16
- end
17
- end
@@ -1,17 +0,0 @@
1
- class CheckoutAddressScreen < BaseAppScreen
2
- include SharedCheckoutAddressScreen
3
-
4
- trait(:page_name) { 'Checkout - Address' }
5
- trait(:page_locator) { { accessibility_id: 'checkout address screen' } }
6
- trait(:page_url) { 'checkout-address' }
7
-
8
- # Checkout Address screen UI elements
9
- textfields fullname_field: { accessibility_id: 'Full Name* input field' },
10
- address1_field: { accessibility_id: 'Address Line 1* input field' },
11
- address2_field: { accessibility_id: 'Address Line 2 input field' },
12
- city_field: { accessibility_id: 'City* input field' },
13
- state_region_field: { accessibility_id: 'State/Region input field' },
14
- zip_code_field: { accessibility_id: 'Zip Code* input field' },
15
- country_field: { accessibility_id: 'Country* input field' }
16
- button :to_payment_button, { accessibility_id: 'To Payment button' }
17
- end
@@ -1,22 +0,0 @@
1
- class CheckoutPaymentScreen < BaseAppScreen
2
- include SharedCheckoutPaymentScreen
3
-
4
- trait(:page_name) { 'Checkout - Payment' }
5
- trait(:page_locator) { { accessibility_id: 'checkout payment screen' } }
6
- trait(:page_url) { 'checkout-payment' }
7
-
8
- # Checkout Payment screen UI elements
9
- textfields payee_name_field: { xpath: '(//XCUIElementTypeTextField[@name="Full Name* input field"])[1]' },
10
- card_number_field: { accessibility_id: 'Card Number* input field' },
11
- expiration_field: { accessibility_id: 'Expiration Date* input field' },
12
- security_code_field: { accessibility_id: 'Security Code* input field' },
13
- recipient_name_field: { xpath: '(//XCUIElementTypeTextField[@name="Full Name* input field"])[2]' },
14
- address1_field: { accessibility_id: 'Address Line 1* input field' },
15
- address2_field: { accessibility_id: 'Address Line 2 input field' },
16
- city_field: { accessibility_id: 'City* input field' },
17
- state_region_field: { accessibility_id: 'State/Region input field' },
18
- zip_code_field: { accessibility_id: 'Zip Code* input field' },
19
- country_field: { accessibility_id: 'Country* input field' }
20
- checkbox :bill_address_check, { xpath: '//XCUIElementTypeOther[contains(@name, "checkbox")]'}
21
- button :review_order_button, { accessibility_id: 'Review Order button' }
22
- end
@@ -1,32 +0,0 @@
1
- class GeoLocationScreen < BaseAppScreen
2
- trait(:page_name) { 'Geo Location' }
3
- trait(:page_locator) { { accessibility_id: 'geo location screen' } }
4
- trait(:page_url) { 'geo-locations' }
5
- trait(:navigator) { nav_menu.open_geo_location }
6
-
7
- # Geo Location screen UI elements
8
- buttons start_observing_button: { accessibility_id: 'Start Observing button'},
9
- stop_observing_button: { accessibility_id: 'Stop Observing button'}
10
- labels latitude_label: { accessibility_id: 'Latitude:' },
11
- latitude_data: { accessibility_id: 'latitude data' },
12
- longitude_label: { accessibility_id: 'Longitude:' },
13
- longitude_data: { accessibility_id: 'longitude data' }
14
-
15
- def verify_page_ui
16
- super
17
- ui = {
18
- header_label => { visible: true, caption: 'Geo Location' },
19
- start_observing_button => { visible: true, enabled: false, caption: 'Start Observing' },
20
- stop_observing_button => { visible: true, enabled: true, caption: 'Stop Observing' },
21
- latitude_label => { visible: true, caption: 'Latitude:' },
22
- latitude_data => { visible: true, caption: { not_equal: '0' } },
23
- longitude_label => { visible: true, caption: 'Longitude:' },
24
- longitude_data => { visible: true, caption: { not_equal: '0' } }
25
- }
26
- verify_ui_states(ui)
27
- end
28
-
29
- def modal_action(action)
30
- alert_modal.await_and_respond(action.downcase.to_sym, timeout = 1, button_name = 'Allow Once')
31
- end
32
- end
@@ -1,18 +0,0 @@
1
- class LoginScreen < BaseAppScreen
2
- include SharedLoginScreen
3
-
4
- trait(:page_name) { 'Login' }
5
- trait(:page_locator) { { accessibility_id: 'login screen' } }
6
- trait(:page_url) { 'login' }
7
- trait(:navigator) { nav_menu.open_log_in }
8
-
9
- # Login screen UI elements
10
- labels username_label: { accessibility_id: 'Username'},
11
- password_label: { xpath: '(//XCUIElementTypeStaticText[@name="Password"])[1]'},
12
- username_error: { accessibility_id: 'Username-error-message' },
13
- password_error: { accessibility_id: 'Password-error-message' },
14
- generic_error: { accessibility_id: 'generic-error-message' }
15
- textfields username_field: { accessibility_id: 'Username input field' },
16
- password_field: { accessibility_id: 'Password input field' }
17
- button :login_button, { accessibility_id: 'Login button' }
18
- end