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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.rspec +2 -1
- data/.ruby-version +1 -0
- data/.simplecov +5 -1
- data/CHANGELOG.md +43 -0
- data/README.md +14 -13
- data/Rakefile +99 -21
- data/config/cucumber.yml +32 -11
- data/config/locales/en-US.yml +56 -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 → docker-compose.yml} +2 -2
- data/features/basic_form_page_css.feature +54 -0
- data/features/basic_form_page_xpath.feature +26 -0
- data/features/custom_controls.feature +29 -0
- data/features/media_players.feature +67 -0
- data/features/step_definitions/generic_steps.rb.rb +87 -0
- data/features/step_definitions/media_steps.rb +30 -0
- data/features/support/data/form_data.rb +43 -0
- data/features/support/env.rb +18 -10
- data/features/support/hooks.rb +26 -1
- data/features/support/pages/base_test_page.rb +22 -0
- data/features/support/pages/{basic_css_test_page.rb → basic_css_form_page.rb} +12 -8
- data/features/support/pages/{basic_test_page.rb → basic_form_page.rb} +227 -36
- data/features/support/pages/{basic_xpath_test_page.rb → basic_xpath_form_page.rb} +12 -7
- data/features/support/pages/custom_controls_page.rb +263 -0
- data/features/support/pages/indexed_sections_page.rb +57 -0
- data/features/support/pages/media_test_page.rb +207 -0
- data/features/support/sections/header_nav.rb +48 -0
- data/features/support/sections/product_card.rb +39 -0
- data/features/support/world_data.rb +12 -0
- data/features/support/world_pages.rb +5 -2
- data/lib/testcentricity_web/appium_server.rb +5 -0
- data/lib/testcentricity_web/browser_helper.rb +0 -6
- data/lib/testcentricity_web/data_objects/data_objects_helper.rb +7 -0
- data/lib/testcentricity_web/data_objects/environment.rb +14 -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 +1 -8
- data/lib/testcentricity_web/web_core/page_objects_helper.rb +4 -2
- data/lib/testcentricity_web/web_core/page_section.rb +1 -1
- data/lib/testcentricity_web/web_core/webdriver_helper.rb +60 -44
- data/lib/testcentricity_web/web_elements/checkbox.rb +49 -19
- 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 +46 -12
- data/lib/testcentricity_web/web_elements/radio.rb +51 -16
- data/lib/testcentricity_web/web_elements/select_list.rb +12 -12
- data/lib/testcentricity_web/web_elements/ui_elements_helper.rb +22 -9
- data/lib/testcentricity_web/web_elements/video.rb +2 -2
- data/spec/fixtures/page_object.rb +22 -0
- data/spec/fixtures/section_object.rb +21 -0
- data/spec/spec_helper.rb +31 -0
- data/spec/testcentricity_web/browser_spec.rb +41 -0
- data/spec/testcentricity_web/elements/audio_spec.rb +68 -0
- data/spec/testcentricity_web/elements/button_spec.rb +18 -0
- data/spec/testcentricity_web/elements/checkbox_spec.rb +33 -0
- data/spec/testcentricity_web/elements/file_field_spec.rb +13 -0
- data/spec/testcentricity_web/elements/image_spec.rb +33 -0
- data/spec/testcentricity_web/elements/label_spec.rb +18 -0
- data/spec/testcentricity_web/elements/link_spec.rb +23 -0
- data/spec/testcentricity_web/elements/list_spec.rb +13 -0
- data/spec/testcentricity_web/elements/radio_spec.rb +28 -0
- data/spec/testcentricity_web/elements/ui_element_spec.rb +125 -0
- data/spec/testcentricity_web/elements/video_spec.rb +68 -0
- data/spec/testcentricity_web/helper_specs/object_helpers_spec.rb +39 -0
- data/spec/testcentricity_web/helper_specs/string_helpers_spec.rb +49 -0
- data/spec/testcentricity_web/page_object_spec.rb +90 -0
- data/spec/testcentricity_web/section_object_spec.rb +72 -0
- data/spec/testcentricity_web/version_spec.rb +7 -0
- data/spec/testcentricity_web/webdriver_connect/grid_webdriver_spec.rb +72 -0
- data/spec/testcentricity_web/webdriver_connect/local_webdriver_spec.rb +86 -0
- data/spec/testcentricity_web/webdriver_connect/mobile_webdriver_spec.rb +65 -0
- data/test_site/basic_test_page.html +51 -1
- data/test_site/chosen-sprite.png +0 -0
- data/test_site/chosen-sprite@2x.png +0 -0
- data/test_site/chosen.css +496 -0
- data/test_site/chosen.jquery.js +1359 -0
- data/test_site/chosen.jquery.min.js +3 -0
- data/test_site/chosen.min.css +11 -0
- data/test_site/chosen.proto.js +1399 -0
- data/test_site/chosen.proto.min.js +3 -0
- data/test_site/composer.json +36 -0
- data/test_site/custom_controls_page.html +629 -0
- data/test_site/docsupport/chosen.png +0 -0
- data/test_site/docsupport/init.js +11 -0
- data/test_site/docsupport/init.proto.js +16 -0
- data/test_site/docsupport/jquery-1.12.4.min.js +5 -0
- data/test_site/docsupport/jquery-3.2.1.min.js +4 -0
- data/test_site/docsupport/oss-credit.png +0 -0
- data/test_site/docsupport/prism.css +108 -0
- data/test_site/docsupport/prism.js +9 -0
- data/test_site/docsupport/prototype-1.7.0.0.js +6082 -0
- data/test_site/docsupport/style.css +219 -0
- data/test_site/images/Blouse_Black.jpg +0 -0
- data/test_site/images/Printed_Dress.jpg +0 -0
- data/test_site/images/T-shirt.jpg +0 -0
- data/test_site/images/jeans3.jpg +0 -0
- data/test_site/indexed_sections_page.html +215 -0
- data/test_site/media/MIB2-subtitles-pt-BR.vtt +49 -0
- data/test_site/media/MIB2.mp4 +0 -0
- data/test_site/media/bbc_scotland_report.mp3 +0 -0
- data/test_site/media/count_and_bars.mp4 +0 -0
- data/test_site/media_page.html +60 -7
- data/testcentricity_web.gemspec +14 -8
- metadata +197 -25
- data/Gemfile.lock +0 -170
- data/features/basic_test_page_css.feature +0 -24
- data/features/basic_test_page_xpath.feature +0 -24
- data/features/support/pages/media_page.rb +0 -11
@@ -0,0 +1,57 @@
|
|
1
|
+
# Page Object class definition for Indexed Sections page with CSS locators
|
2
|
+
|
3
|
+
class IndexedSectionsPage < BaseTestPage
|
4
|
+
trait(:page_name) { 'Indexed Sections' }
|
5
|
+
trait(:page_locator) { 'div.indexed-sections-page-body' }
|
6
|
+
trait(:page_url) { '/indexed_sections_page.html' }
|
7
|
+
trait(:navigator) { header_nav.open_indexed_sections_page }
|
8
|
+
trait(:page_title) { 'Indexed Sections Page'}
|
9
|
+
|
10
|
+
list :product_list, 'div#product_list'
|
11
|
+
section :product_card, ProductCard
|
12
|
+
|
13
|
+
def initialize
|
14
|
+
super
|
15
|
+
# define the list item element for the Product list object
|
16
|
+
list_elements = { list_item: 'div.column' }
|
17
|
+
product_list.define_list_elements(list_elements)
|
18
|
+
# associate the Product Card indexed section object with the Product list object
|
19
|
+
product_card.set_list_index(product_list)
|
20
|
+
end
|
21
|
+
|
22
|
+
def verify_page_ui
|
23
|
+
super
|
24
|
+
|
25
|
+
ui = {
|
26
|
+
product_list => {
|
27
|
+
exists: true,
|
28
|
+
visible: true,
|
29
|
+
itemcount: 4
|
30
|
+
},
|
31
|
+
product_card => { items: ['Tailored Jeans', 'Faded Short Sleeve T-shirts', 'Print Dress', 'Blouse'] }
|
32
|
+
}
|
33
|
+
verify_ui_states(ui)
|
34
|
+
# verify contents of first product card
|
35
|
+
product_card.set_list_index(product_list, 1)
|
36
|
+
card_data = {
|
37
|
+
product_name: 'Tailored Jeans',
|
38
|
+
price: '$59.99',
|
39
|
+
description: 'Some text about the jeans. Super slim and comfy lorem ipsum lorem jeansum. Lorem jeamsun denim lorem jeansum.',
|
40
|
+
rating: 3,
|
41
|
+
image_alt: 'Denim Jeans',
|
42
|
+
image_src: 'images/jeans3.jpg'
|
43
|
+
}
|
44
|
+
product_card.verify_card(card_data)
|
45
|
+
# verify contents of second product card
|
46
|
+
product_card.set_list_index(product_list, 2)
|
47
|
+
card_data = {
|
48
|
+
product_name: 'Faded Short Sleeve T-shirts',
|
49
|
+
price: '$19.99',
|
50
|
+
description: "Faded short sleeve t-shirt with high neckline. Soft and stretchy material for a comfortable fit. Accessorize with a straw hat and you're ready for summer!",
|
51
|
+
rating: 4,
|
52
|
+
image_alt: 'Faded Short Sleeve T-shirts',
|
53
|
+
image_src: 'images/T-shirt.jpg'
|
54
|
+
}
|
55
|
+
product_card.verify_card(card_data)
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,207 @@
|
|
1
|
+
# Page Object class definition for Media Test page with CSS locators
|
2
|
+
|
3
|
+
class MediaTestPage < BaseTestPage
|
4
|
+
trait(:page_name) { 'Media Test' }
|
5
|
+
trait(:page_locator) { 'div.media-page-body' }
|
6
|
+
trait(:page_url) { '/media_page.html' }
|
7
|
+
trait(:navigator) { header_nav.open_media_page }
|
8
|
+
trait(:page_title) { 'Media Page'}
|
9
|
+
|
10
|
+
# Media Test page UI elements
|
11
|
+
videos video_player_1: 'video#video_player1'
|
12
|
+
audios audio_player: 'audio#audio_player'
|
13
|
+
|
14
|
+
def verify_page_ui
|
15
|
+
super
|
16
|
+
|
17
|
+
preload = case
|
18
|
+
when Environ.browser == :safari
|
19
|
+
'auto'
|
20
|
+
when Environ.device_os == :ios && Environ.driver != :webdriver
|
21
|
+
'auto'
|
22
|
+
when %i[firefox firefox_headless].include?(Environ.browser)
|
23
|
+
''
|
24
|
+
else
|
25
|
+
'metadata'
|
26
|
+
end
|
27
|
+
video_player_1.wait_until_ready_state_is(4, 20)
|
28
|
+
audio_player.wait_until_ready_state_is(4, 10)
|
29
|
+
ui = {
|
30
|
+
video_player_1 => {
|
31
|
+
visible: true,
|
32
|
+
paused: true,
|
33
|
+
autoplay: false,
|
34
|
+
loop: false,
|
35
|
+
ended: false,
|
36
|
+
controls: true,
|
37
|
+
current_time: 0,
|
38
|
+
ready_state: 4,
|
39
|
+
default_playback_rate: 1,
|
40
|
+
playback_rate: 1,
|
41
|
+
seeking: false,
|
42
|
+
default_muted: false,
|
43
|
+
muted: false,
|
44
|
+
volume: 1,
|
45
|
+
preload: preload,
|
46
|
+
poster: '',
|
47
|
+
src: '',
|
48
|
+
duration: 17.6
|
49
|
+
},
|
50
|
+
audio_player => {
|
51
|
+
visible: true,
|
52
|
+
paused: true,
|
53
|
+
autoplay: false,
|
54
|
+
loop: false,
|
55
|
+
ended: false,
|
56
|
+
controls: true,
|
57
|
+
current_time: 0,
|
58
|
+
ready_state: 4,
|
59
|
+
default_playback_rate: 1,
|
60
|
+
playback_rate: 1,
|
61
|
+
seeking: false,
|
62
|
+
default_muted: false,
|
63
|
+
muted: false,
|
64
|
+
volume: 1,
|
65
|
+
preload: preload,
|
66
|
+
src: ''
|
67
|
+
}
|
68
|
+
}
|
69
|
+
verify_ui_states(ui)
|
70
|
+
unless Environ.browser == :safari
|
71
|
+
ui = { video_player_1 => {
|
72
|
+
width: video_player_1.video_width,
|
73
|
+
height: video_player_1.video_height
|
74
|
+
}
|
75
|
+
}
|
76
|
+
verify_ui_states(ui)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def perform_action(media_type, action)
|
81
|
+
player = dispatch_player(media_type)
|
82
|
+
case action.downcase.to_sym
|
83
|
+
when :play
|
84
|
+
player.play
|
85
|
+
player.send_keys(:enter) if player.paused?
|
86
|
+
player.click_at(25, 25) if player.paused?
|
87
|
+
when :pause
|
88
|
+
player.pause
|
89
|
+
when :mute
|
90
|
+
player.mute
|
91
|
+
when :unmute
|
92
|
+
player.unmute
|
93
|
+
else
|
94
|
+
raise "#{action} is not a valid selector"
|
95
|
+
end
|
96
|
+
sleep(2)
|
97
|
+
end
|
98
|
+
|
99
|
+
def verify_media_state(media_type, state)
|
100
|
+
player = dispatch_player(media_type)
|
101
|
+
duration = player.duration
|
102
|
+
props = case state.downcase.to_sym
|
103
|
+
when :playing
|
104
|
+
{
|
105
|
+
visible: true,
|
106
|
+
paused: false,
|
107
|
+
ended: false,
|
108
|
+
current_time: { greater_than: 0 },
|
109
|
+
seeking: false
|
110
|
+
}
|
111
|
+
when :paused
|
112
|
+
{
|
113
|
+
visible: true,
|
114
|
+
paused: true,
|
115
|
+
ended: false,
|
116
|
+
current_time: { greater_than: 0 },
|
117
|
+
seeking: false
|
118
|
+
}
|
119
|
+
when :ended
|
120
|
+
{
|
121
|
+
visible: true,
|
122
|
+
paused: true,
|
123
|
+
ended: true,
|
124
|
+
current_time: duration,
|
125
|
+
seeking: false
|
126
|
+
}
|
127
|
+
when :muted
|
128
|
+
{
|
129
|
+
visible: true,
|
130
|
+
muted: true
|
131
|
+
}
|
132
|
+
when :unmuted
|
133
|
+
{
|
134
|
+
visible: true,
|
135
|
+
muted: false
|
136
|
+
}
|
137
|
+
else
|
138
|
+
raise "#{state} is not a valid selector"
|
139
|
+
end
|
140
|
+
verify_ui_states(player => props)
|
141
|
+
end
|
142
|
+
|
143
|
+
def set_playback_rate(media_type, rate)
|
144
|
+
player = dispatch_player(media_type)
|
145
|
+
player.playback_rate = rate.to_f
|
146
|
+
reset_play(player)
|
147
|
+
end
|
148
|
+
|
149
|
+
def verify_playback_rate(media_type, rate)
|
150
|
+
player = dispatch_player(media_type)
|
151
|
+
ui = {
|
152
|
+
player => {
|
153
|
+
playback_rate: rate.to_f,
|
154
|
+
visible: true,
|
155
|
+
paused: false,
|
156
|
+
seeking: false,
|
157
|
+
current_time: { greater_than: 0 }
|
158
|
+
}
|
159
|
+
}
|
160
|
+
verify_ui_states(ui)
|
161
|
+
end
|
162
|
+
|
163
|
+
def set_volume(media_type, volume)
|
164
|
+
player = dispatch_player(media_type)
|
165
|
+
player.volume = volume.to_f
|
166
|
+
reset_play(player)
|
167
|
+
end
|
168
|
+
|
169
|
+
def verify_volume(media_type, volume)
|
170
|
+
player = dispatch_player(media_type)
|
171
|
+
ui = {
|
172
|
+
player => {
|
173
|
+
volume: volume.to_f,
|
174
|
+
visible: true,
|
175
|
+
muted: false,
|
176
|
+
paused: false,
|
177
|
+
seeking: false,
|
178
|
+
current_time: { greater_than: 0 }
|
179
|
+
}
|
180
|
+
}
|
181
|
+
verify_ui_states(ui)
|
182
|
+
end
|
183
|
+
|
184
|
+
private
|
185
|
+
|
186
|
+
def dispatch_player(media_type)
|
187
|
+
player = case media_type.downcase.to_sym
|
188
|
+
when :video
|
189
|
+
video_player_1
|
190
|
+
when :audio
|
191
|
+
audio_player
|
192
|
+
else
|
193
|
+
raise "#{media_type} is not a valid selector"
|
194
|
+
end
|
195
|
+
player.wait_until_ready_state_is(4, 20)
|
196
|
+
player
|
197
|
+
end
|
198
|
+
|
199
|
+
def reset_play(player)
|
200
|
+
player.pause
|
201
|
+
player.current_time = 0
|
202
|
+
player.play
|
203
|
+
player.send_keys(:enter) if player.paused?
|
204
|
+
player.click_at(25, 25) if player.paused?
|
205
|
+
sleep(2)
|
206
|
+
end
|
207
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# Section Object class definition for Top Navigation Bar
|
2
|
+
|
3
|
+
class NavHeader < TestCentricity::PageSection
|
4
|
+
trait(:section_locator) { 'div#nav_bar' }
|
5
|
+
trait(:section_name) { 'Top Navigation Bar' }
|
6
|
+
|
7
|
+
# Top Navigation Bar UI elements
|
8
|
+
links form_link: 'a#form_link',
|
9
|
+
media_link: 'a#media_link',
|
10
|
+
indexed_sections_link: 'a#indexed_sections_link',
|
11
|
+
custom_controls_link: 'a#custom_controls_link'
|
12
|
+
|
13
|
+
def open_form_page
|
14
|
+
form_link.click
|
15
|
+
end
|
16
|
+
|
17
|
+
def open_media_page
|
18
|
+
media_link.click
|
19
|
+
end
|
20
|
+
|
21
|
+
def open_indexed_sections_page
|
22
|
+
indexed_sections_link.click
|
23
|
+
end
|
24
|
+
|
25
|
+
def open_custom_controls_page
|
26
|
+
custom_controls_link.click
|
27
|
+
end
|
28
|
+
|
29
|
+
def verify_nav_bar
|
30
|
+
self.wait_until_visible(5)
|
31
|
+
ui = {
|
32
|
+
self => {
|
33
|
+
exists: true,
|
34
|
+
visible: true,
|
35
|
+
hidden: false,
|
36
|
+
displayed: true,
|
37
|
+
enabled: true,
|
38
|
+
disabled: false,
|
39
|
+
class: 'topnav'
|
40
|
+
},
|
41
|
+
form_link => { visible: true, caption: 'Basic HTML Form' },
|
42
|
+
media_link => { visible: true, caption: 'Media' },
|
43
|
+
indexed_sections_link => { visible: true, caption: 'Indexed Sections' },
|
44
|
+
custom_controls_link => { visible: true, caption: 'Custom Controls' },
|
45
|
+
}
|
46
|
+
verify_ui_states(ui)
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# Section Object class definition for Product Card
|
2
|
+
|
3
|
+
class ProductCard < TestCentricity::PageSection
|
4
|
+
trait(:section_locator) { 'div.column' }
|
5
|
+
trait(:section_name) { 'Product Card' }
|
6
|
+
|
7
|
+
# Product Card UI elements
|
8
|
+
image :product_image, "img[data-test-id='product_image']"
|
9
|
+
labels name_label: "h1[data-test-id='product_name']",
|
10
|
+
price_label: "p[data-test-id='price']",
|
11
|
+
description_label: "p[data-test-id='description']"
|
12
|
+
elements ratings: "div[data-test-id='rating']",
|
13
|
+
checked_star: 'span.fa.fa-star.checked'
|
14
|
+
button :add_to_cart_button, "button[data-test-id='add_to_cart']"
|
15
|
+
|
16
|
+
def get_value
|
17
|
+
name_label.get_caption
|
18
|
+
end
|
19
|
+
|
20
|
+
def verify_card(card_data)
|
21
|
+
ui = {
|
22
|
+
product_image => {
|
23
|
+
visible: true,
|
24
|
+
loaded: true,
|
25
|
+
broken: false,
|
26
|
+
src: { ends_with: card_data[:image_src] },
|
27
|
+
alt: card_data[:image_alt]
|
28
|
+
},
|
29
|
+
name_label => { visible: true, caption: card_data[:product_name] },
|
30
|
+
price_label => { visible: true, caption: card_data[:price] },
|
31
|
+
description_label => { visible: true, caption: card_data[:description] },
|
32
|
+
checked_star => { count: card_data[:rating] },
|
33
|
+
add_to_cart_button => { visible: true, enabled: true, caption: 'Add to Cart' }
|
34
|
+
}
|
35
|
+
within(self.get_locator) do
|
36
|
+
verify_ui_states(ui)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module WorldData
|
2
|
+
#
|
3
|
+
# data_objects method returns a hash table of your web app's data objects and associated data object classes to be instantiated
|
4
|
+
# by the TestCentricity™ DataManager. Data Object class definitions are contained in the features/support/data folder.
|
5
|
+
#
|
6
|
+
def data_objects
|
7
|
+
{ form_data_source: FormDataSource }
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
|
12
|
+
World(WorldData)
|
@@ -5,8 +5,11 @@ module WorldPages
|
|
5
5
|
#
|
6
6
|
def page_objects
|
7
7
|
{
|
8
|
-
|
9
|
-
|
8
|
+
basic_css_form_page: BasicCSSFormPage,
|
9
|
+
basic_xpath_form_page: BasicXpathFormPage,
|
10
|
+
media_test_page: MediaTestPage,
|
11
|
+
indexed_sections_page: IndexedSectionsPage,
|
12
|
+
custom_controls_page: CustomControlsPage
|
10
13
|
}
|
11
14
|
end
|
12
15
|
end
|
@@ -18,10 +18,12 @@ module TestCentricity
|
|
18
18
|
def start
|
19
19
|
# terminate any currently running Appium Server
|
20
20
|
if running?
|
21
|
+
# :nocov:
|
21
22
|
system('killall -9 node')
|
22
23
|
puts 'Terminating existing Appium Server'
|
23
24
|
sleep(5)
|
24
25
|
puts 'Appium Server is being restarted'
|
26
|
+
# :nocov:
|
25
27
|
else
|
26
28
|
puts 'Appium Server is starting'
|
27
29
|
end
|
@@ -56,6 +58,7 @@ module TestCentricity
|
|
56
58
|
|
57
59
|
private
|
58
60
|
|
61
|
+
# :nocov:
|
59
62
|
def parameters
|
60
63
|
cmd = ['appium']
|
61
64
|
@params.each do |key, value|
|
@@ -64,5 +67,7 @@ module TestCentricity
|
|
64
67
|
end
|
65
68
|
cmd
|
66
69
|
end
|
70
|
+
# :nocov:
|
67
71
|
end
|
68
72
|
end
|
73
|
+
|
@@ -95,12 +95,6 @@ module TestCentricity
|
|
95
95
|
Capybara.page.driver.browser.switch_to.window(Capybara.page.driver.browser.window_handles.last)
|
96
96
|
end
|
97
97
|
|
98
|
-
def self.close_named_browser_instance(name)
|
99
|
-
Capybara.page.driver.browser.switch_to.window(Capybara.page.driver.find_window(name))
|
100
|
-
Capybara.page.driver.browser.close
|
101
|
-
Capybara.page.driver.browser.switch_to.window(Capybara.page.driver.browser.window_handles.last)
|
102
|
-
end
|
103
|
-
|
104
98
|
def self.suppress_js_alerts
|
105
99
|
Capybara.page.execute_script('window.alert = function() {}')
|
106
100
|
end
|
@@ -52,6 +52,7 @@ module TestCentricity
|
|
52
52
|
@current = current
|
53
53
|
end
|
54
54
|
|
55
|
+
# :nocov:
|
55
56
|
def to_hash(node_name = nil)
|
56
57
|
data = {}
|
57
58
|
if node_name.nil?
|
@@ -79,9 +80,12 @@ module TestCentricity
|
|
79
80
|
def write_json_data(file_name, mode, node_name = nil)
|
80
81
|
File.open(file_name, mode) { |file| file.write(to_json(node_name)) }
|
81
82
|
end
|
83
|
+
|
84
|
+
# :nocov:
|
82
85
|
end
|
83
86
|
|
84
87
|
|
88
|
+
# :nocov:
|
85
89
|
class DataSource
|
86
90
|
attr_accessor :file_path
|
87
91
|
attr_accessor :node
|
@@ -135,6 +139,7 @@ module TestCentricity
|
|
135
139
|
result.to_s
|
136
140
|
end
|
137
141
|
end
|
142
|
+
# :nocov:
|
138
143
|
|
139
144
|
|
140
145
|
class ExcelDataSource < TestCentricity::DataSource
|
@@ -159,6 +164,7 @@ module TestCentricity
|
|
159
164
|
ExcelData.read_row_data(pick_excel_data_source(sheet, @row_spec), sheet, @row_spec)
|
160
165
|
end
|
161
166
|
|
167
|
+
# :nocov:
|
162
168
|
def read_excel_pool_data(sheet, row_name, parallel = false)
|
163
169
|
@row_spec = parallel == :parallel && ENV['PARALLEL'] ? "#{row_name}#{ENV['TEST_ENV_NUMBER']}" : row_name
|
164
170
|
ExcelData.read_row_from_pool(pick_excel_data_source(sheet, row_name), sheet, @row_spec)
|
@@ -173,6 +179,7 @@ module TestCentricity
|
|
173
179
|
@row_spec = parallel == :parallel && ENV['PARALLEL'] ? "#{row_name}#{ENV['TEST_ENV_NUMBER']}" : row_name
|
174
180
|
ExcelData.write_row_data(pick_excel_data_source(sheet, @row_spec), sheet, @row_spec, row_data)
|
175
181
|
end
|
182
|
+
# :nocov:
|
176
183
|
end
|
177
184
|
end
|
178
185
|
|
@@ -71,6 +71,7 @@ module TestCentricity
|
|
71
71
|
@screen_shots = []
|
72
72
|
|
73
73
|
attr_accessor :test_environment
|
74
|
+
attr_accessor :app_host
|
74
75
|
attr_accessor :browser
|
75
76
|
attr_accessor :browser_size
|
76
77
|
attr_accessor :headless
|
@@ -133,9 +134,20 @@ module TestCentricity
|
|
133
134
|
@db_username = data['DB_USERNAME']
|
134
135
|
@db_password = data['DB_PASSWORD']
|
135
136
|
|
137
|
+
url = @hostname.blank? ? "#{@base_url}#{@append}" : "#{@hostname}/#{@base_url}#{@append}"
|
138
|
+
@app_host = if @user_id.blank? || @password.blank?
|
139
|
+
"#{@protocol}://#{url}"
|
140
|
+
else
|
141
|
+
"#{@protocol}://#{@user_id}:#{@password}@#{url}"
|
142
|
+
end
|
143
|
+
|
136
144
|
super
|
137
145
|
end
|
138
146
|
|
147
|
+
def self.app_host
|
148
|
+
@app_host
|
149
|
+
end
|
150
|
+
|
139
151
|
def self.session_code
|
140
152
|
if @session_code.nil?
|
141
153
|
characters = ('a'..'z').to_a
|
@@ -384,6 +396,7 @@ module TestCentricity
|
|
384
396
|
@screen_shots = []
|
385
397
|
end
|
386
398
|
|
399
|
+
# :nocov:
|
387
400
|
def self.report_header
|
388
401
|
report_header = "\n<b><u>TEST ENVIRONMENT</u>:</b> #{ENV['TEST_ENVIRONMENT']}\n"\
|
389
402
|
" <b>Browser:</b>\t #{Environ.browser.capitalize}\n"
|
@@ -399,6 +412,7 @@ module TestCentricity
|
|
399
412
|
report_header = "#{report_header} <b>WCAG Accessibility Standard:</b>\t #{ENV['ACCESSIBILITY_STANDARD']}\n" if ENV['ACCESSIBILITY_STANDARD']
|
400
413
|
"#{report_header}\n\n"
|
401
414
|
end
|
415
|
+
# :nocov:
|
402
416
|
end
|
403
417
|
end
|
404
418
|
|
@@ -52,6 +52,65 @@ module TestCentricity
|
|
52
52
|
exists
|
53
53
|
end
|
54
54
|
|
55
|
+
def self.read_row_data(file, sheet, row_spec, columns = nil)
|
56
|
+
raise "File #{file} does not exists" unless File.exist?(file)
|
57
|
+
work_book = Spreadsheet.open(file)
|
58
|
+
work_sheet = work_book.worksheet(sheet)
|
59
|
+
# get column headings from row 0 of worksheet
|
60
|
+
headings = work_sheet.row(0)
|
61
|
+
# if row_spec is a string then we have to find a matching row name
|
62
|
+
if row_spec.is_a? String
|
63
|
+
column_number = 0
|
64
|
+
found = false
|
65
|
+
headings.each do |heading|
|
66
|
+
if heading == 'ROW_NAME'
|
67
|
+
found = true
|
68
|
+
break
|
69
|
+
end
|
70
|
+
column_number += 1
|
71
|
+
end
|
72
|
+
raise "Could not find a column named ROW_NAME in worksheet #{sheet}" unless found
|
73
|
+
# find first cell in ROW_NAME column containing a string that matches the row_spec parameter
|
74
|
+
found = false
|
75
|
+
row_number = 0
|
76
|
+
work_sheet.each do |row|
|
77
|
+
if row[column_number] == row_spec
|
78
|
+
found = true
|
79
|
+
break
|
80
|
+
end
|
81
|
+
row_number += 1
|
82
|
+
end
|
83
|
+
raise "Could not find a row named '#{row_spec}' in worksheet #{sheet}" unless found
|
84
|
+
data = work_sheet.row(row_number)
|
85
|
+
# if row_spec is a number then ensure that it doesn't exceed the number of available rows
|
86
|
+
elsif row_spec.is_a? Numeric
|
87
|
+
raise "Row # #{row_spec} is greater than number of rows in worksheet #{sheet}" if row_spec > work_sheet.last_row_index
|
88
|
+
data = work_sheet.row(row_spec)
|
89
|
+
end
|
90
|
+
|
91
|
+
# if no columns have been specified, return all columns
|
92
|
+
columns = headings if columns.nil?
|
93
|
+
# create results hash table
|
94
|
+
result = Hash.new
|
95
|
+
columns.each do |column|
|
96
|
+
column_number = 0
|
97
|
+
found = false
|
98
|
+
headings.each do |heading|
|
99
|
+
if column == heading
|
100
|
+
value = data[column_number].to_s
|
101
|
+
value = calculate_dynamic_value(value) if value.start_with? 'eval!'
|
102
|
+
result[column] = value
|
103
|
+
found = true
|
104
|
+
break
|
105
|
+
end
|
106
|
+
column_number += 1
|
107
|
+
end
|
108
|
+
raise "Could not find a column named '#{column}' in worksheet #{sheet}" unless found
|
109
|
+
end
|
110
|
+
result
|
111
|
+
end
|
112
|
+
|
113
|
+
# :nocov:
|
55
114
|
def self.read_row_from_pool(file, sheet, row_spec, columns = nil)
|
56
115
|
raise "File #{file} does not exists" unless File.exist?(file)
|
57
116
|
work_book = Spreadsheet.open(file)
|
@@ -118,64 +177,6 @@ module TestCentricity
|
|
118
177
|
read_row_data(file, sheet, new_row, columns)
|
119
178
|
end
|
120
179
|
|
121
|
-
def self.read_row_data(file, sheet, row_spec, columns = nil)
|
122
|
-
raise "File #{file} does not exists" unless File.exist?(file)
|
123
|
-
work_book = Spreadsheet.open(file)
|
124
|
-
work_sheet = work_book.worksheet(sheet)
|
125
|
-
# get column headings from row 0 of worksheet
|
126
|
-
headings = work_sheet.row(0)
|
127
|
-
# if row_spec is a string then we have to find a matching row name
|
128
|
-
if row_spec.is_a? String
|
129
|
-
column_number = 0
|
130
|
-
found = false
|
131
|
-
headings.each do |heading|
|
132
|
-
if heading == 'ROW_NAME'
|
133
|
-
found = true
|
134
|
-
break
|
135
|
-
end
|
136
|
-
column_number += 1
|
137
|
-
end
|
138
|
-
raise "Could not find a column named ROW_NAME in worksheet #{sheet}" unless found
|
139
|
-
# find first cell in ROW_NAME column containing a string that matches the row_spec parameter
|
140
|
-
found = false
|
141
|
-
row_number = 0
|
142
|
-
work_sheet.each do |row|
|
143
|
-
if row[column_number] == row_spec
|
144
|
-
found = true
|
145
|
-
break
|
146
|
-
end
|
147
|
-
row_number += 1
|
148
|
-
end
|
149
|
-
raise "Could not find a row named '#{row_spec}' in worksheet #{sheet}" unless found
|
150
|
-
data = work_sheet.row(row_number)
|
151
|
-
# if row_spec is a number then ensure that it doesn't exceed the number of available rows
|
152
|
-
elsif row_spec.is_a? Numeric
|
153
|
-
raise "Row # #{row_spec} is greater than number of rows in worksheet #{sheet}" if row_spec > work_sheet.last_row_index
|
154
|
-
data = work_sheet.row(row_spec)
|
155
|
-
end
|
156
|
-
|
157
|
-
# if no columns have been specified, return all columns
|
158
|
-
columns = headings if columns.nil?
|
159
|
-
# create results hash table
|
160
|
-
result = Hash.new
|
161
|
-
columns.each do |column|
|
162
|
-
column_number = 0
|
163
|
-
found = false
|
164
|
-
headings.each do |heading|
|
165
|
-
if column == heading
|
166
|
-
value = data[column_number].to_s
|
167
|
-
value = calculate_dynamic_value(value) if value.start_with? 'eval!'
|
168
|
-
result[column] = value
|
169
|
-
found = true
|
170
|
-
break
|
171
|
-
end
|
172
|
-
column_number += 1
|
173
|
-
end
|
174
|
-
raise "Could not find a column named '#{column}' in worksheet #{sheet}" unless found
|
175
|
-
end
|
176
|
-
result
|
177
|
-
end
|
178
|
-
|
179
180
|
def self.read_range_data(file, sheet, range_spec)
|
180
181
|
raise "File #{file} does not exists" unless File.exist?(file)
|
181
182
|
work_book = Spreadsheet.open(file)
|
@@ -270,6 +271,6 @@ module TestCentricity
|
|
270
271
|
# rename new Excel document, replacing the original
|
271
272
|
File.rename(outfile, file)
|
272
273
|
end
|
274
|
+
# :nocov:
|
273
275
|
end
|
274
276
|
end
|
275
|
-
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# :nocov:
|
2
|
+
|
1
3
|
module CapybaraExtension
|
2
4
|
def drag_by(right_by, down_by)
|
3
5
|
base.drag_by(right_by, down_by)
|
@@ -11,5 +13,7 @@ module CapybaraSeleniumExtension
|
|
11
13
|
end
|
12
14
|
end
|
13
15
|
|
16
|
+
# :nocov:
|
17
|
+
|
14
18
|
::Capybara::Selenium::Node.send :include, CapybaraSeleniumExtension
|
15
19
|
::Capybara::Node::Element.send :include, CapybaraExtension
|
@@ -312,14 +312,7 @@ module TestCentricity
|
|
312
312
|
end
|
313
313
|
|
314
314
|
def open_portal
|
315
|
-
|
316
|
-
url = environment.hostname.blank? ? "#{environment.base_url}#{environment.append}" : "#{environment.hostname}/#{environment.base_url}#{environment.append}"
|
317
|
-
full_url = if environment.user_id.blank? || environment.password.blank?
|
318
|
-
"#{environment.protocol}://#{url}"
|
319
|
-
else
|
320
|
-
"#{environment.protocol}://#{environment.user_id}:#{environment.password}@#{url}"
|
321
|
-
end
|
322
|
-
visit full_url
|
315
|
+
visit Environ.current.app_host
|
323
316
|
Environ.portal_state = :open
|
324
317
|
end
|
325
318
|
|