testcentricity_web 4.1.8 → 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 (89) 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/CHANGELOG.md +13 -0
  6. data/README.md +11 -12
  7. data/Rakefile +93 -64
  8. data/config/cucumber.yml +1 -0
  9. data/config/locales/en-US.yml +56 -0
  10. data/{docker-compose-v3.yml → docker-compose.yml} +2 -2
  11. data/features/basic_form_page_css.feature +16 -1
  12. data/features/custom_controls.feature +29 -0
  13. data/features/media_players.feature +3 -20
  14. data/features/step_definitions/generic_steps.rb.rb +15 -0
  15. data/features/support/env.rb +3 -2
  16. data/features/support/hooks.rb +8 -3
  17. data/features/support/pages/base_test_page.rb +1 -1
  18. data/features/support/pages/basic_css_form_page.rb +1 -0
  19. data/features/support/pages/basic_form_page.rb +45 -9
  20. data/features/support/pages/basic_xpath_form_page.rb +1 -0
  21. data/features/support/pages/custom_controls_page.rb +250 -0
  22. data/features/support/pages/indexed_sections_page.rb +44 -0
  23. data/features/support/pages/media_test_page.rb +10 -11
  24. data/features/support/sections/header_nav.rb +10 -1
  25. data/features/support/sections/product_card.rb +39 -0
  26. data/lib/testcentricity_web/browser_helper.rb +0 -6
  27. data/lib/testcentricity_web/version.rb +1 -1
  28. data/lib/testcentricity_web/web_core/page_objects_helper.rb +1 -1
  29. data/lib/testcentricity_web/web_core/page_section.rb +1 -1
  30. data/lib/testcentricity_web/web_core/webdriver_helper.rb +44 -44
  31. data/lib/testcentricity_web/web_elements/checkbox.rb +50 -19
  32. data/lib/testcentricity_web/web_elements/media.rb +1 -1
  33. data/lib/testcentricity_web/web_elements/radio.rb +50 -19
  34. data/lib/testcentricity_web/web_elements/select_list.rb +12 -12
  35. data/lib/testcentricity_web/web_elements/ui_elements_helper.rb +3 -3
  36. data/spec/fixtures/page_object.rb +22 -0
  37. data/spec/fixtures/section_object.rb +21 -0
  38. data/spec/spec_helper.rb +31 -0
  39. data/spec/testcentricity_web/browser_spec.rb +41 -0
  40. data/spec/testcentricity_web/elements/audio_spec.rb +68 -0
  41. data/spec/testcentricity_web/elements/button_spec.rb +18 -0
  42. data/spec/testcentricity_web/elements/checkbox_spec.rb +33 -0
  43. data/spec/testcentricity_web/elements/file_field_spec.rb +13 -0
  44. data/spec/testcentricity_web/elements/image_spec.rb +33 -0
  45. data/spec/testcentricity_web/elements/label_spec.rb +18 -0
  46. data/spec/testcentricity_web/elements/link_spec.rb +23 -0
  47. data/spec/testcentricity_web/elements/list_spec.rb +13 -0
  48. data/spec/testcentricity_web/elements/radio_spec.rb +28 -0
  49. data/spec/testcentricity_web/elements/ui_element_spec.rb +125 -0
  50. data/spec/testcentricity_web/elements/video_spec.rb +68 -0
  51. data/spec/testcentricity_web/helper_specs/object_helpers_spec.rb +39 -0
  52. data/spec/testcentricity_web/helper_specs/string_helpers_spec.rb +49 -0
  53. data/spec/testcentricity_web/page_object_spec.rb +90 -0
  54. data/spec/testcentricity_web/section_object_spec.rb +72 -0
  55. data/spec/testcentricity_web/version_spec.rb +7 -0
  56. data/spec/testcentricity_web/webdriver_connect/grid_webdriver_spec.rb +72 -0
  57. data/spec/testcentricity_web/webdriver_connect/local_webdriver_spec.rb +86 -0
  58. data/spec/testcentricity_web/webdriver_connect/mobile_webdriver_spec.rb +65 -0
  59. data/test_site/basic_test_page.html +2 -2
  60. data/test_site/chosen-sprite.png +0 -0
  61. data/test_site/chosen-sprite@2x.png +0 -0
  62. data/test_site/chosen.css +496 -0
  63. data/test_site/chosen.jquery.js +1359 -0
  64. data/test_site/chosen.jquery.min.js +3 -0
  65. data/test_site/chosen.min.css +11 -0
  66. data/test_site/chosen.proto.js +1399 -0
  67. data/test_site/chosen.proto.min.js +3 -0
  68. data/test_site/composer.json +36 -0
  69. data/test_site/custom_controls_page.html +572 -1
  70. data/test_site/docsupport/chosen.png +0 -0
  71. data/test_site/docsupport/init.js +11 -0
  72. data/test_site/docsupport/init.proto.js +16 -0
  73. data/test_site/docsupport/jquery-1.12.4.min.js +5 -0
  74. data/test_site/docsupport/jquery-3.2.1.min.js +4 -0
  75. data/test_site/docsupport/oss-credit.png +0 -0
  76. data/test_site/docsupport/prism.css +108 -0
  77. data/test_site/docsupport/prism.js +9 -0
  78. data/test_site/docsupport/prototype-1.7.0.0.js +6082 -0
  79. data/test_site/docsupport/style.css +219 -0
  80. data/test_site/images/Blouse_Black.jpg +0 -0
  81. data/test_site/images/Printed_Dress.jpg +0 -0
  82. data/test_site/images/T-shirt.jpg +0 -0
  83. data/test_site/images/jeans3.jpg +0 -0
  84. data/test_site/indexed_sections_page.html +158 -1
  85. data/test_site/media/bbc_scotland_report.mp3 +0 -0
  86. data/test_site/media_page.html +2 -2
  87. data/testcentricity_web.gemspec +14 -8
  88. metadata +158 -13
  89. data/Gemfile.lock +0 -170
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ec1cf64d0d0e52b5d49ce5980dc049add4befecbc830650c4c908db5b2e07ac2
4
- data.tar.gz: 841d00666f64914cf72d0f279e060c5ba31c1eb8a056020015a1430daf9c38a6
3
+ metadata.gz: c35f1c09951d1a58be2d3bac921d2d221311edf3b4464c5d4806c7a30a57c0f2
4
+ data.tar.gz: bbe72af137b6808721f7a87b26032c42d78bbf4708ff88ed34c753ebcec85c46
5
5
  SHA512:
6
- metadata.gz: 1e4e6f516c68a18689ccecfa7ee52ca97db9ffb8641c63d21641061e70ca4ac0f1b53d5191b02c6335ac1403e6bdf8afe0b0133d1204f2b87d4496d00a4c4fc1
7
- data.tar.gz: c38230893848b6145e79e131f9e6a99867fa0a1d590d2b272a00709ee107b9a8044180c037cd1182cd6aa13d58c208e3ce154c2de08b66161a7c06ce02e0a8bc
6
+ metadata.gz: 0607f397cd9d6564623218d3e88f541a04f17c9b4b8cc96eb50571bc787cfa46927651dc38cfc7765129dd33303fbd3c130720dc809940cf401a336756c3d7c1
7
+ data.tar.gz: 11cc150624658854f69575361345dca970a3cf567e1b29e6797450dc22df88f53b069374a63ab8e12f83e7638a28386b0edd0d96e6707720f41e1e6fa621c1f5
data/.gitignore CHANGED
@@ -15,6 +15,7 @@ Thumbs.db
15
15
  /pkg/
16
16
  /spec/reports/
17
17
  /tmp/
18
+ Gemfile*.lock
18
19
 
19
20
  # rspec failure tracking
20
21
  .rspec_status
data/.rspec CHANGED
@@ -1,3 +1,4 @@
1
- --format documentation
1
+ # General configuration options
2
2
  --color
3
3
  --require spec_helper
4
+ --format documentation
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ ruby-2.7.5
data/CHANGELOG.md CHANGED
@@ -2,6 +2,19 @@
2
2
  All notable changes to this project will be documented in this file.
3
3
 
4
4
 
5
+ ## [4.1.9] - 18-APR-2022
6
+
7
+ ### Fixed
8
+ * `PageSection.radio` no longer returns `wrong number of arguments` error.
9
+ * `PageObject.populate_data_fields` and `PageSection.populate_data_fields` methods no longer skip setting checkboxes or
10
+ radio buttons to the unchecked state.
11
+
12
+ ### Added
13
+
14
+ * `CheckBox.define_custom_elements` and `Radio.define_custom_elements` methods now support specifying a child `input` component
15
+ contained by a top level `label` element.
16
+
17
+
5
18
  ## [4.1.8] - 31-MAR-2022
6
19
 
7
20
  ### Fixed
data/README.md CHANGED
@@ -874,7 +874,7 @@ present a challenge when attempting to interact with them using Capybara and Sel
874
874
  Sometimes, radio buttons and checkboxes implemented using JS component libraries cannot be interacted with due to other UI elements
875
875
  being overlaid on top of them and the base `input(type='radio')` or `input(type='checkbox')` element not being visible.
876
876
 
877
- In the screenshots below of an airline flight search and booking page, the **Roundtrip** and **One-way** radio buttons are adorned with
877
+ In the screenshots below of an airline flight search and booking page, the **Roundtrip** and **One-way** radio buttons are adorned by
878
878
  `label` elements that also acts as proxies for their associated `input(type='radio')` elements, and they intercept the `click` actions
879
879
  that would normally be handled by the `input(type='radio')` elements.
880
880
 
@@ -892,27 +892,26 @@ elements.
892
892
  <img src="https://i.imgur.com/JcOANqZ.jpg" alt="One-way Radio button Label" title="One-way Radio button Label">
893
893
 
894
894
 
895
- The `Radio.define_custom_elements` and `CheckBox.define_custom_elements` methods provide a way to specify the `proxy` and/or `label`
896
- elements associated with the `input(type='radio')` or `input(type='checkbox')` elements. The `define_custom_elements` method
897
- should be called from an `initialize` method for the `PageObject` or `PageSection` where the `radio` or `checkbox` element is instantiated.
898
- The code snippet below demonstrates the use of the `Radio.define_custom_elements` and `CheckBox.define_custom_elements` methods to
899
- resolve the testability issues posed by the adorned **Roundtrip** and **One-way** radio buttons and the **Flexible dates** checkbox.
895
+ The `Radio.define_custom_elements` and `CheckBox.define_custom_elements` methods provide a way to specify the `input`, `proxy`
896
+ and/or `label` elements associated with the `input(type='radio')` or `input(type='checkbox')` elements. The `define_custom_elements`
897
+ method should be called from an `initialize` method for the `PageObject` or `PageSection` where the `radio` or `checkbox` element is
898
+ instantiated. The code snippet below demonstrates the use of the `Radio.define_custom_elements` and `CheckBox.define_custom_elements`
899
+ methods to resolve the testability issues posed by the adorned **Roundtrip** and **One-way** radio buttons and the **Flexible dates**
900
+ checkbox.
900
901
 
901
902
  class FlightBookingPage < TestCentricity::PageObject
902
903
  trait(:page_name) { 'Flight Booking Home' }
903
904
  trait(:page_locator) { "div[class*='bookerContainer']" }
904
905
 
905
906
  # Flight Booking page UI elements
906
- radios roundtrip_radio: 'input#roundtrip',
907
- one_way_radio: 'input#oneway'
907
+ radios roundtrip_radio: "label[for='roundtrip']",
908
+ one_way_radio: "label[for='oneway']"
908
909
  checkbox :flexible_check, 'input#flexibleDates'
909
910
 
910
911
  def initialize
911
- # define the custom element components for the Round Trip radio button
912
- radio_spec = { proxy: "label[for='roundtrip']" }
912
+ # define the custom element components for the Round Trip and One Way radio buttons
913
+ radio_spec = { input: "input[type='radio']" }
913
914
  roundtrip_radio.define_custom_elements(radio_spec)
914
- # define the custom element components for the One Way radio button
915
- radio_spec = { proxy: "label[for='oneway']" }
916
915
  one_way_radio.define_custom_elements(radio_spec)
917
916
  # define the custom element components for the Flexible Date checkbox
918
917
  check_spec = { proxy: 'label#flexDatesLabel' }
data/Rakefile CHANGED
@@ -1,86 +1,115 @@
1
1
  require 'rubygems'
2
2
  require 'cucumber'
3
3
  require 'cucumber/rake/task'
4
+ require 'docker/compose'
5
+ require 'parallel_tests'
4
6
  require 'rake'
7
+ require 'rspec/core/rake_task'
8
+ require 'simplecov'
9
+ require 'yard'
5
10
 
6
11
 
7
- namespace :features do
8
- Cucumber::Rake::Task.new(:edge_local) do |t|
9
- t.profile = 'edge_local'
10
- end
12
+ desc 'Run required specs'
13
+ RSpec::Core::RakeTask.new(:required_specs) do |t|
14
+ t.rspec_opts = '--tag required'
15
+ end
11
16
 
12
- Cucumber::Rake::Task.new(:chrome_local) do |t|
13
- t.profile = 'chrome_local'
14
- end
15
17
 
16
- Cucumber::Rake::Task.new(:edge_headless) do |t|
17
- t.profile = 'edge_headless'
18
- end
18
+ desc 'Run grid WebDriver specs'
19
+ RSpec::Core::RakeTask.new(:grid_specs) do |t|
20
+ t.rspec_opts = '--tag grid'
21
+ end
19
22
 
20
- Cucumber::Rake::Task.new(:chrome_headless) do |t|
21
- t.profile = 'chrome_headless'
22
- end
23
23
 
24
- Cucumber::Rake::Task.new(:safari_local) do |t|
25
- t.profile = 'safari_local'
26
- end
24
+ desc 'Run mobile WebDriver specs'
25
+ RSpec::Core::RakeTask.new(:mobile_specs) do |t|
26
+ t.rspec_opts = '--tag mobile'
27
+ end
27
28
 
28
- Cucumber::Rake::Task.new(:firefox_local) do |t|
29
- t.profile = 'firefox_local'
30
- end
31
29
 
32
- Cucumber::Rake::Task.new(:firefox_headless) do |t|
33
- t.profile = 'firefox_headless'
34
- end
30
+ desc 'Run Cucumber features on local Safari browser'
31
+ Cucumber::Rake::Task.new(:safari_local) do |t|
32
+ t.profile = 'safari_local'
33
+ end
35
34
 
36
- Cucumber::Rake::Task.new(:edge_grid) do |t|
37
- t.profile = 'edge_grid'
38
- end
39
35
 
40
- Cucumber::Rake::Task.new(:chrome_grid) do |t|
41
- t.profile = 'chrome_grid'
42
- end
36
+ desc 'Run Cucumber features on iOS simulator'
37
+ Cucumber::Rake::Task.new(:ios_remote) do |t|
38
+ t.profile = 'ios_remote'
39
+ end
43
40
 
44
- Cucumber::Rake::Task.new(:firefox_grid) do |t|
45
- t.profile = 'firefox_grid'
46
- end
47
41
 
48
- Cucumber::Rake::Task.new(:ios_remote) do |t|
49
- t.profile = 'ios_remote'
42
+ desc 'Run required Cucumber features on local web browsers'
43
+ task :required_cukes do
44
+ %w[chrome_local chrome_headless firefox_local firefox_headless edge_local edge_headless ipad_pro_12_local].each do |profile|
45
+ system "parallel_cucumber features/ -o '-p #{profile}' -n 6 --group-by scenarios"
50
46
  end
47
+ end
51
48
 
52
- Cucumber::Rake::Task.new(:emulated_mobile) do |t|
53
- t.profile = 'ipad_pro_12_local'
49
+
50
+ desc 'Run grid Cucumber features on Dockerized Selenium 4 Grid'
51
+ task :grid_cukes do
52
+ # start up Selenium 4 Grid
53
+ compose = Docker::Compose.new
54
+ compose.version
55
+ compose.up(detached: true)
56
+ # run grid features
57
+ %w[chrome_grid firefox_grid edge_grid ipad_pro_12_grid].each do |profile|
58
+ system "parallel_cucumber features/ -o '-p #{profile}' -n 4 --group-by scenarios"
54
59
  end
60
+ # shut down Selenium Grid
61
+ compose.down(remove_volumes: true)
62
+ end
55
63
 
56
64
 
57
- task :required => [
58
- :edge_local,
59
- :edge_headless,
60
- :chrome_local,
61
- :chrome_headless,
62
- :firefox_local,
63
- :firefox_headless,
64
- :safari_local,
65
- :emulated_mobile,
66
- ]
67
-
68
- task :grid => [:edge_grid, :chrome_grid, :firefox_grid]
69
-
70
- task :mobile => [:ios_remote]
71
-
72
- task :all => [
73
- :edge_local,
74
- :edge_headless,
75
- :chrome_local,
76
- :chrome_headless,
77
- :firefox_local,
78
- :firefox_headless,
79
- :safari_local,
80
- :edge_grid,
81
- :chrome_grid,
82
- :firefox_grid,
83
- :emulated_mobile,
84
- :ios_remote
85
- ]
65
+ desc 'Run grid specs on Dockerized Selenium 4 Grid'
66
+ task :docker_grid_specs do
67
+ # start up Selenium 4 Grid
68
+ compose = Docker::Compose.new
69
+ compose.version
70
+ compose.up(detached: true)
71
+ # run grid specs
72
+ Rake::Task[:grid_specs].invoke
73
+ # shut down Selenium Grid
74
+ compose.down(remove_volumes: true)
86
75
  end
76
+
77
+
78
+ desc 'Run mobile web specs and Cucumber features'
79
+ task mobile: [:mobile_specs, :ios_remote]
80
+
81
+
82
+ desc 'Run required specs and Cucumber features'
83
+ task required: [:required_specs, :required_cukes]
84
+
85
+
86
+ desc 'Run grid specs and Cucumber features on Dockerized Selenium 4 Grid'
87
+ task grid: [:docker_grid_specs, :grid_cukes]
88
+
89
+
90
+ desc 'Run all specs'
91
+ task all_specs: [:required_specs, :docker_grid_specs, :mobile_specs]
92
+
93
+
94
+ desc 'Run all specs and Cucumber features'
95
+ task all: [:required, :safari_local, :grid, :mobile]
96
+
97
+
98
+ desc 'Update HTML docs'
99
+ YARD::Rake::YardocTask.new(:docs) do |t|
100
+ t.files = ['lib/**/*.rb']
101
+ end
102
+
103
+
104
+ desc 'Build and release new version'
105
+ task :release do
106
+ version = TestCentricityWeb::VERSION
107
+ puts "Releasing #{version}, y/n?"
108
+ exit(1) unless $stdin.gets.chomp == 'y'
109
+ sh 'gem build testcentricity_web.gemspec && ' \
110
+ "gem push testcentricity_web-#{version}.gem"
111
+ end
112
+
113
+
114
+ desc 'Update docs, build gem, and push to RubyGems'
115
+ task ship_it: [:docs, :release]
data/config/cucumber.yml CHANGED
@@ -63,6 +63,7 @@ portrait: ORIENTATION=portrait
63
63
 
64
64
  ipad_pro_11_local: --profile local WEB_BROWSER=ipad_pro_11 HOST_BROWSER=chrome --profile portrait <%= mobile %>
65
65
  ipad_pro_12_local: --profile local WEB_BROWSER=ipad_pro_12_9 HOST_BROWSER=chrome --profile portrait <%= mobile %>
66
+ ipad_pro_12_grid: --profile grid WEB_BROWSER=ipad_pro_12_9 HOST_BROWSER=chrome --profile portrait <%= mobile %>
66
67
 
67
68
 
68
69
  #==============
@@ -0,0 +1,56 @@
1
+ # Localization file for English/U.S. locale.
2
+
3
+ en-US:
4
+ time:
5
+ formats:
6
+ default: "%m/%d/%Y"
7
+ long: "%B %d, %Y"
8
+ short: "%b %d"
9
+ abbrev: "%b %d, %Y"
10
+ abbrev_month: "%b"
11
+ month_year: "%B %Y"
12
+ date:
13
+ abbr_day_names:
14
+ - Sun
15
+ - Mon
16
+ - Tue
17
+ - Wed
18
+ - Thu
19
+ - Fri
20
+ - Sat
21
+ abbr_month_names:
22
+ -
23
+ - Jan
24
+ - Feb
25
+ - Mar
26
+ - Apr
27
+ - May
28
+ - Jun
29
+ - Jul
30
+ - Aug
31
+ - Sep
32
+ - Oct
33
+ - Nov
34
+ - Dec
35
+ day_names:
36
+ - Sunday
37
+ - Monday
38
+ - Tuesday
39
+ - Wednesday
40
+ - Thursday
41
+ - Friday
42
+ - Saturday
43
+ month_names:
44
+ -
45
+ - January
46
+ - February
47
+ - March
48
+ - April
49
+ - May
50
+ - June
51
+ - July
52
+ - August
53
+ - September
54
+ - October
55
+ - November
56
+ - December
@@ -1,6 +1,6 @@
1
- # To execute this docker-compose yml file use `docker-compose -f docker-compose-v3.yml up`
1
+ # To execute this docker-compose yml file use `docker-compose -f docker-compose.yml up`
2
2
  # Add the `-d` flag at the end for detached execution
3
- # To stop the execution, hit Ctrl+C, and then `docker-compose -f docker-compose-v3.yml down`
3
+ # To stop the execution, hit Ctrl+C, and then `docker-compose -f docker-compose.yml down`
4
4
  version: "3"
5
5
  services:
6
6
  chrome:
@@ -12,7 +12,7 @@ Feature: Basic HTML Form Test Page using CSS locators
12
12
  Then I expect the Basic CSS Form page to be correctly displayed
13
13
 
14
14
 
15
- @!mobile @!firefox_headless
15
+ @!mobile @!firefox_headless @!firefox_grid
16
16
  Scenario: Validate verify_focus_order method
17
17
  Then I expect the tab order to be correct
18
18
 
@@ -24,6 +24,21 @@ Feature: Basic HTML Form Test Page using CSS locators
24
24
  Then I expect the Basic CSS Form page to be correctly displayed
25
25
 
26
26
 
27
+ Scenario Outline: Choose selectlist options by index, value, and text
28
+ When I choose selectlist options by <method>
29
+ Then I expect the selected option to be displayed
30
+
31
+ Examples:
32
+ |method |
33
+ |index |
34
+ |text |
35
+
36
+ @!safari @!firefox @!firefox_headless
37
+ Examples:
38
+ |method |
39
+ |value |
40
+
41
+
27
42
  Scenario Outline: Verify functionality of navigation tabs and browser back/forward
28
43
  When I click the <target_page> navigation tab
29
44
  Then I expect the <target_page> page to be correctly displayed
@@ -0,0 +1,29 @@
1
+ Feature: Custom Controls
2
+ In order to ensure comprehensive support for custom UI elements
3
+ As a developer of the TestCentricity web gem
4
+ I expect to validate the interaction and verification capabilities of custom UI elements
5
+
6
+
7
+ Background:
8
+ Given I am on the Custom Controls page
9
+
10
+
11
+ Scenario: Validate populate_data_fields method and associated object action methods
12
+ When I populate the form fields
13
+ Then I expect the form fields to be correctly populated
14
+
15
+
16
+ @!safari @!firefox @!firefox_headless @!ios
17
+ Scenario: Use custom select list input field to choose options
18
+ When I choose custom select options by typing
19
+ Then I expect the form fields to be correctly populated
20
+
21
+
22
+ Scenario Outline: Choose selectlist options by index and text
23
+ When I choose selectlist options by <method>
24
+ Then I expect the selected option to be displayed
25
+
26
+ Examples:
27
+ |method |
28
+ |index |
29
+ |text |
@@ -1,3 +1,6 @@
1
+ @!grid @!mobile
2
+
3
+
1
4
  Feature: HTML5 Audio/Video Test Page using CSS locators
2
5
  In order to ensure comprehensive support for HTML5 Audio and Video media elements
3
6
  As a developer of the TestCentricity web gem
@@ -49,18 +52,8 @@ Feature: HTML5 Audio/Video Test Page using CSS locators
49
52
  Scenario: Verify video playback speed settings
50
53
  When I play the video with a playback speed of 2x
51
54
  Then the video should play at 2x speed
52
- When I play the video with a playback speed of 0.25x
53
- Then the video should play at 0.25x speed
54
- When I play the video with a playback speed of 1.75x
55
- Then the video should play at 1.75x speed
56
55
  When I play the video with a playback speed of 0.5x
57
56
  Then the video should play at 0.5x speed
58
- When I play the video with a playback speed of 1.5x
59
- Then the video should play at 1.5x speed
60
- When I play the video with a playback speed of 0.75x
61
- Then the video should play at 0.75x speed
62
- When I play the video with a playback speed of 1.25x
63
- Then the video should play at 1.25x speed
64
57
  When I play the video with a playback speed of 1x
65
58
  Then the video should play at 1x speed
66
59
 
@@ -68,17 +61,7 @@ Feature: HTML5 Audio/Video Test Page using CSS locators
68
61
  Scenario: Verify audio playback speed settings
69
62
  When I play the audio with a playback speed of 2x
70
63
  Then the audio should play at 2x speed
71
- When I play the audio with a playback speed of 0.25x
72
- Then the audio should play at 0.25x speed
73
- When I play the audio with a playback speed of 1.75x
74
- Then the audio should play at 1.75x speed
75
64
  When I play the audio with a playback speed of 0.5x
76
65
  Then the audio should play at 0.5x speed
77
- When I play the audio with a playback speed of 1.5x
78
- Then the audio should play at 1.5x speed
79
- When I play the audio with a playback speed of 0.75x
80
- Then the audio should play at 0.75x speed
81
- When I play the audio with a playback speed of 1.25x
82
- Then the audio should play at 1.25x speed
83
66
  When I play the audio with a playback speed of 1x
84
67
  Then the audio should play at 1x speed
@@ -107,3 +107,18 @@ end
107
107
  When(/^I set device orientation to (.*)$/) do |orientation|
108
108
  Browsers.set_device_orientation(orientation.downcase.to_sym)
109
109
  end
110
+
111
+
112
+ When(/^I choose custom select options by typing$/) do
113
+ custom_controls_page.set_select_options
114
+ end
115
+
116
+
117
+ When(/^I choose selectlist options by (.*)$/) do |method|
118
+ PageManager.current_page.choose_options_by(method)
119
+ end
120
+
121
+
122
+ Then(/^I expect the selected option to be displayed$/) do
123
+ PageManager.current_page.verify_chosen_options
124
+ end
@@ -7,7 +7,8 @@ require 'testcentricity_web'
7
7
 
8
8
  include TestCentricity
9
9
 
10
- SimpleCov.command_name("features-#{ENV['WEB_BROWSER']}-#{ENV['SELENIUM']}" + (ENV['TEST_ENV_NUMBER'] || ''))
10
+ coverage_report_name = "Features-#{ENV['WEB_BROWSER']}-#{ENV['SELENIUM']}" + (ENV['TEST_ENV_NUMBER'] || '')
11
+ SimpleCov.command_name("#{coverage_report_name}-#{Time.now.strftime('%Y%m%d%H%M%S%L')}")
11
12
 
12
13
  require_relative 'world_data'
13
14
  require_relative 'world_pages'
@@ -42,7 +43,7 @@ WorldPages.instantiate_page_objects
42
43
  Webdrivers.cache_time = 86_400
43
44
 
44
45
 
45
- url = if ENV['TEST_ENVIRONMENT'].downcase == 'local'
46
+ url = if Environ.test_environment == :local
46
47
  "file://#{File.dirname(__FILE__)}/../../test_site"
47
48
  else
48
49
  Environ.current.app_host
@@ -104,6 +104,11 @@ Around('@!firefox') do |scenario, block|
104
104
  end
105
105
 
106
106
 
107
+ Around('@!firefox_headless') do |scenario, block|
108
+ qualify_browser(:firefox_headless, 'Firefox headless', scenario, block)
109
+ end
110
+
111
+
107
112
  # block feature/scenario execution if running against iPad mobile browser
108
113
  Around('@!ipad') do |scenario, block|
109
114
  qualify_device('ipad', scenario, block)
@@ -200,9 +205,9 @@ Around('@!headless') do |scenario, block|
200
205
  end
201
206
 
202
207
 
203
- Around('@!firefox_headless') do |scenario, block|
204
- if Environ.browser == :firefox_headless
205
- log "Scenario '#{scenario.name}' can not be executed on headless Firefox browsers."
208
+ Around('@!firefox_grid') do |scenario, block|
209
+ if Environ.browser == :firefox && Environ.grid
210
+ log "Scenario '#{scenario.name}' can not be executed on grid hosted Firefox browsers."
206
211
  skip_this_scenario
207
212
  else
208
213
  block.call
@@ -2,7 +2,7 @@
2
2
 
3
3
  class BaseTestPage < TestCentricity::PageObject
4
4
  # Base Test page UI elements
5
- label :header_label, 'h2'
5
+ label :header_label, 'h2#header'
6
6
  sections header_nav: NavHeader
7
7
 
8
8
  def navigate_to
@@ -24,6 +24,7 @@ class BasicCSSFormPage < BasicFormPage
24
24
  radio_4: 'input#radio4'
25
25
  selectlists multi_select: 'select#multipleselect',
26
26
  drop_down_select: 'select#dropdown'
27
+ lists links_list: 'ul#links_list'
27
28
  links link_1: 'a#link1',
28
29
  link_2: 'a#link2',
29
30
  link_3: 'a#link3'
@@ -233,6 +233,12 @@ class BasicFormPage < BaseTestPage
233
233
  selected: 'Drop Down Item 1'
234
234
  },
235
235
  link_label => { visible: true, caption: 'Links:' },
236
+ links_list => {
237
+ visible: true,
238
+ enabled: true,
239
+ itemcount: 3,
240
+ items: ['Open Media Page in same window/tab', 'Open Media Page in a new window/tab', 'Disabled Link']
241
+ },
236
242
  link_1 => {
237
243
  visible: true,
238
244
  href: { ends_with: 'media_page.html' },
@@ -315,15 +321,21 @@ class BasicFormPage < BaseTestPage
315
321
  check1: data.check1,
316
322
  check2: data.check2,
317
323
  check3: data.check3,
318
- radio1: false,
319
- radio2: true,
320
- radio3: false,
324
+ radio_select: data.radio_select,
321
325
  multi_select: data.multi_select,
322
326
  drop_select: data.drop_down_item
323
327
  }
324
328
  end
325
329
 
326
330
  def populate_form
331
+ # toggle checks and radios and verify
332
+ check_2.check
333
+ check_2.verify_check_state(true)
334
+ check_2.uncheck
335
+ check_2.verify_check_state(false)
336
+ radio_2.select
337
+ radio_2.unselect
338
+ # populate fields and controls with externally sourced data
327
339
  @data = form_data
328
340
  fields = {
329
341
  username_field => @data[:username],
@@ -337,9 +349,9 @@ class BasicFormPage < BaseTestPage
337
349
  check_1 => @data[:check1],
338
350
  check_2 => @data[:check2],
339
351
  check_3 => @data[:check3],
340
- radio_1 => @data[:radio1],
341
- radio_2 => @data[:radio2],
342
- radio_3 => @data[:radio3],
352
+ radio_1 => @data[:radio_select] == 1,
353
+ radio_2 => @data[:radio_select] == 2,
354
+ radio_3 => @data[:radio_select] == 3,
343
355
  multi_select => @data[:multi_select],
344
356
  drop_down_select => @data[:drop_select]
345
357
  }
@@ -359,9 +371,9 @@ class BasicFormPage < BaseTestPage
359
371
  check_1 => { checked: @data[:check1] },
360
372
  check_2 => { checked: @data[:check2] },
361
373
  check_3 => { checked: @data[:check3] },
362
- radio_1 => { selected: @data[:radio1] },
363
- radio_2 => { selected: @data[:radio2] },
364
- radio_3 => { selected: @data[:radio3] },
374
+ radio_1 => { selected: @data[:radio_select] == 1 },
375
+ radio_2 => { selected: @data[:radio_select] == 2 },
376
+ radio_3 => { selected: @data[:radio_select] == 3 },
365
377
  multi_select => { selected: @data[:multi_select] },
366
378
  drop_down_select => { selected: @data[:drop_select] }
367
379
  }
@@ -390,4 +402,28 @@ class BasicFormPage < BaseTestPage
390
402
  end
391
403
  verify_focus_order(order)
392
404
  end
405
+
406
+ def choose_options_by(method)
407
+ case method.downcase.to_sym
408
+ when :index
409
+ multi_select.choose_option(index: 2)
410
+ drop_down_select.choose_option(index: 3)
411
+ when :value
412
+ multi_select.choose_option(value: 'ms2')
413
+ drop_down_select.choose_option(value: 'dd3')
414
+ when :text
415
+ multi_select.choose_option(text: 'Selection Item 2')
416
+ drop_down_select.choose_option(text: 'Drop Down Item 3')
417
+ else
418
+ raise "#{method} is not a valid selector"
419
+ end
420
+ end
421
+
422
+ def verify_chosen_options
423
+ ui = {
424
+ multi_select => { selected: 'Selection Item 2' },
425
+ drop_down_select => { selected: 'Drop Down Item 3' }
426
+ }
427
+ verify_ui_states(ui)
428
+ end
393
429
  end
@@ -24,6 +24,7 @@ class BasicXpathFormPage < BasicFormPage
24
24
  radio_4: "//input[@id='radio4']"
25
25
  selectlists multi_select: "//select[@id='multipleselect']",
26
26
  drop_down_select: "//select[@id='dropdown']"
27
+ lists links_list: "//ul[@id='links_list']"
27
28
  links link_1: "//a[@id='link1']",
28
29
  link_2: "//a[@id='link2']",
29
30
  link_3: "//a[@id='link3']"