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 +4 -4
- data/README.md +16 -2
- data/lib/devices/devices.yml +1 -1
- data/lib/testcentricity.rb +1 -0
- data/lib/testcentricity/app_core/appium_connect_helper.rb +1 -1
- data/lib/testcentricity/app_core/screen_objects_helper.rb +21 -0
- data/lib/testcentricity/app_core/screen_sections_helper.rb +13 -0
- data/lib/testcentricity/app_elements/app_element_helper.rb +1 -1
- data/lib/testcentricity/app_elements/select_list.rb +147 -0
- data/lib/testcentricity/exception_queue_helper.rb +7 -0
- data/lib/testcentricity/version.rb +1 -1
- data/lib/testcentricity/web_core/page_objects_helper.rb +168 -135
- data/lib/testcentricity/web_core/page_sections_helper.rb +201 -144
- data/lib/testcentricity/web_elements/ui_elements_helper.rb +14 -10
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c527d51d9b0ba53c2c6f7358138def57dc66fde9
|
4
|
+
data.tar.gz: 80c832950b2faf935c688bdcab670a165337a014
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
[](https://badge.fury.io/rb/testcentricity) [](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**.
|
data/lib/devices/devices.yml
CHANGED
@@ -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.
|
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
|
data/lib/testcentricity.rb
CHANGED
@@ -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
|
|
@@ -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
|
@@ -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
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
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
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
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
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
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
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
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
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
|
681
|
-
|
682
|
-
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
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
|
-
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
728
|
-
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
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
|
-
|
747
|
-
|
748
|
-
|
749
|
-
|
750
|
-
|
751
|
-
|
752
|
-
|
753
|
-
|
754
|
-
|
755
|
-
|
756
|
-
|
757
|
-
|
758
|
-
|
759
|
-
|
760
|
-
|
761
|
-
|
762
|
-
|
763
|
-
|
764
|
-
|
765
|
-
|
766
|
-
|
767
|
-
|
768
|
-
|
769
|
-
|
770
|
-
|
771
|
-
|
772
|
-
|
773
|
-
|
774
|
-
|
775
|
-
|
776
|
-
|
777
|
-
|
778
|
-
|
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
|
-
|
826
|
-
|
827
|
-
|
828
|
-
|
829
|
-
|
830
|
-
|
831
|
-
|
832
|
-
|
833
|
-
|
834
|
-
|
835
|
-
|
836
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
72
|
-
obj
|
73
|
-
|
74
|
-
obj.
|
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
|
-
|
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
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
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.
|
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-
|
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
|