testcentricity_web 4.1.6 → 4.1.9

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