testcentricity_web 2.1.8.2 → 2.1.8.3

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 (46) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +27 -0
  3. data/.rubocop.yml +41 -0
  4. data/.yardopts +2 -0
  5. data/Gemfile +6 -0
  6. data/LICENSE.txt +28 -0
  7. data/README.md +1438 -0
  8. data/Rakefile +1 -0
  9. data/lib/devices/devices.yml +280 -0
  10. data/lib/testcentricity_web.rb +140 -0
  11. data/lib/testcentricity_web/browser_helper.rb +173 -0
  12. data/lib/testcentricity_web/data_objects_helper.rb +78 -0
  13. data/lib/testcentricity_web/drag_drop_helper.rb +15 -0
  14. data/lib/testcentricity_web/elements/button.rb +8 -0
  15. data/lib/testcentricity_web/elements/cell_button.rb +8 -0
  16. data/lib/testcentricity_web/elements/cell_checkbox.rb +38 -0
  17. data/lib/testcentricity_web/elements/cell_element.rb +62 -0
  18. data/lib/testcentricity_web/elements/cell_image.rb +8 -0
  19. data/lib/testcentricity_web/elements/cell_radio.rb +31 -0
  20. data/lib/testcentricity_web/elements/checkbox.rb +99 -0
  21. data/lib/testcentricity_web/elements/file_field.rb +45 -0
  22. data/lib/testcentricity_web/elements/image.rb +34 -0
  23. data/lib/testcentricity_web/elements/label.rb +8 -0
  24. data/lib/testcentricity_web/elements/link.rb +8 -0
  25. data/lib/testcentricity_web/elements/list.rb +54 -0
  26. data/lib/testcentricity_web/elements/list_button.rb +8 -0
  27. data/lib/testcentricity_web/elements/list_checkbox.rb +38 -0
  28. data/lib/testcentricity_web/elements/list_element.rb +51 -0
  29. data/lib/testcentricity_web/elements/list_radio.rb +31 -0
  30. data/lib/testcentricity_web/elements/radio.rb +73 -0
  31. data/lib/testcentricity_web/elements/select_list.rb +189 -0
  32. data/lib/testcentricity_web/elements/table.rb +473 -0
  33. data/lib/testcentricity_web/elements/textfield.rb +84 -0
  34. data/lib/testcentricity_web/environment.rb +249 -0
  35. data/lib/testcentricity_web/excel_helper.rb +242 -0
  36. data/lib/testcentricity_web/exception_queue_helper.rb +47 -0
  37. data/lib/testcentricity_web/page_objects_helper.rb +656 -0
  38. data/lib/testcentricity_web/page_sections_helper.rb +811 -0
  39. data/lib/testcentricity_web/siebel_open_ui_helper.rb +15 -0
  40. data/lib/testcentricity_web/ui_elements_helper.rb +425 -0
  41. data/lib/testcentricity_web/utility_helpers.rb +28 -0
  42. data/lib/testcentricity_web/version.rb +3 -0
  43. data/lib/testcentricity_web/webdriver_helper.rb +451 -0
  44. data/lib/testcentricity_web/world_extensions.rb +26 -0
  45. data/testcentricity_web.gemspec +42 -0
  46. metadata +52 -4
@@ -0,0 +1,15 @@
1
+ module TestCentricity
2
+ class UIElement
3
+ def invoke_siebel_dialog(popup, seconds = nil)
4
+ invoke_siebel_popup
5
+ timeout = seconds.nil? ? 15 : seconds
6
+ popup.wait_until_exists(timeout)
7
+ end
8
+
9
+ def get_siebel_object_type
10
+ obj, = find_element
11
+ object_not_found_exception(obj, 'Siebel object')
12
+ obj.native.attribute('ot')
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,425 @@
1
+ require 'test/unit'
2
+
3
+ Capybara::Node::Element.class_eval do
4
+ def click_at(x, y)
5
+ right = x - (native.size.width / 2)
6
+ top = y - (native.size.height / 2)
7
+ driver.browser.action.move_to(native).move_by(right.to_i, top.to_i).click.perform
8
+ end
9
+
10
+ def get_width
11
+ native.size.width
12
+ end
13
+
14
+ def get_height
15
+ native.size.height
16
+ end
17
+ end
18
+
19
+
20
+ module TestCentricity
21
+ class UIElement
22
+ include Capybara::DSL
23
+ include Test::Unit::Assertions
24
+
25
+ attr_reader :parent, :locator, :context, :type, :name
26
+ attr_accessor :alt_locator
27
+
28
+ def initialize(name, parent, locator, context)
29
+ @name = name
30
+ @parent = parent
31
+ @locator = locator
32
+ @context = context
33
+ @type = nil
34
+ @alt_locator = nil
35
+ end
36
+
37
+ def get_object_type
38
+ if @type
39
+ @type
40
+ elsif obj.tag_name
41
+ obj.tag_name
42
+ elsif obj.native.attribute('type')
43
+ obj.native.attribute('type')
44
+ end
45
+ end
46
+
47
+ def get_locator
48
+ @locator
49
+ end
50
+
51
+ def get_name
52
+ @name
53
+ end
54
+
55
+ def set_alt_locator(temp_locator)
56
+ @alt_locator = temp_locator
57
+ end
58
+
59
+ def clear_alt_locator
60
+ @alt_locator = nil
61
+ end
62
+
63
+ # Click on an object
64
+ #
65
+ # @example
66
+ # basket_link.click
67
+ #
68
+ def click
69
+ obj, = find_element
70
+ object_not_found_exception(obj, nil)
71
+ begin
72
+ obj.click
73
+ rescue
74
+ obj.click_at(10, 10) unless Capybara.current_driver == :poltergeist
75
+ end
76
+ end
77
+
78
+ # Double-click on an object
79
+ #
80
+ # @example
81
+ # file_image.double_click
82
+ #
83
+ def double_click
84
+ obj, = find_element
85
+ object_not_found_exception(obj, nil)
86
+ page.driver.browser.action.double_click(obj.native).perform
87
+ end
88
+
89
+ # Right-click on an object
90
+ #
91
+ # @example
92
+ # basket_item_image.right_click
93
+ #
94
+ def right_click
95
+ obj, = find_element
96
+ object_not_found_exception(obj, nil)
97
+ page.driver.browser.action.context_click(obj.native).perform
98
+ end
99
+
100
+ # Click at a specific location within an object
101
+ #
102
+ # @param x [Integer] X offset
103
+ # @param y [Integer] Y offset
104
+ # @example
105
+ # basket_item_image.click_at(10, 10)
106
+ #
107
+ def click_at(x, y)
108
+ obj, = find_element
109
+ raise "UI #{object_ref_message} not found" unless obj
110
+ obj.click_at(x, y)
111
+ end
112
+
113
+ def set(value)
114
+ obj, = find_element
115
+ object_not_found_exception(obj, nil)
116
+ obj.set(value)
117
+ end
118
+
119
+ # Send keystrokes to this object.
120
+ #
121
+ # @param keys [String] keys
122
+ # @example
123
+ # comment_field.send_keys(:enter)
124
+ #
125
+ def send_keys(*keys)
126
+ obj, = find_element
127
+ object_not_found_exception(obj, nil)
128
+ obj.send_keys(*keys)
129
+ end
130
+
131
+ # Does UI object exists?
132
+ #
133
+ # @return [Boolean]
134
+ # @example
135
+ # basket_link.exists?
136
+ #
137
+ def exists?(visible = true)
138
+ obj, = find_object(visible)
139
+ obj != nil
140
+ end
141
+
142
+ # Is UI object visible?
143
+ #
144
+ # @return [Boolean]
145
+ # @example
146
+ # remember_me_checkbox.visible?
147
+ #
148
+ def visible?
149
+ obj, type = find_object
150
+ exists = obj
151
+ invisible = false
152
+ if type == :css
153
+ Capybara.using_wait_time 0.1 do
154
+ # is object itself hidden with .ui-helper-hidden class?
155
+ self_hidden = page.has_css?("#{@locator}.ui-helper-hidden")
156
+ # is parent of object hidden, thus hiding the object?
157
+ parent_hidden = page.has_css?(".ui-helper-hidden > #{@locator}")
158
+ # is grandparent of object, or any other ancestor, hidden?
159
+ other_ancestor_hidden = page.has_css?(".ui-helper-hidden * #{@locator}")
160
+ # if any of the above conditions are true, then object is invisible
161
+ invisible = self_hidden || parent_hidden || other_ancestor_hidden
162
+ end
163
+ else
164
+ invisible = !obj.visible? if exists
165
+ end
166
+ # the object is visible if it exists and it is not invisible
167
+ exists && !invisible ? true : false
168
+ end
169
+
170
+ # Is UI object hidden (not visible)?
171
+ #
172
+ # @return [Boolean]
173
+ # @example
174
+ # remember_me_checkbox.hidden?
175
+ #
176
+ def hidden?
177
+ !visible?
178
+ end
179
+
180
+ # Is UI object enabled?
181
+ #
182
+ # @return [Boolean]
183
+ # @example
184
+ # login_button.enabled?
185
+ #
186
+ def enabled?
187
+ !disabled?
188
+ end
189
+
190
+ # Is UI object disabled (not enabled)?
191
+ #
192
+ # @return [Boolean]
193
+ # @example
194
+ # login_button.disabled?
195
+ #
196
+ def disabled?
197
+ obj, = find_element
198
+ object_not_found_exception(obj, nil)
199
+ obj.disabled?
200
+ end
201
+
202
+ # Wait until the object exists, or until the specified wait time has expired.
203
+ #
204
+ # @param seconds [Integer or Float] wait time in seconds
205
+ # @example
206
+ # run_button.wait_until_exists(0.5)
207
+ #
208
+ def wait_until_exists(seconds = nil)
209
+ timeout = seconds.nil? ? Capybara.default_max_wait_time : seconds
210
+ wait = Selenium::WebDriver::Wait.new(timeout: timeout)
211
+ wait.until { exists? }
212
+ rescue
213
+ raise "Could not find UI #{object_ref_message} after #{timeout} seconds" unless exists?
214
+ end
215
+
216
+ # Wait until the object no longer exists, or until the specified wait time has expired.
217
+ #
218
+ # @param seconds [Integer or Float] wait time in seconds
219
+ # @example
220
+ # logout_button.wait_until_gone(5)
221
+ #
222
+ def wait_until_gone(seconds = nil)
223
+ timeout = seconds.nil? ? Capybara.default_max_wait_time : seconds
224
+ wait = Selenium::WebDriver::Wait.new(timeout: timeout)
225
+ wait.until { !exists? }
226
+ rescue
227
+ raise "UI #{object_ref_message} remained visible after #{timeout} seconds" if exists?
228
+ end
229
+
230
+ # Wait until the object is visible, or until the specified wait time has expired.
231
+ #
232
+ # @param seconds [Integer or Float] wait time in seconds
233
+ # @example
234
+ # run_button.wait_until_visible(0.5)
235
+ #
236
+ def wait_until_visible(seconds = nil)
237
+ timeout = seconds.nil? ? Capybara.default_max_wait_time : seconds
238
+ wait = Selenium::WebDriver::Wait.new(timeout: timeout)
239
+ wait.until { visible? }
240
+ rescue
241
+ raise "Could not find UI #{object_ref_message} after #{timeout} seconds" unless visible?
242
+ end
243
+
244
+ # Wait until the object is hidden, or until the specified wait time has expired.
245
+ #
246
+ # @param seconds [Integer or Float] wait time in seconds
247
+ # @example
248
+ # run_button.wait_until_hidden(10)
249
+ #
250
+ def wait_until_hidden(seconds = nil)
251
+ timeout = seconds.nil? ? Capybara.default_max_wait_time : seconds
252
+ wait = Selenium::WebDriver::Wait.new(timeout: timeout)
253
+ wait.until { hidden? }
254
+ rescue
255
+ raise "UI #{object_ref_message} remained visible after #{timeout} seconds" if visible?
256
+ end
257
+
258
+ # Wait until the object's value equals the specified value, or until the specified wait time has expired.
259
+ #
260
+ # @param seconds [Integer or Float] wait time in seconds
261
+ # @example
262
+ # card_authorized_label.wait_until_value_is(5, 'Card authorized')
263
+ #
264
+ def wait_until_value_is(value, seconds = nil)
265
+ timeout = seconds.nil? ? Capybara.default_max_wait_time : seconds
266
+ wait = Selenium::WebDriver::Wait.new(timeout: timeout)
267
+ wait.until { get_value == value }
268
+ rescue
269
+ raise "Value of UI #{object_ref_message} failed to equal '#{value}' after #{timeout} seconds" unless get_value == value
270
+ end
271
+
272
+ # Wait until the object's value changes to a different value, or until the specified wait time has expired.
273
+ #
274
+ # @param seconds [Integer or Float] wait time in seconds
275
+ # @example
276
+ # basket_grand_total_label.wait_until_value_changes(5)
277
+ #
278
+ def wait_until_value_changes(seconds = nil)
279
+ value = get_value
280
+ timeout = seconds.nil? ? Capybara.default_max_wait_time : seconds
281
+ wait = Selenium::WebDriver::Wait.new(timeout: timeout)
282
+ wait.until { get_value != value }
283
+ rescue
284
+ raise "Value of UI #{object_ref_message} failed to change from '#{value}' after #{timeout} seconds" if get_value == value
285
+ end
286
+
287
+ def get_value(visible = true)
288
+ obj, = find_element(visible)
289
+ object_not_found_exception(obj, nil)
290
+ case obj.tag_name.downcase
291
+ when 'input', 'select', 'textarea'
292
+ obj.value
293
+ else
294
+ obj.text
295
+ end
296
+ end
297
+
298
+ alias get_caption get_value
299
+
300
+ def verify_value(expected, enqueue = false)
301
+ actual = get_value
302
+ enqueue ?
303
+ ExceptionQueue.enqueue_assert_equal(expected.strip, actual.strip, "Expected UI #{object_ref_message}") :
304
+ assert_equal(expected.strip, actual.strip, "Expected UI #{object_ref_message} to display '#{expected}' but found '#{actual}'")
305
+ end
306
+
307
+ alias verify_caption verify_value
308
+
309
+ # Hover the cursor over an object
310
+ #
311
+ # @example
312
+ # basket_link.hover
313
+ #
314
+ def hover
315
+ obj, = find_element
316
+ object_not_found_exception(obj, nil)
317
+ obj.hover
318
+ end
319
+
320
+ def drag_by(right_offset, down_offset)
321
+ obj, = find_element
322
+ object_not_found_exception(obj, nil)
323
+ obj.drag_by(right_offset, down_offset)
324
+ end
325
+
326
+ def drag_and_drop(target, right_offset = nil, down_offset = nil)
327
+ source, = find_element
328
+ object_not_found_exception(source, nil)
329
+ page.driver.browser.action.click_and_hold(source.native).perform
330
+ sleep(0.5)
331
+ target_drop, = target.find_element
332
+ page.driver.browser.action.move_to(target_drop.native, right_offset.to_i, down_offset.to_i).release.perform
333
+ end
334
+
335
+ def get_attribute(attrib)
336
+ obj, = find_element(false)
337
+ object_not_found_exception(obj, nil)
338
+ obj[attrib]
339
+ end
340
+
341
+ def get_native_attribute(attrib)
342
+ obj, = find_element(false)
343
+ object_not_found_exception(obj, nil)
344
+ obj.native.attribute(attrib)
345
+ end
346
+
347
+ private
348
+
349
+ def find_element(visible = true)
350
+ wait = Selenium::WebDriver::Wait.new(timeout: Capybara.default_max_wait_time)
351
+ wait.until { find_object(visible) }
352
+ end
353
+
354
+ def find_object(visible = true)
355
+ @alt_locator.nil? ? obj_locator = @locator : obj_locator = @alt_locator
356
+ parent_section = @context == :section && !@parent.get_locator.nil?
357
+ if parent_section
358
+ attributes = [:id, :ignore_parent_xpath, :ignore_parent_css, :xpath_css, :css_xpath, :xpath, :css]
359
+ tries ||= 6
360
+ else
361
+ attributes = [:id, :xpath, :css]
362
+ tries ||= 2
363
+ end
364
+
365
+ type = attributes[tries]
366
+ if parent_section
367
+ parent_locator = @parent.get_locator
368
+ case type
369
+ when :css
370
+ parent_locator = parent_locator.gsub('|', ' ')
371
+ obj = page.find(:css, parent_locator, :wait => 0.01).find(:css, obj_locator, :wait => 0.01, :visible => visible)
372
+ when :xpath
373
+ parent_locator = parent_locator.delete('|')
374
+ obj = page.find(:xpath, "#{parent_locator}#{obj_locator}", :wait => 0.01, :visible => visible)
375
+ when :css_xpath
376
+ type = :xpath
377
+ parent_locator = parent_locator.gsub('|', ' ')
378
+ obj = page.find(:css, parent_locator, :wait => 0.01).find(:xpath, obj_locator, :wait => 0.01, :visible => visible)
379
+ when :xpath_css
380
+ type = :css
381
+ parent_locator = parent_locator.gsub('|', ' ')
382
+ obj = page.find(:xpath, parent_locator, :wait => 0.01).find(:css, obj_locator, :wait => 0.01, :visible => visible)
383
+ when :ignore_parent_css
384
+ type = :css
385
+ obj = page.find(:css, obj_locator, :wait => 0.01, :visible => visible)
386
+ when :ignore_parent_xpath
387
+ type = :xpath
388
+ obj = page.find(:xpath, obj_locator, :wait => 0.01, :visible => visible)
389
+ end
390
+ else
391
+ obj = page.find(type, obj_locator, :wait => 0.01, :visible => visible)
392
+ end
393
+ [obj, type]
394
+ rescue
395
+ retry if (tries -= 1) > 0
396
+ [nil, nil]
397
+ end
398
+
399
+ def object_not_found_exception(obj, obj_type)
400
+ @alt_locator.nil? ? locator = @locator : locator = @alt_locator
401
+ obj_type.nil? ? object_type = 'Object' : object_type = obj_type
402
+ raise "#{object_type} named '#{@name}' (#{locator}) not found" unless obj
403
+ end
404
+
405
+ def invalid_object_type_exception(obj, obj_type)
406
+ unless obj.tag_name == obj_type || obj.native.attribute('type') == obj_type
407
+ @alt_locator.nil? ? locator = @locator : locator = @alt_locator
408
+ raise "#{locator} is not a #{obj_type} element"
409
+ end
410
+ end
411
+
412
+ def invoke_siebel_popup
413
+ obj, = find_element
414
+ object_not_found_exception(obj, 'Siebel object')
415
+ trigger_name = obj.native.attribute('aria-describedby').strip
416
+ trigger = "span##{trigger_name}"
417
+ trigger = "#{@parent.get_locator} #{trigger}" if @context == :section && !@parent.get_locator.nil?
418
+ first(trigger).click
419
+ end
420
+
421
+ def object_ref_message
422
+ "object '#{get_name}' (#{get_locator})"
423
+ end
424
+ end
425
+ 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