testcentricity_web 3.2.0 → 3.2.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA256:
3
- metadata.gz: 676c8b3a7cd7c2381b6b9c62f1cf300ec4a7c74ebd110e865a5c1607eedd4e7f
4
- data.tar.gz: 23f02fd3a177c4d51394f944f4e6ffd5a8ad9b098c26412cf30342ccdf703268
2
+ SHA1:
3
+ metadata.gz: c875303a27c1eaa23f786550d0b3c32738e84e9d
4
+ data.tar.gz: 1ddf7a0bc2f69efbd98c4331e09770bf74fe88b3
5
5
  SHA512:
6
- metadata.gz: 271668919d950079396cc792b4d0ecf39189de49923d5c7d634b91444b786d8609740dfb7bdf33aa73b7a1b296780adb07391406808c2b5ed785d40071f76845
7
- data.tar.gz: 3debabb5962cc9b1be7af9196ab3445b58e0639737060c1ce6751c7f7455f1ebaebb494575e248772c35495772980d67277e376b96c0cd18a874aca214f9776c
6
+ metadata.gz: 557a3f34be2aff3383ac17ed402b72eb039e8d4b9ad8945c16be513db1179813b4c2f980d9b74e100f75228c8314412766c22ea9384e22744c8c03f3832c8b12
7
+ data.tar.gz: cb41453fd495fcd1b50ccf9a4da1d8a4b67afad02c2029f8952fa5e9eb6cda657603ffbcbe421f18b79f84a716d24bbd4f9edd1e85e8a209a13dd2566d7547ba
@@ -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
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- testcentricity_web (3.2.0)
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.1)
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.27.0)
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 [Browserstack](https://www.browserstack.com/list-of-browsers-and-platforms?product=automate),
19
- [Sauce Labs](https://saucelabs.com/open-source#automated-testing-platform), [CrossBrowserTesting](https://crossbrowsertesting.com/selenium-testing),
20
- [TestingBot](https://testingbot.com/features), [Gridlastic](https://www.gridlastic.com/test-environments.html), or [LambdaTest](https://www.lambdatest.com/selenium-automation) services.
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 `11.2`, `10.3`, `9.3`, or which ever iOS version you wish to run within the XCode Simulator
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)
@@ -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/page_sections_helper'
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
- when :excel
10
- data = ExcelData.read_row_data(XL_PRIMARY_DATA_FILE, WKS_ENVIRONS, environ_name)
11
- when :yaml
12
- data = read_yaml_node_data('environments.yml', environ_name)
13
- when :json
14
- data = read_json_node_data('environments.json', environ_name)
15
- end
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
@@ -1,3 +1,3 @@
1
1
  module TestCentricityWeb
2
- VERSION = '3.2.0'
2
+ VERSION = '3.2.1'
3
3
  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