testcentricity 2.3.14 → 2.3.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 57c238014ed1bde365574c49dfd63c8e9716ea5e
4
- data.tar.gz: a6bbe0079660a63178e943152ebac311c710f9f5
3
+ metadata.gz: c527d51d9b0ba53c2c6f7358138def57dc66fde9
4
+ data.tar.gz: 80c832950b2faf935c688bdcab670a165337a014
5
5
  SHA512:
6
- metadata.gz: 0f758a336d3f13a2257a7661160f2019725b98ec108146e9ec2b4c3ae540608721d246ac0b4c559f227234aae2238815b9a08f11ebeb2ac637fed6530e17222e
7
- data.tar.gz: d06d2ffca2e97581347f713eefe91b5ed177ba350419c85f3b75dc549c04a507dd5da982db3f1e3800567df1adc42aa5d56f4112a921c5442f546e57147b6f9f
6
+ metadata.gz: f874c255a407a3b3204d7936d1450a939964ed214b5d20dc43962d957f379f7f5f9bba79c81aafae8bc4d661df3d7f49709f3667fbe4da89b58d799f6a18519f
7
+ data.tar.gz: 8cd9c7c077a5649f3ff477288b3fb49c4f66bad4b1b3db9c840b0babd321dd981aac664008e98068f418b0e7f18e38374d33c2ca7ecc9df6482eb959130160b6
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
- # TestCentricity™
1
+ # TestCentricity™ Web
2
2
 
3
- [![Gem Version](https://badge.fury.io/rb/testcentricity_web.svg)](https://badge.fury.io/rb/testcentricity_web) [![License (3-Clause BSD)](https://img.shields.io/badge/license-BSD%203--Clause-blue.svg?style=flat-square)](http://opensource.org/licenses/BSD-3-Clause)
3
+ [![Gem Version](https://badge.fury.io/rb/testcentricity.svg)](https://badge.fury.io/rb/testcentricity) [![License (3-Clause BSD)](https://img.shields.io/badge/license-BSD%203--Clause-blue.svg?style=flat-square)](http://opensource.org/licenses/BSD-3-Clause)
4
4
 
5
5
 
6
6
  The TestCentricity™ Web core generic framework for desktop and mobile web site testing implements a Page Object and Data Object Model DSL for
@@ -28,6 +28,14 @@ hosted instances of Chrome, Firefox, Safari, and IE web browsers.
28
28
 
29
29
 
30
30
  ## What's New
31
+ ###Version 2.3.16
32
+
33
+ * Added `PageSection.double_click`, `PageObject.right_click`, and `PageObject.send_keys` methods.
34
+
35
+ ###Version 2.3.15
36
+
37
+ * Added `PageObject.wait_until_exists` and `PageObject.wait_until_gone` methods.
38
+
31
39
  ###Version 2.3.14
32
40
 
33
41
  * Updated device profiles for iPhone 7 (iOS 10) with MS Edge browser.
@@ -132,6 +140,12 @@ use the [parallel_tests gem](https://rubygems.org/gems/parallel_tests) to decrea
132
140
 
133
141
 
134
142
  ## What's Fixed
143
+
144
+ ###Version 2.3.15
145
+
146
+ * Fixed bug in `UIElement.get_object_type` method that could result in a `NoMethodError obj not defined` error.
147
+ * Fixed bug in `PageObject.verify_ui_states` and `PageSection.verify_ui_states` methods that failed to enqueue errors when UI elements could not be found.
148
+
135
149
  ###Version 2.3.8
136
150
 
137
151
  * Fixed locator resolution for **Indexed PageSection Objects**.
@@ -77,7 +77,7 @@
77
77
  :css_width: 375
78
78
  :css_height: 667
79
79
  :default_orientation: portrait
80
- :user_agent: "Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_3 like Mac OS X) AppleWebKit/603.3.8 (KHTML, like Gecko) Version/10.0 EdgiOS/41.10.1.0 Mobile/14G60 Safari/603.3.8"
80
+ :user_agent: "Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_3 like Mac OS X) AppleWebKit/603.3.8 (KHTML, like Gecko) Version/10.0 EdgiOS/41.11.0.0 Mobile/14G60 Safari/603.3.8"
81
81
  :iphone8:
82
82
  :name: "iPhone 8"
83
83
  :os: ios
@@ -53,6 +53,7 @@ require 'testcentricity/app_elements/switch'
53
53
  require 'testcentricity/app_elements/textfield'
54
54
  require 'testcentricity/app_elements/list'
55
55
  require 'testcentricity/app_elements/image'
56
+ require 'testcentricity/app_elements/select_list'
56
57
  require 'testcentricity/app_elements/alert'
57
58
 
58
59
 
@@ -170,7 +170,7 @@ module TestCentricity
170
170
 
171
171
  def self.webview_context
172
172
  contexts = available_contexts
173
- set_context(contexts[1])
173
+ set_context(contexts.last)
174
174
  end
175
175
  end
176
176
  end
@@ -85,6 +85,16 @@ module TestCentricity
85
85
  end
86
86
  end
87
87
 
88
+ def self.selectlist(element_name, locator)
89
+ class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::AppSelectList.new("#{element_name}", self, #{locator}, :page);end))
90
+ end
91
+
92
+ def self.selectlists(element_hash)
93
+ element_hash.each do |element_name, locator|
94
+ selectlist(element_name, locator)
95
+ end
96
+ end
97
+
88
98
  def self.image(element_name, locator)
89
99
  class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::AppImage.new("#{element_name}", self, #{locator}, :page);end))
90
100
  end
@@ -138,6 +148,14 @@ module TestCentricity
138
148
  false
139
149
  end
140
150
 
151
+ def wait_until_exists(seconds = nil)
152
+ timeout = seconds.nil? ? Environ.default_max_wait_time : seconds
153
+ wait = Selenium::WebDriver::Wait.new(timeout: timeout)
154
+ wait.until { exists? }
155
+ rescue
156
+ raise "Screen object #{self.class.name} not found after #{timeout} seconds" unless exists?
157
+ end
158
+
141
159
  def wait_until_gone(seconds = nil)
142
160
  timeout = seconds.nil? ? Environ.default_max_wait_time : seconds
143
161
  wait = Selenium::WebDriver::Wait.new(timeout: timeout)
@@ -249,6 +267,9 @@ module TestCentricity
249
267
  end
250
268
  end
251
269
  end
270
+ rescue ObjectNotFoundError => e
271
+ ExceptionQueue.enqueue_exception(e.message)
272
+ ensure
252
273
  ExceptionQueue.post_exceptions
253
274
  end
254
275
 
@@ -146,6 +146,16 @@ module TestCentricity
146
146
  end
147
147
  end
148
148
 
149
+ def self.selectlist(element_name, locator)
150
+ class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::AppSelectList.new("#{element_name}", self, #{locator}, :section);end))
151
+ end
152
+
153
+ def self.selectlists(element_hash)
154
+ element_hash.each do |element_name, locator|
155
+ selectlist(element_name, locator)
156
+ end
157
+ end
158
+
149
159
  def self.image(element_name, locator)
150
160
  class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::AppImage.new("#{element_name}", self, #{locator}, :section);end))
151
161
  end
@@ -376,6 +386,9 @@ module TestCentricity
376
386
  end
377
387
  end
378
388
  end
389
+ rescue ObjectNotFoundError => e
390
+ ExceptionQueue.enqueue_exception(e.message)
391
+ ensure
379
392
  ExceptionQueue.post_exceptions
380
393
  end
381
394
 
@@ -331,7 +331,7 @@ module TestCentricity
331
331
 
332
332
  def object_not_found_exception(obj)
333
333
  @type.nil? ? object_type = 'Object' : object_type = @type
334
- raise "#{object_type} named '#{@name}' (#{get_locator}) not found" unless obj
334
+ raise ObjectNotFoundError.new("#{object_type} named '#{@name}' (#{get_locator}) not found") unless obj
335
335
  end
336
336
 
337
337
  def object_ref_message
@@ -0,0 +1,147 @@
1
+ module TestCentricity
2
+ class AppSelectList < UIElement
3
+ attr_accessor :list_item
4
+ attr_accessor :selected_item
5
+
6
+ def initialize(name, parent, locator, context)
7
+ super
8
+ @type = :selectlist
9
+ list_spec = {
10
+ :list_item => 'option',
11
+ :selected_item => 'option[selected]'
12
+ }
13
+ define_list_elements(list_spec)
14
+ end
15
+
16
+ def define_list_elements(element_spec)
17
+ element_spec.each do |element, value|
18
+ case element
19
+ when :list_item
20
+ @list_item = value
21
+ when :selected_item
22
+ @selected_item = value
23
+ else
24
+ raise "#{element} is not a recognized selectlist element"
25
+ end
26
+ end
27
+ end
28
+
29
+ # Select the specified option in a select box object. Accepts a String or Hash.
30
+ # Supports standard HTML select objects and Chosen select objects.
31
+ #
32
+ # @param option [String] text of option to select
33
+ # OR
34
+ # @param option [Hash] :value, :index, or :text of option to select
35
+ #
36
+ # @example
37
+ # province_select.choose_option('Alberta')
38
+ # province_select.choose_option(:value => 'AB')
39
+ # state_select.choose_option(:index => 24)
40
+ # state_select.choose_option(:text => 'Maryland')
41
+ #
42
+ def choose_option(option)
43
+ obj, = find_element
44
+ object_not_found_exception(obj, nil)
45
+ obj.click
46
+ if first(:css, "li[class*='active-result']")
47
+ if option.is_a?(Array)
48
+ option.each do |item|
49
+ page.find(:css, "li[class*='active-result']", text: item.strip).click
50
+ end
51
+ else
52
+ if option.is_a?(Hash)
53
+ page.find(:css, "li[class*='active-result']:nth-of-type(#{option[:index]})").click if option.has_key?(:index)
54
+ else
55
+ options = obj.all("li[class*='active-result']").collect(&:text)
56
+ sleep(2) unless options.include?(option)
57
+ first(:css, "li[class*='active-result']", text: option).click
58
+ end
59
+ end
60
+ else
61
+ if option.is_a?(Array)
62
+ option.each do |item|
63
+ select_item(obj, item)
64
+ end
65
+ else
66
+ select_item(obj, option)
67
+ end
68
+ end
69
+ end
70
+
71
+ # Return array of strings of all options in a select box object.
72
+ # Supports standard HTML select objects and Chosen select objects.
73
+ #
74
+ # @return [Array]
75
+ # @example
76
+ # all_colors = color_select.get_options
77
+ #
78
+ def get_options
79
+ obj, = find_element
80
+ object_not_found_exception(obj, nil)
81
+ if first(:css, "li[class*='active-result']")
82
+ obj.all("li[class*='active-result']").collect(&:text)
83
+ else
84
+ obj.all(@list_item).collect(&:text)
85
+ end
86
+ end
87
+
88
+ alias get_list_items get_options
89
+
90
+ # Return the number of options in a select box object.
91
+ # Supports standard HTML select objects and Chosen select objects.
92
+ #
93
+ # @return [Integer]
94
+ # @example
95
+ # num_colors = color_select.get_option_count
96
+ #
97
+ def get_option_count
98
+ obj, = find_element
99
+ object_not_found_exception(obj, nil)
100
+ if first(:css, "li[class*='active-result']")
101
+ obj.all("li[class*='active-result']").count
102
+ else
103
+ obj.all(@list_item).count
104
+ end
105
+ end
106
+
107
+ alias get_item_count get_option_count
108
+
109
+ def verify_options(expected, enqueue = false)
110
+ actual = get_options
111
+ enqueue ?
112
+ ExceptionQueue.enqueue_assert_equal(expected, actual, "Expected list of options in list #{object_ref_message}") :
113
+ assert_equal(expected, actual, "Expected list of options in list #{object_ref_message} to be #{expected} but found #{actual}")
114
+ end
115
+
116
+ # Return text of first selected option in a select box object.
117
+ # Supports standard HTML select objects and Chosen select objects.
118
+ #
119
+ # @return [String]
120
+ # @example
121
+ # current_color = color_select.get_selected_option
122
+ #
123
+ def get_selected_option
124
+ obj, = find_element
125
+ object_not_found_exception(obj, nil)
126
+ if first(:css, "li[class*='active-result']")
127
+ obj.first(:css, "li[class*='result-selected']").text
128
+ else
129
+ obj.first(@selected_item).text
130
+ end
131
+ end
132
+
133
+ alias selected? get_selected_option
134
+
135
+ private
136
+
137
+ def select_item(obj, option)
138
+ if option.is_a?(Hash)
139
+ obj.find("option[value='#{option[:value]}']").click if option.has_key?(:value)
140
+ obj.find(:xpath, "option[#{option[:index]}]").select_option if option.has_key?(:index)
141
+ obj.select option[:text] if option.has_key?(:text)
142
+ else
143
+ obj.select option
144
+ end
145
+ end
146
+ end
147
+ end
@@ -48,4 +48,11 @@ module TestCentricity
48
48
  Environ.save_screen_shot(screen_shot)
49
49
  end
50
50
  end
51
+
52
+
53
+ class ObjectNotFoundError < StandardError
54
+ def initialize(message)
55
+ super(message)
56
+ end
57
+ end
51
58
  end
@@ -1,3 +1,3 @@
1
1
  module TestCentricity
2
- VERSION = '2.3.14'
2
+ VERSION = '2.3.16'
3
3
  end
@@ -458,6 +458,36 @@ module TestCentricity
458
458
  Capybara.default_max_wait_time = saved_wait_time
459
459
  end
460
460
 
461
+ # Wait until the page object exists, or until the specified wait time has expired. If the wait time is nil, then the wait
462
+ # time will be Capybara.default_max_wait_time.
463
+ #
464
+ # @param seconds [Integer or Float] wait time in seconds
465
+ # @example
466
+ # home_page.wait_until_exists(15)
467
+ #
468
+ def wait_until_exists(seconds = nil)
469
+ timeout = seconds.nil? ? Capybara.default_max_wait_time : seconds
470
+ wait = Selenium::WebDriver::Wait.new(timeout: timeout)
471
+ wait.until { exists? }
472
+ rescue
473
+ raise "Page object #{self.class.name} not found after #{timeout} seconds" unless exists?
474
+ end
475
+
476
+ # Wait until the page object no longer exists, or until the specified wait time has expired. If the wait time is nil, then
477
+ # the wait time will be Capybara.default_max_wait_time.
478
+ #
479
+ # @param seconds [Integer or Float] wait time in seconds
480
+ # @example
481
+ # verifying_page.wait_until_gone(15)
482
+ #
483
+ def wait_until_gone(seconds = nil)
484
+ timeout = seconds.nil? ? Capybara.default_max_wait_time : seconds
485
+ wait = Selenium::WebDriver::Wait.new(timeout: timeout)
486
+ wait.until { !exists? }
487
+ rescue
488
+ raise "Page object #{self.class.name} remained visible after #{timeout} seconds" if exists?
489
+ end
490
+
461
491
  # Is current Page object URL secure?
462
492
  #
463
493
  # @return [Boolean]
@@ -472,137 +502,137 @@ module TestCentricity
472
502
  ui_states.each do |ui_object, object_states|
473
503
  object_states.each do |property, state|
474
504
  case property
475
- when :class
476
- actual = ui_object.get_attribute(:class)
477
- when :exists
478
- actual = ui_object.exists?
479
- when :enabled
480
- actual = ui_object.enabled?
481
- when :disabled
482
- actual = ui_object.disabled?
483
- when :visible
484
- actual = ui_object.visible?
485
- when :hidden
486
- actual = ui_object.hidden?
487
- when :displayed
488
- actual = ui_object.displayed?
489
- when :width
490
- actual = ui_object.width
491
- when :height
492
- actual = ui_object.height
493
- when :x
494
- actual = ui_object.x
495
- when :y
496
- actual = ui_object.y
497
- when :readonly
498
- actual = ui_object.read_only?
499
- when :checked
500
- actual = ui_object.checked?
501
- when :selected
502
- actual = ui_object.selected?
503
- when :value, :caption
504
- actual = ui_object.get_value
505
- when :maxlength
506
- actual = ui_object.get_max_length
507
- when :rowcount
508
- actual = ui_object.get_row_count
509
- when :columncount
510
- actual = ui_object.get_column_count
511
- when :placeholder
512
- actual = ui_object.get_placeholder
513
- when :min
514
- actual = ui_object.get_min
515
- when :max
516
- actual = ui_object.get_max
517
- when :step
518
- actual = ui_object.get_step
519
- when :options, :items, :list_items
520
- actual = ui_object.get_list_items
521
- when :optioncount, :itemcount
522
- actual = ui_object.get_item_count
523
- when :all_items, :all_list_items
524
- actual = ui_object.get_all_list_items
525
- when :all_items_count
526
- actual = ui_object.get_all_items_count
527
- when :column_headers
528
- actual = ui_object.get_header_columns
529
- when :siebel_options
530
- actual = ui_object.get_siebel_options
531
- else
532
- if property.is_a?(Hash)
533
- property.each do |key, value|
534
- case key
535
- when :cell
536
- actual = ui_object.get_table_cell(value[0].to_i, value[1].to_i)
537
- when :row
538
- actual = ui_object.get_table_row(value.to_i)
539
- when :column
540
- actual = ui_object.get_table_column(value.to_i)
541
- when :item
542
- actual = ui_object.get_list_item(value.to_i)
543
- when :attribute
544
- actual = ui_object.get_attribute(value)
545
- when :native_attribute
546
- actual = ui_object.get_native_attribute(value)
547
- end
548
- end
505
+ when :class
506
+ actual = ui_object.get_attribute(:class)
507
+ when :exists
508
+ actual = ui_object.exists?
509
+ when :enabled
510
+ actual = ui_object.enabled?
511
+ when :disabled
512
+ actual = ui_object.disabled?
513
+ when :visible
514
+ actual = ui_object.visible?
515
+ when :hidden
516
+ actual = ui_object.hidden?
517
+ when :displayed
518
+ actual = ui_object.displayed?
519
+ when :width
520
+ actual = ui_object.width
521
+ when :height
522
+ actual = ui_object.height
523
+ when :x
524
+ actual = ui_object.x
525
+ when :y
526
+ actual = ui_object.y
527
+ when :readonly
528
+ actual = ui_object.read_only?
529
+ when :checked
530
+ actual = ui_object.checked?
531
+ when :selected
532
+ actual = ui_object.selected?
533
+ when :value, :caption
534
+ actual = ui_object.get_value
535
+ when :maxlength
536
+ actual = ui_object.get_max_length
537
+ when :rowcount
538
+ actual = ui_object.get_row_count
539
+ when :columncount
540
+ actual = ui_object.get_column_count
541
+ when :placeholder
542
+ actual = ui_object.get_placeholder
543
+ when :min
544
+ actual = ui_object.get_min
545
+ when :max
546
+ actual = ui_object.get_max
547
+ when :step
548
+ actual = ui_object.get_step
549
+ when :options, :items, :list_items
550
+ actual = ui_object.get_list_items
551
+ when :optioncount, :itemcount
552
+ actual = ui_object.get_item_count
553
+ when :all_items, :all_list_items
554
+ actual = ui_object.get_all_list_items
555
+ when :all_items_count
556
+ actual = ui_object.get_all_items_count
557
+ when :column_headers
558
+ actual = ui_object.get_header_columns
559
+ when :siebel_options
560
+ actual = ui_object.get_siebel_options
549
561
  else
550
- props = property.to_s.split('_')
551
- case props[0].to_sym
552
- when :cell
553
- cell = property.to_s.delete('cell_')
554
- cell = cell.split('_')
555
- actual = ui_object.get_table_cell(cell[0].to_i, cell[1].to_i)
556
- when :row
557
- row = property.to_s.delete('row_')
558
- actual = ui_object.get_table_row(row.to_i)
559
- when :column
560
- column = property.to_s.delete('column_')
561
- actual = ui_object.get_table_column(column.to_i)
562
- when :item
563
- item = property.to_s.delete('item_')
564
- actual = ui_object.get_list_item(item.to_i)
562
+ if property.is_a?(Hash)
563
+ property.each do |key, value|
564
+ case key
565
+ when :cell
566
+ actual = ui_object.get_table_cell(value[0].to_i, value[1].to_i)
567
+ when :row
568
+ actual = ui_object.get_table_row(value.to_i)
569
+ when :column
570
+ actual = ui_object.get_table_column(value.to_i)
571
+ when :item
572
+ actual = ui_object.get_list_item(value.to_i)
573
+ when :attribute
574
+ actual = ui_object.get_attribute(value)
575
+ when :native_attribute
576
+ actual = ui_object.get_native_attribute(value)
577
+ end
578
+ end
579
+ else
580
+ props = property.to_s.split('_')
581
+ case props[0].to_sym
582
+ when :cell
583
+ cell = property.to_s.delete('cell_')
584
+ cell = cell.split('_')
585
+ actual = ui_object.get_table_cell(cell[0].to_i, cell[1].to_i)
586
+ when :row
587
+ row = property.to_s.delete('row_')
588
+ actual = ui_object.get_table_row(row.to_i)
589
+ when :column
590
+ column = property.to_s.delete('column_')
591
+ actual = ui_object.get_table_column(column.to_i)
592
+ when :item
593
+ item = property.to_s.delete('item_')
594
+ actual = ui_object.get_list_item(item.to_i)
595
+ end
565
596
  end
566
- end
567
597
  end
568
598
 
569
599
  if state.is_a?(Hash) && state.length == 1
570
600
  error_msg = "Expected UI object '#{ui_object.get_name}' (#{ui_object.get_locator}) #{property} property to"
571
601
  state.each do |key, value|
572
602
  case key
573
- when :lt, :less_than
574
- ExceptionQueue.enqueue_exception("#{error_msg} be less than #{value} but found '#{actual}'") unless actual < value
575
- when :lt_eq, :less_than_or_equal
576
- ExceptionQueue.enqueue_exception("#{error_msg} be less than or equal to #{value} but found '#{actual}'") unless actual <= value
577
- when :gt, :greater_than
578
- ExceptionQueue.enqueue_exception("#{error_msg} be greater than #{value} but found '#{actual}'") unless actual > value
579
- when :gt_eq, :greater_than_or_equal
580
- ExceptionQueue.enqueue_exception("#{error_msg} be greater than or equal to #{value} but found '#{actual}'") unless actual >= value
581
- when :starts_with
582
- ExceptionQueue.enqueue_exception("#{error_msg} start with '#{value}' but found '#{actual}'") unless actual.start_with?(value)
583
- when :ends_with
584
- ExceptionQueue.enqueue_exception("#{error_msg} end with '#{value}' but found '#{actual}'") unless actual.end_with?(value)
585
- when :contains
586
- ExceptionQueue.enqueue_exception("#{error_msg} contain '#{value}' but found '#{actual}'") unless actual.include?(value)
587
- when :not_contains, :does_not_contain
588
- ExceptionQueue.enqueue_exception("#{error_msg} not contain '#{value}' but found '#{actual}'") if actual.include?(value)
589
- when :not_equal
590
- ExceptionQueue.enqueue_exception("#{error_msg} not equal '#{value}' but found '#{actual}'") if actual == value
591
- when :like, :is_like
592
- actual_like = actual.delete("\n")
593
- actual_like = actual_like.delete("\r")
594
- actual_like = actual_like.delete("\t")
595
- actual_like = actual_like.delete(' ')
596
- actual_like = actual_like.downcase
597
- expected = value.delete("\n")
598
- expected = expected.delete("\r")
599
- expected = expected.delete("\t")
600
- expected = expected.delete(' ')
601
- expected = expected.downcase
602
- ExceptionQueue.enqueue_exception("#{error_msg} be like '#{value}' but found '#{actual}'") unless actual_like.include?(expected)
603
- when :translate
604
- expected = I18n.t(value)
605
- ExceptionQueue.enqueue_assert_equal(expected, actual, "Expected UI object '#{ui_object.get_name}' (#{ui_object.get_locator}) translated #{property} property")
603
+ when :lt, :less_than
604
+ ExceptionQueue.enqueue_exception("#{error_msg} be less than #{value} but found '#{actual}'") unless actual < value
605
+ when :lt_eq, :less_than_or_equal
606
+ ExceptionQueue.enqueue_exception("#{error_msg} be less than or equal to #{value} but found '#{actual}'") unless actual <= value
607
+ when :gt, :greater_than
608
+ ExceptionQueue.enqueue_exception("#{error_msg} be greater than #{value} but found '#{actual}'") unless actual > value
609
+ when :gt_eq, :greater_than_or_equal
610
+ ExceptionQueue.enqueue_exception("#{error_msg} be greater than or equal to #{value} but found '#{actual}'") unless actual >= value
611
+ when :starts_with
612
+ ExceptionQueue.enqueue_exception("#{error_msg} start with '#{value}' but found '#{actual}'") unless actual.start_with?(value)
613
+ when :ends_with
614
+ ExceptionQueue.enqueue_exception("#{error_msg} end with '#{value}' but found '#{actual}'") unless actual.end_with?(value)
615
+ when :contains
616
+ ExceptionQueue.enqueue_exception("#{error_msg} contain '#{value}' but found '#{actual}'") unless actual.include?(value)
617
+ when :not_contains, :does_not_contain
618
+ ExceptionQueue.enqueue_exception("#{error_msg} not contain '#{value}' but found '#{actual}'") if actual.include?(value)
619
+ when :not_equal
620
+ ExceptionQueue.enqueue_exception("#{error_msg} not equal '#{value}' but found '#{actual}'") if actual == value
621
+ when :like, :is_like
622
+ actual_like = actual.delete("\n")
623
+ actual_like = actual_like.delete("\r")
624
+ actual_like = actual_like.delete("\t")
625
+ actual_like = actual_like.delete(' ')
626
+ actual_like = actual_like.downcase
627
+ expected = value.delete("\n")
628
+ expected = expected.delete("\r")
629
+ expected = expected.delete("\t")
630
+ expected = expected.delete(' ')
631
+ expected = expected.downcase
632
+ ExceptionQueue.enqueue_exception("#{error_msg} be like '#{value}' but found '#{actual}'") unless actual_like.include?(expected)
633
+ when :translate
634
+ expected = I18n.t(value)
635
+ ExceptionQueue.enqueue_assert_equal(expected, actual, "Expected UI object '#{ui_object.get_name}' (#{ui_object.get_locator}) translated #{property} property")
606
636
  end
607
637
  end
608
638
  else
@@ -610,6 +640,9 @@ module TestCentricity
610
640
  end
611
641
  end
612
642
  end
643
+ rescue ObjectNotFoundError => e
644
+ ExceptionQueue.enqueue_exception(e.message)
645
+ ensure
613
646
  ExceptionQueue.post_exceptions
614
647
  end
615
648
 
@@ -648,18 +681,18 @@ module TestCentricity
648
681
  data_field.clear
649
682
  else
650
683
  case data_field.get_object_type
651
- when :checkbox
652
- data_field.set_checkbox_state(data_param.to_bool)
653
- when :selectlist
654
- data_field.get_siebel_object_type == 'JComboBox' ?
655
- data_field.set("#{data_param}\t") :
656
- data_field.choose_option(data_param)
657
- when :radio
658
- data_field.set_selected_state(data_param.to_bool)
659
- when :textfield
660
- data_field.set("#{data_param}\t")
661
- when :section
662
- data_field.set(data_param)
684
+ when :checkbox
685
+ data_field.set_checkbox_state(data_param.to_bool)
686
+ when :selectlist
687
+ data_field.get_siebel_object_type == 'JComboBox' ?
688
+ data_field.set("#{data_param}\t") :
689
+ data_field.choose_option(data_param)
690
+ when :radio
691
+ data_field.set_selected_state(data_param.to_bool)
692
+ when :textfield
693
+ data_field.set("#{data_param}\t")
694
+ when :section
695
+ data_field.set(data_param)
663
696
  end
664
697
  end
665
698
  end
@@ -48,10 +48,10 @@ module TestCentricity
48
48
  locator = "#{@parent_list.get_locator}|#{locator}"
49
49
  unless @list_index.nil?
50
50
  case @locator_type
51
- when :xpath
52
- locator = "(#{locator})[#{@list_index}]"
53
- when :css
54
- locator = "#{locator}:nth-of-type(#{@list_index})"
51
+ when :xpath
52
+ locator = "(#{locator})[#{@list_index}]"
53
+ when :css
54
+ locator = "#{locator}:nth-of-type(#{@list_index})"
55
55
  end
56
56
  end
57
57
  end
@@ -527,7 +527,7 @@ module TestCentricity
527
527
  #
528
528
  def disabled?
529
529
  section, = find_section
530
- raise "Section object '#{get_name}' (#{get_locator}) not found" unless section
530
+ section_not_found_exception(section)
531
531
  section.disabled?
532
532
  end
533
533
 
@@ -564,7 +564,7 @@ module TestCentricity
564
564
  #
565
565
  def displayed?
566
566
  section, = find_section
567
- raise "Section object '#{get_name}' (#{get_locator}) not found" unless section
567
+ section_not_found_exception(section)
568
568
  section.displayed?
569
569
  end
570
570
 
@@ -628,6 +628,43 @@ module TestCentricity
628
628
  raise "Section object '#{get_name}' (#{get_locator}) remained visible after #{timeout} seconds" if visible?
629
629
  end
630
630
 
631
+ # Click on a Section object
632
+ #
633
+ # @example
634
+ # bar_chart_section.click
635
+ #
636
+ def click
637
+ section, = find_section
638
+ section_not_found_exception(section)
639
+ begin
640
+ section.click
641
+ rescue
642
+ section.click_at(10, 10) unless Capybara.current_driver == :poltergeist
643
+ end
644
+ end
645
+
646
+ # Double-click on a Section object
647
+ #
648
+ # @example
649
+ # bar_chart_section.double_click
650
+ #
651
+ def double_click
652
+ section, = find_section
653
+ section_not_found_exception(section)
654
+ page.driver.browser.action.double_click(section.native).perform
655
+ end
656
+
657
+ # Right-click on a Section object
658
+ #
659
+ # @example
660
+ # bar_chart_section.right_click
661
+ #
662
+ def right_click
663
+ section, = find_section
664
+ section_not_found_exception(section)
665
+ page.driver.browser.action.context_click(section.native).perform
666
+ end
667
+
631
668
  # Click at a specific location within a Section object
632
669
  #
633
670
  # @param x [Integer] X offset
@@ -637,145 +674,157 @@ module TestCentricity
637
674
  #
638
675
  def click_at(x, y)
639
676
  section, = find_section
640
- raise "Section object '#{get_name}' (#{get_locator}) not found" unless section
677
+ section_not_found_exception(section)
641
678
  section.click_at(x, y)
642
679
  end
643
680
 
681
+ # Send keystrokes to a Section object
682
+ #
683
+ # @param keys [String] keys
684
+ # @example
685
+ # bar_chart_section.send_keys(:enter)
686
+ #
687
+ def send_keys(*keys)
688
+ section, = find_section
689
+ section_not_found_exception(section)
690
+ section.send_keys(*keys)
691
+ end
692
+
644
693
  def verify_ui_states(ui_states)
645
694
  ui_states.each do |ui_object, object_states|
646
695
  object_states.each do |property, state|
647
696
  case property
648
- when :class
649
- actual = ui_object.get_attribute(:class)
650
- when :exists
651
- actual = ui_object.exists?
652
- when :enabled
653
- actual = ui_object.enabled?
654
- when :disabled
655
- actual = ui_object.disabled?
656
- when :visible
657
- actual = ui_object.visible?
658
- when :hidden
659
- actual = ui_object.hidden?
660
- when :displayed
661
- actual = ui_object.displayed?
662
- when :width
663
- actual = ui_object.width
664
- when :height
665
- actual = ui_object.height
666
- when :x
667
- actual = ui_object.x
668
- when :y
669
- actual = ui_object.y
670
- when :readonly
671
- actual = ui_object.read_only?
672
- when :checked
673
- actual = ui_object.checked?
674
- when :selected
675
- actual = ui_object.selected?
676
- when :value, :caption
677
- actual = ui_object.get_value
678
- when :maxlength
679
- actual = ui_object.get_max_length
680
- when :rowcount
681
- actual = ui_object.get_row_count
682
- when :columncount
683
- actual = ui_object.get_column_count
684
- when :placeholder
685
- actual = ui_object.get_placeholder
686
- when :min
687
- actual = ui_object.get_min
688
- when :max
689
- actual = ui_object.get_max
690
- when :step
691
- actual = ui_object.get_step
692
- when :options, :items, :list_items
693
- actual = ui_object.get_list_items
694
- when :optioncount, :itemcount
695
- actual = ui_object.get_item_count
696
- when :all_items, :all_list_items
697
- actual = ui_object.get_all_list_items
698
- when :all_items_count
699
- actual = ui_object.get_all_items_count
700
- when :column_headers
701
- actual = ui_object.get_header_columns
702
- when :siebel_options
703
- actual = ui_object.get_siebel_options
704
- else
705
- if property.is_a?(Hash)
706
- property.each do |key, value|
707
- case key
708
- when :cell
709
- actual = ui_object.get_table_cell(value[0].to_i, value[1].to_i)
710
- when :row
711
- actual = ui_object.get_table_row(value.to_i)
712
- when :column
713
- actual = ui_object.get_table_column(value.to_i)
714
- when :item
715
- actual = ui_object.get_list_item(value.to_i)
716
- when :attribute
717
- actual = ui_object.get_attribute(value)
718
- when :native_attribute
719
- actual = ui_object.get_native_attribute(value)
720
- end
721
- end
697
+ when :class
698
+ actual = ui_object.get_attribute(:class)
699
+ when :exists
700
+ actual = ui_object.exists?
701
+ when :enabled
702
+ actual = ui_object.enabled?
703
+ when :disabled
704
+ actual = ui_object.disabled?
705
+ when :visible
706
+ actual = ui_object.visible?
707
+ when :hidden
708
+ actual = ui_object.hidden?
709
+ when :displayed
710
+ actual = ui_object.displayed?
711
+ when :width
712
+ actual = ui_object.width
713
+ when :height
714
+ actual = ui_object.height
715
+ when :x
716
+ actual = ui_object.x
717
+ when :y
718
+ actual = ui_object.y
719
+ when :readonly
720
+ actual = ui_object.read_only?
721
+ when :checked
722
+ actual = ui_object.checked?
723
+ when :selected
724
+ actual = ui_object.selected?
725
+ when :value, :caption
726
+ actual = ui_object.get_value
727
+ when :maxlength
728
+ actual = ui_object.get_max_length
729
+ when :rowcount
730
+ actual = ui_object.get_row_count
731
+ when :columncount
732
+ actual = ui_object.get_column_count
733
+ when :placeholder
734
+ actual = ui_object.get_placeholder
735
+ when :min
736
+ actual = ui_object.get_min
737
+ when :max
738
+ actual = ui_object.get_max
739
+ when :step
740
+ actual = ui_object.get_step
741
+ when :options, :items, :list_items
742
+ actual = ui_object.get_list_items
743
+ when :optioncount, :itemcount
744
+ actual = ui_object.get_item_count
745
+ when :all_items, :all_list_items
746
+ actual = ui_object.get_all_list_items
747
+ when :all_items_count
748
+ actual = ui_object.get_all_items_count
749
+ when :column_headers
750
+ actual = ui_object.get_header_columns
751
+ when :siebel_options
752
+ actual = ui_object.get_siebel_options
722
753
  else
723
- props = property.to_s.split('_')
724
- case props[0].to_sym
725
- when :cell
726
- cell = property.to_s.delete('cell_')
727
- cell = cell.split('_')
728
- actual = ui_object.get_table_cell(cell[0].to_i, cell[1].to_i)
729
- when :row
730
- row = property.to_s.delete('row_')
731
- actual = ui_object.get_table_row(row.to_i)
732
- when :column
733
- column = property.to_s.delete('column_')
734
- actual = ui_object.get_table_column(column.to_i)
735
- when :item
736
- item = property.to_s.delete('item_')
737
- actual = ui_object.get_list_item(item.to_i)
754
+ if property.is_a?(Hash)
755
+ property.each do |key, value|
756
+ case key
757
+ when :cell
758
+ actual = ui_object.get_table_cell(value[0].to_i, value[1].to_i)
759
+ when :row
760
+ actual = ui_object.get_table_row(value.to_i)
761
+ when :column
762
+ actual = ui_object.get_table_column(value.to_i)
763
+ when :item
764
+ actual = ui_object.get_list_item(value.to_i)
765
+ when :attribute
766
+ actual = ui_object.get_attribute(value)
767
+ when :native_attribute
768
+ actual = ui_object.get_native_attribute(value)
769
+ end
770
+ end
771
+ else
772
+ props = property.to_s.split('_')
773
+ case props[0].to_sym
774
+ when :cell
775
+ cell = property.to_s.delete('cell_')
776
+ cell = cell.split('_')
777
+ actual = ui_object.get_table_cell(cell[0].to_i, cell[1].to_i)
778
+ when :row
779
+ row = property.to_s.delete('row_')
780
+ actual = ui_object.get_table_row(row.to_i)
781
+ when :column
782
+ column = property.to_s.delete('column_')
783
+ actual = ui_object.get_table_column(column.to_i)
784
+ when :item
785
+ item = property.to_s.delete('item_')
786
+ actual = ui_object.get_list_item(item.to_i)
787
+ end
738
788
  end
739
- end
740
789
  end
741
790
 
742
791
  if state.is_a?(Hash) && state.length == 1
743
792
  error_msg = "Expected UI object '#{ui_object.get_name}' (#{ui_object.get_locator}) #{property} property to"
744
793
  state.each do |key, value|
745
794
  case key
746
- when :lt, :less_than
747
- ExceptionQueue.enqueue_exception("#{error_msg} be less than #{value} but found '#{actual}'") unless actual < value
748
- when :lt_eq, :less_than_or_equal
749
- ExceptionQueue.enqueue_exception("#{error_msg} be less than or equal to #{value} but found '#{actual}'") unless actual <= value
750
- when :gt, :greater_than
751
- ExceptionQueue.enqueue_exception("#{error_msg} be greater than #{value} but found '#{actual}'") unless actual > value
752
- when :gt_eq, :greater_than_or_equal
753
- ExceptionQueue.enqueue_exception("#{error_msg} be greater than or equal to #{value} but found '#{actual}'") unless actual >= value
754
- when :starts_with
755
- ExceptionQueue.enqueue_exception("#{error_msg} start with '#{value}' but found '#{actual}'") unless actual.start_with?(value)
756
- when :ends_with
757
- ExceptionQueue.enqueue_exception("#{error_msg} end with '#{value}' but found '#{actual}'") unless actual.end_with?(value)
758
- when :contains
759
- ExceptionQueue.enqueue_exception("#{error_msg} contain '#{value}' but found '#{actual}'") unless actual.include?(value)
760
- when :not_contains, :does_not_contain
761
- ExceptionQueue.enqueue_exception("#{error_msg} not contain '#{value}' but found '#{actual}'") if actual.include?(value)
762
- when :not_equal
763
- ExceptionQueue.enqueue_exception("#{error_msg} not equal '#{value}' but found '#{actual}'") if actual == value
764
- when :like, :is_like
765
- actual_like = actual.delete("\n")
766
- actual_like = actual_like.delete("\r")
767
- actual_like = actual_like.delete("\t")
768
- actual_like = actual_like.delete(' ')
769
- actual_like = actual_like.downcase
770
- expected = value.delete("\n")
771
- expected = expected.delete("\r")
772
- expected = expected.delete("\t")
773
- expected = expected.delete(' ')
774
- expected = expected.downcase
775
- ExceptionQueue.enqueue_exception("#{error_msg} be like '#{value}' but found '#{actual}'") unless actual_like.include?(expected)
776
- when :translate
777
- expected = I18n.t(value)
778
- ExceptionQueue.enqueue_assert_equal(expected, actual, "Expected UI object '#{ui_object.get_name}' (#{ui_object.get_locator}) translated #{property} property")
795
+ when :lt, :less_than
796
+ ExceptionQueue.enqueue_exception("#{error_msg} be less than #{value} but found '#{actual}'") unless actual < value
797
+ when :lt_eq, :less_than_or_equal
798
+ ExceptionQueue.enqueue_exception("#{error_msg} be less than or equal to #{value} but found '#{actual}'") unless actual <= value
799
+ when :gt, :greater_than
800
+ ExceptionQueue.enqueue_exception("#{error_msg} be greater than #{value} but found '#{actual}'") unless actual > value
801
+ when :gt_eq, :greater_than_or_equal
802
+ ExceptionQueue.enqueue_exception("#{error_msg} be greater than or equal to #{value} but found '#{actual}'") unless actual >= value
803
+ when :starts_with
804
+ ExceptionQueue.enqueue_exception("#{error_msg} start with '#{value}' but found '#{actual}'") unless actual.start_with?(value)
805
+ when :ends_with
806
+ ExceptionQueue.enqueue_exception("#{error_msg} end with '#{value}' but found '#{actual}'") unless actual.end_with?(value)
807
+ when :contains
808
+ ExceptionQueue.enqueue_exception("#{error_msg} contain '#{value}' but found '#{actual}'") unless actual.include?(value)
809
+ when :not_contains, :does_not_contain
810
+ ExceptionQueue.enqueue_exception("#{error_msg} not contain '#{value}' but found '#{actual}'") if actual.include?(value)
811
+ when :not_equal
812
+ ExceptionQueue.enqueue_exception("#{error_msg} not equal '#{value}' but found '#{actual}'") if actual == value
813
+ when :like, :is_like
814
+ actual_like = actual.delete("\n")
815
+ actual_like = actual_like.delete("\r")
816
+ actual_like = actual_like.delete("\t")
817
+ actual_like = actual_like.delete(' ')
818
+ actual_like = actual_like.downcase
819
+ expected = value.delete("\n")
820
+ expected = expected.delete("\r")
821
+ expected = expected.delete("\t")
822
+ expected = expected.delete(' ')
823
+ expected = expected.downcase
824
+ ExceptionQueue.enqueue_exception("#{error_msg} be like '#{value}' but found '#{actual}'") unless actual_like.include?(expected)
825
+ when :translate
826
+ expected = I18n.t(value)
827
+ ExceptionQueue.enqueue_assert_equal(expected, actual, "Expected UI object '#{ui_object.get_name}' (#{ui_object.get_locator}) translated #{property} property")
779
828
  end
780
829
  end
781
830
  else
@@ -783,6 +832,9 @@ module TestCentricity
783
832
  end
784
833
  end
785
834
  end
835
+ rescue ObjectNotFoundError => e
836
+ ExceptionQueue.enqueue_exception(e.message)
837
+ ensure
786
838
  ExceptionQueue.post_exceptions
787
839
  end
788
840
 
@@ -822,18 +874,18 @@ module TestCentricity
822
874
  data_field.clear
823
875
  else
824
876
  case data_field.get_object_type
825
- when :checkbox
826
- data_field.set_checkbox_state(data_param.to_bool)
827
- when :selectlist
828
- data_field.get_siebel_object_type == 'JComboBox' ?
829
- data_field.set("#{data_param}\t") :
830
- data_field.choose_option(data_param)
831
- when :radio
832
- data_field.set_selected_state(data_param.to_bool)
833
- when :textfield
834
- data_field.set("#{data_param}\t")
835
- when :section
836
- data_field.set(data_param)
877
+ when :checkbox
878
+ data_field.set_checkbox_state(data_param.to_bool)
879
+ when :selectlist
880
+ data_field.get_siebel_object_type == 'JComboBox' ?
881
+ data_field.set("#{data_param}\t") :
882
+ data_field.choose_option(data_param)
883
+ when :radio
884
+ data_field.set_selected_state(data_param.to_bool)
885
+ when :textfield
886
+ data_field.set("#{data_param}\t")
887
+ when :section
888
+ data_field.set(data_param)
837
889
  end
838
890
  end
839
891
  end
@@ -842,13 +894,13 @@ module TestCentricity
842
894
 
843
895
  def get_attribute(attrib)
844
896
  section, = find_section
845
- raise "Section object '#{get_name}' (#{get_locator}) not found" unless section
897
+ section_not_found_exception(section)
846
898
  section[attrib]
847
899
  end
848
900
 
849
901
  def get_native_attribute(attrib)
850
902
  section, = find_section
851
- raise "Section object '#{get_name}' (#{get_locator}) not found" unless section
903
+ section_not_found_exception(section)
852
904
  section.native.attribute(attrib)
853
905
  end
854
906
 
@@ -862,5 +914,10 @@ module TestCentricity
862
914
  rescue
863
915
  [nil, nil]
864
916
  end
917
+
918
+ def section_not_found_exception(section)
919
+ raise ObjectNotFoundError.new("Section object '#{get_name}' (#{get_locator}) not found") unless section
920
+ end
921
+
865
922
  end
866
923
  end
@@ -68,10 +68,14 @@ module TestCentricity
68
68
  def get_object_type
69
69
  if @type
70
70
  @type
71
- elsif obj.tag_name
72
- obj.tag_name
73
- elsif obj.native.attribute('type')
74
- obj.native.attribute('type')
71
+ else
72
+ obj, type = find_element
73
+ object_not_found_exception(obj, type)
74
+ if obj.tag_name
75
+ obj.tag_name
76
+ elsif obj.native.attribute('type')
77
+ obj.native.attribute('type')
78
+ end
75
79
  end
76
80
  end
77
81
 
@@ -150,7 +154,7 @@ module TestCentricity
150
154
  # Send keystrokes to this object.
151
155
  #
152
156
  # @param keys [String] keys
153
- # @example
157
+ # @example
154
158
  # comment_field.send_keys(:enter)
155
159
  #
156
160
  def send_keys(*keys)
@@ -389,10 +393,10 @@ module TestCentricity
389
393
  obj, type = find_element(visible)
390
394
  object_not_found_exception(obj, type)
391
395
  case obj.tag_name.downcase
392
- when 'input', 'select', 'textarea'
393
- obj.value
394
- else
395
- obj.text
396
+ when 'input', 'select', 'textarea'
397
+ obj.value
398
+ else
399
+ obj.text
396
400
  end
397
401
  end
398
402
 
@@ -476,7 +480,7 @@ module TestCentricity
476
480
  def object_not_found_exception(obj, obj_type)
477
481
  @alt_locator.nil? ? locator = @locator : locator = @alt_locator
478
482
  obj_type.nil? ? object_type = 'Object' : object_type = obj_type
479
- raise "#{object_type} named '#{@name}' (#{locator}) not found" unless obj
483
+ raise ObjectNotFoundError.new("#{object_type} named '#{@name}' (#{locator}) not found") unless obj
480
484
  end
481
485
 
482
486
  def invalid_object_type_exception(obj, obj_type)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: testcentricity
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.14
4
+ version: 2.3.16
5
5
  platform: ruby
6
6
  authors:
7
7
  - A.J. Mrozinski
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-02-28 00:00:00.000000000 Z
11
+ date: 2018-03-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -259,6 +259,7 @@ files:
259
259
  - lib/testcentricity/app_elements/image.rb
260
260
  - lib/testcentricity/app_elements/label.rb
261
261
  - lib/testcentricity/app_elements/list.rb
262
+ - lib/testcentricity/app_elements/select_list.rb
262
263
  - lib/testcentricity/app_elements/switch.rb
263
264
  - lib/testcentricity/app_elements/textfield.rb
264
265
  - lib/testcentricity/browser_helper.rb