testcentricity 3.0.4 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
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