testcentricity_web 4.1.3 → 4.1.6

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 (38) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +18 -0
  3. data/.simplecov +5 -0
  4. data/CHANGELOG.md +30 -1
  5. data/Gemfile.lock +170 -0
  6. data/README.md +287 -102
  7. data/Rakefile +37 -1
  8. data/config/cucumber.yml +150 -0
  9. data/docker-compose-v3.yml +48 -0
  10. data/features/basic_test_page_css.feature +24 -0
  11. data/features/basic_test_page_xpath.feature +24 -0
  12. data/features/step_definitions/generic_steps.rb.rb +37 -0
  13. data/features/support/env.rb +43 -0
  14. data/features/support/hooks.rb +245 -0
  15. data/features/support/pages/basic_css_test_page.rb +49 -0
  16. data/features/support/pages/basic_test_page.rb +238 -0
  17. data/features/support/pages/basic_xpath_test_page.rb +49 -0
  18. data/features/support/pages/media_page.rb +11 -0
  19. data/features/support/world_pages.rb +15 -0
  20. data/lib/testcentricity_web/data_objects/environment.rb +4 -0
  21. data/lib/testcentricity_web/version.rb +1 -1
  22. data/lib/testcentricity_web/web_core/page_object.rb +13 -6
  23. data/lib/testcentricity_web/web_core/page_objects_helper.rb +41 -8
  24. data/lib/testcentricity_web/web_core/page_section.rb +1 -16
  25. data/lib/testcentricity_web/web_core/webdriver_helper.rb +78 -120
  26. data/lib/testcentricity_web/web_elements/select_list.rb +18 -7
  27. data/lib/testcentricity_web/web_elements/ui_elements_helper.rb +13 -0
  28. data/reports/.keep +1 -0
  29. data/test_site/basic_test_page.html +240 -0
  30. data/test_site/images/Granny.jpg +0 -0
  31. data/test_site/images/Wilder.jpg +0 -0
  32. data/test_site/images/You_Betcha.jpg +0 -0
  33. data/test_site/media/MP4_small.mp4 +0 -0
  34. data/test_site/media/MPS_sample.mp3 +0 -0
  35. data/test_site/media_page.html +33 -0
  36. data/testcentricity_web.gemspec +5 -0
  37. metadata +105 -4
  38. data/test_site/test_page.html +0 -11
data/Rakefile CHANGED
@@ -1 +1,37 @@
1
- require 'bundler/gem_tasks'
1
+ require 'rubygems'
2
+ require 'cucumber'
3
+ require 'cucumber/rake/task'
4
+ require 'rake'
5
+
6
+
7
+ namespace :features do
8
+ Cucumber::Rake::Task.new(:edge) do |t|
9
+ t.profile = 'edge'
10
+ end
11
+
12
+ Cucumber::Rake::Task.new(:chrome) do |t|
13
+ t.profile = 'chrome'
14
+ end
15
+
16
+ Cucumber::Rake::Task.new(:edge_headless) do |t|
17
+ t.profile = 'edge_headless'
18
+ end
19
+
20
+ Cucumber::Rake::Task.new(:chrome_headless) do |t|
21
+ t.profile = 'chrome_headless'
22
+ end
23
+
24
+ Cucumber::Rake::Task.new(:safari) do |t|
25
+ t.profile = 'safari'
26
+ end
27
+
28
+ Cucumber::Rake::Task.new(:firefox) do |t|
29
+ t.profile = 'firefox'
30
+ end
31
+
32
+ Cucumber::Rake::Task.new(:firefox_headless) do |t|
33
+ t.profile = 'firefox_headless'
34
+ end
35
+
36
+ task :all => [:edge, :edge_headless, :chrome, :chrome_headless, :safari]
37
+ end
@@ -0,0 +1,150 @@
1
+ <% desktop = "--require features BROWSER_TILE=true BROWSER_SIZE=1300,1000 --publish-quiet" %>
2
+ <% tablet = "--tags @desktop --require features BROWSER_TILE=true --publish-quiet" %>
3
+ <% mobile = "--tags @mobile --require features BROWSER_TILE=true --publish-quiet" %>
4
+ <% reports = "--require features --format pretty --format html --out reports/test_results.html --format junit --out reports --format json --out reports/test_results.json" %>
5
+
6
+
7
+ #==============
8
+ # generic test context profiles
9
+ #==============
10
+
11
+ failing: --tags '@failing and not @wip'
12
+ wip: --tags '@wip and not @failing'
13
+ dev: --tags '@dev and (not @wip and not @failing)'
14
+
15
+
16
+ #==============
17
+ # test reporting profiles
18
+ #==============
19
+
20
+ report: <%= reports %> REPORTING=true
21
+ parallel: PARALLEL=true REPORTING=true --require features --format pretty --format html --out reports/test_results<%= ENV['TEST_ENV_NUMBER'] %>.html --format junit --out reports --format json --out reports/test_results<%= ENV['TEST_ENV_NUMBER'] %>.json
22
+
23
+
24
+ #==============
25
+ # profiles for locally hosted desktop web browsers
26
+ #==============
27
+
28
+ chrome: WEB_BROWSER=chrome <%= desktop %>
29
+ firefox: WEB_BROWSER=firefox <%= desktop %>
30
+ edge: WEB_BROWSER=edge <%= desktop %>
31
+ safari: WEB_BROWSER=safari <%= desktop %>
32
+
33
+ firefox_headless: WEB_BROWSER=firefox_headless <%= desktop %>
34
+ chrome_headless: WEB_BROWSER=chrome_headless <%= desktop %>
35
+ edge_headless: WEB_BROWSER=edge_headless <%= desktop %>
36
+
37
+
38
+ #==============
39
+ # profile for Selenium Grid and Dockerized Selenium Grid hosted desktop web browsers
40
+ #==============
41
+ grid: SELENIUM=remote REMOTE_ENDPOINT="http://localhost:4444/wd/hub"
42
+
43
+
44
+ #==============
45
+ # profiles for mobile device screen orientation
46
+ #==============
47
+
48
+ landscape: ORIENTATION=landscape
49
+ portrait: ORIENTATION=portrait
50
+
51
+
52
+ #==============
53
+ # profile to start Appium Server prior to running mobile browser tests on iOS or Android simulators or physical devices
54
+ #==============
55
+ run_appium: APPIUM_SERVER=run
56
+
57
+
58
+ #==============
59
+ # profiles for mobile Safari web browsers hosted within XCode iOS simulators
60
+ # NOTE: Requires installation of XCode, iOS version specific target simulators, Appium, and the appium_capybara gem
61
+ #==============
62
+
63
+ appium_ios: WEB_BROWSER=appium AUTOMATION_ENGINE=XCUITest APP_PLATFORM_NAME="ios" APP_BROWSER="Safari" NEW_COMMAND_TIMEOUT=30 SHOW_SIM_KEYBOARD=false <%= desktop %>
64
+ app_ios_15: --profile appium_ios APP_VERSION="15.4"
65
+
66
+ ipad_pro_12_15_sim: --profile app_ios_15 DEVICE_TYPE=tablet APP_DEVICE="iPad Pro (12.9-inch) (5th generation)"
67
+ ipad_air_15_sim: --profile app_ios_15 DEVICE_TYPE=tablet APP_DEVICE="iPad Air (5th generation)" <%= desktop %>
68
+
69
+
70
+ #==============
71
+ # profiles for Android mobile web browsers hosted within Android Studio Android Virtual Device emulators
72
+ # NOTE: Requires installation of Android Studio, Android version specific virtual device simulators, Appium, and the appium_capybara gem
73
+ #==============
74
+
75
+ appium_android: WEB_BROWSER=appium APP_PLATFORM_NAME="Android" <%= desktop %>
76
+ app_android_12: --profile appium_android APP_BROWSER="Chrome" APP_VERSION="12.0"
77
+ pixel_c_api31_sim: --profile app_android_12 DEVICE_TYPE=tablet APP_DEVICE="Pixel_C_API_31"
78
+
79
+
80
+ #==============
81
+ # profiles for remotely hosted web browsers on the BrowserStack service
82
+ #==============
83
+
84
+ browserstack: WEB_BROWSER=browserstack BS_USERNAME="<INSERT USER NAME HERE>" BS_AUTHKEY="<INSERT PASSWORD HERE>" AUTOMATE_PROJECT="TC_Web_Sample - BrowserStack"
85
+ bs_desktop: --profile browserstack <%= desktop %> RESOLUTION="1920x1080"
86
+ bs_mobile: --profile browserstack <%= mobile %>
87
+
88
+ # BrowserStack macOS desktop browser profiles
89
+ bs_macos_monterey: --profile bs_desktop BS_OS="OS X" BS_OS_VERSION="Monterey"
90
+ bs_chrome_monterey: --profile bs_macos_monterey BS_BROWSER="Chrome" BS_VERSION="latest"
91
+ bs_edge_monterey: --profile bs_macos_monterey BS_BROWSER="Edge" BS_VERSION="latest"
92
+ bs_safari_monterey: --profile bs_macos_monterey BS_BROWSER="Safari" BS_VERSION="latest"
93
+
94
+ # BrowserStack iOS mobile browser profiles
95
+ bs_ipad: --profile bs_mobile BS_OS=ios BS_BROWSER=Safari DEVICE_TYPE=tablet BS_REAL_MOBILE="true"
96
+ bs_ipad_pro_12: --profile bs_ipad BS_DEVICE="iPad Pro 12.9 2018" BS_OS_VERSION="15"
97
+
98
+ # BrowserStack Android mobile browser profiles
99
+ bs_android: --profile bs_mobile BS_OS=android BS_BROWSER=Chrome DEVICE_TYPE=tablet BS_REAL_MOBILE="true"
100
+ bs_android_tablet: --profile bs_android BS_DEVICE="Samsung Galaxy Tab S7" BS_OS_VERSION="10.0"
101
+
102
+
103
+ #==============
104
+ # profiles for remotely hosted web browsers on the LambdaTest service
105
+ #==============
106
+
107
+ lambdatest: WEB_BROWSER=lambdatest LT_USERNAME="<INSERT USER NAME HERE>" LT_AUTHKEY="<INSERT PASSWORD HERE>" AUTOMATE_PROJECT="TC_Web_Sample - LambdaTest"
108
+ lt_desktop: --profile lambdatest <%= desktop %> RESOLUTION="2560x1440"
109
+
110
+ # LambdaTest macOS desktop browser profiles
111
+ lt_macos_monterey: --profile lt_desktop LT_OS="MacOS Monterey"
112
+ lt_chrome_monterey: --profile lt_macos_monterey LT_BROWSER="Chrome" LT_VERSION="98.0"
113
+ lt_edge_monterey: --profile lt_macos_monterey LT_BROWSER="MicrosoftEdge" LT_VERSION="97.0"
114
+
115
+
116
+ #==============
117
+ # profiles for remotely hosted web browsers on the TestingBot service
118
+ #==============
119
+
120
+ testingbot: WEB_BROWSER=testingbot TB_USERNAME="<INSERT USER NAME HERE>" TB_AUTHKEY="<INSERT PASSWORD HERE>" AUTOMATE_PROJECT="TC_Web_Sample - TestingBot"
121
+ tb_desktop: --profile testingbot <%= desktop %> RESOLUTION="1920x1200"
122
+
123
+ # TestingBot macOS desktop browser profiles
124
+ tb_macos_monterey: --profile tb_desktop TB_OS="MONTEREY"
125
+ tb_chrome_monterey: --profile tb_macos_monterey TB_BROWSER="chrome" TB_VERSION="latest"
126
+ tb_edge_monterey: --profile tb_macos_monterey TB_BROWSER="microsoftedge" TB_VERSION="latest"
127
+
128
+
129
+ #==============
130
+ # profiles for remotely hosted web browsers on the SauceLabs service
131
+ #==============
132
+
133
+ saucelabs: WEB_BROWSER=saucelabs SL_USERNAME="<INSERT USER NAME HERE>" SL_AUTHKEY="<INSERT PASSWORD HERE>" DATA_CENTER="us-west-1" AUTOMATE_PROJECT="TC_Web_Sample - SauceLabs"
134
+ sl_desktop: --profile saucelabs <%= desktop %>
135
+ sl_mobile: --profile saucelabs <%= mobile %>
136
+
137
+ # SauceLabs macOS desktop browser profiles
138
+ sl_macos_monterey: --profile sl_desktop SL_OS="macOS 12" RESOLUTION="1920x1440"
139
+ sl_chrome_monterey: --profile sl_macos_monterey SL_BROWSER="chrome" SL_VERSION="latest"
140
+ sl_edge_monterey: --profile sl_macos_monterey SL_BROWSER="MicrosoftEdge" SL_VERSION="latest"
141
+ sl_firefox_monterey: --profile sl_macos_monterey SL_BROWSER="Firefox" SL_VERSION="latest"
142
+
143
+ # SauceLabs Windows desktop browser profiles
144
+ sl_windows: --profile sl_desktop RESOLUTION="1920x1200"
145
+ sl_edge_win11: --profile sl_windows SL_OS="Windows 11" SL_BROWSER="MicrosoftEdge" SL_VERSION="latest"
146
+ sl_ie_win10: --profile sl_windows SL_OS="Windows 10" SL_BROWSER="internet explorer" SL_VERSION="11"
147
+
148
+ # SauceLabs iOS mobile browser profiles
149
+ sl_ipad: --profile sl_mobile DEVICE_TYPE=tablet SL_PLATFORM=iOS SL_BROWSER=Safari
150
+ sl_ipad_pro_12: --profile sl_ipad SL_DEVICE="iPad Pro (12.9 inch) (5th generation) Simulator" SL_VERSION="15.0"
@@ -0,0 +1,48 @@
1
+ # To execute this docker-compose yml file use `docker-compose -f docker-compose-v3.yml up`
2
+ # Add the `-d` flag at the end for detached execution
3
+ # To stop the execution, hit Ctrl+C, and then `docker-compose -f docker-compose-v3.yml down`
4
+ version: "3"
5
+ services:
6
+ chrome:
7
+ image: selenium/node-chrome:4.1.2-20220217
8
+ shm_size: 2gb
9
+ depends_on:
10
+ - selenium-hub
11
+ environment:
12
+ - SE_EVENT_BUS_HOST=selenium-hub
13
+ - SE_EVENT_BUS_PUBLISH_PORT=4442
14
+ - SE_EVENT_BUS_SUBSCRIBE_PORT=4443
15
+ - SE_NODE_MAX_SESSIONS=4
16
+ - SE_NODE_OVERRIDE_MAX_SESSIONS=true
17
+
18
+ edge:
19
+ image: selenium/node-edge:4.1.2-20220217
20
+ shm_size: 2gb
21
+ depends_on:
22
+ - selenium-hub
23
+ environment:
24
+ - SE_EVENT_BUS_HOST=selenium-hub
25
+ - SE_EVENT_BUS_PUBLISH_PORT=4442
26
+ - SE_EVENT_BUS_SUBSCRIBE_PORT=4443
27
+ - SE_NODE_MAX_SESSIONS=4
28
+ - SE_NODE_OVERRIDE_MAX_SESSIONS=true
29
+
30
+ firefox:
31
+ image: selenium/node-firefox:4.1.2-20220217
32
+ shm_size: 2gb
33
+ depends_on:
34
+ - selenium-hub
35
+ environment:
36
+ - SE_EVENT_BUS_HOST=selenium-hub
37
+ - SE_EVENT_BUS_PUBLISH_PORT=4442
38
+ - SE_EVENT_BUS_SUBSCRIBE_PORT=4443
39
+ - SE_NODE_MAX_SESSIONS=4
40
+ - SE_NODE_OVERRIDE_MAX_SESSIONS=true
41
+
42
+ selenium-hub:
43
+ image: selenium/hub:4.1.2-20220217
44
+ container_name: selenium-hub
45
+ ports:
46
+ - "4442:4442"
47
+ - "4443:4443"
48
+ - "4444:4444"
@@ -0,0 +1,24 @@
1
+ Feature: Basic HTML Test Page using CSS locators
2
+ In order to xxx
3
+ As a xxxx
4
+ I expect to xxxx
5
+
6
+
7
+ Background:
8
+ Given I am on the Basic CSS Test page
9
+
10
+
11
+ Scenario: xxxxx
12
+ Then I expect the Basic CSS Test page to be correctly displayed
13
+
14
+
15
+ @!mobile
16
+ Scenario: xxxxx
17
+ Then I expect the tab order to be correct
18
+
19
+
20
+ Scenario: xxxxx
21
+ When I populate the form fields
22
+ Then I expect the form fields to be correctly populated
23
+ When I cancel my changes
24
+ Then I expect the Basic CSS Test page to be correctly displayed
@@ -0,0 +1,24 @@
1
+ Feature: Basic HTML Test Page using Xpath locators
2
+ In order to xxx
3
+ As a xxxx
4
+ I expect to xxxx
5
+
6
+
7
+ Background:
8
+ Given I am on the Basic Xpath Test page
9
+
10
+
11
+ Scenario: xxxxx
12
+ Then I expect the Basic Xpath Test page to be correctly displayed
13
+
14
+
15
+ @!mobile
16
+ Scenario: xxxxx
17
+ Then I expect the tab order to be correct
18
+
19
+
20
+ Scenario: xxxxx
21
+ When I populate the form fields
22
+ Then I expect the form fields to be correctly populated
23
+ When I cancel my changes
24
+ Then I expect the Basic Xpath Test page to be correctly displayed
@@ -0,0 +1,37 @@
1
+ include TestCentricity
2
+
3
+
4
+ Given(/^I am (?:on|viewing) the (.*) page$/) do |page_name|
5
+ # find and load the specified target page
6
+ target_page = PageManager.find_page(page_name)
7
+ target_page.load_page
8
+ end
9
+
10
+
11
+ Then(/^I expect the (.*) page to be correctly displayed$/) do |page_name|
12
+ # find and verify that the specified target page is loaded
13
+ target_page = PageManager.find_page(page_name)
14
+ target_page.verify_page_exists
15
+ # verify that target page is correctly displayed
16
+ target_page.verify_page_ui
17
+ end
18
+
19
+
20
+ When(/^I populate the form fields$/) do
21
+ PageManager.current_page.populate_form
22
+ end
23
+
24
+
25
+ Then(/^I expect the form fields to be correctly populated$/) do
26
+ PageManager.current_page.verify_form_data
27
+ end
28
+
29
+
30
+ When(/^I (.*) my changes$/) do | action|
31
+ PageManager.current_page.perform_action(action.downcase.to_sym)
32
+ end
33
+
34
+
35
+ Then(/^I expect the tab order to be correct$/) do
36
+ PageManager.current_page.verify_tab_order
37
+ end
@@ -0,0 +1,43 @@
1
+ require 'capybara/cucumber'
2
+ require 'parallel_tests'
3
+ require 'appium_capybara'
4
+ require 'require_all'
5
+ require 'simplecov'
6
+ require 'testcentricity_web'
7
+
8
+ SimpleCov.command_name "features #{ENV['WEB_BROWSER']}" + (ENV['TEST_ENV_NUMBER'] || '')
9
+
10
+ # require_relative 'world_data'
11
+ require_relative 'world_pages'
12
+
13
+ # require_rel 'data'
14
+ # require_rel 'sections'
15
+ require_rel 'pages'
16
+
17
+ $LOAD_PATH << './lib'
18
+
19
+ # set Capybara's default max wait time to 20 seconds
20
+ Capybara.default_max_wait_time = 20
21
+
22
+ # set the default locale and auto load all translations from config/locales/*.rb,yml.
23
+ ENV['LOCALE'] = 'en-US' unless ENV['LOCALE']
24
+ I18n.load_path += Dir['config/locales/*.{rb,yml}']
25
+ I18n.default_locale = ENV['LOCALE']
26
+ I18n.locale = ENV['LOCALE']
27
+ Faker::Config.locale = ENV['LOCALE']
28
+
29
+ # instantiate all data objects and target test environment
30
+ # include WorldData
31
+ # environs.find_environ(ENV['TEST_ENVIRONMENT'], :yaml)
32
+ # WorldData.instantiate_data_objects
33
+
34
+ # instantiate all page objects
35
+ include WorldPages
36
+ WorldPages.instantiate_page_objects
37
+
38
+ # establish connection to WebDriver and target web browser
39
+ Webdrivers.cache_time = 86_400
40
+
41
+ options = { app_host: "file://#{File.dirname(__FILE__)}/../../test_site" }
42
+ options = { app_host: "http://192.168.1.129"}
43
+ TestCentricity::WebDriverConnect.initialize_web_driver(options)
@@ -0,0 +1,245 @@
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
+ end
9
+
10
+
11
+ AfterAll do
12
+ # terminate Appium Server if command line option was specified and target browser is mobile simulator or device
13
+ if ENV['APPIUM_SERVER'] == 'run' && Environ.driver == :appium && $server.running?
14
+ $server.stop
15
+ end
16
+ # close driver
17
+ terminate_session
18
+ end
19
+
20
+
21
+ Before do |scenario|
22
+ # if executing tests in parallel concurrent threads, print thread number with scenario name
23
+ message = Environ.parallel ? "Thread ##{Environ.process_num} | Scenario: #{scenario.name}" : "Scenario: #{scenario.name}"
24
+ log message
25
+ $initialized ||= false
26
+ unless $initialized
27
+ $initialized = true
28
+ $test_start_time = Time.now
29
+ # HTML report header information if reporting is enabled
30
+ log Environ.report_header if ENV['REPORTING']
31
+ end
32
+ end
33
+
34
+
35
+ After do |scenario|
36
+ # process and embed any screenshots recorded during execution of scenario
37
+ process_embed_screenshots(scenario)
38
+ # clear out any queued screenshots
39
+ Environ.reset_contexts
40
+ # close any external pages that may have been opened
41
+ if Environ.external_page
42
+ Browsers.close_current_browser_instance
43
+ begin
44
+ page.driver.browser.switch_to.alert.accept
45
+ Browsers.switch_to_new_browser_instance
46
+ rescue
47
+ end
48
+ Environ.set_external_page(false)
49
+ end
50
+ # block any JavaScript modals that may appear as a result of ending the session
51
+ Browsers.suppress_js_leave_page_modal
52
+ # close Capybara Appium driver if it was opened
53
+ Capybara.page.driver.quit if Capybara.default_driver == :appium
54
+
55
+ if ENV['QUIT_DRIVER']
56
+ terminate_session
57
+ elsif Environ.grid == :browserstack
58
+ # restart BrowserStack test sessions if test duration exceeds 110 minutes to avoid the 2 hour test limit
59
+ test_elapsed_time = Time.now - $test_start_time
60
+ if test_elapsed_time > 6600
61
+ terminate_session
62
+ log 'Restarting BrowserStack test session'
63
+ $test_start_time = Time.now
64
+ else
65
+ Capybara.reset_sessions!
66
+ end
67
+ end
68
+ end
69
+
70
+
71
+ # exclusionary Around hooks to prevent running feature/scenario on unsupported browsers, devices, or
72
+ # cloud remote browser hosting platforms. Use the following tags to block test execution:
73
+ # desktop web browsers: @!safari, @!ie, @!firefox, @!chrome, @!edge
74
+ # mobile devices: @!ipad, @!iphone
75
+ # remotely hosted browsers: @!browserstack, @!saucelabs
76
+
77
+ # block feature/scenario execution if running against Safari browser
78
+ Around('@!safari') do |scenario, block|
79
+ qualify_browser(:safari, 'Safari', scenario, block)
80
+ end
81
+
82
+
83
+ # block feature/scenario execution if running against Internet Explorer browser
84
+ Around('@!ie') do |scenario, block|
85
+ qualify_browser(:ie, 'Internet Explorer', scenario, block)
86
+ end
87
+
88
+
89
+ # block feature/scenario execution if running against Microsoft Edge browser
90
+ Around('@!edge') do |scenario, block|
91
+ qualify_browser(:edge, 'Edge', scenario, block)
92
+ end
93
+
94
+
95
+ # block feature/scenario execution if running against Chrome browser
96
+ Around('@!chrome') do |scenario, block|
97
+ qualify_browser(:chrome, 'Chrome', scenario, block)
98
+ end
99
+
100
+
101
+ # block feature/scenario execution if running against Firefox browser
102
+ Around('@!firefox') do |scenario, block|
103
+ qualify_browser(:firefox, 'Firefox', scenario, block)
104
+ end
105
+
106
+
107
+ # block feature/scenario execution if running against iPad mobile browser
108
+ Around('@!ipad') do |scenario, block|
109
+ qualify_device('ipad', scenario, block)
110
+ end
111
+
112
+
113
+ # block feature/scenario execution if running against iPhone mobile browser
114
+ Around('@!iphone') do |scenario, block|
115
+ qualify_device('iphone', scenario, block)
116
+ end
117
+
118
+
119
+ # block feature/scenario execution if running on Selenium Grid or cloud-hosted services
120
+ Around('@!grid') do |scenario, block|
121
+ if !Environ.grid
122
+ block.call
123
+ else
124
+ log "Scenario '#{scenario.name}' cannot be executed on Selenium Grid or cloud-hosted services."
125
+ skip_this_scenario
126
+ end
127
+ end
128
+
129
+
130
+ # block feature/scenario execution if running against Browserstack cloud-hosted service
131
+ Around('@!browserstack') do |scenario, block|
132
+ if Environ.grid != :browserstack
133
+ block.call
134
+ else
135
+ log "Scenario '#{scenario.name}' cannot be executed on the BrowserStack service."
136
+ skip_this_scenario
137
+ end
138
+ end
139
+
140
+
141
+ # block feature/scenario execution if running against Sauce Labs cloud-hosted service
142
+ Around('@!saucelabs') do |scenario, block|
143
+ if Environ.grid != :saucelabs
144
+ block.call
145
+ else
146
+ log "Scenario '#{scenario.name}' cannot be executed on the SauceLabs service."
147
+ skip_this_scenario
148
+ end
149
+ end
150
+
151
+
152
+ # block feature/scenario execution if running against a physical or emulated mobile device
153
+ Around('@!device') do |scenario, block|
154
+ if Environ.is_device?
155
+ log "Scenario '#{scenario.name}' cannot be executed on physical or emulated devices."
156
+ skip_this_scenario
157
+ else
158
+ block.call
159
+ end
160
+ end
161
+
162
+
163
+ Around('@!ios') do |scenario, block|
164
+ if Environ.device_os == :android
165
+ block.call
166
+ else
167
+ log "Scenario '#{scenario.name}' can not be executed on iOS devices."
168
+ skip_this_scenario
169
+ end
170
+ end
171
+
172
+
173
+ Around('@!android') do |scenario, block|
174
+ if Environ.device_os == :ios
175
+ block.call
176
+ else
177
+ log "Scenario '#{scenario.name}' can not be executed on Android devices."
178
+ skip_this_scenario
179
+ end
180
+ end
181
+
182
+
183
+ Around('@!mobile') do |scenario, block|
184
+ if Environ.platform == :mobile
185
+ log "Scenario '#{scenario.name}' can not be executed on mobile devices or simulators."
186
+ skip_this_scenario
187
+ else
188
+ block.call
189
+ end
190
+ end
191
+
192
+
193
+ # supporting methods
194
+
195
+ def qualify_browser(browser_type, browser_name, scenario, block)
196
+ if Environ.browser != browser_type && ENV['HOST_BROWSER'] != browser_name.downcase
197
+ block.call
198
+ else
199
+ log "Scenario '#{scenario.name}' cannot be executed with the #{browser_name} browser."
200
+ skip_this_scenario
201
+ end
202
+ end
203
+
204
+ def qualify_device(device, scenario, block)
205
+ if Environ.is_device?
206
+ if Environ.device_type.include? device
207
+ log "Scenario '#{scenario.name}' cannot be executed on #{device} devices."
208
+ skip_this_scenario
209
+ else
210
+ block.call
211
+ end
212
+ else
213
+ block.call
214
+ end
215
+ end
216
+
217
+ def terminate_session
218
+ Capybara.page.driver.quit
219
+ Capybara.reset_sessions!
220
+ Environ.session_state = :quit
221
+ $driver_scenario_count = 0
222
+ end
223
+
224
+ def screen_shot_and_save_page(scenario)
225
+ timestamp = Time.now.strftime('%Y%m%d%H%M%S%L')
226
+ filename = scenario.nil? ? "Screenshot-#{timestamp}.png" : "Screenshot-#{scenario.__id__}-#{timestamp}.png"
227
+ path = File.join Dir.pwd, 'reports/screenshots/', filename
228
+ save_screenshot path
229
+ log "Screenshot saved at #{path}"
230
+ screen_shot = { path: path, filename: filename }
231
+ Environ.save_screen_shot(screen_shot)
232
+ attach(path, 'image/png') unless scenario.nil?
233
+ end
234
+
235
+ def process_embed_screenshots(scenario)
236
+ screen_shots = Environ.get_screen_shots
237
+ if screen_shots.count > 0
238
+ screen_shots.each do |row|
239
+ path = row[:path]
240
+ attach(path, 'image/png')
241
+ end
242
+ else
243
+ screen_shot_and_save_page(scenario) if scenario.failed?
244
+ end
245
+ end
@@ -0,0 +1,49 @@
1
+ # Page Object class definition for Basic HTML Test page with CSS locators
2
+
3
+ class BasicCSSTestPage < BasicTestPage
4
+ trait(:page_name) { 'Basic CSS Test' }
5
+ trait(:page_locator) { 'form#HTMLFormElements' }
6
+
7
+ # Basic HTML Test page UI elements
8
+ textfields username_field: 'input#username',
9
+ password_field: 'input#password',
10
+ max_length_field: 'input#maxlength',
11
+ read_only_field: 'input#readonly',
12
+ number_field: 'input#number-field',
13
+ color_picker: 'input#color-picker',
14
+ comments_field: 'textarea#comments'
15
+ range :slider, 'input#slider'
16
+ filefield :upload_file, 'input#filename'
17
+ checkboxes check_1: 'input#check1',
18
+ check_2: 'input#check2',
19
+ check_3: 'input#check3',
20
+ check_4: 'input#check4'
21
+ radios radio_1: 'input#radio1',
22
+ radio_2: 'input#radio2',
23
+ radio_3: 'input#radio3',
24
+ radio_4: 'input#radio4'
25
+ selectlists multi_select: 'select#multipleselect',
26
+ drop_down_select: 'select#dropdown'
27
+ table :static_table, 'table#table'
28
+ images image_1: 'img#image1',
29
+ image_2: 'img#image2',
30
+ image_3: 'img#image3'
31
+ buttons cancel_button: 'input#cancel',
32
+ submit_button: 'input#submit'
33
+ labels header_label: 'h1',
34
+ username_label: "label[for='username']",
35
+ password_label: "label[for='password']",
36
+ max_length_label: "label[for='maxlength']",
37
+ read_only_label: "label[for='readonly']",
38
+ number_label: "label[for='number-field']",
39
+ color_label: "label[for='color-picker']",
40
+ slider_label: "label[for='slider']",
41
+ comments_label: "label[for='comments']",
42
+ filename_label: "label[for='filename']",
43
+ checkboxes_label: 'label#checkboxes',
44
+ radios_label: 'label#radios',
45
+ multiselect_label: "label[for='multipleselect']",
46
+ dropdown_label: "label[for='dropdown']",
47
+ table_label: "label[for='table']",
48
+ images_label: 'label#images'
49
+ end