testcentricity 2.3.14 → 2.3.16

Sign up to get free protection for your applications and to get access to all the features.
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