testcentricity 2.4.1 → 3.0.0

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