testcentricity_web 4.1.5 → 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 (37) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +18 -0
  3. data/.simplecov +5 -0
  4. data/CHANGELOG.md +14 -0
  5. data/Gemfile.lock +59 -1
  6. data/README.md +14 -6
  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_elements/select_list.rb +11 -3
  26. data/lib/testcentricity_web/web_elements/ui_elements_helper.rb +13 -0
  27. data/reports/.keep +1 -0
  28. data/test_site/basic_test_page.html +240 -0
  29. data/test_site/images/Granny.jpg +0 -0
  30. data/test_site/images/Wilder.jpg +0 -0
  31. data/test_site/images/You_Betcha.jpg +0 -0
  32. data/test_site/media/MP4_small.mp4 +0 -0
  33. data/test_site/media/MPS_sample.mp3 +0 -0
  34. data/test_site/media_page.html +33 -0
  35. data/testcentricity_web.gemspec +5 -0
  36. metadata +104 -4
  37. data/test_site/test_page.html +0 -11
@@ -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
@@ -0,0 +1,238 @@
1
+ # Page Object class definition for Basic HTML Test page
2
+
3
+ class BasicTestPage < TestCentricity::PageObject
4
+ trait(:page_url) { '/basic_test_page.html' }
5
+ trait(:tab_order) {
6
+ [
7
+ username_field,
8
+ password_field,
9
+ max_length_field,
10
+ read_only_field,
11
+ number_field,
12
+ color_picker,
13
+ slider,
14
+ comments_field,
15
+ upload_file,
16
+ check_1,
17
+ check_2,
18
+ check_3,
19
+ radio_1,
20
+ [
21
+ radio_2,
22
+ radio_3
23
+ ],
24
+ multi_select,
25
+ drop_down_select,
26
+ cancel_button,
27
+ submit_button
28
+ ]
29
+ }
30
+ trait(:safari_tab_order) {
31
+ [
32
+ username_field,
33
+ password_field,
34
+ max_length_field,
35
+ read_only_field,
36
+ number_field,
37
+ comments_field,
38
+ multi_select,
39
+ drop_down_select
40
+ ]
41
+ }
42
+
43
+ def verify_page_ui
44
+ ui = {
45
+ self => { exists: true, secure: false, title: 'Basic HTML Form' },
46
+ header_label => { visible: true, caption: 'Basic HTML Form Example' },
47
+ username_label => { visible: true, caption: 'Username:' },
48
+ username_field => { visible: true, enabled: true, required: true, value: '', placeholder: 'User name' },
49
+ password_label => { visible: true, caption: 'Password:' },
50
+ password_field => { visible: true, enabled: true, required: true, value: '', placeholder: 'Password' },
51
+ max_length_label => { visible: true, caption: 'Max Length:' },
52
+ max_length_field => {
53
+ visible: true,
54
+ enabled: true,
55
+ placeholder: 'up to 64 characters',
56
+ value: '',
57
+ maxlength: 64
58
+ },
59
+ read_only_label => { visible: true, caption: 'Read Only:' },
60
+ read_only_field => {
61
+ visible: true,
62
+ enabled: true,
63
+ readonly: true,
64
+ value: 'I am a read only text field'
65
+ },
66
+ number_label => { visible: true, caption: 'Number:' },
67
+ number_field => {
68
+ visible: true,
69
+ enabled: true,
70
+ value: '41',
71
+ min: 10,
72
+ max: 1024,
73
+ step: 1
74
+ },
75
+ color_label => { visible: true, caption: 'Color:' },
76
+ color_picker => { visible: true, enabled: true, value: '#000000' },
77
+ slider_label => { visible: true, caption: 'Range:' },
78
+ slider => {
79
+ visible: true,
80
+ enabled: true,
81
+ value: 25,
82
+ min: 0,
83
+ max: 50,
84
+ },
85
+ comments_label => { visible: true, caption: 'TextArea:' },
86
+ comments_field => { visible: true, enabled: true, value: '' },
87
+ filename_label => { visible: true, caption: 'Filename:' },
88
+ upload_file => { visible: true, enabled: true, value: '' },
89
+ checkboxes_label => { visible: true, caption: 'Checkbox Items:' },
90
+ check_1 => { visible: true, enabled: true, checked: false },
91
+ check_2 => { visible: true, enabled: true, checked: false },
92
+ check_3 => { visible: true, enabled: true, checked: false },
93
+ check_4 => { visible: true, enabled: false, checked: false },
94
+ radios_label => { visible: true, caption: 'Radio Items:' },
95
+ radio_1 => { visible: true, enabled: true, selected: false },
96
+ radio_2 => { visible: true, enabled: true, selected: false },
97
+ radio_3 => { visible: true, enabled: true, selected: false },
98
+ radio_4 => { visible: true, enabled: false, selected: false },
99
+ multiselect_label => { visible: true, caption: 'Multiple Select Values:' },
100
+ multi_select => {
101
+ visible: true,
102
+ enabled: true,
103
+ optioncount: 4,
104
+ options: ['Selection Item 1', 'Selection Item 2', 'Selection Item 3', 'Selection Item 4'],
105
+ selected: ''
106
+ },
107
+ dropdown_label => { visible: true, caption: 'Dropdown:' },
108
+ drop_down_select => {
109
+ visible: true,
110
+ enabled: true,
111
+ optioncount: 6,
112
+ options: ['Drop Down Item 1', 'Drop Down Item 2', 'Drop Down Item 3', 'Drop Down Item 4', 'Drop Down Item 5', 'Drop Down Item 6'],
113
+ selected: 'Drop Down Item 1'
114
+ },
115
+ table_label => { visible: true, caption: 'Table:' },
116
+ static_table => {
117
+ visible: true,
118
+ columncount: 3,
119
+ rowcount: 4,
120
+ column_headers: %w[Company Contact Country],
121
+ { row: 1 } => [['Alfreds Futterkiste', 'Maria Anders', 'Germany']],
122
+ { row: 2 } => [['Centro comercial Moctezuma', 'Francisco Chang', 'Mexico']],
123
+ { row: 3 } => [['Ernst Handel', 'Roland Mendel', 'Austria']],
124
+ { row: 4 } => [['Island Trading', 'Helen Bennett', 'UK']]
125
+ },
126
+ images_label => { visible: true, caption: 'Images:' },
127
+ image_1 => {
128
+ visible: true,
129
+ broken: false,
130
+ src: { ends_with: 'images/Wilder.jpg' },
131
+ alt: "It's alive"
132
+ },
133
+ image_2 => {
134
+ visible: true,
135
+ broken: false,
136
+ src: { ends_with: 'images/You_Betcha.jpg' },
137
+ alt: 'You Betcha'
138
+ },
139
+ image_3 => {
140
+ visible: true,
141
+ broken: true,
142
+ src: { ends_with: 'wrongname.gif' },
143
+ alt: 'A broken image'
144
+ },
145
+ cancel_button => { visible: true, enabled: true, caption: 'Cancel' },
146
+ submit_button => { visible: true, enabled: true, caption: 'Submit' }
147
+ }
148
+ verify_ui_states(ui)
149
+ end
150
+
151
+ def form_data
152
+ file_path = Environ.platform == :mobile ? nil : "#{Dir.pwd}/test_site/images/Wilder.jpg"
153
+ {
154
+ username: Faker::Name.name,
155
+ password: 'T0p_Sekrit',
156
+ maxlength: Faker::Marketing.buzzwords,
157
+ number: Faker::Number.between(from: 10, to: 1024),
158
+ color: Faker::Color.hex_color,
159
+ slider: 45,
160
+ comments: Faker::Hipster.paragraph,
161
+ filepath: file_path,
162
+ filename: "Wilder.jpg",
163
+ check1: true,
164
+ check2: true,
165
+ check3: false,
166
+ radio1: true,
167
+ radio2: false,
168
+ radio3: false,
169
+ multi_select: 'Selection Item 2',
170
+ drop_select: 'Drop Down Item 5'
171
+ }
172
+ end
173
+
174
+ def populate_form
175
+ @data = form_data
176
+ fields = {
177
+ username_field => @data[:username],
178
+ password_field => @data[:password],
179
+ max_length_field => @data[:maxlength],
180
+ number_field => @data[:number],
181
+ color_picker => @data[:color],
182
+ slider => @data[:slider],
183
+ comments_field => @data[:comments],
184
+ upload_file => @data[:filepath],
185
+ check_1 => @data[:check1],
186
+ check_2 => @data[:check2],
187
+ check_3 => @data[:check3],
188
+ radio_1 => @data[:radio1],
189
+ radio_2 => @data[:radio2],
190
+ radio_3 => @data[:radio3],
191
+ multi_select => @data[:multi_select],
192
+ drop_down_select => @data[:drop_select]
193
+ }
194
+ populate_data_fields(fields)
195
+ end
196
+
197
+ def verify_form_data
198
+ ui = {
199
+ username_field => { value: @data[:username] },
200
+ password_field => { value: @data[:password] },
201
+ max_length_field => { value: @data[:maxlength] },
202
+ number_field => { value: @data[:number].to_s },
203
+ color_picker => { value: @data[:color] },
204
+ slider => { value: @data[:slider] },
205
+ comments_field => { value: @data[:comments] },
206
+ upload_file => { value: { ends_with: @data[:filename] } },
207
+ check_1 => { checked: @data[:check1] },
208
+ check_2 => { checked: @data[:check2] },
209
+ check_3 => { checked: @data[:check3] },
210
+ radio_1 => { selected: @data[:radio1] },
211
+ radio_2 => { selected: @data[:radio2] },
212
+ radio_3 => { selected: @data[:radio3] },
213
+ multi_select => { selected: @data[:multi_select] },
214
+ drop_down_select => { selected: @data[:drop_select] }
215
+ }
216
+ verify_ui_states(ui)
217
+ end
218
+
219
+ def perform_action(action)
220
+ case action
221
+ when :submit
222
+ submit_button.click
223
+ when :cancel
224
+ cancel_button.click
225
+ else
226
+ raise "#{action} is not a valid selector"
227
+ end
228
+ end
229
+
230
+ def verify_tab_order
231
+ order = if Environ.browser == :safari
232
+ safari_tab_order
233
+ else
234
+ tab_order
235
+ end
236
+ verify_focus_order(order)
237
+ end
238
+ end
@@ -0,0 +1,49 @@
1
+ # Page Object class definition for Basic HTML Test page with Xpath locators
2
+
3
+ class BasicXpathTestPage < BasicTestPage
4
+ trait(:page_name) { 'Basic Xpath Test' }
5
+ trait(:page_locator) { "//form[@id='HTMLFormElements']" }
6
+
7
+ # Basic HTML Test page UI elements
8
+ textfields username_field: "//input[@id='username']",
9
+ password_field: "//input[@id='password']",
10
+ max_length_field: "//input[@id='maxlength']",
11
+ read_only_field: "//input[@id='readonly']",
12
+ number_field: "//input[@id='number-field']",
13
+ comments_field: "//textarea[@id='comments']",
14
+ color_picker: "//input[@id='color-picker']"
15
+ range :slider, "//input[@id='slider']"
16
+ filefield :upload_file, "//input[@id='filename']"
17
+ checkboxes check_1: "//input[@id='check1']",
18
+ check_2: "//input[@id='check2']",
19
+ check_3: "//input[@id='check3']",
20
+ check_4: "//input[@id='check4']"
21
+ radios radio_1: "//input[@id='radio1']",
22
+ radio_2: "//input[@id='radio2']",
23
+ radio_3: "//input[@id='radio3']",
24
+ radio_4: "//input[@id='radio4']"
25
+ selectlists multi_select: "//select[@id='multipleselect']",
26
+ drop_down_select: "//select[@id='dropdown']"
27
+ table :static_table, "//table[@id='table']"
28
+ images image_1: "//img[@id='image1']",
29
+ image_2: "//img[@id='image2']",
30
+ image_3: "//img[@id='image3']"
31
+ buttons cancel_button: "//input[@id='cancel']",
32
+ submit_button: "//input[@id='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[@id='checkboxes']",
44
+ radios_label: "//label[@id='radios']",
45
+ multiselect_label: "//label[@for='multipleselect']",
46
+ dropdown_label: "//label[@for='dropdown']",
47
+ table_label: "//label[@for='table']",
48
+ images_label: "//label[@id='images']"
49
+ end
@@ -0,0 +1,11 @@
1
+ # Page Object class definition for Media Test page with CSS locators
2
+
3
+ class MediaTestPage < TestCentricity::PageObject
4
+ trait(:page_name) { 'Media Test' }
5
+ trait(:page_locator) { 'div.media-page-body' }
6
+ trait(:page_url) { '/media_page.html' }
7
+
8
+ # Media Test page UI elements
9
+ video :video_player, 'video#video_player'
10
+ audio :audio_player, 'audio#audio_player'
11
+ end
@@ -0,0 +1,15 @@
1
+ module WorldPages
2
+ #
3
+ # page_objects method returns a hash table of your web app's page objects and associated page classes to be instantiated
4
+ # by the TestCentricity™ PageManager. Page Object class definitions are contained in the features/support/pages folder.
5
+ #
6
+ def page_objects
7
+ {
8
+ basic_css_test_page: BasicCSSTestPage,
9
+ basic_xpath_test_page: BasicXpathTestPage,
10
+ }
11
+ end
12
+ end
13
+
14
+
15
+ World(WorldPages)
@@ -328,6 +328,10 @@ module TestCentricity
328
328
  @platform = platform
329
329
  end
330
330
 
331
+ def self.platform
332
+ @platform
333
+ end
334
+
331
335
  def self.is_mobile?
332
336
  @platform == :mobile
333
337
  end
@@ -1,3 +1,3 @@
1
1
  module TestCentricityWeb
2
- VERSION = '4.1.5'
2
+ VERSION = '4.1.6'
3
3
  end
@@ -1,5 +1,9 @@
1
1
  module TestCentricity
2
2
  class PageObject < BasePageSectionObject
3
+ def initialize
4
+ set_locator_type(page_locator) if defined?(page_locator)
5
+ end
6
+
3
7
  # Declare and instantiate a single generic UI Element for this page object.
4
8
  #
5
9
  # @param element_name [Symbol] name of UI object (as a symbol)
@@ -310,17 +314,20 @@ module TestCentricity
310
314
  def open_portal
311
315
  environment = Environ.current
312
316
  url = environment.hostname.blank? ? "#{environment.base_url}#{environment.append}" : "#{environment.hostname}/#{environment.base_url}#{environment.append}"
313
- if environment.user_id.blank? || environment.password.blank?
314
- visit "#{environment.protocol}://#{url}"
315
- else
316
- visit "#{environment.protocol}://#{environment.user_id}:#{environment.password}@#{url}"
317
- end
317
+ full_url = if environment.user_id.blank? || environment.password.blank?
318
+ "#{environment.protocol}://#{url}"
319
+ else
320
+ "#{environment.protocol}://#{environment.user_id}:#{environment.password}@#{url}"
321
+ end
322
+ visit full_url
318
323
  Environ.portal_state = :open
319
324
  end
320
325
 
321
326
  def verify_page_exists
322
327
  raise "Page object #{self.class.name} does not have a page_locator trait defined" unless defined?(page_locator)
323
- unless page.has_selector?(page_locator)
328
+
329
+ set_locator_type(page_locator) if @locator_type.blank?
330
+ unless page.has_selector?(@locator_type, page_locator)
324
331
  body_class = find(:xpath, '//body')[:class]
325
332
  error_message = %(
326
333
  Expected page to have selector '#{page_locator}' but found '#{body_class}' instead.