testcentricity_web 4.1.5 → 4.1.8
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.
- checksums.yaml +4 -4
- data/.gitignore +18 -0
- data/.simplecov +9 -0
- data/CHANGELOG.md +44 -0
- data/Gemfile.lock +60 -2
- data/README.md +17 -7
- data/Rakefile +86 -1
- data/config/cucumber.yml +170 -0
- data/config/test_data/LOCAL_data.json +15 -0
- data/config/test_data/LOCAL_data.xls +0 -0
- data/config/test_data/LOCAL_data.yml +11 -0
- data/config/test_data/data.json +25 -0
- data/config/test_data/data.xls +0 -0
- data/config/test_data/data.yml +20 -0
- data/docker-compose-v3.yml +48 -0
- data/features/basic_form_page_css.feature +39 -0
- data/features/basic_form_page_xpath.feature +26 -0
- data/features/media_players.feature +84 -0
- data/features/step_definitions/generic_steps.rb.rb +109 -0
- data/features/step_definitions/media_steps.rb +30 -0
- data/features/support/data/form_data.rb +43 -0
- data/features/support/env.rb +50 -0
- data/features/support/hooks.rb +265 -0
- data/features/support/pages/base_test_page.rb +22 -0
- data/features/support/pages/basic_css_form_page.rb +52 -0
- data/features/support/pages/basic_form_page.rb +393 -0
- data/features/support/pages/basic_xpath_form_page.rb +53 -0
- data/features/support/pages/custom_controls_page.rb +13 -0
- data/features/support/pages/indexed_sections_page.rb +13 -0
- data/features/support/pages/media_test_page.rb +208 -0
- data/features/support/sections/header_nav.rb +39 -0
- data/features/support/world_data.rb +12 -0
- data/features/support/world_pages.rb +18 -0
- data/lib/testcentricity_web/appium_server.rb +5 -0
- data/lib/testcentricity_web/data_objects/data_objects_helper.rb +7 -0
- data/lib/testcentricity_web/data_objects/environment.rb +18 -0
- data/lib/testcentricity_web/data_objects/excel_helper.rb +60 -59
- data/lib/testcentricity_web/version.rb +1 -1
- data/lib/testcentricity_web/web_core/drag_drop_helper.rb +4 -0
- data/lib/testcentricity_web/web_core/page_object.rb +8 -8
- data/lib/testcentricity_web/web_core/page_objects_helper.rb +43 -8
- data/lib/testcentricity_web/web_core/page_section.rb +1 -16
- data/lib/testcentricity_web/web_core/webdriver_helper.rb +16 -0
- data/lib/testcentricity_web/web_elements/checkbox.rb +3 -4
- data/lib/testcentricity_web/web_elements/file_field.rb +9 -5
- data/lib/testcentricity_web/web_elements/image.rb +2 -1
- data/lib/testcentricity_web/web_elements/media.rb +45 -11
- data/lib/testcentricity_web/web_elements/radio.rb +5 -1
- data/lib/testcentricity_web/web_elements/select_list.rb +11 -3
- data/lib/testcentricity_web/web_elements/ui_elements_helper.rb +33 -7
- data/lib/testcentricity_web/web_elements/video.rb +2 -2
- data/reports/.keep +1 -0
- data/test_site/basic_test_page.html +290 -0
- data/test_site/custom_controls_page.html +58 -0
- data/test_site/images/Granny.jpg +0 -0
- data/test_site/images/Wilder.jpg +0 -0
- data/test_site/images/You_Betcha.jpg +0 -0
- data/test_site/indexed_sections_page.html +58 -0
- data/test_site/media/MIB2-subtitles-pt-BR.vtt +49 -0
- data/test_site/media/MIB2.mp4 +0 -0
- data/test_site/media/MP4_small.mp4 +0 -0
- data/test_site/media/MPS_sample.mp3 +0 -0
- data/test_site/media/count_and_bars.mp4 +0 -0
- data/test_site/media_page.html +86 -0
- data/testcentricity_web.gemspec +5 -0
- metadata +131 -4
- data/test_site/test_page.html +0 -11
@@ -5,10 +5,6 @@ module TestCentricity
|
|
5
5
|
attr_accessor :parent
|
6
6
|
attr_accessor :parent_list
|
7
7
|
attr_accessor :list_index
|
8
|
-
attr_accessor :locator_type
|
9
|
-
|
10
|
-
XPATH_SELECTORS = ['//', '[@', '[contains(']
|
11
|
-
CSS_SELECTORS = ['#', ':nth-child(', ':first-child', ':last-child', ':nth-of-type(', ':first-of-type', ':last-of-type', '^=', '$=', '*=', ':contains(']
|
12
8
|
|
13
9
|
def initialize(name, parent, locator, context)
|
14
10
|
@name = name
|
@@ -17,18 +13,7 @@ module TestCentricity
|
|
17
13
|
@context = context
|
18
14
|
@parent_list = nil
|
19
15
|
@list_index = nil
|
20
|
-
|
21
|
-
is_xpath = XPATH_SELECTORS.any? { |selector| @locator.include?(selector) }
|
22
|
-
is_css = CSS_SELECTORS.any? { |selector| @locator.include?(selector) }
|
23
|
-
@locator_type = if is_xpath && !is_css
|
24
|
-
:xpath
|
25
|
-
elsif is_css && !is_xpath
|
26
|
-
:css
|
27
|
-
elsif !is_css && !is_xpath
|
28
|
-
:css
|
29
|
-
else
|
30
|
-
:css
|
31
|
-
end
|
16
|
+
set_locator_type
|
32
17
|
end
|
33
18
|
|
34
19
|
def get_locator
|
@@ -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,7 @@ module TestCentricity
|
|
255
267
|
Capybara.default_driver = :selenium
|
256
268
|
end
|
257
269
|
|
270
|
+
# :nocov:
|
258
271
|
def self.initialize_browserstack
|
259
272
|
browser = ENV['BS_BROWSER']
|
260
273
|
Environ.grid = :browserstack
|
@@ -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
|
@@ -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
|
-
|
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?
|
@@ -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
|
@@ -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
|
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
|
-
#
|
250
|
+
# Mute the media's audio
|
251
251
|
#
|
252
|
-
# @return crossorigin value
|
253
252
|
# @example
|
254
|
-
#
|
253
|
+
# media_player.mute
|
255
254
|
#
|
256
|
-
def
|
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
|
-
|
293
|
+
page.execute_script('arguments[0].volume = arguments[1]', obj, value)
|
260
294
|
end
|
261
295
|
|
262
296
|
# Return media preload property
|
@@ -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
|
-
|
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,15 +246,23 @@ module TestCentricity
|
|
246
246
|
def get_selected_option
|
247
247
|
@base_object, = find_element
|
248
248
|
object_not_found_exception(@base_object, nil)
|
249
|
-
trigger_list
|
249
|
+
trigger_list unless @options_list.nil?
|
250
250
|
selection = if @base_object.first(:css, @list_item, minimum: 0, wait: 1, visible: :all)
|
251
251
|
@base_object.first(:css, @selected_item, wait: 1, visible: :all).text
|
252
252
|
elsif @base_object.first(:css, @selected_item, minimum: 0, wait: 1, visible: :all)
|
253
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
|
254
256
|
else
|
255
|
-
|
257
|
+
index = get_attribute(:selectedIndex).to_i
|
258
|
+
if index >= 0
|
259
|
+
options = get_options
|
260
|
+
options[index]
|
261
|
+
else
|
262
|
+
''
|
263
|
+
end
|
256
264
|
end
|
257
|
-
trigger_list
|
265
|
+
trigger_list unless @options_list.nil?
|
258
266
|
selection
|
259
267
|
end
|
260
268
|
|
@@ -168,7 +168,7 @@ module TestCentricity
|
|
168
168
|
def scroll_to(position)
|
169
169
|
obj, type = find_element
|
170
170
|
object_not_found_exception(obj, type)
|
171
|
-
|
171
|
+
page.scroll_to(obj, align: position)
|
172
172
|
end
|
173
173
|
|
174
174
|
def set(value)
|
@@ -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]
|
@@ -508,12 +521,13 @@ module TestCentricity
|
|
508
521
|
def get_value(visible = true)
|
509
522
|
obj, type = find_element(visible)
|
510
523
|
object_not_found_exception(obj, type)
|
511
|
-
case obj.tag_name.downcase
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
524
|
+
text = case obj.tag_name.downcase
|
525
|
+
when 'input', 'select', 'textarea'
|
526
|
+
obj.value
|
527
|
+
else
|
528
|
+
obj.text
|
529
|
+
end
|
530
|
+
text.gsub(/[[:space:]]+/, ' ').strip
|
517
531
|
end
|
518
532
|
|
519
533
|
alias get_caption get_value
|
@@ -985,6 +999,18 @@ module TestCentricity
|
|
985
999
|
state.boolean? ? state : state == 'true'
|
986
1000
|
end
|
987
1001
|
|
1002
|
+
# Return crossorigin property
|
1003
|
+
#
|
1004
|
+
# @return crossorigin value
|
1005
|
+
# @example
|
1006
|
+
# with_creds = media_player.crossorigin == 'use-credentials'
|
1007
|
+
#
|
1008
|
+
def crossorigin
|
1009
|
+
obj, = find_element
|
1010
|
+
object_not_found_exception(obj, @type)
|
1011
|
+
obj.native.attribute('crossorigin')
|
1012
|
+
end
|
1013
|
+
|
988
1014
|
def get_attribute(attrib)
|
989
1015
|
obj, type = find_element(visible = false)
|
990
1016
|
object_not_found_exception(obj, type)
|
@@ -14,7 +14,7 @@ module TestCentricity
|
|
14
14
|
def video_height
|
15
15
|
obj, = find_element
|
16
16
|
object_not_found_exception(obj, :video)
|
17
|
-
obj.native.attribute('videoHeight')
|
17
|
+
obj.native.attribute('videoHeight').to_i
|
18
18
|
end
|
19
19
|
|
20
20
|
# Return video Width property
|
@@ -26,7 +26,7 @@ module TestCentricity
|
|
26
26
|
def video_width
|
27
27
|
obj, = find_element
|
28
28
|
object_not_found_exception(obj, :video)
|
29
|
-
obj.native.attribute('videoWidth')
|
29
|
+
obj.native.attribute('videoWidth').to_i
|
30
30
|
end
|
31
31
|
|
32
32
|
# Return video poster property
|
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.
|