testcentricity 2.4.3 → 3.0.2

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 (126) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +29 -0
  3. data/.rspec +2 -1
  4. data/.rubocop.yml +38 -0
  5. data/.ruby-version +1 -1
  6. data/.simplecov +9 -0
  7. data/.yardopts +3 -0
  8. data/CHANGELOG.md +282 -0
  9. data/CODE_OF_CONDUCT.md +13 -0
  10. data/{LICENSE.txt → LICENSE.md} +3 -4
  11. data/README.md +938 -1384
  12. data/Rakefile +63 -1
  13. data/config/cucumber.yml +145 -0
  14. data/config/locales/en-US.yml +56 -0
  15. data/config/test_data/LOCAL_data.yml +11 -0
  16. data/config/test_data/data.yml +10 -0
  17. data/features/deep_links.feature +26 -0
  18. data/features/login.feature +30 -0
  19. data/features/navigation.feature +31 -0
  20. data/features/step_definitions/generic_steps.rb +72 -0
  21. data/features/support/android/screens/about_screen.rb +11 -0
  22. data/features/support/android/screens/base_app_screen.rb +29 -0
  23. data/features/support/android/screens/checkout_address_screen.rb +17 -0
  24. data/features/support/android/screens/checkout_payment_screen.rb +22 -0
  25. data/features/support/android/screens/login_screen.rb +18 -0
  26. data/features/support/android/screens/products_screen.rb +13 -0
  27. data/features/support/android/screens/saucebot_screen.rb +16 -0
  28. data/features/support/android/screens/webview_screen.rb +13 -0
  29. data/features/support/android/sections/nav_widgets/nav_menu.rb +39 -0
  30. data/features/support/env.rb +61 -0
  31. data/features/support/hooks.rb +135 -0
  32. data/features/support/ios/screens/about_screen.rb +11 -0
  33. data/features/support/ios/screens/base_app_screen.rb +19 -0
  34. data/features/support/ios/screens/checkout_address_screen.rb +17 -0
  35. data/features/support/ios/screens/checkout_payment_screen.rb +22 -0
  36. data/features/support/ios/screens/login_screen.rb +18 -0
  37. data/features/support/ios/screens/products_screen.rb +13 -0
  38. data/features/support/ios/screens/saucebot_screen.rb +16 -0
  39. data/features/support/ios/screens/webview_screen.rb +13 -0
  40. data/features/support/ios/sections/list_items/product_cell_item.rb +13 -0
  41. data/features/support/ios/sections/modals/base_modal.rb +23 -0
  42. data/features/support/ios/sections/modals/logout_modal.rb +6 -0
  43. data/features/support/ios/sections/modals/reset_app_state_modal.rb +6 -0
  44. data/features/support/ios/sections/nav_widgets/nav_bar.rb +31 -0
  45. data/features/support/ios/sections/nav_widgets/nav_menu.rb +41 -0
  46. data/features/support/shared_components/screens/base_app_screen.rb +31 -0
  47. data/features/support/shared_components/screens/checkout_address_screen.rb +17 -0
  48. data/features/support/shared_components/screens/checkout_payment_screen.rb +22 -0
  49. data/features/support/shared_components/screens/login_screen.rb +39 -0
  50. data/features/support/shared_components/screens/saucebot_screen.rb +17 -0
  51. data/features/support/shared_components/screens/webview_screen.rb +12 -0
  52. data/features/support/shared_components/sections/nav_menu.rb +58 -0
  53. data/features/support/world_data.rb +12 -0
  54. data/features/support/world_pages.rb +26 -0
  55. data/lib/testcentricity/app_core/appium_connect_helper.rb +343 -111
  56. data/lib/testcentricity/app_core/screen_object.rb +252 -0
  57. data/lib/testcentricity/app_core/screen_objects_helper.rb +29 -201
  58. data/lib/testcentricity/app_core/{screen_sections_helper.rb → screen_section.rb} +40 -105
  59. data/lib/testcentricity/app_elements/app_element_helper.rb +17 -8
  60. data/lib/testcentricity/app_elements/checkbox.rb +3 -3
  61. data/lib/testcentricity/data_objects/environment.rb +133 -39
  62. data/lib/testcentricity/version.rb +1 -1
  63. data/lib/testcentricity.rb +4 -129
  64. data/reports/.keep +1 -0
  65. data/spec/fixtures/page_object.rb +22 -0
  66. data/spec/fixtures/page_section_object.rb +21 -0
  67. data/spec/fixtures/screen_object.rb +16 -0
  68. data/spec/fixtures/screen_section_object.rb +16 -0
  69. data/spec/spec_helper.rb +28 -9
  70. data/spec/testcentricity/elements/button_spec.rb +18 -0
  71. data/spec/testcentricity/elements/checkbox_spec.rb +28 -0
  72. data/spec/testcentricity/elements/image_spec.rb +13 -0
  73. data/spec/testcentricity/elements/label_spec.rb +18 -0
  74. data/spec/testcentricity/elements/list_spec.rb +13 -0
  75. data/spec/testcentricity/elements/ui_element_spec.rb +72 -0
  76. data/spec/testcentricity/mobile/appium_connect_spec.rb +117 -0
  77. data/spec/testcentricity/mobile/screen_object_spec.rb +63 -0
  78. data/spec/testcentricity/mobile/screen_section_object_spec.rb +56 -0
  79. data/spec/testcentricity/version_spec.rb +7 -0
  80. data/spec/testcentricity/web/browser_spec.rb +41 -0
  81. data/spec/testcentricity/web/local_webdriver_spec.rb +86 -0
  82. data/spec/testcentricity/web/mobile_webdriver_spec.rb +123 -0
  83. data/spec/testcentricity/web/page_object_spec.rb +85 -0
  84. data/spec/testcentricity/web/page_section_object_spec.rb +72 -0
  85. data/testcentricity.gemspec +30 -27
  86. metadata +216 -119
  87. data/.ruby-gemset +0 -1
  88. data/Gemfile.lock +0 -93
  89. data/bin/console +0 -14
  90. data/bin/setup +0 -8
  91. data/lib/devices/devices.yml +0 -352
  92. data/lib/testcentricity/app_core/appium_server.rb +0 -69
  93. data/lib/testcentricity/browser_helper.rb +0 -174
  94. data/lib/testcentricity/data_objects/data_objects_helper.rb +0 -78
  95. data/lib/testcentricity/data_objects/excel_helper.rb +0 -242
  96. data/lib/testcentricity/exception_queue_helper.rb +0 -111
  97. data/lib/testcentricity/utility_helpers.rb +0 -32
  98. data/lib/testcentricity/web_core/drag_drop_helper.rb +0 -15
  99. data/lib/testcentricity/web_core/page_objects_helper.rb +0 -677
  100. data/lib/testcentricity/web_core/page_sections_helper.rb +0 -895
  101. data/lib/testcentricity/web_core/webdriver_helper.rb +0 -588
  102. data/lib/testcentricity/web_elements/button.rb +0 -8
  103. data/lib/testcentricity/web_elements/cell_button.rb +0 -8
  104. data/lib/testcentricity/web_elements/cell_checkbox.rb +0 -38
  105. data/lib/testcentricity/web_elements/cell_element.rb +0 -69
  106. data/lib/testcentricity/web_elements/cell_image.rb +0 -8
  107. data/lib/testcentricity/web_elements/cell_radio.rb +0 -31
  108. data/lib/testcentricity/web_elements/checkbox.rb +0 -100
  109. data/lib/testcentricity/web_elements/file_field.rb +0 -45
  110. data/lib/testcentricity/web_elements/image.rb +0 -34
  111. data/lib/testcentricity/web_elements/label.rb +0 -8
  112. data/lib/testcentricity/web_elements/link.rb +0 -8
  113. data/lib/testcentricity/web_elements/list.rb +0 -100
  114. data/lib/testcentricity/web_elements/list_button.rb +0 -8
  115. data/lib/testcentricity/web_elements/list_checkbox.rb +0 -38
  116. data/lib/testcentricity/web_elements/list_element.rb +0 -61
  117. data/lib/testcentricity/web_elements/list_radio.rb +0 -31
  118. data/lib/testcentricity/web_elements/radio.rb +0 -74
  119. data/lib/testcentricity/web_elements/select_list.rb +0 -208
  120. data/lib/testcentricity/web_elements/siebel_open_ui_helper.rb +0 -15
  121. data/lib/testcentricity/web_elements/table.rb +0 -612
  122. data/lib/testcentricity/web_elements/textfield.rb +0 -114
  123. data/lib/testcentricity/web_elements/ui_elements_helper.rb +0 -532
  124. data/lib/testcentricity/world_extensions.rb +0 -26
  125. data/my_templates/default/method_details/setup.rb +0 -3
  126. data/spec/testcentricity_spec.rb +0 -9
@@ -1,895 +0,0 @@
1
- require 'test/unit'
2
-
3
- module TestCentricity
4
- class PageSection
5
- include Capybara::DSL
6
- include Capybara::Node::Matchers
7
- include Test::Unit::Assertions
8
-
9
- attr_reader :context, :name
10
- attr_accessor :locator
11
- attr_accessor :parent
12
- attr_accessor :parent_list
13
- attr_accessor :list_index
14
- attr_accessor :locator_type
15
-
16
- XPATH_SELECTORS = ['//', '[@', '[contains(@']
17
- CSS_SELECTORS = ['#', ':nth-child(', ':nth-of-type(', '^=', '$=', '*=']
18
-
19
- def initialize(name, parent, locator, context)
20
- @name = name
21
- @parent = parent
22
- @locator = locator
23
- @context = context
24
- @parent_list = nil
25
- @list_index = nil
26
-
27
- is_xpath = XPATH_SELECTORS.any? { |selector| @locator.include?(selector) }
28
- is_css = CSS_SELECTORS.any? { |selector| @locator.include?(selector) }
29
- if is_xpath && !is_css
30
- @locator_type = :xpath
31
- elsif is_css && !is_xpath
32
- @locator_type = :css
33
- elsif !is_css && !is_xpath
34
- @locator_type = :css
35
- else
36
- raise "Cannot determine type of locator for PageSection '#{@name}' - locator = #{@locator}"
37
- end
38
- end
39
-
40
- def get_locator
41
- if @locator.empty? && defined?(section_locator)
42
- locator = section_locator
43
- else
44
- locator = @locator
45
- end
46
-
47
- unless @parent_list.nil?
48
- locator = "#{@parent_list.get_locator}|#{locator}"
49
- unless @list_index.nil?
50
- case @locator_type
51
- when :xpath
52
- locator = "(#{locator})[#{@list_index}]"
53
- when :css
54
- locator = "#{locator}:nth-of-type(#{@list_index})"
55
- end
56
- end
57
- end
58
-
59
- if @context == :section && !@parent.nil? && !@parent.get_locator.nil?
60
- "#{@parent.get_locator}|#{locator}"
61
- else
62
- locator
63
- end
64
- end
65
-
66
- def get_locator_type
67
- @locator_type
68
- end
69
-
70
- def set_list_index(list, index = 1)
71
- @parent_list = list unless list.nil?
72
- @list_index = index
73
- end
74
-
75
- def get_item_count
76
- raise 'No parent list defined' if @parent_list.nil?
77
- @parent_list.get_item_count
78
- end
79
-
80
- def get_list_items
81
- items = []
82
- (1..get_item_count).each do |item|
83
- set_list_index(nil, item)
84
- items.push(get_value)
85
- end
86
- items
87
- end
88
-
89
- def get_all_items_count
90
- raise 'No parent list defined' if @parent_list.nil?
91
- @parent_list.get_all_items_count
92
- end
93
-
94
- def get_all_list_items
95
- items = []
96
- (1..get_all_items_count).each do |item|
97
- set_list_index(nil, item)
98
- items.push(get_value(:all))
99
- end
100
- items
101
- end
102
-
103
- def verify_list_items(expected, enqueue = false)
104
- actual = get_list_items
105
- enqueue ?
106
- ExceptionQueue.enqueue_assert_equal(expected, actual, "Expected list '#{get_name}' (#{get_locator})") :
107
- assert_equal(expected, actual, "Expected list object '#{get_name}' (#{get_locator}) to be #{expected} but found #{actual}")
108
- end
109
-
110
- def get_object_type
111
- :section
112
- end
113
-
114
- def get_name
115
- @name
116
- end
117
-
118
- def set_parent(parent)
119
- @parent = parent
120
- end
121
-
122
- # Define a trait for this page section.
123
- #
124
- # @param trait_name [Symbol] name of trait (as a symbol)
125
- # @param block [&block] trait value
126
- # @example
127
- # trait(:section_locator) { "//div[@class='Messaging_Applet']" }
128
- # trait(:list_table_name) { '#Messages' }
129
- #
130
- def self.trait(trait_name, &block)
131
- define_method(trait_name.to_s, &block)
132
- end
133
-
134
- # Declare and instantiate a single generic UI Element for this page section.
135
- #
136
- # @param element_name [Symbol] name of UI object (as a symbol)
137
- # @param locator [String] CSS selector or XPath expression that uniquely identifies object
138
- # @example
139
- # element :undo_record_item, "//li[@rn='Undo Record']/a"
140
- # element :basket_header, 'div.basket_header'
141
- #
142
- def self.element(element_name, locator)
143
- define_element(element_name, TestCentricity::UIElement, locator)
144
- end
145
-
146
- # Declare and instantiate a collection of generic UI Elements for this page section.
147
- #
148
- # @param element_hash [Hash] names of UI objects (as a symbol) and CSS selectors or XPath expressions that uniquely identifies objects
149
- # @example
150
- # elements profile_item: 'a#profile',
151
- # settings_item: 'a#userPreferencesTrigger',
152
- # log_out_item: 'a#logout'
153
- #
154
- def self.elements(element_hash)
155
- element_hash.each do |element_name, locator|
156
- element(element_name, locator)
157
- end
158
- end
159
-
160
- # Declare and instantiate a single button UI Element for this page section.
161
- #
162
- # @param element_name [Symbol] name of button object (as a symbol)
163
- # @param locator [String] CSS selector or XPath expression that uniquely identifies object
164
- # @example
165
- # button :checkout_button, 'button.checkout_button'
166
- # button :login_button, "//input[@id='submit_button']"
167
- #
168
- def self.button(element_name, locator)
169
- define_element(element_name, TestCentricity::Button, locator)
170
- end
171
-
172
- # Declare and instantiate a collection of buttons for this page section.
173
- #
174
- # @param element_hash [Hash] names of buttons (as a symbol) and CSS selectors or XPath expressions that uniquely identifies buttons
175
- # @example
176
- # buttons new_account_button: 'button#new-account',
177
- # save_button: 'button#save',
178
- # cancel_button: 'button#cancel'
179
- #
180
- def self.buttons(element_hash)
181
- element_hash.each do |element_name, locator|
182
- button(element_name, locator)
183
- end
184
- end
185
-
186
- # Declare and instantiate a single text field UI Element for this page section.
187
- #
188
- # @param element_name [Symbol] name of text field object (as a symbol)
189
- # @param locator [String] CSS selector or XPath expression that uniquely identifies object
190
- # @example
191
- # textfield :user_id_field, "//input[@id='UserName']"
192
- # textfield :password_field, 'input#consumer_password'
193
- #
194
- def self.textfield(element_name, locator)
195
- define_element(element_name, TestCentricity::TextField, locator)
196
- end
197
-
198
- # Declare and instantiate a collection of text fields for this page section.
199
- #
200
- # @param element_hash [Hash] names of text fields (as a symbol) and CSS selectors or XPath expressions that uniquely identifies text fields
201
- # @example
202
- # textfields name_field: 'input#Name',
203
- # title_field: 'input#Title',
204
- # phone_field: 'input#PhoneNumber',
205
- # fax_field: 'input#FaxNumber',
206
- # email_field: 'input#Email'
207
- #
208
- def self.textfields(element_hash)
209
- element_hash.each do |element_name, locator|
210
- textfield(element_name, locator)
211
- end
212
- end
213
-
214
- # Declare and instantiate a single checkbox UI Element for this page section.
215
- #
216
- # @param element_name [Symbol] name of checkbox object (as a symbol)
217
- # @param locator [String] CSS selector or XPath expression that uniquely identifies object
218
- # @param proxy [Symbol] Optional name (as a symbol) of proxy object to receive click actions
219
- # @example
220
- # checkbox :remember_checkbox, "//input[@id='RememberUser']"
221
- # checkbox :accept_terms_checkbox, 'input#accept_terms_conditions', :accept_terms_label
222
- #
223
- def self.checkbox(element_name, locator, proxy = nil)
224
- class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::CheckBox.new("#{element_name}", self, "#{locator}", :section, #{proxy});end))
225
- end
226
-
227
- # Declare and instantiate a collection of checkboxes for this page section.
228
- #
229
- # @param element_hash [Hash] names of checkboxes (as a symbol) and CSS selectors or XPath expressions that uniquely identifies checkboxes
230
- # @example
231
- # checkboxes hazmat_certified_check: 'input#hazmatCertified',
232
- # epa_certified_check: 'input#epaCertified',
233
- # dhs_certified_check: 'input#homelandSecurityCertified',
234
- # carb_compliant_check: 'input#carbCompliant'
235
- #
236
- def self.checkboxes(element_hash)
237
- element_hash.each do |element_name, locator|
238
- checkbox(element_name, locator)
239
- end
240
- end
241
-
242
- # Declare and instantiate a single radio button UI Element for this page section.
243
- #
244
- # @param element_name [Symbol] name of radio object (as a symbol)
245
- # @param locator [String] CSS selector or XPath expression that uniquely identifies object
246
- # @param proxy [Symbol] Optional name (as a symbol) of proxy object to receive click actions
247
- # @example
248
- # radio :accept_terms_radio, "//input[@id='Accept_Terms']"
249
- # radio :decline_terms_radio, 'input#decline_terms_conditions', :decline_terms_label
250
- #
251
- def self.radio(element_name, locator, proxy = nil)
252
- class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::Radio.new("#{element_name}", self, "#{locator}", :section, #{proxy});end))
253
- end
254
-
255
- # Declare and instantiate a collection of radio buttons for this page section.
256
- #
257
- # @param element_hash [Hash] names of radio buttons (as a symbol) and CSS selectors or XPath expressions that uniquely identifies radio buttons
258
- # @example
259
- # radios visa_radio: 'input#payWithVisa',
260
- # mastercard_radio: 'input#payWithMastercard',
261
- # discover_radio: 'input#payWithDiscover',
262
- # amex_radio: 'input#payWithAmEx'
263
- #
264
- def self.radios(element_hash)
265
- element_hash.each do |element_name, locator|
266
- radio(element_name, locator)
267
- end
268
- end
269
-
270
- # Declare and instantiate a single label UI Element for this page section.
271
- #
272
- # @param element_name [Symbol] name of label object (as a symbol)
273
- # @param locator [String] CSS selector or XPath expression that uniquely identifies object
274
- # @example
275
- # label :welcome_label, 'div.Welcome'
276
- # label :rollup_price_label, "//div[contains(@id, 'Rollup Item Price')]"
277
- #
278
- def self.label(element_name, locator)
279
- define_element(element_name, TestCentricity::Label, locator)
280
- end
281
-
282
- def self.labels(element_hash)
283
- element_hash.each do |element_name, locator|
284
- label(element_name, locator)
285
- end
286
- end
287
-
288
- # Declare and instantiate a single link UI Element for this page section.
289
- #
290
- # @param element_name [Symbol] name of link object (as a symbol)
291
- # @param locator [String] CSS selector or XPath expression that uniquely identifies object
292
- # @example
293
- # link :registration_link, 'a.account-nav__link.register'
294
- # link :shopping_basket_link, "//a[@href='shopping_basket']"
295
- #
296
- def self.link(element_name, locator)
297
- define_element(element_name, TestCentricity::Link, locator)
298
- end
299
-
300
- def self.links(element_hash)
301
- element_hash.each do |element_name, locator|
302
- link(element_name, locator)
303
- end
304
- end
305
-
306
- # Declare and instantiate a single table UI Element for this page section.
307
- #
308
- # @param element_name [Symbol] name of table object (as a symbol)
309
- # @param locator [String] CSS selector or XPath expression that uniquely identifies object
310
- # @example
311
- # table :payments_table, "//table[@class='payments_table']"
312
- #
313
- def self.table(element_name, locator)
314
- define_element(element_name, TestCentricity::Table, locator)
315
- end
316
-
317
- def self.tables(element_hash)
318
- element_hash.each do |element_name, locator|
319
- table(element_name, locator)
320
- end
321
- end
322
-
323
- # Declare and instantiate a single select list UI Element for this page section.
324
- #
325
- # @param element_name [Symbol] name of select list object (as a symbol)
326
- # @param locator [String] CSS selector or XPath expression that uniquely identifies object
327
- # @example
328
- # selectlist :category_selector, 'select#search_form_category_chosen'
329
- # selectlist :gender_select, "//select[@id='customer_gender']"
330
- #
331
- def self.selectlist(element_name, locator)
332
- define_element(element_name, TestCentricity::SelectList, locator)
333
- end
334
-
335
- def self.selectlists(element_hash)
336
- element_hash.each do |element_name, locator|
337
- selectlist(element_name, locator)
338
- end
339
- end
340
-
341
- # Declare and instantiate a single list UI Element for this page section.
342
- #
343
- # @param element_name [Symbol] name of list object (as a symbol)
344
- # @param locator [String] CSS selector or XPath expression that uniquely identifies object
345
- # @example
346
- # list :y_axis_list, 'g.y_axis'
347
- #
348
- def self.list(element_name, locator)
349
- define_element(element_name, TestCentricity::List, locator)
350
- end
351
-
352
- def self.lists(element_hash)
353
- element_hash.each do |element_name, locator|
354
- list(element_name, locator)
355
- end
356
- end
357
-
358
- # Declare and instantiate an single image UI Element for this page section.
359
- #
360
- # @param element_name [Symbol] name of image object (as a symbol)
361
- # @param locator [String] CSS selector or XPath expression that uniquely identifies object
362
- # @example
363
- # image :basket_item_image, 'div.product_image'
364
- # image :corporate_logo_image, "//img[@alt='MyCompany_logo']"
365
- #
366
- def self.image(element_name, locator)
367
- define_element(element_name, TestCentricity::Image, locator)
368
- end
369
-
370
- def self.images(element_hash)
371
- element_hash.each do |element_name, locator|
372
- image(element_name, locator)
373
- end
374
- end
375
-
376
- # Declare and instantiate a single File Field UI Element for this page section.
377
- #
378
- # @param element_name [Symbol] name of file field object (as a symbol)
379
- # @param locator [String] CSS selector or XPath expression that uniquely identifies object
380
- # @example
381
- # filefield :attach_file, 's_SweFileName'
382
- #
383
- def self.filefield(element_name, locator)
384
- define_element(element_name, TestCentricity::FileField, locator)
385
- end
386
-
387
- def self.filefields(element_hash)
388
- element_hash.each do |element_name, locator|
389
- filefield(element_name, locator)
390
- end
391
- end
392
-
393
- # Declare and instantiate a cell button in a table column on this page section.
394
- #
395
- # @param element_name [Symbol] name of cell button object (as a symbol)
396
- # @param locator [String] XPath expression that uniquely identifies cell button within row and column of parent table object
397
- # @param table [Symbol] Name (as a symbol) of parent table object
398
- # @param column [Integer] 1-based index of table column that contains the cell button object
399
- # @example
400
- # cell_button :show_button, "a[@class='show']", :data_table, 5
401
- # cell_button :edit_button, "a[@class='edit']", :data_table, 5
402
- #
403
- def self.cell_button(element_name, locator, table, column)
404
- class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::CellButton.new("#{element_name}", self, "#{locator}", :section, #{table}, #{column});end))
405
- end
406
-
407
- # Declare and instantiate a cell checkbox in a table column on this page section.
408
- #
409
- # @param element_name [Symbol] name of cell checkbox object (as a symbol)
410
- # @param locator [String] XPath expression that uniquely identifies cell checkbox within row and column of parent table object
411
- # @param table [Symbol] Name (as a symbol) of parent table object
412
- # @param column [Integer] 1-based index of table column that contains the cell checkbox object
413
- # @example
414
- # cell_checkbox :is_registered_check, "a[@class='registered']", :data_table, 4
415
- #
416
- def self.cell_checkbox(element_name, locator, table, column, proxy = nil)
417
- class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::CellCheckBox.new("#{element_name}", self, "#{locator}", :section, #{table}, #{column}, #{proxy});end))
418
- end
419
-
420
- # Declare and instantiate a cell radio in a table column on this page section.
421
- #
422
- # @param element_name [Symbol] name of cell radio object (as a symbol)
423
- # @param locator [String] XPath expression that uniquely identifies cell radio within row and column of parent table object
424
- # @param table [Symbol] Name (as a symbol) of parent table object
425
- # @param column [Integer] 1-based index of table column that contains the cell radio object
426
- # @example
427
- # cell_radio :track_a_radio, "a[@class='track_a']", :data_table, 8
428
- #
429
- def self.cell_radio(element_name, locator, table, column, proxy = nil)
430
- class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::CellRadio.new("#{element_name}", self, "#{locator}", :section, #{table}, #{column}, #{proxy});end))
431
- end
432
-
433
- # Declare and instantiate a cell image in a table column on this page object.
434
- #
435
- # @param element_name [Symbol] name of cell image object (as a symbol)
436
- # @param locator [String] XPath expression that uniquely identifies cell image within row and column of parent table object
437
- # @param table [Symbol] Name (as a symbol) of parent table object
438
- # @param column [Integer] 1-based index of table column that contains the cell image object
439
- # @example
440
- # cell_image :ready_icon, "img[@class='ready']", :data_table, 3
441
- # cell_image :send_icon, "img[@class='send']", :data_table, 3
442
- #
443
- def self.cell_image(element_name, locator, table, column)
444
- class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::CellImage.new("#{element_name}", self, "#{locator}", :section, #{table}, #{column});end))
445
- end
446
-
447
- # Declare and instantiate a list button in a row of a list object on this section object.
448
- #
449
- # @param element_name [Symbol] name of list button object (as a symbol)
450
- # @param locator [String] XPath expression that uniquely identifies list button within row of parent list object
451
- # @param list [Symbol] Name (as a symbol) of parent list object
452
- # @example
453
- # list_button :delete_button, "a[@class='delete']", :icon_list
454
- # list_button :edit_button, "a[@class='edit']", :icon_list
455
- #
456
- def self.list_button(element_name, locator, list)
457
- class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::ListButton.new("#{element_name}", self, "#{locator}", :section, #{list});end))
458
- end
459
-
460
- # Declare and instantiate a list checkbox in a row of a list object on this section object.
461
- #
462
- # @param element_name [Symbol] name of list checkbox object (as a symbol)
463
- # @param locator [String] XPath expression that uniquely identifies list checkbox within row of parent list object
464
- # @param list [Symbol] Name (as a symbol) of parent list object
465
- # @example
466
- # list_checkbox :is_registered_check, "a[@class='registered']", :data_list
467
- #
468
- def self.list_checkbox(element_name, locator, list, proxy = nil)
469
- class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::ListCheckBox.new("#{element_name}", self, "#{locator}", :section, #{list}, #{proxy});end))
470
- end
471
-
472
- # Declare and instantiate a list radio in a row of a list object on this section object.
473
- #
474
- # @param element_name [Symbol] name of list radio object (as a symbol)
475
- # @param locator [String] XPath expression that uniquely identifies list radio within row of parent list object
476
- # @param list [Symbol] Name (as a symbol) of parent list object
477
- # @example
478
- # list_radio :sharing_radio, "a[@class='sharing']", :data_list
479
- #
480
- def self.list_radio(element_name, locator, list, proxy = nil)
481
- class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::CellRadio.new("#{element_name}", self, "#{locator}", :section, #{list}, #{proxy});end))
482
- end
483
-
484
- # Instantiate a single PageSection object within this PageSection object.
485
- #
486
- # @param section_name [Symbol] name of PageSection object (as a symbol)
487
- # @param class_name [String] Class name of PageSection object
488
- # @example
489
- # section :search_form, SearchForm
490
- #
491
- def self.section(section_name, obj, locator = nil)
492
- define_method(section_name) do
493
- ivar_name = "@#{section_name}"
494
- ivar = instance_variable_get(ivar_name)
495
- return ivar if ivar
496
- instance_variable_set(ivar_name, obj.new(section_name, self, "#{locator}", :section))
497
- end
498
- end
499
-
500
- def self.sections(section_hash)
501
- section_hash.each do |section_name, class_name|
502
- section(section_name, class_name)
503
- end
504
- end
505
-
506
- # Does Section object exists?
507
- #
508
- # @return [Boolean]
509
- # @example
510
- # navigation_toolbar.exists?
511
- #
512
- def exists?
513
- section, = find_section
514
- section != nil
515
- end
516
-
517
- # Is Section object enabled?
518
- #
519
- # @return [Boolean]
520
- # @example
521
- # bar_chart_section.enabled?
522
- #
523
- def enabled?
524
- !disabled?
525
- end
526
-
527
- # Is Section object disabled (not enabled)?
528
- #
529
- # @return [Boolean]
530
- # @example
531
- # bar_chart_section.disabled?
532
- #
533
- def disabled?
534
- section, = find_section
535
- section_not_found_exception(section)
536
- section.disabled?
537
- end
538
-
539
- # Is Section object visible?
540
- #
541
- # @return [Boolean]
542
- # @example
543
- # navigation_toolbar.visible?
544
- #
545
- def visible?
546
- section, = find_section
547
- exists = section
548
- visible = false
549
- visible = section.visible? if exists
550
- # the section is visible if it exists and it is not invisible
551
- exists && visible ? true : false
552
- end
553
-
554
- # Is Section object hidden (not visible)?
555
- #
556
- # @return [Boolean]
557
- # @example
558
- # navigation_toolbar.hidden?
559
- #
560
- def hidden?
561
- !visible?
562
- end
563
-
564
- # Is section object displayed in browser window?
565
- #
566
- # @return [Boolean]
567
- # @example
568
- # navigation_toolbar.displayed??
569
- #
570
- def displayed?
571
- section, = find_section
572
- section_not_found_exception(section)
573
- section.displayed?
574
- end
575
-
576
- # Wait until the Section object exists, or until the specified wait time has expired. If the wait time is nil, then
577
- # the wait time will be Capybara.default_max_wait_time.
578
- #
579
- # @param seconds [Integer or Float] wait time in seconds
580
- # @example
581
- # navigation_toolbar.wait_until_exists(0.5)
582
- #
583
- def wait_until_exists(seconds = nil)
584
- timeout = seconds.nil? ? Capybara.default_max_wait_time : seconds
585
- wait = Selenium::WebDriver::Wait.new(timeout: timeout)
586
- wait.until { exists? }
587
- rescue
588
- raise "Could not find Section object '#{get_name}' (#{get_locator}) after #{timeout} seconds" unless exists?
589
- end
590
-
591
- # Wait until the Section object no longer exists, or until the specified wait time has expired. If the wait time is
592
- # nil, then the wait time will be Capybara.default_max_wait_time.
593
- #
594
- # @param seconds [Integer or Float] wait time in seconds
595
- # @example
596
- # navigation_toolbar.wait_until_gone(5)
597
- #
598
- def wait_until_gone(seconds = nil)
599
- timeout = seconds.nil? ? Capybara.default_max_wait_time : seconds
600
- wait = Selenium::WebDriver::Wait.new(timeout: timeout)
601
- wait.until { !exists? }
602
- rescue
603
- raise "Section object '#{get_name}' (#{get_locator}) remained visible after #{timeout} seconds" if exists?
604
- end
605
-
606
- # Wait until the Section object is visible, or until the specified wait time has expired. If the wait time is nil,
607
- # then the wait time will be Capybara.default_max_wait_time.
608
- #
609
- # @param seconds [Integer or Float] wait time in seconds
610
- # @example
611
- # bar_chart_section.wait_until_visible(0.5)
612
- #
613
- def wait_until_visible(seconds = nil)
614
- timeout = seconds.nil? ? Capybara.default_max_wait_time : seconds
615
- wait = Selenium::WebDriver::Wait.new(timeout: timeout)
616
- wait.until { visible? }
617
- rescue
618
- raise "Could not find Section object '#{get_name}' (#{get_locator}) after #{timeout} seconds" unless visible?
619
- end
620
-
621
- # Wait until the Section object is hidden, or until the specified wait time has expired. If the wait time is nil,
622
- # then the wait time will be Capybara.default_max_wait_time.
623
- #
624
- # @param seconds [Integer or Float] wait time in seconds
625
- # @example
626
- # bar_chart_section.wait_until_hidden(10)
627
- #
628
- def wait_until_hidden(seconds = nil)
629
- timeout = seconds.nil? ? Capybara.default_max_wait_time : seconds
630
- wait = Selenium::WebDriver::Wait.new(timeout: timeout)
631
- wait.until { hidden? }
632
- rescue
633
- raise "Section object '#{get_name}' (#{get_locator}) remained visible after #{timeout} seconds" if visible?
634
- end
635
-
636
- # Click on a Section object
637
- #
638
- # @example
639
- # bar_chart_section.click
640
- #
641
- def click
642
- section, = find_section
643
- section_not_found_exception(section)
644
- begin
645
- section.click
646
- rescue
647
- section.click_at(10, 10) unless Capybara.current_driver == :poltergeist
648
- end
649
- end
650
-
651
- # Double-click on a Section object
652
- #
653
- # @example
654
- # bar_chart_section.double_click
655
- #
656
- def double_click
657
- section, = find_section
658
- section_not_found_exception(section)
659
- page.driver.browser.action.double_click(section.native).perform
660
- end
661
-
662
- # Right-click on a Section object
663
- #
664
- # @example
665
- # bar_chart_section.right_click
666
- #
667
- def right_click
668
- section, = find_section
669
- section_not_found_exception(section)
670
- page.driver.browser.action.context_click(section.native).perform
671
- end
672
-
673
- # Click at a specific location within a Section object
674
- #
675
- # @param x [Integer] X offset
676
- # @param y [Integer] Y offset
677
- # @example
678
- # bar_chart_section.click_at(10, 10)
679
- #
680
- def click_at(x, y)
681
- section, = find_section
682
- section_not_found_exception(section)
683
- section.click_at(x, y)
684
- end
685
-
686
- # Send keystrokes to a Section object
687
- #
688
- # @param keys [String] keys
689
- # @example
690
- # bar_chart_section.send_keys(:enter)
691
- #
692
- def send_keys(*keys)
693
- section, = find_section
694
- section_not_found_exception(section)
695
- section.send_keys(*keys)
696
- end
697
-
698
- def verify_ui_states(ui_states)
699
- ui_states.each do |ui_object, object_states|
700
- object_states.each do |property, state|
701
- case property
702
- when :class
703
- actual = ui_object.get_attribute(:class)
704
- when :exists
705
- actual = ui_object.exists?
706
- when :enabled
707
- actual = ui_object.enabled?
708
- when :disabled
709
- actual = ui_object.disabled?
710
- when :visible
711
- actual = ui_object.visible?
712
- when :hidden
713
- actual = ui_object.hidden?
714
- when :displayed
715
- actual = ui_object.displayed?
716
- when :width
717
- actual = ui_object.width
718
- when :height
719
- actual = ui_object.height
720
- when :x
721
- actual = ui_object.x
722
- when :y
723
- actual = ui_object.y
724
- when :readonly
725
- actual = ui_object.read_only?
726
- when :checked
727
- actual = ui_object.checked?
728
- when :selected
729
- actual = ui_object.selected?
730
- when :value, :caption
731
- actual = ui_object.get_value
732
- when :maxlength
733
- actual = ui_object.get_max_length
734
- when :rowcount
735
- actual = ui_object.get_row_count
736
- when :columncount
737
- actual = ui_object.get_column_count
738
- when :placeholder
739
- actual = ui_object.get_placeholder
740
- when :min
741
- actual = ui_object.get_min
742
- when :max
743
- actual = ui_object.get_max
744
- when :step
745
- actual = ui_object.get_step
746
- when :options, :items, :list_items
747
- actual = ui_object.get_list_items
748
- when :optioncount, :itemcount
749
- actual = ui_object.get_item_count
750
- when :all_items, :all_list_items
751
- actual = ui_object.get_all_list_items
752
- when :all_items_count
753
- actual = ui_object.get_all_items_count
754
- when :column_headers
755
- actual = ui_object.get_header_columns
756
- when :siebel_options
757
- actual = ui_object.get_siebel_options
758
- else
759
- if property.is_a?(Hash)
760
- property.each do |key, value|
761
- case key
762
- when :cell
763
- actual = ui_object.get_table_cell(value[0].to_i, value[1].to_i)
764
- when :row
765
- actual = ui_object.get_table_row(value.to_i)
766
- when :column
767
- actual = ui_object.get_table_column(value.to_i)
768
- when :item
769
- actual = ui_object.get_list_item(value.to_i)
770
- when :attribute
771
- actual = ui_object.get_attribute(value)
772
- when :native_attribute
773
- actual = ui_object.get_native_attribute(value)
774
- end
775
- end
776
- else
777
- props = property.to_s.split('_')
778
- case props[0].to_sym
779
- when :cell
780
- cell = property.to_s.delete('cell_')
781
- cell = cell.split('_')
782
- actual = ui_object.get_table_cell(cell[0].to_i, cell[1].to_i)
783
- when :row
784
- row = property.to_s.delete('row_')
785
- actual = ui_object.get_table_row(row.to_i)
786
- when :column
787
- column = property.to_s.delete('column_')
788
- actual = ui_object.get_table_column(column.to_i)
789
- when :item
790
- item = property.to_s.delete('item_')
791
- actual = ui_object.get_list_item(item.to_i)
792
- end
793
- end
794
- end
795
- error_msg = "Expected UI object '#{ui_object.get_name}' (#{ui_object.get_locator}) #{property} property to"
796
- ExceptionQueue.enqueue_comparison(state, actual, error_msg)
797
- end
798
- end
799
- rescue ObjectNotFoundError => e
800
- ExceptionQueue.enqueue_exception(e.message)
801
- ensure
802
- ExceptionQueue.post_exceptions
803
- end
804
-
805
- # Populate the specified UI elements in this Section object with the associated data from a Hash passed as an
806
- # argument. Data values must be in the form of a String for textfield and select list controls. For checkbox
807
- # and radio buttons, data must either be a Boolean or a String that evaluates to a Boolean value (Yes, No, 1,
808
- # 0, true, false).
809
- #
810
- # The optional wait_time parameter is used to specify the time (in seconds) to wait for each UI element to become
811
- # visible before entering the associated data value. This option is useful in situations where entering data, or
812
- # setting the state of a UI element might cause other UI elements to become visible or active. Specifying a wait_time
813
- # value ensures that the subsequent UI elements will be ready to be interacted with as states are changed. If the wait
814
- # time is nil, then the wait time will be 5 seconds.
815
- #
816
- # To delete all text content in a text field, pass !DELETE as the data to be entered.
817
- #
818
- # @param data [Hash] UI element(s) and associated data to be entered
819
- # @param wait_time [Integer] wait time in seconds
820
- # @example
821
- # data = { prefix_select => 'Mr.',
822
- # first_name_field => 'Ignatious',
823
- # last_name_field => 'Snickelfritz',
824
- # gender_select => 'Male',
825
- # dob_field => '12/14/1957',
826
- # organ_donor_check => 'Yes',
827
- # dnr_on_file_check => 'Yes'
828
- # }
829
- # populate_data_fields(data)
830
- #
831
- def populate_data_fields(data, wait_time = nil)
832
- timeout = wait_time.nil? ? 5 : wait_time
833
- data.each do |data_field, data_param|
834
- unless data_param.blank?
835
- # make sure the intended UI target element is visible before trying to set its value
836
- data_field.wait_until_visible(timeout)
837
- if data_param == '!DELETE'
838
- data_field.clear
839
- else
840
- case data_field.get_object_type
841
- when :checkbox
842
- data_field.set_checkbox_state(data_param.to_bool)
843
- when :selectlist
844
- data_field.get_siebel_object_type == 'JComboBox' ?
845
- data_field.set("#{data_param}\t") :
846
- data_field.choose_option(data_param)
847
- when :radio
848
- data_field.set_selected_state(data_param.to_bool)
849
- when :textfield
850
- data_field.set("#{data_param}\t")
851
- when :section
852
- data_field.set(data_param)
853
- end
854
- end
855
- end
856
- end
857
- end
858
-
859
- def get_attribute(attrib)
860
- section, = find_section
861
- section_not_found_exception(section)
862
- section[attrib]
863
- end
864
-
865
- def get_native_attribute(attrib)
866
- section, = find_section
867
- section_not_found_exception(section)
868
- section.native.attribute(attrib)
869
- end
870
-
871
- private
872
-
873
- def find_section
874
- locator = get_locator
875
- locator = locator.gsub('|', ' ')
876
- obj = page.find(@locator_type, locator, :wait => 0.1)
877
- [obj, @locator_type]
878
- rescue
879
- [nil, nil]
880
- end
881
-
882
- def section_not_found_exception(section)
883
- raise ObjectNotFoundError.new("Section object '#{get_name}' (#{get_locator}) not found") unless section
884
- end
885
-
886
- def self.define_element(element_name, obj, locator)
887
- define_method(element_name) do
888
- ivar_name = "@#{element_name}"
889
- ivar = instance_variable_get(ivar_name)
890
- return ivar if ivar
891
- instance_variable_set(ivar_name, obj.new(element_name, self, locator, :section))
892
- end
893
- end
894
- end
895
- end