testcentricity 2.3.13

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.
Files changed (64) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +11 -0
  3. data/.rspec +3 -0
  4. data/.ruby-gemset +1 -0
  5. data/.ruby-version +1 -0
  6. data/Gemfile +6 -0
  7. data/Gemfile.lock +93 -0
  8. data/LICENSE.txt +28 -0
  9. data/README.md +1634 -0
  10. data/Rakefile +1 -0
  11. data/bin/console +14 -0
  12. data/bin/setup +8 -0
  13. data/lib/devices/devices.yml +344 -0
  14. data/lib/testcentricity.rb +144 -0
  15. data/lib/testcentricity/app_core/appium_connect_helper.rb +154 -0
  16. data/lib/testcentricity/app_core/appium_server.rb +69 -0
  17. data/lib/testcentricity/app_core/screen_objects_helper.rb +180 -0
  18. data/lib/testcentricity/app_core/screen_sections_helper.rb +332 -0
  19. data/lib/testcentricity/app_elements/app_element_helper.rb +293 -0
  20. data/lib/testcentricity/app_elements/button.rb +8 -0
  21. data/lib/testcentricity/app_elements/checkbox.rb +20 -0
  22. data/lib/testcentricity/app_elements/label.rb +8 -0
  23. data/lib/testcentricity/app_elements/list.rb +25 -0
  24. data/lib/testcentricity/app_elements/switch.rb +20 -0
  25. data/lib/testcentricity/app_elements/textfield.rb +12 -0
  26. data/lib/testcentricity/browser_helper.rb +174 -0
  27. data/lib/testcentricity/data_objects/data_objects_helper.rb +78 -0
  28. data/lib/testcentricity/data_objects/environment.rb +281 -0
  29. data/lib/testcentricity/data_objects/excel_helper.rb +242 -0
  30. data/lib/testcentricity/exception_queue_helper.rb +51 -0
  31. data/lib/testcentricity/utility_helpers.rb +28 -0
  32. data/lib/testcentricity/version.rb +3 -0
  33. data/lib/testcentricity/web_core/drag_drop_helper.rb +15 -0
  34. data/lib/testcentricity/web_core/page_objects_helper.rb +669 -0
  35. data/lib/testcentricity/web_core/page_sections_helper.rb +866 -0
  36. data/lib/testcentricity/web_core/webdriver_helper.rb +579 -0
  37. data/lib/testcentricity/web_elements/button.rb +8 -0
  38. data/lib/testcentricity/web_elements/cell_button.rb +8 -0
  39. data/lib/testcentricity/web_elements/cell_checkbox.rb +38 -0
  40. data/lib/testcentricity/web_elements/cell_element.rb +69 -0
  41. data/lib/testcentricity/web_elements/cell_image.rb +8 -0
  42. data/lib/testcentricity/web_elements/cell_radio.rb +31 -0
  43. data/lib/testcentricity/web_elements/checkbox.rb +100 -0
  44. data/lib/testcentricity/web_elements/file_field.rb +45 -0
  45. data/lib/testcentricity/web_elements/image.rb +34 -0
  46. data/lib/testcentricity/web_elements/label.rb +8 -0
  47. data/lib/testcentricity/web_elements/link.rb +8 -0
  48. data/lib/testcentricity/web_elements/list.rb +73 -0
  49. data/lib/testcentricity/web_elements/list_button.rb +8 -0
  50. data/lib/testcentricity/web_elements/list_checkbox.rb +38 -0
  51. data/lib/testcentricity/web_elements/list_element.rb +61 -0
  52. data/lib/testcentricity/web_elements/list_radio.rb +31 -0
  53. data/lib/testcentricity/web_elements/radio.rb +74 -0
  54. data/lib/testcentricity/web_elements/select_list.rb +197 -0
  55. data/lib/testcentricity/web_elements/siebel_open_ui_helper.rb +15 -0
  56. data/lib/testcentricity/web_elements/table.rb +612 -0
  57. data/lib/testcentricity/web_elements/textfield.rb +114 -0
  58. data/lib/testcentricity/web_elements/ui_elements_helper.rb +502 -0
  59. data/lib/testcentricity/world_extensions.rb +26 -0
  60. data/my_templates/default/method_details/setup.rb +3 -0
  61. data/spec/spec_helper.rb +14 -0
  62. data/spec/testcentricity_spec.rb +9 -0
  63. data/testcentricity.gemspec +47 -0
  64. metadata +328 -0
@@ -0,0 +1,51 @@
1
+ module TestCentricity
2
+ class ExceptionQueue
3
+ include Capybara::DSL
4
+
5
+ @error_queue
6
+
7
+ def self.enqueue_assert_equal(expected, actual, error_message)
8
+ unless expected == actual
9
+ enqueue("#{error_message} to be\n '#{expected}'\nbut found\n '#{actual}'")
10
+ enqueue_screenshot
11
+ end
12
+ end
13
+
14
+ def self.enqueue_assert_not_equal(expected, actual, error_message)
15
+ unless expected != actual
16
+ enqueue("#{error_message} to not be equal to '#{expected}'")
17
+ enqueue_screenshot
18
+ end
19
+ end
20
+
21
+ def self.enqueue_exception(error_message)
22
+ enqueue(error_message)
23
+ end
24
+
25
+ def self.post_exceptions
26
+ raise @error_queue unless @error_queue.nil?
27
+ ensure
28
+ @error_queue = nil
29
+ end
30
+
31
+ private
32
+
33
+ def self.enqueue(message)
34
+ @error_queue = "#{@error_queue}#{message}\n\n"
35
+ end
36
+
37
+ def self.enqueue_screenshot
38
+ timestamp = Time.now.strftime('%Y%m%d%H%M%S')
39
+ filename = "Screenshot-#{timestamp}"
40
+ path = File.join Dir.pwd, 'reports/screenshots/', filename
41
+ if Environ.driver == :appium
42
+ AppiumConnect.take_screenshot("#{path}.png")
43
+ else
44
+ Capybara.save_screenshot "#{path}.png"
45
+ end
46
+ puts "Screenshot saved at #{path}.png"
47
+ screen_shot = { :path => path, :filename => filename }
48
+ Environ.save_screen_shot(screen_shot)
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,28 @@
1
+ class Object
2
+ def blank?
3
+ respond_to?(:empty?) ? empty? : !self
4
+ end
5
+
6
+ def present?
7
+ !blank?
8
+ end
9
+ end
10
+
11
+
12
+ class String
13
+ def to_bool
14
+ return true if self == true || self =~ (/(true|t|yes|y|x|1)$/i)
15
+ return false if self == false || self.blank? || self =~ (/(false|f|no|n|0)$/i)
16
+ raise ArgumentError.new("invalid value for Boolean: \"#{self}\"")
17
+ end
18
+
19
+ def string_between(marker1, marker2)
20
+ self[/#{Regexp.escape(marker1)}(.*?)#{Regexp.escape(marker2)}/m, 1]
21
+ end
22
+
23
+ def format_date_time(date_time_format)
24
+ return if self.blank?
25
+ new_date = DateTime.parse(self)
26
+ new_date.strftime(date_time_format)
27
+ end
28
+ end
@@ -0,0 +1,3 @@
1
+ module TestCentricity
2
+ VERSION = '2.3.13'
3
+ end
@@ -0,0 +1,15 @@
1
+ module CapybaraExtension
2
+ def drag_by(right_by, down_by)
3
+ base.drag_by(right_by, down_by)
4
+ end
5
+ end
6
+
7
+
8
+ module CapybaraSeleniumExtension
9
+ def drag_by(right_by, down_by)
10
+ driver.browser.action.drag_and_drop_by(native, right_by, down_by).perform
11
+ end
12
+ end
13
+
14
+ ::Capybara::Selenium::Node.send :include, CapybaraSeleniumExtension
15
+ ::Capybara::Node::Element.send :include, CapybaraExtension
@@ -0,0 +1,669 @@
1
+ require 'test/unit'
2
+
3
+ module TestCentricity
4
+ class PageObject
5
+ include Capybara::DSL
6
+ include Capybara::Node::Matchers
7
+ include Test::Unit::Assertions
8
+
9
+ # Define a trait for this page object.
10
+ #
11
+ # @param trait_name [Symbol] name of trait (as a symbol)
12
+ # @param block [&block] trait value
13
+ # @example
14
+ # trait(:page_name) { 'Shopping Basket' }
15
+ # trait(:page_url) { '/shopping_basket' }
16
+ # trait(:page_locator) { "//body[@class='shopping_baskets']" }
17
+ #
18
+ def self.trait(trait_name, &block)
19
+ define_method(trait_name.to_s, &block)
20
+ end
21
+
22
+ # Declare and instantiate a single generic UI Element for this page object.
23
+ #
24
+ # @param element_name [Symbol] name of UI object (as a symbol)
25
+ # @param locator [String] CSS selector or XPath expression that uniquely identifies object
26
+ # @example
27
+ # element :siebel_view, 'div#_sweview'
28
+ # element :siebel_busy, "//html[contains(@class, 'siebui-busy')]"
29
+ #
30
+ def self.element(element_name, locator)
31
+ class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::UIElement.new("#{element_name}", self, "#{locator}", :page);end))
32
+ end
33
+
34
+ # Declare and instantiate a collection of generic UI Elements for this page object.
35
+ #
36
+ # @param element_hash [Hash] names of UI objects (as a symbol) and CSS selectors or XPath expressions that uniquely identifies objects
37
+ # @example
38
+ # elements profile_item: 'a#profile',
39
+ # settings_item: 'a#userPreferencesTrigger',
40
+ # log_out_item: 'a#logout'
41
+ #
42
+ def self.elements(element_hash)
43
+ element_hash.each do |element_name, locator|
44
+ element(element_name, locator)
45
+ end
46
+ end
47
+
48
+ # Declare and instantiate a single button UI Element for this page object.
49
+ #
50
+ # @param element_name [Symbol] name of button object (as a symbol)
51
+ # @param locator [String] CSS selector or XPath expression that uniquely identifies object
52
+ # @example
53
+ # button :checkout_button, 'button.checkout_button'
54
+ # button :login_button, "//input[@id='submit_button']"
55
+ #
56
+ def self.button(element_name, locator)
57
+ class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::Button.new("#{element_name}", self, "#{locator}", :page);end))
58
+ end
59
+
60
+ # Declare and instantiate a collection of buttons for this page object.
61
+ #
62
+ # @param element_hash [Hash] names of buttons (as a symbol) and CSS selectors or XPath expressions that uniquely identifies buttons
63
+ # @example
64
+ # buttons new_account_button: 'button#new-account',
65
+ # save_button: 'button#save',
66
+ # cancel_button: 'button#cancel'
67
+ #
68
+ def self.buttons(element_hash)
69
+ element_hash.each do |element_name, locator|
70
+ button(element_name, locator)
71
+ end
72
+ end
73
+
74
+ # Declare and instantiate a single text field UI Element for this page object.
75
+ #
76
+ # @param element_name [Symbol] name of text field object (as a symbol)
77
+ # @param locator [String] CSS selector or XPath expression that uniquely identifies object
78
+ # @example
79
+ # textfield :user_id_field, "//input[@id='UserName']"
80
+ # textfield :password_field, 'consumer_password'
81
+ #
82
+ def self.textfield(element_name, locator)
83
+ class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::TextField.new("#{element_name}", self, "#{locator}", :page);end))
84
+ end
85
+
86
+ # Declare and instantiate a collection of text fields for this page object.
87
+ #
88
+ # @param element_hash [Hash] names of text fields (as a symbol) and CSS selectors or XPath expressions that uniquely identifies text fields
89
+ # @example
90
+ # textfields name_field: 'input#Name',
91
+ # title_field: 'input#Title',
92
+ # phone_field: 'input#PhoneNumber',
93
+ # fax_field: 'input#FaxNumber',
94
+ # email_field: 'input#Email'
95
+ #
96
+ def self.textfields(element_hash)
97
+ element_hash.each do |element_name, locator|
98
+ textfield(element_name, locator)
99
+ end
100
+ end
101
+
102
+ # Declare and instantiate a single checkbox UI Element for this page object.
103
+ #
104
+ # @param element_name [Symbol] name of checkbox object (as a symbol)
105
+ # @param locator [String] CSS selector or XPath expression that uniquely identifies object
106
+ # @param proxy [Symbol] Optional name (as a symbol) of proxy object to receive click actions
107
+ # @example
108
+ # checkbox :remember_checkbox, "//input[@id='RememberUser']"
109
+ # checkbox :accept_terms_checkbox, 'input#accept_terms_conditions', :accept_terms_label
110
+ #
111
+ def self.checkbox(element_name, locator, proxy = nil)
112
+ class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::CheckBox.new("#{element_name}", self, "#{locator}", :page, #{proxy});end))
113
+ end
114
+
115
+ # Declare and instantiate a collection of checkboxes for this page object.
116
+ #
117
+ # @param element_hash [Hash] names of checkboxes (as a symbol) and CSS selectors or XPath expressions that uniquely identifies checkboxes
118
+ # @example
119
+ # checkboxes hazmat_certified_check: 'input#hazmatCertified',
120
+ # epa_certified_check: 'input#epaCertified',
121
+ # dhs_certified_check: 'input#homelandSecurityCertified',
122
+ # carb_compliant_check: 'input#carbCompliant'
123
+ #
124
+ def self.checkboxes(element_hash)
125
+ element_hash.each do |element_name, locator|
126
+ checkbox(element_name, locator)
127
+ end
128
+ end
129
+
130
+ # Declare and instantiate a single radio button UI Element for this page object.
131
+ #
132
+ # @param element_name [Symbol] name of radio object (as a symbol)
133
+ # @param locator [String] CSS selector or XPath expression that uniquely identifies object
134
+ # @param proxy [Symbol] Optional name (as a symbol) of proxy object to receive click actions
135
+ # @example
136
+ # radio :accept_terms_radio, "//input[@id='Accept_Terms']"
137
+ # radio :decline_terms_radio, '#decline_terms_conditions', :decline_terms_label
138
+ #
139
+ def self.radio(element_name, locator, proxy = nil)
140
+ class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::Radio.new("#{element_name}", self, "#{locator}", :page, #{proxy});end))
141
+ end
142
+
143
+ # Declare and instantiate a collection of radio buttons for this page object.
144
+ #
145
+ # @param element_hash [Hash] names of radio buttons (as a symbol) and CSS selectors or XPath expressions that uniquely identifies radio buttons
146
+ # @example
147
+ # radios visa_radio: 'input#payWithVisa',
148
+ # mastercard_radio: 'input#payWithMastercard',
149
+ # discover_radio: 'input#payWithDiscover',
150
+ # amex_radio: 'input#payWithAmEx'
151
+ #
152
+ def self.radios(element_hash)
153
+ element_hash.each do |element_name, locator|
154
+ radio(element_name, locator)
155
+ end
156
+ end
157
+
158
+ # Declare and instantiate a single label UI Element for this page object.
159
+ #
160
+ # @param element_name [Symbol] name of label object (as a symbol)
161
+ # @param locator [String] CSS selector or XPath expression that uniquely identifies object
162
+ # @example
163
+ # label :welcome_label, 'div.Welcome'
164
+ # label :rollup_price_label, "//div[contains(@id, 'Rollup Item Price')]"
165
+ #
166
+ def self.label(element_name, locator)
167
+ class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::Label.new("#{element_name}", self, "#{locator}", :page);end))
168
+ end
169
+
170
+ def self.labels(element_hash)
171
+ element_hash.each do |element_name, locator|
172
+ label(element_name, locator)
173
+ end
174
+ end
175
+
176
+ # Declare and instantiate a single link UI Element for this page object.
177
+ #
178
+ # @param element_name [Symbol] name of link object (as a symbol)
179
+ # @param locator [String] CSS selector or XPath expression that uniquely identifies object
180
+ # @example
181
+ # link :registration_link, 'a.account-nav__link.register'
182
+ # link :shopping_basket_link, "//a[@href='shopping_basket']"
183
+ #
184
+ def self.link(element_name, locator)
185
+ class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::Link.new("#{element_name}", self, "#{locator}", :page);end))
186
+ end
187
+
188
+ def self.links(element_hash)
189
+ element_hash.each do |element_name, locator|
190
+ link(element_name, locator)
191
+ end
192
+ end
193
+
194
+ # Declare and instantiate a single table UI Element for this page object.
195
+ #
196
+ # @param element_name [Symbol] name of table object (as a symbol)
197
+ # @param locator [String] XPath expression that uniquely identifies object
198
+ # @example
199
+ # table :payments_table, "//table[@class='payments_table']"
200
+ #
201
+ def self.table(element_name, locator)
202
+ class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::Table.new("#{element_name}", self, "#{locator}", :page);end))
203
+ end
204
+
205
+ def self.tables(element_hash)
206
+ element_hash.each do |element_name, locator|
207
+ table(element_name, locator)
208
+ end
209
+ end
210
+
211
+ # Declare and instantiate a single select list UI Element for this page object.
212
+ #
213
+ # @param element_name [Symbol] name of select list object (as a symbol)
214
+ # @param locator [String] CSS selector or XPath expression that uniquely identifies object
215
+ # @example
216
+ # selectlist :category_selector, 'select#search_form_category_chosen'
217
+ # selectlist :gender_select, "//select[@id='customer_gender']"
218
+ #
219
+ def self.selectlist(element_name, locator)
220
+ class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::SelectList.new("#{element_name}", self, "#{locator}", :page);end))
221
+ end
222
+
223
+ def self.selectlists(element_hash)
224
+ element_hash.each do |element_name, locator|
225
+ selectlist(element_name, locator)
226
+ end
227
+ end
228
+
229
+ # Declare and instantiate a single list UI Element for this page object.
230
+ #
231
+ # @param element_name [Symbol] name of list object (as a symbol)
232
+ # @param locator [String] CSS selector or XPath expression that uniquely identifies object
233
+ # @example
234
+ # list :x_axis_list, 'g.x-axis'
235
+ #
236
+ def self.list(element_name, locator)
237
+ class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::List.new("#{element_name}", self, "#{locator}", :page);end))
238
+ end
239
+
240
+ def self.lists(element_hash)
241
+ element_hash.each do |element_name, locator|
242
+ list(element_name, locator)
243
+ end
244
+ end
245
+
246
+ # Declare and instantiate an single image UI Element for this page object.
247
+ #
248
+ # @param element_name [Symbol] name of image object (as a symbol)
249
+ # @param locator [String] CSS selector or XPath expression that uniquely identifies object
250
+ # @example
251
+ # image :basket_item_image, 'div.product_image'
252
+ # image :corporate_logo_image, "//img[@alt='MyCompany_logo']"
253
+ #
254
+ def self.image(element_name, locator)
255
+ class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::Image.new("#{element_name}", self, "#{locator}", :page);end))
256
+ end
257
+
258
+ def self.images(element_hash)
259
+ element_hash.each do |element_name, locator|
260
+ image(element_name, locator)
261
+ end
262
+ end
263
+
264
+ # Declare and instantiate a single File Field UI Element for this page object.
265
+ #
266
+ # @param element_name [Symbol] name of file field object (as a symbol)
267
+ # @param locator [String] CSS selector or XPath expression that uniquely identifies object
268
+ # @example
269
+ # filefield :attach_file, 's_SweFileName'
270
+ #
271
+ def self.filefield(element_name, locator)
272
+ class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::FileField.new("#{element_name}", self, "#{locator}", :page);end))
273
+ end
274
+
275
+ def self.filefields(element_hash)
276
+ element_hash.each do |element_name, locator|
277
+ filefield(element_name, locator)
278
+ end
279
+ end
280
+
281
+ # Declare and instantiate a cell button in a table column on this page object.
282
+ #
283
+ # @param element_name [Symbol] name of cell button object (as a symbol)
284
+ # @param locator [String] XPath expression that uniquely identifies cell button within row and column of parent table object
285
+ # @param table [Symbol] Name (as a symbol) of parent table object
286
+ # @param column [Integer] 1-based index of table column that contains the cell button object
287
+ # @example
288
+ # cell_button :show_button, "a[@class='show']", :data_table, 5
289
+ # cell_button :edit_button, "a[@class='edit']", :data_table, 5
290
+ #
291
+ def self.cell_button(element_name, locator, table, column)
292
+ class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::CellButton.new("#{element_name}", self, "#{locator}", :page, #{table}, #{column});end))
293
+ end
294
+
295
+ # Declare and instantiate a cell checkbox in a table column on this page object.
296
+ #
297
+ # @param element_name [Symbol] name of cell checkbox object (as a symbol)
298
+ # @param locator [String] XPath expression that uniquely identifies cell checkbox 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 checkbox object
301
+ # @example
302
+ # cell_checkbox :is_registered_check, "a[@class='registered']", :data_table, 4
303
+ #
304
+ def self.cell_checkbox(element_name, locator, table, column, proxy = nil)
305
+ class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::CellCheckBox.new("#{element_name}", self, "#{locator}", :page, #{table}, #{column}, #{proxy});end))
306
+ end
307
+
308
+ # Declare and instantiate a cell radio in a table column on this page object.
309
+ #
310
+ # @param element_name [Symbol] name of cell radio object (as a symbol)
311
+ # @param locator [String] XPath expression that uniquely identifies cell radio 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 radio object
314
+ # @example
315
+ # cell_radio :track_a_radio, "a[@class='track_a']", :data_table, 8
316
+ #
317
+ def self.cell_radio(element_name, locator, table, column, proxy = nil)
318
+ class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::CellRadio.new("#{element_name}", self, "#{locator}", :page, #{table}, #{column}, #{proxy});end))
319
+ end
320
+
321
+ # Declare and instantiate a cell image in a table column on this page object.
322
+ #
323
+ # @param element_name [Symbol] name of cell image object (as a symbol)
324
+ # @param locator [String] XPath expression that uniquely identifies cell image within row and column of parent table object
325
+ # @param table [Symbol] Name (as a symbol) of parent table object
326
+ # @param column [Integer] 1-based index of table column that contains the cell image object
327
+ # @example
328
+ # cell_image :ready_icon, "img[@class='ready']", :data_table, 3
329
+ # cell_image :send_icon, "img[@class='send']", :data_table, 3
330
+ #
331
+ def self.cell_image(element_name, locator, table, column)
332
+ class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::CellImage.new("#{element_name}", self, "#{locator}", :page, #{table}, #{column});end))
333
+ end
334
+
335
+ # Declare and instantiate a list button in a row of a list object on this page object.
336
+ #
337
+ # @param element_name [Symbol] name of list button object (as a symbol)
338
+ # @param locator [String] XPath expression that uniquely identifies list button within row of parent list object
339
+ # @param list [Symbol] Name (as a symbol) of parent list object
340
+ # @example
341
+ # list_button :delete_button, "a[@class='delete']", :icon_list
342
+ # list_button :edit_button, "a[@class='edit']", :icon_list
343
+ #
344
+ def self.list_button(element_name, locator, list)
345
+ class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::ListButton.new("#{element_name}", self, "#{locator}", :page, #{list});end))
346
+ end
347
+
348
+ # Declare and instantiate a list checkbox in a row of a list object on this page object.
349
+ #
350
+ # @param element_name [Symbol] name of list checkbox object (as a symbol)
351
+ # @param locator [String] XPath expression that uniquely identifies list checkbox within row of parent list object
352
+ # @param list [Symbol] Name (as a symbol) of parent list object
353
+ # @example
354
+ # list_checkbox :is_registered_check, "a[@class='registered']", :data_list
355
+ #
356
+ def self.list_checkbox(element_name, locator, list, proxy = nil)
357
+ class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::ListCheckBox.new("#{element_name}", self, "#{locator}", :page, #{list}, #{proxy});end))
358
+ end
359
+
360
+ # Declare and instantiate a list radio in a row of a list object on this page object.
361
+ #
362
+ # @param element_name [Symbol] name of list radio object (as a symbol)
363
+ # @param locator [String] XPath expression that uniquely identifies list radio within row of parent list object
364
+ # @param list [Symbol] Name (as a symbol) of parent list object
365
+ # @example
366
+ # list_radio :sharing_radio, "a[@class='sharing']", :data_list
367
+ #
368
+ def self.list_radio(element_name, locator, list, proxy = nil)
369
+ class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::ListRadio.new("#{element_name}", self, "#{locator}", :page, #{list}, #{proxy});end))
370
+ end
371
+
372
+ # Instantiate a single PageSection object for this page object.
373
+ #
374
+ # @param section_name [Symbol] name of PageSection object (as a symbol)
375
+ # @param class_name [String] Class name of PageSection object
376
+ # @example
377
+ # section :search_form, SearchForm
378
+ #
379
+ def self.section(section_name, class_name, locator = nil)
380
+ class_eval(%(def #{section_name};@#{section_name} ||= #{class_name}.new("#{section_name}", self, "#{locator}", :page);end))
381
+ end
382
+
383
+ def self.sections(section_hash)
384
+ section_hash.each do |section_name, class_name|
385
+ section(section_name, class_name)
386
+ end
387
+ end
388
+
389
+ def open_portal
390
+ environment = Environ.current
391
+ environment.hostname.blank? ?
392
+ url = "#{environment.base_url}#{environment.append}" :
393
+ url = "#{environment.hostname}/#{environment.base_url}#{environment.append}"
394
+ if environment.user_id.blank? || environment.password.blank?
395
+ visit "#{environment.protocol}://#{url}"
396
+ else
397
+ visit "#{environment.protocol}://#{environment.user_id}:#{environment.password}@#{url}"
398
+ end
399
+ Environ.portal_state = :open
400
+ end
401
+
402
+ def verify_page_exists
403
+ raise "Page object #{self.class.name} does not have a page_locator trait defined" unless defined?(page_locator)
404
+ unless page.has_selector?(page_locator)
405
+ body_class = find(:xpath, '//body')[:class]
406
+ error_message = %(
407
+ Expected page to have selector '#{page_locator}' but found '#{body_class}' instead.
408
+ Actual URL of page loaded = #{URI.parse(current_url)}.
409
+ )
410
+ error_message = "#{error_message}\nExpected URL of page was #{page_url}." if defined?(page_url)
411
+ raise error_message
412
+ end
413
+ PageManager.current_page = self
414
+ end
415
+
416
+ def navigate_to; end
417
+
418
+ def verify_page_ui; end
419
+
420
+ def load_page
421
+ return if exists?
422
+ if defined?(page_url) && !page_url.nil?
423
+ visit page_url
424
+ begin
425
+ page.driver.browser.switch_to.alert.accept
426
+ rescue => e
427
+ end unless Environ.browser == :safari || Environ.browser == :ie || Environ.is_device?
428
+ else
429
+ navigate_to
430
+ end
431
+ verify_page_exists
432
+ end
433
+
434
+ def verify_page_contains(content)
435
+ raise "Expected page to have content '#{content}'" unless page.has_content?(:visible, content)
436
+ end
437
+
438
+ # Does Page object exists?
439
+ #
440
+ # @return [Boolean]
441
+ # @example
442
+ # home_page.exists?
443
+ #
444
+ def exists?
445
+ raise "Page object #{self.class.name} does not have a page_locator trait defined" unless defined?(page_locator)
446
+ saved_wait_time = Capybara.default_max_wait_time
447
+ Capybara.default_max_wait_time = 0.1
448
+ tries ||= 2
449
+ attributes = [:id, :css, :xpath]
450
+ type = attributes[tries]
451
+ obj = page.find(type, page_locator)
452
+ obj != nil
453
+ rescue
454
+ Capybara.default_max_wait_time = saved_wait_time
455
+ retry if (tries -= 1) > 0
456
+ false
457
+ ensure
458
+ Capybara.default_max_wait_time = saved_wait_time
459
+ end
460
+
461
+ # Is current Page object URL secure?
462
+ #
463
+ # @return [Boolean]
464
+ # @example
465
+ # home_page.secure?
466
+ #
467
+ def secure?
468
+ !current_url.match(/^https/).nil?
469
+ end
470
+
471
+ def verify_ui_states(ui_states)
472
+ ui_states.each do |ui_object, object_states|
473
+ object_states.each do |property, state|
474
+ case property
475
+ when :class
476
+ actual = ui_object.get_attribute(:class)
477
+ when :exists
478
+ actual = ui_object.exists?
479
+ when :enabled
480
+ actual = ui_object.enabled?
481
+ when :disabled
482
+ actual = ui_object.disabled?
483
+ when :visible
484
+ actual = ui_object.visible?
485
+ when :hidden
486
+ actual = ui_object.hidden?
487
+ when :displayed
488
+ actual = ui_object.displayed?
489
+ when :width
490
+ actual = ui_object.width
491
+ when :height
492
+ actual = ui_object.height
493
+ when :x
494
+ actual = ui_object.x
495
+ when :y
496
+ actual = ui_object.y
497
+ when :readonly
498
+ actual = ui_object.read_only?
499
+ when :checked
500
+ actual = ui_object.checked?
501
+ when :selected
502
+ actual = ui_object.selected?
503
+ when :value, :caption
504
+ actual = ui_object.get_value
505
+ when :maxlength
506
+ actual = ui_object.get_max_length
507
+ when :rowcount
508
+ actual = ui_object.get_row_count
509
+ when :columncount
510
+ actual = ui_object.get_column_count
511
+ when :placeholder
512
+ actual = ui_object.get_placeholder
513
+ when :min
514
+ actual = ui_object.get_min
515
+ when :max
516
+ actual = ui_object.get_max
517
+ when :step
518
+ actual = ui_object.get_step
519
+ when :options, :items, :list_items
520
+ actual = ui_object.get_list_items
521
+ when :optioncount, :itemcount
522
+ actual = ui_object.get_item_count
523
+ when :all_items, :all_list_items
524
+ actual = ui_object.get_all_list_items
525
+ when :all_items_count
526
+ actual = ui_object.get_all_items_count
527
+ when :column_headers
528
+ actual = ui_object.get_header_columns
529
+ when :siebel_options
530
+ actual = ui_object.get_siebel_options
531
+ else
532
+ if property.is_a?(Hash)
533
+ property.each do |key, value|
534
+ case key
535
+ when :cell
536
+ actual = ui_object.get_table_cell(value[0].to_i, value[1].to_i)
537
+ when :row
538
+ actual = ui_object.get_table_row(value.to_i)
539
+ when :column
540
+ actual = ui_object.get_table_column(value.to_i)
541
+ when :item
542
+ actual = ui_object.get_list_item(value.to_i)
543
+ when :attribute
544
+ actual = ui_object.get_attribute(value)
545
+ when :native_attribute
546
+ actual = ui_object.get_native_attribute(value)
547
+ end
548
+ end
549
+ else
550
+ props = property.to_s.split('_')
551
+ case props[0].to_sym
552
+ when :cell
553
+ cell = property.to_s.delete('cell_')
554
+ cell = cell.split('_')
555
+ actual = ui_object.get_table_cell(cell[0].to_i, cell[1].to_i)
556
+ when :row
557
+ row = property.to_s.delete('row_')
558
+ actual = ui_object.get_table_row(row.to_i)
559
+ when :column
560
+ column = property.to_s.delete('column_')
561
+ actual = ui_object.get_table_column(column.to_i)
562
+ when :item
563
+ item = property.to_s.delete('item_')
564
+ actual = ui_object.get_list_item(item.to_i)
565
+ end
566
+ end
567
+ end
568
+
569
+ if state.is_a?(Hash) && state.length == 1
570
+ error_msg = "Expected UI object '#{ui_object.get_name}' (#{ui_object.get_locator}) #{property} property to"
571
+ state.each do |key, value|
572
+ case key
573
+ when :lt, :less_than
574
+ ExceptionQueue.enqueue_exception("#{error_msg} be less than #{value} but found '#{actual}'") unless actual < value
575
+ when :lt_eq, :less_than_or_equal
576
+ ExceptionQueue.enqueue_exception("#{error_msg} be less than or equal to #{value} but found '#{actual}'") unless actual <= value
577
+ when :gt, :greater_than
578
+ ExceptionQueue.enqueue_exception("#{error_msg} be greater than #{value} but found '#{actual}'") unless actual > value
579
+ when :gt_eq, :greater_than_or_equal
580
+ ExceptionQueue.enqueue_exception("#{error_msg} be greater than or equal to #{value} but found '#{actual}'") unless actual >= value
581
+ when :starts_with
582
+ ExceptionQueue.enqueue_exception("#{error_msg} start with '#{value}' but found '#{actual}'") unless actual.start_with?(value)
583
+ when :ends_with
584
+ ExceptionQueue.enqueue_exception("#{error_msg} end with '#{value}' but found '#{actual}'") unless actual.end_with?(value)
585
+ when :contains
586
+ ExceptionQueue.enqueue_exception("#{error_msg} contain '#{value}' but found '#{actual}'") unless actual.include?(value)
587
+ when :not_contains, :does_not_contain
588
+ ExceptionQueue.enqueue_exception("#{error_msg} not contain '#{value}' but found '#{actual}'") if actual.include?(value)
589
+ when :not_equal
590
+ ExceptionQueue.enqueue_exception("#{error_msg} not equal '#{value}' but found '#{actual}'") if actual == value
591
+ when :like, :is_like
592
+ actual_like = actual.delete("\n")
593
+ actual_like = actual_like.delete("\r")
594
+ actual_like = actual_like.delete("\t")
595
+ actual_like = actual_like.delete(' ')
596
+ actual_like = actual_like.downcase
597
+ expected = value.delete("\n")
598
+ expected = expected.delete("\r")
599
+ expected = expected.delete("\t")
600
+ expected = expected.delete(' ')
601
+ expected = expected.downcase
602
+ ExceptionQueue.enqueue_exception("#{error_msg} be like '#{value}' but found '#{actual}'") unless actual_like.include?(expected)
603
+ when :translate
604
+ expected = I18n.t(value)
605
+ ExceptionQueue.enqueue_assert_equal(expected, actual, "Expected UI object '#{ui_object.get_name}' (#{ui_object.get_locator}) translated #{property} property")
606
+ end
607
+ end
608
+ else
609
+ ExceptionQueue.enqueue_assert_equal(state, actual, "Expected UI object '#{ui_object.get_name}' (#{ui_object.get_locator}) #{property} property")
610
+ end
611
+ end
612
+ end
613
+ ExceptionQueue.post_exceptions
614
+ end
615
+
616
+ # Populate the specified UI elements on this page with the associated data from a Hash passed as an argument. Data
617
+ # values must be in the form of a String for textfield and select list controls. For checkbox and radio buttons,
618
+ # data must either be a Boolean or a String that evaluates to a Boolean value (Yes, No, 1, 0, true, false).
619
+ #
620
+ # The optional wait_time parameter is used to specify the time (in seconds) to wait for each UI element to become
621
+ # visible before entering the associated data value. This option is useful in situations where entering data, or
622
+ # setting the state of a UI element might cause other UI elements to become visible or active. Specifying a wait_time
623
+ # value ensures that the subsequent UI elements will be ready to be interacted with as states are changed. If the wait
624
+ # time is nil, then the wait time will be 5 seconds.
625
+ #
626
+ # To delete all text content in a text field, pass !DELETE as the data to be entered.
627
+ #
628
+ # @param data [Hash] UI element(s) and associated data to be entered
629
+ # @param wait_time [Integer] wait time in seconds
630
+ # @example
631
+ # field_data = { prefix_select => 'Ms',
632
+ # first_name_field => 'Priscilla',
633
+ # last_name_field => 'Pumperknickle',
634
+ # gender_select => 'Female',
635
+ # dob_field => '11/18/1976',
636
+ # email_field => 'p.pumperknickle4876@gmail.com',
637
+ # mailing_list_check => 'Yes'
638
+ # }
639
+ # populate_data_fields(field_data)
640
+ #
641
+ def populate_data_fields(data, wait_time = nil)
642
+ timeout = wait_time.nil? ? 5 : wait_time
643
+ data.each do |data_field, data_param|
644
+ unless data_param.blank?
645
+ # make sure the intended UI target element is visible before trying to set its value
646
+ data_field.wait_until_visible(timeout)
647
+ if data_param == '!DELETE'
648
+ data_field.clear
649
+ else
650
+ case data_field.get_object_type
651
+ when :checkbox
652
+ data_field.set_checkbox_state(data_param.to_bool)
653
+ when :selectlist
654
+ data_field.get_siebel_object_type == 'JComboBox' ?
655
+ data_field.set("#{data_param}\t") :
656
+ data_field.choose_option(data_param)
657
+ when :radio
658
+ data_field.set_selected_state(data_param.to_bool)
659
+ when :textfield
660
+ data_field.set("#{data_param}\t")
661
+ when :section
662
+ data_field.set(data_param)
663
+ end
664
+ end
665
+ end
666
+ end
667
+ end
668
+ end
669
+ end