testcentricity_web 3.2.0 → 3.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/CHANGELOG.md +8 -0
- data/Gemfile.lock +4 -4
- data/README.md +8 -4
- data/lib/testcentricity_web.rb +2 -1
- data/lib/testcentricity_web/data_objects/environment.rb +8 -8
- data/lib/testcentricity_web/version.rb +1 -1
- data/lib/testcentricity_web/web_core/page_object.rb +537 -0
- data/lib/testcentricity_web/web_core/page_objects_helper.rb +269 -801
- data/lib/testcentricity_web/web_core/{page_sections_helper.rb → page_section.rb} +1 -261
- data/lib/testcentricity_web/web_elements/cell_element.rb +6 -6
- data/lib/testcentricity_web/web_elements/checkbox.rb +33 -0
- data/lib/testcentricity_web/web_elements/list_element.rb +6 -6
- data/lib/testcentricity_web/web_elements/radio.rb +33 -0
- data/lib/testcentricity_web/web_elements/ui_elements_helper.rb +4 -4
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: c875303a27c1eaa23f786550d0b3c32738e84e9d
|
4
|
+
data.tar.gz: 1ddf7a0bc2f69efbd98c4331e09770bf74fe88b3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 557a3f34be2aff3383ac17ed402b72eb039e8d4b9ad8945c16be513db1179813b4c2f980d9b74e100f75228c8314412766c22ea9384e22744c8c03f3832c8b12
|
7
|
+
data.tar.gz: cb41453fd495fcd1b50ccf9a4da1d8a4b67afad02c2029f8952fa5e9eb6cda657603ffbcbe421f18b79f84a716d24bbd4f9edd1e85e8a209a13dd2566d7547ba
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,14 @@
|
|
2
2
|
All notable changes to this project will be documented in this file.
|
3
3
|
|
4
4
|
|
5
|
+
## [3.2.1] - 2019-10-03
|
6
|
+
|
7
|
+
### Changed
|
8
|
+
* `CheckBox.visible?`, `CheckBox.disabled?`, and `CheckBox.get_value` methods now work with React and Ember checkboxes with
|
9
|
+
proxy elements.
|
10
|
+
* `Radio.visible?`, `Radio.disabled?`, and `Radio.get_value` methods now work with React and Ember radio buttons with
|
11
|
+
proxy elements.
|
12
|
+
|
5
13
|
## [3.2.0] - 2019-07-28
|
6
14
|
|
7
15
|
### Added
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
testcentricity_web (3.2.
|
4
|
+
testcentricity_web (3.2.1)
|
5
5
|
appium_lib
|
6
6
|
browserstack-local
|
7
7
|
capybara (>= 3.1, < 4)
|
@@ -25,7 +25,7 @@ GEM
|
|
25
25
|
appium_lib_core (~> 3.2)
|
26
26
|
nokogiri (~> 1.8, >= 1.8.1)
|
27
27
|
tomlrb (~> 1.1)
|
28
|
-
appium_lib_core (3.2.
|
28
|
+
appium_lib_core (3.2.2)
|
29
29
|
faye-websocket (~> 0.10.0)
|
30
30
|
selenium-webdriver (~> 3.14, >= 3.14.1)
|
31
31
|
axiom-types (0.1.1)
|
@@ -33,7 +33,7 @@ GEM
|
|
33
33
|
ice_nine (~> 0.11.0)
|
34
34
|
thread_safe (~> 0.3, >= 0.3.1)
|
35
35
|
browserstack-local (1.3.0)
|
36
|
-
capybara (3.
|
36
|
+
capybara (3.28.0)
|
37
37
|
addressable
|
38
38
|
mini_mime (>= 0.1.3)
|
39
39
|
nokogiri (~> 1.8)
|
@@ -51,7 +51,7 @@ GEM
|
|
51
51
|
thread_safe (~> 0.3, >= 0.3.1)
|
52
52
|
equalizer (0.0.11)
|
53
53
|
eventmachine (1.2.7)
|
54
|
-
faker (2.0)
|
54
|
+
faker (2.1.0)
|
55
55
|
i18n (>= 0.7)
|
56
56
|
faye-websocket (0.10.9)
|
57
57
|
eventmachine (>= 0.12.0)
|
data/README.md
CHANGED
@@ -15,9 +15,13 @@ The TestCentricity™ Web gem supports running automated tests against the follo
|
|
15
15
|
* desktop and emulated mobile web browsers hosted on Selenium Grid and Dockerized Selenium Grid environments
|
16
16
|
* mobile Safari browsers on iOS device simulators or physical iOS devices (using Appium and XCode on OS X)
|
17
17
|
* mobile Chrome or Android browsers on Android Studio virtual device emulators (using Appium and Android Studio on OS X)
|
18
|
-
* cloud hosted desktop (Firefox, Chrome, Safari, IE, or Edge) or mobile (iOS Mobile Safari or Android) web browsers using the
|
19
|
-
[
|
20
|
-
|
18
|
+
* cloud hosted desktop (Firefox, Chrome, Safari, IE, or Edge) or mobile (iOS Mobile Safari or Android) web browsers using the following service:
|
19
|
+
* [Browserstack](https://www.browserstack.com/list-of-browsers-and-platforms?product=automate)
|
20
|
+
* [Sauce Labs](https://saucelabs.com/open-source#automated-testing-platform)
|
21
|
+
* [CrossBrowserTesting](https://crossbrowsertesting.com/selenium-testing)
|
22
|
+
* [TestingBot](https://testingbot.com/features)
|
23
|
+
* [Gridlastic](https://www.gridlastic.com/test-environments.html)
|
24
|
+
* [LambdaTest](https://www.lambdatest.com/selenium-automation)
|
21
25
|
* web portals utilizing JavaScript front end application frameworks like Ember, React, Angular, and GWT
|
22
26
|
* enterprise web portals built using Siebel Open UI
|
23
27
|
* web pages containing HTML5 Video and Audio objects
|
@@ -855,7 +859,7 @@ Once your test environment is properly configured, the following **Environment V
|
|
855
859
|
`WEB_BROWSER` | Must be set to `appium`
|
856
860
|
`APP_PLATFORM_NAME` | Must be set to `iOS`
|
857
861
|
`APP_BROWSER` | Must be set to `Safari`
|
858
|
-
`APP_VERSION` | Must be set to `
|
862
|
+
`APP_VERSION` | Must be set to `12.2`, `11.4`, `10.3.1`, or which ever iOS version you wish to run within the XCode Simulator
|
859
863
|
`APP_DEVICE` | Set to iOS device name supported by the iOS Simulator (`iPhone 6s Plus`, `iPad Pro (10.5-inch)`, `iPad Air 2`, etc.) or name of physically connected iOS device
|
860
864
|
`DEVICE_TYPE` | Must be set to `phone` or `tablet`
|
861
865
|
`APP_UDID` | UDID of physically connected iOS device (not used for simulators)
|
data/lib/testcentricity_web.rb
CHANGED
@@ -11,7 +11,8 @@ require 'testcentricity_web/appium_server'
|
|
11
11
|
|
12
12
|
require 'testcentricity_web/web_core/drag_drop_helper'
|
13
13
|
require 'testcentricity_web/web_core/page_objects_helper'
|
14
|
-
require 'testcentricity_web/web_core/
|
14
|
+
require 'testcentricity_web/web_core/page_object'
|
15
|
+
require 'testcentricity_web/web_core/page_section'
|
15
16
|
require 'testcentricity_web/web_core/webdriver_helper'
|
16
17
|
|
17
18
|
require 'testcentricity_web/data_objects/data_objects_helper'
|
@@ -5,14 +5,14 @@ module TestCentricity
|
|
5
5
|
WKS_ENVIRONS ||= 'Environments'
|
6
6
|
|
7
7
|
def find_environ(environ_name, source_type = :excel)
|
8
|
-
case source_type
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
8
|
+
data = case source_type
|
9
|
+
when :excel
|
10
|
+
ExcelData.read_row_data(XL_PRIMARY_DATA_FILE, WKS_ENVIRONS, environ_name)
|
11
|
+
when :yaml
|
12
|
+
read_yaml_node_data('environments.yml', environ_name)
|
13
|
+
when :json
|
14
|
+
read_json_node_data('environments.json', environ_name)
|
15
|
+
end
|
16
16
|
@current = Environ.new(data)
|
17
17
|
Environ.current = @current
|
18
18
|
end
|
@@ -0,0 +1,537 @@
|
|
1
|
+
module TestCentricity
|
2
|
+
class PageObject < BasePageSectionObject
|
3
|
+
# Declare and instantiate a single generic UI Element for this page object.
|
4
|
+
#
|
5
|
+
# @param element_name [Symbol] name of UI object (as a symbol)
|
6
|
+
# @param locator [String] CSS selector or XPath expression that uniquely identifies object
|
7
|
+
# @example
|
8
|
+
# element :siebel_view, 'div#_sweview'
|
9
|
+
# element :siebel_busy, "//html[contains(@class, 'siebui-busy')]"
|
10
|
+
#
|
11
|
+
def self.element(element_name, locator)
|
12
|
+
define_page_element(element_name, TestCentricity::UIElement, locator)
|
13
|
+
end
|
14
|
+
|
15
|
+
# Declare and instantiate a collection of generic UI Elements for this page object.
|
16
|
+
#
|
17
|
+
# @param element_hash [Hash] names of UI objects (as a symbol) and CSS selectors or XPath expressions that uniquely identifies objects
|
18
|
+
# @example
|
19
|
+
# elements profile_item: 'a#profile',
|
20
|
+
# settings_item: 'a#userPreferencesTrigger',
|
21
|
+
# log_out_item: 'a#logout'
|
22
|
+
#
|
23
|
+
def self.elements(element_hash)
|
24
|
+
element_hash.each(&method(:element))
|
25
|
+
end
|
26
|
+
|
27
|
+
# Declare and instantiate a single button UI Element for this page object.
|
28
|
+
#
|
29
|
+
# @param element_name [Symbol] name of button object (as a symbol)
|
30
|
+
# @param locator [String] CSS selector or XPath expression that uniquely identifies object
|
31
|
+
# @example
|
32
|
+
# button :checkout_button, 'button.checkout_button'
|
33
|
+
# button :login_button, "//input[@id='submit_button']"
|
34
|
+
#
|
35
|
+
def self.button(element_name, locator)
|
36
|
+
define_page_element(element_name, TestCentricity::Button, locator)
|
37
|
+
end
|
38
|
+
|
39
|
+
# Declare and instantiate a collection of buttons for this page object.
|
40
|
+
#
|
41
|
+
# @param element_hash [Hash] names of buttons (as a symbol) and CSS selectors or XPath expressions that uniquely identifies buttons
|
42
|
+
# @example
|
43
|
+
# buttons new_account_button: 'button#new-account',
|
44
|
+
# save_button: 'button#save',
|
45
|
+
# cancel_button: 'button#cancel'
|
46
|
+
#
|
47
|
+
def self.buttons(element_hash)
|
48
|
+
element_hash.each(&method(:button))
|
49
|
+
end
|
50
|
+
|
51
|
+
# Declare and instantiate a single text field UI Element for this page object.
|
52
|
+
#
|
53
|
+
# @param element_name [Symbol] name of text field object (as a symbol)
|
54
|
+
# @param locator [String] CSS selector or XPath expression that uniquely identifies object
|
55
|
+
# @example
|
56
|
+
# textfield :user_id_field, "//input[@id='UserName']"
|
57
|
+
# textfield :password_field, 'consumer_password'
|
58
|
+
#
|
59
|
+
def self.textfield(element_name, locator)
|
60
|
+
define_page_element(element_name, TestCentricity::TextField, locator)
|
61
|
+
end
|
62
|
+
|
63
|
+
# Declare and instantiate a collection of text fields for this page object.
|
64
|
+
#
|
65
|
+
# @param element_hash [Hash] names of text fields (as a symbol) and CSS selectors or XPath expressions that uniquely identifies text fields
|
66
|
+
# @example
|
67
|
+
# textfields name_field: 'input#Name',
|
68
|
+
# title_field: 'input#Title',
|
69
|
+
# phone_field: 'input#PhoneNumber',
|
70
|
+
# fax_field: 'input#FaxNumber',
|
71
|
+
# email_field: 'input#Email'
|
72
|
+
#
|
73
|
+
def self.textfields(element_hash)
|
74
|
+
element_hash.each(&method(:textfield))
|
75
|
+
end
|
76
|
+
|
77
|
+
# Declare and instantiate a single checkbox UI Element for this page object.
|
78
|
+
#
|
79
|
+
# @param element_name [Symbol] name of checkbox object (as a symbol)
|
80
|
+
# @param locator [String] CSS selector or XPath expression that uniquely identifies object
|
81
|
+
# @param proxy [Symbol] Optional name (as a symbol) of proxy object to receive click actions
|
82
|
+
# @example
|
83
|
+
# checkbox :remember_checkbox, "//input[@id='RememberUser']"
|
84
|
+
# checkbox :accept_terms_checkbox, 'input#accept_terms_conditions', :accept_terms_label
|
85
|
+
#
|
86
|
+
def self.checkbox(element_name, locator, proxy = nil)
|
87
|
+
class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::CheckBox.new("#{element_name}", self, "#{locator}", :page, #{proxy});end))
|
88
|
+
end
|
89
|
+
|
90
|
+
# Declare and instantiate a collection of checkboxes for this page object.
|
91
|
+
#
|
92
|
+
# @param element_hash [Hash] names of checkboxes (as a symbol) and CSS selectors or XPath expressions that uniquely identifies checkboxes
|
93
|
+
# @example
|
94
|
+
# checkboxes hazmat_certified_check: 'input#hazmatCertified',
|
95
|
+
# epa_certified_check: 'input#epaCertified',
|
96
|
+
# dhs_certified_check: 'input#homelandSecurityCertified',
|
97
|
+
# carb_compliant_check: 'input#carbCompliant'
|
98
|
+
#
|
99
|
+
def self.checkboxes(element_hash)
|
100
|
+
element_hash.each(&method(:checkbox))
|
101
|
+
end
|
102
|
+
|
103
|
+
# Declare and instantiate a single radio button UI Element for this page object.
|
104
|
+
#
|
105
|
+
# @param element_name [Symbol] name of radio object (as a symbol)
|
106
|
+
# @param locator [String] CSS selector or XPath expression that uniquely identifies object
|
107
|
+
# @param proxy [Symbol] Optional name (as a symbol) of proxy object to receive click actions
|
108
|
+
# @example
|
109
|
+
# radio :accept_terms_radio, "//input[@id='Accept_Terms']"
|
110
|
+
# radio :decline_terms_radio, '#decline_terms_conditions', :decline_terms_label
|
111
|
+
#
|
112
|
+
def self.radio(element_name, locator, proxy = nil)
|
113
|
+
class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::Radio.new("#{element_name}", self, "#{locator}", :page, #{proxy});end))
|
114
|
+
end
|
115
|
+
|
116
|
+
# Declare and instantiate a collection of radio buttons for this page object.
|
117
|
+
#
|
118
|
+
# @param element_hash [Hash] names of radio buttons (as a symbol) and CSS selectors or XPath expressions that uniquely identifies radio buttons
|
119
|
+
# @example
|
120
|
+
# radios visa_radio: 'input#payWithVisa',
|
121
|
+
# mastercard_radio: 'input#payWithMastercard',
|
122
|
+
# discover_radio: 'input#payWithDiscover',
|
123
|
+
# amex_radio: 'input#payWithAmEx'
|
124
|
+
#
|
125
|
+
def self.radios(element_hash)
|
126
|
+
element_hash.each(&method(:radio))
|
127
|
+
end
|
128
|
+
|
129
|
+
# Declare and instantiate a single label UI Element for this page object.
|
130
|
+
#
|
131
|
+
# @param element_name [Symbol] name of label object (as a symbol)
|
132
|
+
# @param locator [String] CSS selector or XPath expression that uniquely identifies object
|
133
|
+
# @example
|
134
|
+
# label :welcome_label, 'div.Welcome'
|
135
|
+
# label :rollup_price_label, "//div[contains(@id, 'Rollup Item Price')]"
|
136
|
+
#
|
137
|
+
def self.label(element_name, locator)
|
138
|
+
define_page_element(element_name, TestCentricity::Label, locator)
|
139
|
+
end
|
140
|
+
|
141
|
+
def self.labels(element_hash)
|
142
|
+
element_hash.each(&method(:label))
|
143
|
+
end
|
144
|
+
|
145
|
+
# Declare and instantiate a single link UI Element for this page object.
|
146
|
+
#
|
147
|
+
# @param element_name [Symbol] name of link object (as a symbol)
|
148
|
+
# @param locator [String] CSS selector or XPath expression that uniquely identifies object
|
149
|
+
# @example
|
150
|
+
# link :registration_link, 'a.account-nav__link.register'
|
151
|
+
# link :shopping_basket_link, "//a[@href='shopping_basket']"
|
152
|
+
#
|
153
|
+
def self.link(element_name, locator)
|
154
|
+
define_page_element(element_name, TestCentricity::Link, locator)
|
155
|
+
end
|
156
|
+
|
157
|
+
def self.links(element_hash)
|
158
|
+
element_hash.each(&method(:link))
|
159
|
+
end
|
160
|
+
|
161
|
+
# Declare and instantiate a single table UI Element for this page object.
|
162
|
+
#
|
163
|
+
# @param element_name [Symbol] name of table object (as a symbol)
|
164
|
+
# @param locator [String] XPath expression that uniquely identifies object
|
165
|
+
# @example
|
166
|
+
# table :payments_table, "//table[@class='payments_table']"
|
167
|
+
#
|
168
|
+
def self.table(element_name, locator)
|
169
|
+
define_page_element(element_name, TestCentricity::Table, locator)
|
170
|
+
end
|
171
|
+
|
172
|
+
def self.tables(element_hash)
|
173
|
+
element_hash.each(&method(:table))
|
174
|
+
end
|
175
|
+
|
176
|
+
# Declare and instantiate a single select list UI Element for this page object.
|
177
|
+
#
|
178
|
+
# @param element_name [Symbol] name of select list object (as a symbol)
|
179
|
+
# @param locator [String] CSS selector or XPath expression that uniquely identifies object
|
180
|
+
# @example
|
181
|
+
# selectlist :category_selector, 'select#search_form_category_chosen'
|
182
|
+
# selectlist :gender_select, "//select[@id='customer_gender']"
|
183
|
+
#
|
184
|
+
def self.selectlist(element_name, locator)
|
185
|
+
define_page_element(element_name, TestCentricity::SelectList, locator)
|
186
|
+
end
|
187
|
+
|
188
|
+
def self.selectlists(element_hash)
|
189
|
+
element_hash.each(&method(:selectlist))
|
190
|
+
end
|
191
|
+
|
192
|
+
# Declare and instantiate a single list UI Element for this page object.
|
193
|
+
#
|
194
|
+
# @param element_name [Symbol] name of list object (as a symbol)
|
195
|
+
# @param locator [String] CSS selector or XPath expression that uniquely identifies object
|
196
|
+
# @example
|
197
|
+
# list :x_axis_list, 'g.x-axis'
|
198
|
+
#
|
199
|
+
def self.list(element_name, locator)
|
200
|
+
define_page_element(element_name, TestCentricity::List, locator)
|
201
|
+
end
|
202
|
+
|
203
|
+
def self.lists(element_hash)
|
204
|
+
element_hash.each(&method(:list))
|
205
|
+
end
|
206
|
+
|
207
|
+
# Declare and instantiate an single image UI Element for this page object.
|
208
|
+
#
|
209
|
+
# @param element_name [Symbol] name of image object (as a symbol)
|
210
|
+
# @param locator [String] CSS selector or XPath expression that uniquely identifies object
|
211
|
+
# @example
|
212
|
+
# image :basket_item_image, 'div.product_image'
|
213
|
+
# image :corporate_logo_image, "//img[@alt='MyCompany_logo']"
|
214
|
+
#
|
215
|
+
def self.image(element_name, locator)
|
216
|
+
define_page_element(element_name, TestCentricity::Image, locator)
|
217
|
+
end
|
218
|
+
|
219
|
+
def self.images(element_hash)
|
220
|
+
element_hash.each(&method(:image))
|
221
|
+
end
|
222
|
+
|
223
|
+
# Declare and instantiate a single HTML5 video UI Element for this page object.
|
224
|
+
#
|
225
|
+
# @param element_name [Symbol] name of an HTML5 video object (as a symbol)
|
226
|
+
# @param locator [String] CSS selector or XPath expression that uniquely identifies object
|
227
|
+
# @example
|
228
|
+
# video :video_player, 'video#my_video_player'
|
229
|
+
#
|
230
|
+
def self.video(element_name, locator)
|
231
|
+
define_page_element(element_name, TestCentricity::Video, locator)
|
232
|
+
end
|
233
|
+
|
234
|
+
def self.videos(element_hash)
|
235
|
+
element_hash.each(&method(:video))
|
236
|
+
end
|
237
|
+
|
238
|
+
# Declare and instantiate a single HTML5 audio UI Element for this page object.
|
239
|
+
#
|
240
|
+
# @param element_name [Symbol] name of an HTML5 audio object (as a symbol)
|
241
|
+
# @param locator [String] CSS selector or XPath expression that uniquely identifies object
|
242
|
+
# @example
|
243
|
+
# audio :audio_player, 'audio#my_audio_player'
|
244
|
+
#
|
245
|
+
def self.audio(element_name, locator)
|
246
|
+
define_page_element(element_name, TestCentricity::Audio, locator)
|
247
|
+
end
|
248
|
+
|
249
|
+
def self.audios(element_hash)
|
250
|
+
element_hash.each(&method(:audio))
|
251
|
+
end
|
252
|
+
|
253
|
+
# Declare and instantiate a single File Field UI Element for this page object.
|
254
|
+
#
|
255
|
+
# @param element_name [Symbol] name of file field object (as a symbol)
|
256
|
+
# @param locator [String] CSS selector or XPath expression that uniquely identifies object
|
257
|
+
# @example
|
258
|
+
# filefield :attach_file, 's_SweFileName'
|
259
|
+
#
|
260
|
+
def self.filefield(element_name, locator)
|
261
|
+
define_page_element(element_name, TestCentricity::FileField, locator)
|
262
|
+
end
|
263
|
+
|
264
|
+
def self.filefields(element_hash)
|
265
|
+
element_hash.each(&method(:filefield))
|
266
|
+
end
|
267
|
+
|
268
|
+
# Declare and instantiate a cell button in a table column on this page object.
|
269
|
+
#
|
270
|
+
# @param element_name [Symbol] name of cell button object (as a symbol)
|
271
|
+
# @param locator [String] XPath expression that uniquely identifies cell button within row and column of parent table object
|
272
|
+
# @param table [Symbol] Name (as a symbol) of parent table object
|
273
|
+
# @param column [Integer] 1-based index of table column that contains the cell button object
|
274
|
+
# @example
|
275
|
+
# cell_button :show_button, "a[@class='show']", :data_table, 5
|
276
|
+
# cell_button :edit_button, "a[@class='edit']", :data_table, 5
|
277
|
+
#
|
278
|
+
def self.cell_button(element_name, locator, table, column)
|
279
|
+
class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::CellButton.new("#{element_name}", self, "#{locator}", :page, #{table}, #{column});end))
|
280
|
+
end
|
281
|
+
|
282
|
+
# Declare and instantiate a cell checkbox in a table column on this page object.
|
283
|
+
#
|
284
|
+
# @param element_name [Symbol] name of cell checkbox object (as a symbol)
|
285
|
+
# @param locator [String] XPath expression that uniquely identifies cell checkbox within row and column of parent table object
|
286
|
+
# @param table [Symbol] Name (as a symbol) of parent table object
|
287
|
+
# @param column [Integer] 1-based index of table column that contains the cell checkbox object
|
288
|
+
# @example
|
289
|
+
# cell_checkbox :is_registered_check, "a[@class='registered']", :data_table, 4
|
290
|
+
#
|
291
|
+
def self.cell_checkbox(element_name, locator, table, column, proxy = nil)
|
292
|
+
class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::CellCheckBox.new("#{element_name}", self, "#{locator}", :page, #{table}, #{column}, #{proxy});end))
|
293
|
+
end
|
294
|
+
|
295
|
+
# Declare and instantiate a cell radio in a table column on this page object.
|
296
|
+
#
|
297
|
+
# @param element_name [Symbol] name of cell radio object (as a symbol)
|
298
|
+
# @param locator [String] XPath expression that uniquely identifies cell radio within row and column of parent table object
|
299
|
+
# @param table [Symbol] Name (as a symbol) of parent table object
|
300
|
+
# @param column [Integer] 1-based index of table column that contains the cell radio object
|
301
|
+
# @example
|
302
|
+
# cell_radio :track_a_radio, "a[@class='track_a']", :data_table, 8
|
303
|
+
#
|
304
|
+
def self.cell_radio(element_name, locator, table, column, proxy = nil)
|
305
|
+
class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::CellRadio.new("#{element_name}", self, "#{locator}", :page, #{table}, #{column}, #{proxy});end))
|
306
|
+
end
|
307
|
+
|
308
|
+
# Declare and instantiate a cell image in a table column on this page object.
|
309
|
+
#
|
310
|
+
# @param element_name [Symbol] name of cell image object (as a symbol)
|
311
|
+
# @param locator [String] XPath expression that uniquely identifies cell image within row and column of parent table object
|
312
|
+
# @param table [Symbol] Name (as a symbol) of parent table object
|
313
|
+
# @param column [Integer] 1-based index of table column that contains the cell image object
|
314
|
+
# @example
|
315
|
+
# cell_image :ready_icon, "img[@class='ready']", :data_table, 3
|
316
|
+
# cell_image :send_icon, "img[@class='send']", :data_table, 3
|
317
|
+
#
|
318
|
+
def self.cell_image(element_name, locator, table, column)
|
319
|
+
class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::CellImage.new("#{element_name}", self, "#{locator}", :page, #{table}, #{column});end))
|
320
|
+
end
|
321
|
+
|
322
|
+
# Declare and instantiate a list button in a row of a list object on this page object.
|
323
|
+
#
|
324
|
+
# @param element_name [Symbol] name of list button object (as a symbol)
|
325
|
+
# @param locator [String] XPath expression that uniquely identifies list button within row of parent list object
|
326
|
+
# @param list [Symbol] Name (as a symbol) of parent list object
|
327
|
+
# @example
|
328
|
+
# list_button :delete_button, "a[@class='delete']", :icon_list
|
329
|
+
# list_button :edit_button, "a[@class='edit']", :icon_list
|
330
|
+
#
|
331
|
+
def self.list_button(element_name, locator, list)
|
332
|
+
class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::ListButton.new("#{element_name}", self, "#{locator}", :page, #{list});end))
|
333
|
+
end
|
334
|
+
|
335
|
+
# Declare and instantiate a list checkbox in a row of a list object on this page object.
|
336
|
+
#
|
337
|
+
# @param element_name [Symbol] name of list checkbox object (as a symbol)
|
338
|
+
# @param locator [String] XPath expression that uniquely identifies list checkbox within row of parent list object
|
339
|
+
# @param list [Symbol] Name (as a symbol) of parent list object
|
340
|
+
# @example
|
341
|
+
# list_checkbox :is_registered_check, "a[@class='registered']", :data_list
|
342
|
+
#
|
343
|
+
def self.list_checkbox(element_name, locator, list, proxy = nil)
|
344
|
+
class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::ListCheckBox.new("#{element_name}", self, "#{locator}", :page, #{list}, #{proxy});end))
|
345
|
+
end
|
346
|
+
|
347
|
+
# Declare and instantiate a list radio in a row of a list object on this page object.
|
348
|
+
#
|
349
|
+
# @param element_name [Symbol] name of list radio object (as a symbol)
|
350
|
+
# @param locator [String] XPath expression that uniquely identifies list radio within row of parent list object
|
351
|
+
# @param list [Symbol] Name (as a symbol) of parent list object
|
352
|
+
# @example
|
353
|
+
# list_radio :sharing_radio, "a[@class='sharing']", :data_list
|
354
|
+
#
|
355
|
+
def self.list_radio(element_name, locator, list, proxy = nil)
|
356
|
+
class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::ListRadio.new("#{element_name}", self, "#{locator}", :page, #{list}, #{proxy});end))
|
357
|
+
end
|
358
|
+
|
359
|
+
# Instantiate a single PageSection object for this page object.
|
360
|
+
#
|
361
|
+
# @param section_name [Symbol] name of PageSection object (as a symbol)
|
362
|
+
# @param class_name [String] Class name of PageSection object
|
363
|
+
# @example
|
364
|
+
# section :search_form, SearchForm
|
365
|
+
#
|
366
|
+
def self.section(section_name, obj, locator = nil)
|
367
|
+
define_method(section_name) do
|
368
|
+
ivar_name = "@#{section_name}"
|
369
|
+
ivar = instance_variable_get(ivar_name)
|
370
|
+
return ivar if ivar
|
371
|
+
instance_variable_set(ivar_name, obj.new(section_name, self, "#{locator}", :page))
|
372
|
+
end
|
373
|
+
end
|
374
|
+
|
375
|
+
def self.sections(section_hash)
|
376
|
+
section_hash.each do |section_name, class_name|
|
377
|
+
section(section_name, class_name)
|
378
|
+
end
|
379
|
+
end
|
380
|
+
|
381
|
+
def open_portal
|
382
|
+
environment = Environ.current
|
383
|
+
url = environment.hostname.blank? ? "#{environment.base_url}#{environment.append}" : "#{environment.hostname}/#{environment.base_url}#{environment.append}"
|
384
|
+
if environment.user_id.blank? || environment.password.blank?
|
385
|
+
visit "#{environment.protocol}://#{url}"
|
386
|
+
else
|
387
|
+
visit "#{environment.protocol}://#{environment.user_id}:#{environment.password}@#{url}"
|
388
|
+
end
|
389
|
+
Environ.portal_state = :open
|
390
|
+
end
|
391
|
+
|
392
|
+
def verify_page_exists
|
393
|
+
raise "Page object #{self.class.name} does not have a page_locator trait defined" unless defined?(page_locator)
|
394
|
+
unless page.has_selector?(page_locator)
|
395
|
+
body_class = find(:xpath, '//body')[:class]
|
396
|
+
error_message = %(
|
397
|
+
Expected page to have selector '#{page_locator}' but found '#{body_class}' instead.
|
398
|
+
Actual URL of page loaded = #{URI.parse(current_url)}.
|
399
|
+
)
|
400
|
+
error_message = "#{error_message}\nExpected URL of page was #{page_url}." if defined?(page_url)
|
401
|
+
raise error_message
|
402
|
+
end
|
403
|
+
PageManager.current_page = self
|
404
|
+
end
|
405
|
+
|
406
|
+
def navigate_to; end
|
407
|
+
|
408
|
+
def verify_page_ui; end
|
409
|
+
|
410
|
+
def load_page
|
411
|
+
return if exists?
|
412
|
+
if defined?(page_url) && !page_url.nil?
|
413
|
+
visit page_url
|
414
|
+
begin
|
415
|
+
page.driver.browser.switch_to.alert.accept
|
416
|
+
rescue => e
|
417
|
+
end unless Environ.browser == :safari || Environ.browser == :ie || Environ.is_device?
|
418
|
+
else
|
419
|
+
navigate_to
|
420
|
+
end
|
421
|
+
verify_page_exists
|
422
|
+
end
|
423
|
+
|
424
|
+
def verify_page_contains(content)
|
425
|
+
raise "Expected page to have content '#{content}'" unless page.has_content?(:visible, content)
|
426
|
+
end
|
427
|
+
|
428
|
+
# Does Page object exists?
|
429
|
+
#
|
430
|
+
# @return [Boolean]
|
431
|
+
# @example
|
432
|
+
# home_page.exists?
|
433
|
+
#
|
434
|
+
def exists?
|
435
|
+
raise "Page object #{self.class.name} does not have a page_locator trait defined" unless defined?(page_locator)
|
436
|
+
saved_wait_time = Capybara.default_max_wait_time
|
437
|
+
Capybara.default_max_wait_time = 0.1
|
438
|
+
tries ||= 2
|
439
|
+
attributes = [:id, :css, :xpath]
|
440
|
+
type = attributes[tries]
|
441
|
+
obj = page.find(type, page_locator)
|
442
|
+
obj != nil
|
443
|
+
rescue
|
444
|
+
Capybara.default_max_wait_time = saved_wait_time
|
445
|
+
retry if (tries -= 1) > 0
|
446
|
+
false
|
447
|
+
ensure
|
448
|
+
Capybara.default_max_wait_time = saved_wait_time
|
449
|
+
end
|
450
|
+
|
451
|
+
# Return page title
|
452
|
+
#
|
453
|
+
# @return [String]
|
454
|
+
# @example
|
455
|
+
# home_page.title
|
456
|
+
#
|
457
|
+
def title
|
458
|
+
page.driver.browser.title
|
459
|
+
end
|
460
|
+
|
461
|
+
# Wait until the page object exists, or until the specified wait time has expired. If the wait time is nil, then the wait
|
462
|
+
# time will be Capybara.default_max_wait_time.
|
463
|
+
#
|
464
|
+
# @param seconds [Integer or Float] wait time in seconds
|
465
|
+
# @example
|
466
|
+
# home_page.wait_until_exists(15)
|
467
|
+
#
|
468
|
+
def wait_until_exists(seconds = nil, post_exception = true)
|
469
|
+
timeout = seconds.nil? ? Capybara.default_max_wait_time : seconds
|
470
|
+
wait = Selenium::WebDriver::Wait.new(timeout: timeout)
|
471
|
+
wait.until { exists? }
|
472
|
+
rescue
|
473
|
+
if post_exception
|
474
|
+
raise "Page object #{self.class.name} not found after #{timeout} seconds" unless exists?
|
475
|
+
else
|
476
|
+
exists?
|
477
|
+
end
|
478
|
+
end
|
479
|
+
|
480
|
+
# Wait until the page object no longer exists, or until the specified wait time has expired. If the wait time is nil, then
|
481
|
+
# the wait time will be Capybara.default_max_wait_time.
|
482
|
+
#
|
483
|
+
# @param seconds [Integer or Float] wait time in seconds
|
484
|
+
# @example
|
485
|
+
# payment_processing_page.wait_until_gone(15)
|
486
|
+
#
|
487
|
+
def wait_until_gone(seconds = nil, post_exception = true)
|
488
|
+
timeout = seconds.nil? ? Capybara.default_max_wait_time : seconds
|
489
|
+
wait = Selenium::WebDriver::Wait.new(timeout: timeout)
|
490
|
+
wait.until { !exists? }
|
491
|
+
rescue
|
492
|
+
if post_exception
|
493
|
+
raise "Page object #{self.class.name} remained visible after #{timeout} seconds" if exists?
|
494
|
+
else
|
495
|
+
exists?
|
496
|
+
end
|
497
|
+
end
|
498
|
+
|
499
|
+
# Wait until all AJAX requests have completed, or until the specified wait time has expired. If the wait time is nil, then
|
500
|
+
# the wait time will be Capybara.default_max_wait_time.
|
501
|
+
#
|
502
|
+
# @param seconds [Integer or Float] wait time in seconds
|
503
|
+
# @example
|
504
|
+
# shopping_basket_page.wait_for_ajax(15)
|
505
|
+
#
|
506
|
+
def wait_for_ajax(seconds = nil)
|
507
|
+
wait_time = seconds.nil? ? Capybara.default_max_wait_time : seconds
|
508
|
+
Timeout.timeout(wait_time) do
|
509
|
+
loop do
|
510
|
+
active = page.evaluate_script('jQuery.active')
|
511
|
+
break if active.zero?
|
512
|
+
end
|
513
|
+
end
|
514
|
+
end
|
515
|
+
|
516
|
+
# Is current Page object URL secure?
|
517
|
+
#
|
518
|
+
# @return [Boolean]
|
519
|
+
# @example
|
520
|
+
# home_page.secure?
|
521
|
+
#
|
522
|
+
def secure?
|
523
|
+
current_url.start_with?('https')
|
524
|
+
end
|
525
|
+
|
526
|
+
private
|
527
|
+
|
528
|
+
def self.define_page_element(element_name, obj, locator)
|
529
|
+
define_method(element_name) do
|
530
|
+
ivar_name = "@#{element_name}"
|
531
|
+
ivar = instance_variable_get(ivar_name)
|
532
|
+
return ivar if ivar
|
533
|
+
instance_variable_set(ivar_name, obj.new(element_name, self, locator, :page))
|
534
|
+
end
|
535
|
+
end
|
536
|
+
end
|
537
|
+
end
|