testcentricity_web 4.1.6 → 4.1.9

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 (116) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.rspec +2 -1
  4. data/.ruby-version +1 -0
  5. data/.simplecov +5 -1
  6. data/CHANGELOG.md +43 -0
  7. data/README.md +14 -13
  8. data/Rakefile +99 -21
  9. data/config/cucumber.yml +32 -11
  10. data/config/locales/en-US.yml +56 -0
  11. data/config/test_data/LOCAL_data.json +15 -0
  12. data/config/test_data/LOCAL_data.xls +0 -0
  13. data/config/test_data/LOCAL_data.yml +11 -0
  14. data/config/test_data/data.json +25 -0
  15. data/config/test_data/data.xls +0 -0
  16. data/config/test_data/data.yml +20 -0
  17. data/{docker-compose-v3.yml → docker-compose.yml} +2 -2
  18. data/features/basic_form_page_css.feature +54 -0
  19. data/features/basic_form_page_xpath.feature +26 -0
  20. data/features/custom_controls.feature +29 -0
  21. data/features/media_players.feature +67 -0
  22. data/features/step_definitions/generic_steps.rb.rb +87 -0
  23. data/features/step_definitions/media_steps.rb +30 -0
  24. data/features/support/data/form_data.rb +43 -0
  25. data/features/support/env.rb +18 -10
  26. data/features/support/hooks.rb +26 -1
  27. data/features/support/pages/base_test_page.rb +22 -0
  28. data/features/support/pages/{basic_css_test_page.rb → basic_css_form_page.rb} +12 -8
  29. data/features/support/pages/{basic_test_page.rb → basic_form_page.rb} +227 -36
  30. data/features/support/pages/{basic_xpath_test_page.rb → basic_xpath_form_page.rb} +12 -7
  31. data/features/support/pages/custom_controls_page.rb +263 -0
  32. data/features/support/pages/indexed_sections_page.rb +57 -0
  33. data/features/support/pages/media_test_page.rb +207 -0
  34. data/features/support/sections/header_nav.rb +48 -0
  35. data/features/support/sections/product_card.rb +39 -0
  36. data/features/support/world_data.rb +12 -0
  37. data/features/support/world_pages.rb +5 -2
  38. data/lib/testcentricity_web/appium_server.rb +5 -0
  39. data/lib/testcentricity_web/browser_helper.rb +0 -6
  40. data/lib/testcentricity_web/data_objects/data_objects_helper.rb +7 -0
  41. data/lib/testcentricity_web/data_objects/environment.rb +14 -0
  42. data/lib/testcentricity_web/data_objects/excel_helper.rb +60 -59
  43. data/lib/testcentricity_web/version.rb +1 -1
  44. data/lib/testcentricity_web/web_core/drag_drop_helper.rb +4 -0
  45. data/lib/testcentricity_web/web_core/page_object.rb +1 -8
  46. data/lib/testcentricity_web/web_core/page_objects_helper.rb +4 -2
  47. data/lib/testcentricity_web/web_core/page_section.rb +1 -1
  48. data/lib/testcentricity_web/web_core/webdriver_helper.rb +60 -44
  49. data/lib/testcentricity_web/web_elements/checkbox.rb +49 -19
  50. data/lib/testcentricity_web/web_elements/file_field.rb +9 -5
  51. data/lib/testcentricity_web/web_elements/image.rb +2 -1
  52. data/lib/testcentricity_web/web_elements/media.rb +46 -12
  53. data/lib/testcentricity_web/web_elements/radio.rb +51 -16
  54. data/lib/testcentricity_web/web_elements/select_list.rb +12 -12
  55. data/lib/testcentricity_web/web_elements/ui_elements_helper.rb +22 -9
  56. data/lib/testcentricity_web/web_elements/video.rb +2 -2
  57. data/spec/fixtures/page_object.rb +22 -0
  58. data/spec/fixtures/section_object.rb +21 -0
  59. data/spec/spec_helper.rb +31 -0
  60. data/spec/testcentricity_web/browser_spec.rb +41 -0
  61. data/spec/testcentricity_web/elements/audio_spec.rb +68 -0
  62. data/spec/testcentricity_web/elements/button_spec.rb +18 -0
  63. data/spec/testcentricity_web/elements/checkbox_spec.rb +33 -0
  64. data/spec/testcentricity_web/elements/file_field_spec.rb +13 -0
  65. data/spec/testcentricity_web/elements/image_spec.rb +33 -0
  66. data/spec/testcentricity_web/elements/label_spec.rb +18 -0
  67. data/spec/testcentricity_web/elements/link_spec.rb +23 -0
  68. data/spec/testcentricity_web/elements/list_spec.rb +13 -0
  69. data/spec/testcentricity_web/elements/radio_spec.rb +28 -0
  70. data/spec/testcentricity_web/elements/ui_element_spec.rb +125 -0
  71. data/spec/testcentricity_web/elements/video_spec.rb +68 -0
  72. data/spec/testcentricity_web/helper_specs/object_helpers_spec.rb +39 -0
  73. data/spec/testcentricity_web/helper_specs/string_helpers_spec.rb +49 -0
  74. data/spec/testcentricity_web/page_object_spec.rb +90 -0
  75. data/spec/testcentricity_web/section_object_spec.rb +72 -0
  76. data/spec/testcentricity_web/version_spec.rb +7 -0
  77. data/spec/testcentricity_web/webdriver_connect/grid_webdriver_spec.rb +72 -0
  78. data/spec/testcentricity_web/webdriver_connect/local_webdriver_spec.rb +86 -0
  79. data/spec/testcentricity_web/webdriver_connect/mobile_webdriver_spec.rb +65 -0
  80. data/test_site/basic_test_page.html +51 -1
  81. data/test_site/chosen-sprite.png +0 -0
  82. data/test_site/chosen-sprite@2x.png +0 -0
  83. data/test_site/chosen.css +496 -0
  84. data/test_site/chosen.jquery.js +1359 -0
  85. data/test_site/chosen.jquery.min.js +3 -0
  86. data/test_site/chosen.min.css +11 -0
  87. data/test_site/chosen.proto.js +1399 -0
  88. data/test_site/chosen.proto.min.js +3 -0
  89. data/test_site/composer.json +36 -0
  90. data/test_site/custom_controls_page.html +629 -0
  91. data/test_site/docsupport/chosen.png +0 -0
  92. data/test_site/docsupport/init.js +11 -0
  93. data/test_site/docsupport/init.proto.js +16 -0
  94. data/test_site/docsupport/jquery-1.12.4.min.js +5 -0
  95. data/test_site/docsupport/jquery-3.2.1.min.js +4 -0
  96. data/test_site/docsupport/oss-credit.png +0 -0
  97. data/test_site/docsupport/prism.css +108 -0
  98. data/test_site/docsupport/prism.js +9 -0
  99. data/test_site/docsupport/prototype-1.7.0.0.js +6082 -0
  100. data/test_site/docsupport/style.css +219 -0
  101. data/test_site/images/Blouse_Black.jpg +0 -0
  102. data/test_site/images/Printed_Dress.jpg +0 -0
  103. data/test_site/images/T-shirt.jpg +0 -0
  104. data/test_site/images/jeans3.jpg +0 -0
  105. data/test_site/indexed_sections_page.html +215 -0
  106. data/test_site/media/MIB2-subtitles-pt-BR.vtt +49 -0
  107. data/test_site/media/MIB2.mp4 +0 -0
  108. data/test_site/media/bbc_scotland_report.mp3 +0 -0
  109. data/test_site/media/count_and_bars.mp4 +0 -0
  110. data/test_site/media_page.html +60 -7
  111. data/testcentricity_web.gemspec +14 -8
  112. metadata +197 -25
  113. data/Gemfile.lock +0 -170
  114. data/features/basic_test_page_css.feature +0 -24
  115. data/features/basic_test_page_xpath.feature +0 -24
  116. data/features/support/pages/media_page.rb +0 -11
@@ -65,6 +65,8 @@ module TestCentricity
65
65
  ui_object.hidden?
66
66
  when :displayed
67
67
  ui_object.displayed?
68
+ when :obscured
69
+ ui_object.obscured?
68
70
  when :focused
69
71
  ui_object.focused?
70
72
  when :width
@@ -296,7 +298,7 @@ module TestCentricity
296
298
  def populate_data_fields(data, wait_time = nil, integrity_check = false)
297
299
  timeout = wait_time.nil? ? 5 : wait_time
298
300
  data.each do |data_field, data_param|
299
- unless data_param.blank?
301
+ unless data_param != false && data_param.blank?
300
302
  # make sure the intended UI target element is visible before trying to set its value
301
303
  data_field.wait_until_visible(timeout)
302
304
  if data_param == '!DELETE'
@@ -312,7 +314,7 @@ module TestCentricity
312
314
  check_state = data_param.is_a?(String) ? data_param.to_bool : data_param
313
315
  data_field.set_selected_state(check_state)
314
316
  when :textfield
315
- if data_field.get_attribute(:type) == 'color'
317
+ if %w[color number].include?(data_field.get_attribute(:type))
316
318
  data_field.set(data_param)
317
319
  else
318
320
  data_field.set("#{data_param}\t")
@@ -234,7 +234,7 @@ module TestCentricity
234
234
  # radio :accept_terms_radio, "//input[@id='Accept_Terms']"
235
235
  # radio :decline_terms_radio, 'input#decline_terms_conditions'
236
236
  #
237
- def self.radio(element_name, locator, proxy = nil)
237
+ def self.radio(element_name, locator)
238
238
  define_element(element_name, TestCentricity::Radio, locator)
239
239
  end
240
240
 
@@ -29,10 +29,12 @@ module TestCentricity
29
29
  # set downloads folder path
30
30
  @downloads_path = "#{Dir.pwd}/downloads"
31
31
  if ENV['PARALLEL']
32
+ # :nocov:
32
33
  Environ.parallel = true
33
34
  Environ.process_num = ENV['TEST_ENV_NUMBER']
34
35
  @downloads_path = "#{@downloads_path}/#{ENV['TEST_ENV_NUMBER']}"
35
36
  Dir.mkdir(@downloads_path) unless Dir.exist?(@downloads_path)
37
+ # :nocov:
36
38
  else
37
39
  Environ.parallel = false
38
40
  end
@@ -50,6 +52,7 @@ module TestCentricity
50
52
  when :appium
51
53
  initialize_appium
52
54
  'Appium'
55
+ # :nocov:
53
56
  when :browserstack
54
57
  initialize_browserstack
55
58
  'Browserstack cloud service'
@@ -62,6 +65,7 @@ module TestCentricity
62
65
  when :testingbot
63
66
  initialize_testingbot
64
67
  'TestingBot cloud service'
68
+ # :nocov:
65
69
  else
66
70
  if ENV['SELENIUM'] == 'remote'
67
71
  initialize_remote
@@ -91,11 +95,13 @@ module TestCentricity
91
95
  def self.initialize_browser_size
92
96
  # tile browser windows if running in multiple parallel threads and BROWSER_TILE environment variable is true
93
97
  if ENV['PARALLEL'] && ENV['BROWSER_TILE']
98
+ # :nocov:
94
99
  thread = ENV['TEST_ENV_NUMBER'].to_i
95
100
  if thread > 1
96
101
  Browsers.set_browser_window_position(100 * thread - 1, 100 * thread - 1)
97
102
  sleep(1)
98
103
  end
104
+ # :nocov:
99
105
  else
100
106
  Browsers.set_browser_window_position(10, 10)
101
107
  sleep(1)
@@ -116,6 +122,7 @@ module TestCentricity
116
122
  Environ.session_state = :running
117
123
  end
118
124
 
125
+ # :nocov:
119
126
  def self.close_tunnel
120
127
  unless @bs_local.nil?
121
128
  @bs_local.stop
@@ -126,6 +133,7 @@ module TestCentricity
126
133
  end
127
134
  end
128
135
  end
136
+ # :nocov:
129
137
 
130
138
  private
131
139
 
@@ -147,10 +155,12 @@ module TestCentricity
147
155
  desired_capabilities[:avd] = ENV['APP_DEVICE'] if Environ.device_os == :android
148
156
  desired_capabilities[:automationName] = ENV['AUTOMATION_ENGINE'] if ENV['AUTOMATION_ENGINE']
149
157
  if ENV['UDID']
158
+ # :nocov:
150
159
  Environ.device = :device
151
160
  desired_capabilities[:udid] = ENV['UDID']
152
161
  desired_capabilities[:xcodeOrgId] = ENV['TEAM_ID'] if ENV['TEAM_ID']
153
162
  desired_capabilities[:xcodeSigningId] = ENV['TEAM_NAME'] if ENV['TEAM_NAME']
163
+ # :nocov:
154
164
  else
155
165
  Environ.device = :simulator
156
166
  desired_capabilities[:orientation] = Environ.device_orientation.upcase if Environ.device_orientation
@@ -179,11 +189,13 @@ module TestCentricity
179
189
  desired_capabilities[:chromedriverExecutable] = ENV['CHROMEDRIVER_EXECUTABLE'] if ENV['CHROMEDRIVER_EXECUTABLE']
180
190
  # set wdaLocalPort (iOS) or systemPort (Android) if PARALLEL_PORT is true
181
191
  if ENV['PARALLEL'] && ENV['PARALLEL_PORT']
192
+ # :nocov:
182
193
  if Environ.device_os == :ios
183
194
  desired_capabilities[:wdaLocalPort] = 8100 + ENV['TEST_ENV_NUMBER'].to_i
184
195
  else
185
196
  desired_capabilities[:systemPort] = 8200 + ENV['TEST_ENV_NUMBER'].to_i
186
197
  end
198
+ # :nocov:
187
199
  else
188
200
  desired_capabilities[:wdaLocalPort] = ENV['WDA_LOCAL_PORT'] if ENV['WDA_LOCAL_PORT']
189
201
  desired_capabilities[:systemPort] = ENV['SYSTEM_PORT'] if ENV['SYSTEM_PORT']
@@ -255,6 +267,51 @@ module TestCentricity
255
267
  Capybara.default_driver = :selenium
256
268
  end
257
269
 
270
+ def self.initialize_remote
271
+ Environ.grid = :selenium_grid
272
+ browser = ENV['WEB_BROWSER'].downcase.to_sym
273
+ @endpoint = ENV['REMOTE_ENDPOINT'] || 'http://127.0.0.1:4444/wd/hub' if @endpoint.nil?
274
+
275
+ case browser
276
+ when :safari
277
+ options = Selenium::WebDriver::Safari::Options.new
278
+ when :ie
279
+ options = Selenium::WebDriver::IE::Options.new
280
+ when :firefox, :firefox_headless
281
+ options = firefox_options(browser)
282
+ when :chrome, :chrome_headless, :edge, :edge_headless
283
+ options = chrome_edge_options(browser)
284
+ else
285
+ if ENV['HOST_BROWSER'] && ENV['HOST_BROWSER'].downcase.to_sym == :chrome
286
+ Environ.platform = :mobile
287
+ Environ.device_name = Browsers.mobile_device_name(ENV['WEB_BROWSER'])
288
+ user_agent = Browsers.mobile_device_agent(ENV['WEB_BROWSER'])
289
+ options = Selenium::WebDriver::Chrome::Options.new(options: {'excludeSwitches' => ['enable-automation']})
290
+ options.add_argument('--disable-dev-shm-usage')
291
+ options.add_argument("--user-agent='#{user_agent}'")
292
+ options.add_argument("--lang=#{ENV['LOCALE']}") if ENV['LOCALE']
293
+ else
294
+ raise "Requested browser '#{browser}' is not supported on Selenium Grid"
295
+ end
296
+ end
297
+
298
+ Capybara.register_driver :remote_browser do |app|
299
+ Capybara::Selenium::Driver.new(app,
300
+ browser: :remote,
301
+ url: @endpoint,
302
+ capabilities: [options]).tap do |driver|
303
+ # configure file_detector for remote uploads
304
+ driver.browser.file_detector = lambda do |args|
305
+ str = args.first.to_s
306
+ str if File.exist?(str)
307
+ end
308
+ end
309
+ end
310
+ Capybara.current_driver = :remote_browser
311
+ Capybara.default_driver = :remote_browser
312
+ end
313
+
314
+ # :nocov:
258
315
  def self.initialize_browserstack
259
316
  browser = ENV['BS_BROWSER']
260
317
  Environ.grid = :browserstack
@@ -401,50 +458,6 @@ module TestCentricity
401
458
  config_file_uploads
402
459
  end
403
460
 
404
- def self.initialize_remote
405
- Environ.grid = :selenium_grid
406
- browser = ENV['WEB_BROWSER'].downcase.to_sym
407
- @endpoint = ENV['REMOTE_ENDPOINT'] || 'http://127.0.0.1:4444/wd/hub' if @endpoint.nil?
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'])
423
- options = Selenium::WebDriver::Chrome::Options.new(options: {'excludeSwitches' => ['enable-automation']})
424
- options.add_argument('--disable-dev-shm-usage')
425
- options.add_argument("--user-agent='#{user_agent}'")
426
- options.add_argument("--lang=#{ENV['LOCALE']}") if ENV['LOCALE']
427
- else
428
- raise "Requested browser '#{browser}' is not supported on Selenium Grid"
429
- end
430
- end
431
-
432
- Capybara.register_driver :remote_browser do |app|
433
- Capybara::Selenium::Driver.new(app,
434
- browser: :remote,
435
- url: @endpoint,
436
- capabilities: [options]).tap do |driver|
437
- # configure file_detector for remote uploads
438
- driver.browser.file_detector = lambda do |args|
439
- str = args.first.to_s
440
- str if File.exist?(str)
441
- end
442
- end
443
- end
444
- Capybara.current_driver = :remote_browser
445
- Capybara.default_driver = :remote_browser
446
- end
447
-
448
461
  def self.initialize_saucelabs
449
462
  browser = ENV['SL_BROWSER']
450
463
  Environ.grid = :saucelabs
@@ -554,6 +567,7 @@ module TestCentricity
554
567
  # configure file_detector for remote uploads if target is desktop web browser
555
568
  config_file_uploads unless ENV['TB_PLATFORM']
556
569
  end
570
+ # :nocov:
557
571
 
558
572
  def self.chrome_edge_options(browser)
559
573
  options = case browser
@@ -599,6 +613,7 @@ module TestCentricity
599
613
  options
600
614
  end
601
615
 
616
+ # :nocov:
602
617
  def self.test_context_message
603
618
  context_message = if ENV['TEST_CONTEXT']
604
619
  "#{Environ.test_environment.to_s.upcase} - #{ENV['TEST_CONTEXT']}"
@@ -636,5 +651,6 @@ module TestCentricity
636
651
  str if File.exist?(str)
637
652
  end
638
653
  end
654
+ # :nocov:
639
655
  end
640
656
  end
@@ -2,11 +2,13 @@ module TestCentricity
2
2
  class CheckBox < UIElement
3
3
  attr_accessor :proxy
4
4
  attr_accessor :label
5
+ attr_accessor :input
5
6
 
6
7
  def initialize(name, parent, locator, context)
7
8
  super
8
9
  @type = :checkbox
9
10
  check_spec = {
11
+ input: nil,
10
12
  proxy: nil,
11
13
  label: nil
12
14
  }
@@ -16,6 +18,8 @@ module TestCentricity
16
18
  def define_custom_elements(element_spec)
17
19
  element_spec.each do |element, value|
18
20
  case element
21
+ when :input
22
+ @input = value
19
23
  when :proxy
20
24
  @proxy = value
21
25
  when :label
@@ -44,9 +48,14 @@ module TestCentricity
44
48
  # remember_me_checkbox.checked?
45
49
  #
46
50
  def checked?
47
- obj, = find_element(:all)
48
- object_not_found_exception(obj, 'Checkbox')
49
- obj.checked?
51
+ @base_object, = find_element(:all)
52
+ object_not_found_exception(@base_object, 'Checkbox')
53
+ chk = if @input.nil?
54
+ @base_object
55
+ else
56
+ find_component(@input, 'checkbox')
57
+ end
58
+ chk.checked?
50
59
  end
51
60
 
52
61
  # Is checkbox state indeterminate?
@@ -67,7 +76,14 @@ module TestCentricity
67
76
  # remember_me_checkbox.visible?
68
77
  #
69
78
  def visible?
70
- @proxy.nil? ? super : page.find(:css, @proxy).visible?
79
+ if @proxy.nil?
80
+ super
81
+ else
82
+ @base_object, = find_element(:all)
83
+ object_not_found_exception(@base_object, 'Checkbox')
84
+ proxy = find_component(@proxy, 'checkbox proxy')
85
+ proxy.visible?
86
+ end
71
87
  end
72
88
 
73
89
  # Is checkbox disabled (not enabled)?
@@ -77,10 +93,14 @@ module TestCentricity
77
93
  # remember_me_checkbox.disabled?
78
94
  #
79
95
  def disabled?
80
- visibility = @proxy.nil? ? true : :all
81
- obj, type = find_element(visibility)
82
- object_not_found_exception(obj, type)
83
- obj.disabled?
96
+ if @input.nil?
97
+ super
98
+ else
99
+ @base_object, = find_element(:all)
100
+ object_not_found_exception(@base_object, 'Checkbox')
101
+ chk = find_component(@input, 'checkbox')
102
+ chk.disabled?
103
+ end
84
104
  end
85
105
 
86
106
  # Return checkbox caption
@@ -91,9 +111,15 @@ module TestCentricity
91
111
  #
92
112
  def get_value
93
113
  if @label.nil?
94
- @proxy.nil? ? super : page.find(:css, @proxy).text
114
+ if @proxy.nil?
115
+ super
116
+ else
117
+ proxy = find_component(@proxy, 'checkbox proxy')
118
+ proxy.text
119
+ end
95
120
  else
96
- page.find(:css, @label).text
121
+ label = find_component(@label, 'checkbox label')
122
+ label.text
97
123
  end
98
124
  end
99
125
 
@@ -108,18 +134,22 @@ module TestCentricity
108
134
  # remember_me_checkbox.set_checkbox_state(true)
109
135
  #
110
136
  def set_checkbox_state(state)
111
- obj, = find_element(:all)
112
- object_not_found_exception(obj, 'Checkbox')
113
- invalid_object_type_exception(obj, 'checkbox')
114
- if @proxy.nil?
115
- if obj.native.attribute('ot') == 'JCheckBox'
116
- expected = state.to_bool
117
- obj.click unless expected == obj.checked?
137
+ @base_object, = find_element(:all)
138
+ object_not_found_exception(@base_object, 'Checkbox')
139
+ proxy = find_component(@proxy, 'checkbox proxy') unless @proxy.nil?
140
+ chk = find_component(@input, 'checkbox') unless @input.nil?
141
+ if @input.nil?
142
+ if @proxy.nil?
143
+ @base_object.click unless state == @base_object.checked?
118
144
  else
119
- obj.set(state)
145
+ proxy.click unless state == @base_object.checked?
120
146
  end
121
147
  else
122
- page.find(:css, @proxy).click unless state == obj.checked?
148
+ if @proxy.nil?
149
+ @base_object.click unless state == chk.checked?
150
+ else
151
+ proxy.click unless state == chk.checked?
152
+ end
123
153
  end
124
154
  end
125
155
 
@@ -5,17 +5,19 @@ module TestCentricity
5
5
  @type = :filefield
6
6
  end
7
7
 
8
+ def file_upload(file_path)
9
+ obj, = find_element(visible = false)
10
+ obj.send_keys(file_path)
11
+ end
12
+
13
+ # :nocov:
14
+
8
15
  def file_attach(file_path)
9
16
  Capybara.ignore_hidden_elements = false
10
17
  page.attach_file(@locator, file_path)
11
18
  Capybara.ignore_hidden_elements = true
12
19
  end
13
20
 
14
- def file_upload(file_path)
15
- obj, = find_element(visible = false)
16
- obj.send_keys(file_path)
17
- end
18
-
19
21
  def drop_files(files)
20
22
  js_script = 'fileList = Array();'
21
23
  files.count.times do |i|
@@ -41,5 +43,7 @@ module TestCentricity
41
43
  # trigger the fake drop event
42
44
  page.execute_script(js_script)
43
45
  end
46
+
47
+ # :nocov:
44
48
  end
45
49
  end
@@ -14,7 +14,8 @@ module TestCentricity
14
14
  def loaded?
15
15
  obj, = find_element
16
16
  object_not_found_exception(obj, nil)
17
- obj.native.attribute('complete')
17
+ state = obj.native.attribute('complete')
18
+ state.boolean? ? state : state == 'true'
18
19
  end
19
20
 
20
21
  alias is_loaded? loaded?
@@ -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
@@ -178,7 +178,7 @@ module TestCentricity
178
178
  def ready_state
179
179
  obj, = find_element(visible = :all)
180
180
  object_not_found_exception(obj, @type)
181
- obj.native.attribute('readyState').to_i
181
+ page.execute_script('return arguments[0].readyState', obj)
182
182
  end
183
183
 
184
184
  # Wait until the media object's readyState value equals the specified value, or until the specified wait time has expired. If the wait
@@ -195,7 +195,7 @@ module TestCentricity
195
195
  wait.until { ready_state == value }
196
196
  rescue StandardError
197
197
  if post_exception
198
- raise "Ready state of Audio #{object_ref_message} failed to equal '#{value}' after #{timeout} seconds" unless get_value == value
198
+ raise "Ready state of media #{object_ref_message} failed to equal '#{value}' after #{timeout} seconds" unless get_value == value
199
199
  else
200
200
  ready_state == value
201
201
  end
@@ -247,16 +247,50 @@ module TestCentricity
247
247
  page.execute_script('arguments[0].pause()', obj)
248
248
  end
249
249
 
250
- # Return media crossorigin property
250
+ # Mute the media's audio
251
251
  #
252
- # @return crossorigin value
253
252
  # @example
254
- # with_creds = media_player.crossorigin == 'use-credentials'
253
+ # media_player.mute
255
254
  #
256
- def crossorigin
257
- obj, = find_element
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)
258
292
  object_not_found_exception(obj, @type)
259
- obj.native.attribute('crossorigin')
293
+ page.execute_script('arguments[0].volume = arguments[1]', obj, value)
260
294
  end
261
295
 
262
296
  # Return media preload property
@@ -2,11 +2,13 @@ module TestCentricity
2
2
  class Radio < UIElement
3
3
  attr_accessor :proxy
4
4
  attr_accessor :label
5
+ attr_accessor :input
5
6
 
6
7
  def initialize(name, parent, locator, context)
7
8
  super
8
9
  @type = :radio
9
10
  radio_spec = {
11
+ input: nil,
10
12
  proxy: nil,
11
13
  label: nil
12
14
  }
@@ -16,6 +18,8 @@ module TestCentricity
16
18
  def define_custom_elements(element_spec)
17
19
  element_spec.each do |element, value|
18
20
  case element
21
+ when :input
22
+ @input = value
19
23
  when :proxy
20
24
  @proxy = value
21
25
  when :label
@@ -44,9 +48,14 @@ module TestCentricity
44
48
  # accept_terms_radio.selected?
45
49
  #
46
50
  def selected?
47
- obj, = find_element(:all)
48
- object_not_found_exception(obj, 'Radio')
49
- obj.checked?
51
+ @base_object, = find_element(:all)
52
+ object_not_found_exception(@base_object, 'Radio')
53
+ rad = if @input.nil?
54
+ @base_object
55
+ else
56
+ find_component(@input, 'Radio')
57
+ end
58
+ rad.checked?
50
59
  end
51
60
 
52
61
  # Is radio button visible?
@@ -56,7 +65,14 @@ module TestCentricity
56
65
  # accept_terms_radio.visible?
57
66
  #
58
67
  def visible?
59
- @proxy.nil? ? super : page.find(:css, @proxy).visible?
68
+ if @proxy.nil?
69
+ super
70
+ else
71
+ @base_object, = find_element(:all)
72
+ object_not_found_exception(@base_object, 'Radio')
73
+ proxy = find_component(@proxy, 'radio proxy')
74
+ proxy.visible?
75
+ end
60
76
  end
61
77
 
62
78
  # Is radio button disabled (not enabled)?
@@ -66,10 +82,14 @@ module TestCentricity
66
82
  # accept_terms_radio.disabled?
67
83
  #
68
84
  def disabled?
69
- visibility = @proxy.nil? ? true : :all
70
- obj, type = find_element(visibility)
71
- object_not_found_exception(obj, type)
72
- obj.disabled?
85
+ if @input.nil?
86
+ super
87
+ else
88
+ @base_object, = find_element(:all)
89
+ object_not_found_exception(@base_object, 'Radio')
90
+ rad = find_component(@input, 'radio')
91
+ rad.disabled?
92
+ end
73
93
  end
74
94
 
75
95
  # Return radio button caption
@@ -80,9 +100,15 @@ module TestCentricity
80
100
  #
81
101
  def get_value
82
102
  if @label.nil?
83
- @proxy.nil? ? super : page.find(:css, @proxy).text
103
+ if @proxy.nil?
104
+ super
105
+ else
106
+ proxy = find_component(@proxy, 'radio proxy')
107
+ proxy.text
108
+ end
84
109
  else
85
- page.find(:css, @label).text
110
+ label = find_component(@label, 'radio label')
111
+ label.text
86
112
  end
87
113
  end
88
114
 
@@ -97,13 +123,22 @@ module TestCentricity
97
123
  # accept_terms_radio.set_selected_state(true)
98
124
  #
99
125
  def set_selected_state(state)
100
- obj, = find_element(:all)
101
- object_not_found_exception(obj, 'Radio')
102
- invalid_object_type_exception(obj, 'radio')
103
- if @proxy.nil?
104
- obj.set(state)
126
+ @base_object, = find_element(:all)
127
+ object_not_found_exception(@base_object, 'Radio')
128
+ proxy = find_component(@proxy, 'radio proxy') unless @proxy.nil?
129
+ rad = find_component(@input, 'radio') unless @input.nil?
130
+ if @input.nil?
131
+ if @proxy.nil?
132
+ @base_object.click unless state == @base_object.checked?
133
+ else
134
+ proxy.click unless state == @base_object.checked?
135
+ end
105
136
  else
106
- page.find(:css, @proxy).click unless state == obj.checked?
137
+ if @proxy.nil?
138
+ @base_object.click unless state == rad.checked?
139
+ else
140
+ proxy.click unless state == rad.checked?
141
+ end
107
142
  end
108
143
  end
109
144