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.
- 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
|
|