testcentricity_web 4.1.4 → 4.1.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +18 -0
  3. data/.simplecov +5 -0
  4. data/CHANGELOG.md +43 -1
  5. data/Gemfile.lock +60 -2
  6. data/README.md +166 -21
  7. data/Rakefile +60 -1
  8. data/config/cucumber.yml +163 -0
  9. data/config/test_data/data.json +12 -0
  10. data/config/test_data/data.xls +0 -0
  11. data/config/test_data/data.yml +12 -0
  12. data/docker-compose-v3.yml +48 -0
  13. data/features/basic_test_page_css.feature +35 -0
  14. data/features/basic_test_page_xpath.feature +27 -0
  15. data/features/media_players.feature +87 -0
  16. data/features/step_definitions/generic_steps.rb.rb +44 -0
  17. data/features/step_definitions/media_steps.rb +30 -0
  18. data/features/support/env.rb +50 -0
  19. data/features/support/hooks.rb +245 -0
  20. data/features/support/pages/base_test_page.rb +11 -0
  21. data/features/support/pages/basic_css_test_page.rb +52 -0
  22. data/features/support/pages/basic_test_page.rb +297 -0
  23. data/features/support/pages/basic_xpath_test_page.rb +53 -0
  24. data/features/support/pages/custom_controls_page.rb +16 -0
  25. data/features/support/pages/indexed_sections_page.rb +16 -0
  26. data/features/support/pages/media_test_page.rb +195 -0
  27. data/features/support/sections/header_nav.rb +28 -0
  28. data/features/support/world_data.rb +12 -0
  29. data/features/support/world_pages.rb +18 -0
  30. data/lib/testcentricity_web/data_objects/environment.rb +16 -0
  31. data/lib/testcentricity_web/version.rb +1 -1
  32. data/lib/testcentricity_web/web_core/page_object.rb +8 -8
  33. data/lib/testcentricity_web/web_core/page_objects_helper.rb +41 -8
  34. data/lib/testcentricity_web/web_core/page_section.rb +1 -16
  35. data/lib/testcentricity_web/web_core/webdriver_helper.rb +77 -120
  36. data/lib/testcentricity_web/web_elements/checkbox.rb +3 -4
  37. data/lib/testcentricity_web/web_elements/media.rb +50 -4
  38. data/lib/testcentricity_web/web_elements/radio.rb +5 -1
  39. data/lib/testcentricity_web/web_elements/select_list.rb +18 -7
  40. data/lib/testcentricity_web/web_elements/ui_elements_helper.rb +13 -0
  41. data/reports/.keep +1 -0
  42. data/test_site/basic_test_page.html +290 -0
  43. data/test_site/custom_controls_page.html +58 -0
  44. data/test_site/images/Granny.jpg +0 -0
  45. data/test_site/images/Wilder.jpg +0 -0
  46. data/test_site/images/You_Betcha.jpg +0 -0
  47. data/test_site/indexed_sections_page.html +58 -0
  48. data/test_site/media/MIB2-subtitles-pt-BR.vtt +49 -0
  49. data/test_site/media/MIB2.mp4 +0 -0
  50. data/test_site/media/MP4_small.mp4 +0 -0
  51. data/test_site/media/MPS_sample.mp3 +0 -0
  52. data/test_site/media_page.html +86 -0
  53. data/testcentricity_web.gemspec +5 -0
  54. metadata +125 -4
  55. data/test_site/test_page.html +0 -11
@@ -49,7 +49,7 @@ module TestCentricity
49
49
  context = case browser.downcase.to_sym
50
50
  when :appium
51
51
  initialize_appium
52
- 'mobile device emulator'
52
+ 'Appium'
53
53
  when :browserstack
54
54
  initialize_browserstack
55
55
  'Browserstack cloud service'
@@ -138,7 +138,6 @@ module TestCentricity
138
138
  Environ.device_orientation = ENV['ORIENTATION'] if ENV['ORIENTATION']
139
139
  Capybara.default_driver = :appium
140
140
  Environ.driver = :appium
141
- @endpoint = 'http://localhost:4723/wd/hub' if @endpoint.nil?
142
141
  desired_capabilities = {
143
142
  platformName: Environ.device_os,
144
143
  platformVersion: Environ.device_os_version,
@@ -190,14 +189,13 @@ module TestCentricity
190
189
  desired_capabilities[:systemPort] = ENV['SYSTEM_PORT'] if ENV['SYSTEM_PORT']
191
190
  end
192
191
 
193
- unless @capabilities.nil?
194
- desired_capabilities = @capabilities
195
- end
192
+ desired_capabilities = @capabilities unless @capabilities.nil?
193
+ # specify endpoint url
194
+ @endpoint = 'http://localhost:4723/wd/hub' if @endpoint.nil?
196
195
 
197
- Capybara.register_driver :appium do |app|
198
- appium_lib_options = { server_url: @endpoint }
196
+ Capybara.register_driver(:appium) do |app|
199
197
  all_options = {
200
- appium_lib: appium_lib_options,
198
+ appium_lib: { server_url: @endpoint },
201
199
  caps: desired_capabilities
202
200
  }
203
201
  Appium::Capybara::Driver.new(app, all_options)
@@ -233,63 +231,18 @@ module TestCentricity
233
231
  when :safari, :ie
234
232
  Capybara::Selenium::Driver.new(app, browser: browser)
235
233
  when :firefox, :firefox_headless
236
- profile = Selenium::WebDriver::Firefox::Profile.new
237
- profile['browser.download.dir'] = @downloads_path
238
- profile['browser.download.folderList'] = 2
239
- profile['browser.download.manager.showWhenStarting'] = false
240
- profile['browser.download.manager.closeWhenDone'] = true
241
- profile['browser.download.manager.showAlertOnComplete'] = false
242
- profile['browser.download.manager.alertOnEXEOpen'] = false
243
- profile['browser.download.manager.useWindow'] = false
244
- profile['browser.helperApps.alwaysAsk.force'] = false
245
- profile['pdfjs.disabled'] = true
246
-
247
- mime_types = ENV['MIME_TYPES'] || 'images/jpeg, application/pdf, application/octet-stream'
248
- profile['browser.helperApps.neverAsk.saveToDisk'] = mime_types
249
-
250
- profile['intl.accept_languages'] = ENV['LOCALE'] if ENV['LOCALE']
251
- options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
252
- options.args << '--headless' if browser == :firefox_headless
234
+ options = firefox_options(browser)
253
235
  Capybara::Selenium::Driver.new(app, browser: :firefox, capabilities: [options])
254
236
  when :chrome, :chrome_headless
255
- options = Selenium::WebDriver::Chrome::Options.new(options: {'excludeSwitches' => ['enable-automation']})
256
- prefs = {
257
- prompt_for_download: false,
258
- directory_upgrade: true,
259
- default_directory: @downloads_path
260
- }
261
- options.add_preference(:download, prefs)
262
- options.add_argument('--disable-dev-shm-usage')
263
- options.add_argument("--lang=#{ENV['LOCALE']}") if ENV['LOCALE']
264
- if browser == :chrome_headless
265
- options.add_argument('--headless')
266
- options.add_argument('--disable-gpu')
267
- options.add_argument('--no-sandbox')
268
- end
269
-
237
+ options = chrome_edge_options(browser)
270
238
  Capybara::Selenium::Driver.new(app, browser: :chrome, capabilities: [options])
271
239
  when :edge, :edge_headless
272
- options = Selenium::WebDriver::Edge::Options.new(options: {'excludeSwitches' => ['enable-automation']})
273
- prefs = {
274
- prompt_for_download: false,
275
- directory_upgrade: true,
276
- default_directory: @downloads_path
277
- }
278
- options.add_preference(:download, prefs)
279
- options.add_argument('--disable-dev-shm-usage')
280
- options.add_argument("--lang=#{ENV['LOCALE']}") if ENV['LOCALE']
281
- if browser == :edge_headless
282
- options.add_argument('--headless')
283
- options.add_argument('--disable-gpu')
284
- options.add_argument('--no-sandbox')
285
- end
286
-
240
+ options = chrome_edge_options(browser)
287
241
  Capybara::Selenium::Driver.new(app, browser: :edge, capabilities: [options])
288
242
  else
289
243
  if ENV['HOST_BROWSER'] && ENV['HOST_BROWSER'].downcase.to_sym == :chrome
290
244
  user_agent = Browsers.mobile_device_agent(ENV['WEB_BROWSER'])
291
245
  options = Selenium::WebDriver::Chrome::Options.new(options: {'excludeSwitches' => ['enable-automation']})
292
- options.add_argument('--disable-infobars')
293
246
  options.add_argument('--disable-dev-shm-usage')
294
247
  options.add_argument("--user-agent='#{user_agent}'")
295
248
  options.add_argument("--lang=#{ENV['LOCALE']}") if ENV['LOCALE']
@@ -452,74 +405,31 @@ module TestCentricity
452
405
  Environ.grid = :selenium_grid
453
406
  browser = ENV['WEB_BROWSER'].downcase.to_sym
454
407
  @endpoint = ENV['REMOTE_ENDPOINT'] || 'http://127.0.0.1:4444/wd/hub' if @endpoint.nil?
455
- Capybara.register_driver :remote_browser do |app|
456
- case browser
457
- when :safari
458
- options = Selenium::WebDriver::Safari::Options.new
459
- when :ie
460
- options = Selenium::WebDriver::IE::Options.new
461
- when :firefox, :firefox_headless
462
- profile = Selenium::WebDriver::Firefox::Profile.new
463
- profile['browser.download.dir'] = @downloads_path
464
- profile['browser.download.folderList'] = 2
465
- profile['browser.download.manager.showWhenStarting'] = false
466
- profile['browser.download.manager.closeWhenDone'] = true
467
- profile['browser.download.manager.showAlertOnComplete'] = false
468
- profile['browser.download.manager.alertOnEXEOpen'] = false
469
- profile['browser.download.manager.useWindow'] = false
470
- profile['browser.helperApps.alwaysAsk.force'] = false
471
- profile['pdfjs.disabled'] = true
472
-
473
- mime_types = ENV['MIME_TYPES'] || 'images/jpeg, application/pdf, application/octet-stream'
474
- profile['browser.helperApps.neverAsk.saveToDisk'] = mime_types
475
-
476
- profile['intl.accept_languages'] = ENV['LOCALE'] if ENV['LOCALE']
477
- options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
478
- options.args << '--headless' if browser == :firefox_headless
479
- when :chrome, :chrome_headless
408
+
409
+ case browser
410
+ when :safari
411
+ options = Selenium::WebDriver::Safari::Options.new
412
+ when :ie
413
+ options = Selenium::WebDriver::IE::Options.new
414
+ when :firefox, :firefox_headless
415
+ options = firefox_options(browser)
416
+ when :chrome, :chrome_headless, :edge, :edge_headless
417
+ options = chrome_edge_options(browser)
418
+ else
419
+ if ENV['HOST_BROWSER'] && ENV['HOST_BROWSER'].downcase.to_sym == :chrome
420
+ Environ.platform = :mobile
421
+ Environ.device_name = Browsers.mobile_device_name(ENV['WEB_BROWSER'])
422
+ user_agent = Browsers.mobile_device_agent(ENV['WEB_BROWSER'])
480
423
  options = Selenium::WebDriver::Chrome::Options.new(options: {'excludeSwitches' => ['enable-automation']})
481
- prefs = {
482
- prompt_for_download: false,
483
- directory_upgrade: true,
484
- default_directory: @downloads_path
485
- }
486
- options.add_preference(:download, prefs)
487
- options.add_argument('--disable-dev-shm-usage')
488
- options.add_argument("--lang=#{ENV['LOCALE']}") if ENV['LOCALE']
489
- if browser == :chrome_headless
490
- options.add_argument('--headless')
491
- options.add_argument('--disable-gpu')
492
- options.add_argument('--no-sandbox')
493
- end
494
- when :edge, :edge_headless
495
- options = Selenium::WebDriver::Edge::Options.new(options: {'excludeSwitches' => ['enable-automation']})
496
- prefs = {
497
- prompt_for_download: false,
498
- directory_upgrade: true,
499
- default_directory: @downloads_path
500
- }
501
- options.add_preference(:download, prefs)
502
424
  options.add_argument('--disable-dev-shm-usage')
425
+ options.add_argument("--user-agent='#{user_agent}'")
503
426
  options.add_argument("--lang=#{ENV['LOCALE']}") if ENV['LOCALE']
504
- if browser == :edge_headless
505
- options.add_argument('--headless')
506
- options.add_argument('--disable-gpu')
507
- options.add_argument('--no-sandbox')
508
- end
509
427
  else
510
- if ENV['HOST_BROWSER'] && ENV['HOST_BROWSER'].downcase.to_sym == :chrome
511
- Environ.platform = :mobile
512
- Environ.device_name = Browsers.mobile_device_name(ENV['WEB_BROWSER'])
513
- user_agent = Browsers.mobile_device_agent(ENV['WEB_BROWSER'])
514
- options = Selenium::WebDriver::Chrome::Options.new(options: {'excludeSwitches' => ['enable-automation']})
515
- options.add_argument('--disable-infobars')
516
- options.add_argument('--disable-dev-shm-usage')
517
- options.add_argument("--user-agent='#{user_agent}'")
518
- options.add_argument("--lang=#{ENV['LOCALE']}") if ENV['LOCALE']
519
- else
520
- raise "Requested browser '#{browser}' is not supported on Selenium Grid"
521
- end
428
+ raise "Requested browser '#{browser}' is not supported on Selenium Grid"
522
429
  end
430
+ end
431
+
432
+ Capybara.register_driver :remote_browser do |app|
523
433
  Capybara::Selenium::Driver.new(app,
524
434
  browser: :remote,
525
435
  url: @endpoint,
@@ -645,6 +555,50 @@ module TestCentricity
645
555
  config_file_uploads unless ENV['TB_PLATFORM']
646
556
  end
647
557
 
558
+ def self.chrome_edge_options(browser)
559
+ options = case browser
560
+ when :chrome, :chrome_headless
561
+ Selenium::WebDriver::Chrome::Options.new(options: {'excludeSwitches' => ['enable-automation']})
562
+ when :edge, :edge_headless
563
+ Selenium::WebDriver::Edge::Options.new(options: {'excludeSwitches' => ['enable-automation']})
564
+ end
565
+ prefs = {
566
+ prompt_for_download: false,
567
+ directory_upgrade: true,
568
+ default_directory: @downloads_path
569
+ }
570
+ options.add_preference(:download, prefs)
571
+ options.add_argument('--disable-dev-shm-usage')
572
+ options.add_argument("--lang=#{ENV['LOCALE']}") if ENV['LOCALE']
573
+ if browser == :chrome_headless || browser == :edge_headless
574
+ options.add_argument('--headless')
575
+ options.add_argument('--disable-gpu')
576
+ options.add_argument('--no-sandbox')
577
+ end
578
+ options
579
+ end
580
+
581
+ def self.firefox_options(browser)
582
+ profile = Selenium::WebDriver::Firefox::Profile.new
583
+ profile['browser.download.dir'] = @downloads_path
584
+ profile['browser.download.folderList'] = 2
585
+ profile['browser.download.manager.showWhenStarting'] = false
586
+ profile['browser.download.manager.closeWhenDone'] = true
587
+ profile['browser.download.manager.showAlertOnComplete'] = false
588
+ profile['browser.download.manager.alertOnEXEOpen'] = false
589
+ profile['browser.download.manager.useWindow'] = false
590
+ profile['browser.helperApps.alwaysAsk.force'] = false
591
+ profile['pdfjs.disabled'] = true
592
+
593
+ mime_types = ENV['MIME_TYPES'] || 'images/jpeg, application/pdf, application/octet-stream'
594
+ profile['browser.helperApps.neverAsk.saveToDisk'] = mime_types
595
+
596
+ profile['intl.accept_languages'] = ENV['LOCALE'] if ENV['LOCALE']
597
+ options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
598
+ options.args << '--headless' if browser == :firefox_headless
599
+ options
600
+ end
601
+
648
602
  def self.test_context_message
649
603
  context_message = if ENV['TEST_CONTEXT']
650
604
  "#{Environ.test_environment.to_s.upcase} - #{ENV['TEST_CONTEXT']}"
@@ -662,7 +616,10 @@ module TestCentricity
662
616
  def self.register_remote_driver(driver, browser, options)
663
617
  Capybara.register_driver driver do |app|
664
618
  capabilities = Selenium::WebDriver::Remote::Capabilities.send(browser.gsub(/\s+/, '_').downcase.to_sym, options)
665
- Capybara::Selenium::Driver.new(app, browser: :remote, url: @endpoint, capabilities: capabilities)
619
+ Capybara::Selenium::Driver.new(app,
620
+ browser: :remote,
621
+ url: @endpoint,
622
+ capabilities: capabilities)
666
623
  end
667
624
 
668
625
  Environ.browser = browser
@@ -112,11 +112,10 @@ module TestCentricity
112
112
  object_not_found_exception(obj, 'Checkbox')
113
113
  invalid_object_type_exception(obj, 'checkbox')
114
114
  if @proxy.nil?
115
- if obj.native.attribute('ot') == 'JCheckBox'
116
- expected = state.to_bool
117
- obj.click unless expected == obj.checked?
118
- else
115
+ begin
119
116
  obj.set(state)
117
+ rescue
118
+ obj.click unless state == obj.checked?
120
119
  end
121
120
  else
122
121
  page.find(:css, @proxy).click unless state == obj.checked?
@@ -125,7 +125,7 @@ module TestCentricity
125
125
  def current_time
126
126
  obj, = find_element(visible = :all)
127
127
  object_not_found_exception(obj, @type)
128
- obj.native.attribute('currentTime').to_f
128
+ obj.native.attribute('currentTime').to_f.round(2)
129
129
  end
130
130
 
131
131
  # Return media defaultPlaybackRate property
@@ -137,7 +137,7 @@ module TestCentricity
137
137
  def default_playback_rate
138
138
  obj, = find_element(visible = :all)
139
139
  object_not_found_exception(obj, @type)
140
- obj.native.attribute('defaultPlaybackRate')
140
+ obj.native.attribute('defaultPlaybackRate').to_f
141
141
  end
142
142
 
143
143
  # Return media duration property
@@ -149,7 +149,7 @@ module TestCentricity
149
149
  def duration
150
150
  obj, = find_element(visible = :all)
151
151
  object_not_found_exception(obj, @type)
152
- obj.native.attribute('duration').to_f
152
+ obj.native.attribute('duration').to_f.round(2)
153
153
  end
154
154
 
155
155
  # Return media playbackRate property
@@ -161,7 +161,7 @@ module TestCentricity
161
161
  def playback_rate
162
162
  obj, = find_element(visible = :all)
163
163
  object_not_found_exception(obj, @type)
164
- obj.native.attribute('playbackRate')
164
+ obj.native.attribute('playbackRate').to_f
165
165
  end
166
166
 
167
167
  # Return media readyState property
@@ -247,6 +247,52 @@ module TestCentricity
247
247
  page.execute_script('arguments[0].pause()', obj)
248
248
  end
249
249
 
250
+ # Mute the media's audio
251
+ #
252
+ # @example
253
+ # media_player.mute
254
+ #
255
+ def mute
256
+ obj, = find_element(visible = :all)
257
+ object_not_found_exception(obj, @type)
258
+ page.execute_script('arguments[0].muted = true;', obj)
259
+ end
260
+
261
+ # Unmute the media's audio
262
+ #
263
+ # @example
264
+ # media_player.unmute
265
+ #
266
+ def unmute
267
+ obj, = find_element(visible = :all)
268
+ object_not_found_exception(obj, @type)
269
+ page.execute_script('arguments[0].muted = false;', obj)
270
+ end
271
+
272
+ # Set the media playbackRate property
273
+ #
274
+ # @param value [Float]
275
+ # @example
276
+ # media_player.playback_rate = 1.5
277
+ #
278
+ def playback_rate=(value)
279
+ obj, = find_element(visible = :all)
280
+ object_not_found_exception(obj, @type)
281
+ page.execute_script('arguments[0].playbackRate = arguments[1]', obj, value)
282
+ end
283
+
284
+ # Set the media volume property
285
+ #
286
+ # @param value [Float] between 0 and 1
287
+ # @example
288
+ # media_player.volume = 0.5
289
+ #
290
+ def volume=(value)
291
+ obj, = find_element(visible = :all)
292
+ object_not_found_exception(obj, @type)
293
+ page.execute_script('arguments[0].volume = arguments[1]', obj, value)
294
+ end
295
+
250
296
  # Return media crossorigin property
251
297
  #
252
298
  # @return crossorigin value
@@ -101,7 +101,11 @@ module TestCentricity
101
101
  object_not_found_exception(obj, 'Radio')
102
102
  invalid_object_type_exception(obj, 'radio')
103
103
  if @proxy.nil?
104
- obj.set(state)
104
+ begin
105
+ obj.set(state)
106
+ rescue
107
+ obj.click unless state == obj.checked?
108
+ end
105
109
  else
106
110
  page.find(:css, @proxy).click unless state == obj.checked?
107
111
  end
@@ -246,13 +246,24 @@ module TestCentricity
246
246
  def get_selected_option
247
247
  @base_object, = find_element
248
248
  object_not_found_exception(@base_object, nil)
249
- if @base_object.first(:css, @list_item, minimum: 0)
250
- @base_object.first(:css, @selected_item).text
251
- elsif @base_object.first(:css, @selected_item, minimum: 0)
252
- @base_object.first(:css, @selected_item).text
253
- else
254
- @base_object.first('option[selected]', visible: :all).text
255
- end
249
+ trigger_list unless @options_list.nil?
250
+ selection = if @base_object.first(:css, @list_item, minimum: 0, wait: 1, visible: :all)
251
+ @base_object.first(:css, @selected_item, wait: 1, visible: :all).text
252
+ elsif @base_object.first(:css, @selected_item, minimum: 0, wait: 1, visible: :all)
253
+ @base_object.first(:css, @selected_item, visible: :all).text
254
+ elsif @base_object.first('option[selected]', minimum: 0, wait: 1, visible: :all)
255
+ @base_object.first('option[selected]', wait: 1, visible: :all).text
256
+ else
257
+ index = get_attribute(:selectedIndex).to_i
258
+ if index >= 0
259
+ options = get_options
260
+ options[index]
261
+ else
262
+ ''
263
+ end
264
+ end
265
+ trigger_list unless @options_list.nil?
266
+ selection
256
267
  end
257
268
 
258
269
  alias selected? get_selected_option
@@ -264,6 +264,19 @@ module TestCentricity
264
264
  obj.disabled?
265
265
  end
266
266
 
267
+ # Is UI object's required attribute set?
268
+ #
269
+ # @return [Boolean]
270
+ # @example
271
+ # first_name_field.required?
272
+ #
273
+ def required?
274
+ obj, type = find_element
275
+ object_not_found_exception(obj, type)
276
+ state = get_attribute(:required)
277
+ state.boolean? ? state : state == 'true'
278
+ end
279
+
267
280
  # Is UI object obscured (not currently in viewport and not clickable)?
268
281
  #
269
282
  # @return [Boolean]
data/reports/.keep ADDED
@@ -0,0 +1 @@
1
+ Placeholder file to allow the reports folder to be saved to repository. This folder is required for Jenkins test jobs using the Cucumber Reporting plug-in.