testcentricity_apps 4.0.10
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 +7 -0
- data/.yardopts +3 -0
- data/CHANGELOG.md +193 -0
- data/LICENSE.md +27 -0
- data/README.md +2297 -0
- data/lib/testcentricity_apps/app_core/appium_connect_helper.rb +667 -0
- data/lib/testcentricity_apps/app_core/screen_object.rb +494 -0
- data/lib/testcentricity_apps/app_core/screen_objects_helper.rb +211 -0
- data/lib/testcentricity_apps/app_core/screen_section.rb +669 -0
- data/lib/testcentricity_apps/app_elements/alert.rb +152 -0
- data/lib/testcentricity_apps/app_elements/app_element.rb +728 -0
- data/lib/testcentricity_apps/app_elements/button.rb +10 -0
- data/lib/testcentricity_apps/app_elements/checkbox.rb +61 -0
- data/lib/testcentricity_apps/app_elements/image.rb +10 -0
- data/lib/testcentricity_apps/app_elements/label.rb +10 -0
- data/lib/testcentricity_apps/app_elements/list.rb +188 -0
- data/lib/testcentricity_apps/app_elements/menu.rb +159 -0
- data/lib/testcentricity_apps/app_elements/menubar.rb +78 -0
- data/lib/testcentricity_apps/app_elements/radio.rb +61 -0
- data/lib/testcentricity_apps/app_elements/selectlist.rb +126 -0
- data/lib/testcentricity_apps/app_elements/switch.rb +66 -0
- data/lib/testcentricity_apps/app_elements/textfield.rb +51 -0
- data/lib/testcentricity_apps/appium_server.rb +76 -0
- data/lib/testcentricity_apps/data_objects/data_objects_helper.rb +100 -0
- data/lib/testcentricity_apps/data_objects/environment.rb +423 -0
- data/lib/testcentricity_apps/exception_queue_helper.rb +160 -0
- data/lib/testcentricity_apps/utility_helpers.rb +48 -0
- data/lib/testcentricity_apps/version.rb +3 -0
- data/lib/testcentricity_apps/world_extensions.rb +61 -0
- data/lib/testcentricity_apps.rb +103 -0
- metadata +322 -0
@@ -0,0 +1,211 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
|
3
|
+
module TestCentricity
|
4
|
+
class BaseScreenSectionObject
|
5
|
+
# Define a trait for this screen or section object.
|
6
|
+
#
|
7
|
+
# Refer to the `Adding Traits to your ScreenObject` and `Adding Traits to a ScreenSection` sections of the ruby docs
|
8
|
+
# for this gem.
|
9
|
+
#
|
10
|
+
# @param trait_name [Symbol] name of trait (as a symbol)
|
11
|
+
# @param block [&block] trait value
|
12
|
+
# @example
|
13
|
+
# trait(:screen_name) { 'Shopping Basket' }
|
14
|
+
# trait(:screen_locator) { accessibility_id: 'My Contacts View' }
|
15
|
+
# trait(:deep_link) { 'geo-locations' }
|
16
|
+
# trait(:section_name) { 'Cart List Item' }
|
17
|
+
# trait(:section_locator) { xpath: '(//XCUIElementTypeOther[@name="product row"])' }
|
18
|
+
#
|
19
|
+
def self.trait(trait_name, &block)
|
20
|
+
define_method(trait_name.to_s, &block)
|
21
|
+
end
|
22
|
+
|
23
|
+
# Populate the specified UI elements on this screen or section object with the associated data from a Hash passed as
|
24
|
+
# an argument. Data values must be in the form of a String for textfield controls. For checkboxes, radios and switches,
|
25
|
+
# data must either be a Boolean or a String that evaluates to a Boolean value (Yes, No, 1, 0, true, false). For screen
|
26
|
+
# section objects, data values must be a String, and the screen section object must have a set method defined.
|
27
|
+
#
|
28
|
+
# The optional wait_time parameter is used to specify the time (in seconds) to wait for each UI element to become
|
29
|
+
# visible before entering the associated data value. This option is useful in situations where entering data, or
|
30
|
+
# setting the state of a UI element might cause other UI elements to become visible or active. Specifying a wait_time
|
31
|
+
# value ensures that the subsequent UI elements will be ready to be interacted with as states are changed. If the wait
|
32
|
+
# time is nil, then the wait time will be 5 seconds.
|
33
|
+
#
|
34
|
+
# To delete all text content in a text field, pass !DELETE as the data to be entered.
|
35
|
+
#
|
36
|
+
# If any of the specified UI elements are not currently visible, an attempt will be made to scroll the object in view.
|
37
|
+
#
|
38
|
+
# Refer to the `Populating your ScreenObject or ScreenSection with data` section of the ruby docs for this gem.
|
39
|
+
#
|
40
|
+
# @param data [Hash] UI element(s) and associated data to be entered
|
41
|
+
# @param wait_time [Integer] wait time in seconds
|
42
|
+
# @example
|
43
|
+
# fields = {
|
44
|
+
# payee_name_field => UserData.current.cardholder_name,
|
45
|
+
# card_number_field => UserData.current.card_num,
|
46
|
+
# expiration_field => UserData.current.expiry,
|
47
|
+
# security_code_field => UserData.current.cvv
|
48
|
+
# }
|
49
|
+
# populate_data_fields(fields)
|
50
|
+
def populate_data_fields(data, wait_time = nil)
|
51
|
+
timeout = wait_time.nil? ? 2 : wait_time
|
52
|
+
data.each do |data_field, data_param|
|
53
|
+
unless data_param.blank?
|
54
|
+
# make sure the intended UI target element is visible before trying to set its value
|
55
|
+
data_field.scroll_into_view unless data_field.wait_until_visible(timeout, post_exception = false)
|
56
|
+
if data_param == '!DELETE'
|
57
|
+
data_field.clear
|
58
|
+
else
|
59
|
+
case data_field.get_object_type
|
60
|
+
when :checkbox
|
61
|
+
data_field.set_checkbox_state(data_param.to_bool)
|
62
|
+
when :radio
|
63
|
+
data_field.set_selected_state(data_param.to_bool)
|
64
|
+
when :textfield
|
65
|
+
data_field.clear
|
66
|
+
data_field.set(data_param)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# Verify one or more properties of one or more UI elements on a ScreenObject or ScreenSection. This method accepts
|
74
|
+
# a hash containing key/hash pairs of UI elements and their properties or attributes to be verified.
|
75
|
+
#
|
76
|
+
# Refer to the `Verifying AppUIElements on your ScreenObject or ScreenSection` section of the ruby docs for this gem.
|
77
|
+
#
|
78
|
+
# @param ui_states [Hash] UI element(s) and associated properties to be validated
|
79
|
+
# @param auto_scroll [Boolean] automatically scroll UI elements that are expected to be visible into view (default = true)
|
80
|
+
#
|
81
|
+
def verify_ui_states(ui_states, auto_scroll = true)
|
82
|
+
ui_states.each do |ui_object, object_states|
|
83
|
+
object_states.each do |property, state|
|
84
|
+
actual = case property
|
85
|
+
when :visible
|
86
|
+
if auto_scroll && state && !Environ.is_macos?
|
87
|
+
ui_object.scroll_into_view if ui_object.hidden?
|
88
|
+
end
|
89
|
+
ui_object.visible?
|
90
|
+
when :class
|
91
|
+
ui_object.get_attribute(:class)
|
92
|
+
when :exists
|
93
|
+
ui_object.exists?
|
94
|
+
when :enabled
|
95
|
+
ui_object.enabled?
|
96
|
+
when :disabled
|
97
|
+
ui_object.disabled?
|
98
|
+
when :hidden
|
99
|
+
ui_object.hidden?
|
100
|
+
when :checked
|
101
|
+
ui_object.checked?
|
102
|
+
when :selected
|
103
|
+
ui_object.selected?
|
104
|
+
when :value
|
105
|
+
ui_object.get_value
|
106
|
+
when :caption
|
107
|
+
ui_object.get_caption
|
108
|
+
when :placeholder
|
109
|
+
ui_object.get_placeholder
|
110
|
+
when :readonly
|
111
|
+
ui_object.read_only?
|
112
|
+
when :maxlength
|
113
|
+
ui_object.get_max_length
|
114
|
+
when :items
|
115
|
+
ui_object.get_list_items
|
116
|
+
when :itemcount
|
117
|
+
ui_object.get_item_count
|
118
|
+
when :width
|
119
|
+
ui_object.width
|
120
|
+
when :height
|
121
|
+
ui_object.height
|
122
|
+
when :x
|
123
|
+
ui_object.x_loc
|
124
|
+
when :y
|
125
|
+
ui_object.y_loc
|
126
|
+
when :count
|
127
|
+
ui_object.count
|
128
|
+
when :buttons
|
129
|
+
ui_object.buttons
|
130
|
+
when :identifier
|
131
|
+
ui_object.identifier
|
132
|
+
when :title
|
133
|
+
ui_object.title
|
134
|
+
when :item_data
|
135
|
+
ui_object.get_item_data
|
136
|
+
else
|
137
|
+
if property.is_a?(Hash)
|
138
|
+
property.map do |key, value|
|
139
|
+
case key
|
140
|
+
when :item
|
141
|
+
ui_object.get_list_item(value.to_i)
|
142
|
+
when :item_enabled
|
143
|
+
ui_object.get_item_enabled(value.to_i)
|
144
|
+
when :item_data
|
145
|
+
ui_object.get_item_data(value.to_i)
|
146
|
+
else
|
147
|
+
raise "#{key} is not a valid property key"
|
148
|
+
end
|
149
|
+
end
|
150
|
+
else
|
151
|
+
raise "#{property} is not a valid property"
|
152
|
+
end
|
153
|
+
end
|
154
|
+
error_msg = if ui_object.respond_to?(:get_name)
|
155
|
+
"Expected UI object '#{ui_object.get_name}' (#{ui_object.get_locator}) #{property} property to"
|
156
|
+
else
|
157
|
+
"Expected '#{screen_name}' screen object #{property} property to"
|
158
|
+
end
|
159
|
+
ExceptionQueue.enqueue_comparison(ui_object, state, actual, error_msg)
|
160
|
+
end
|
161
|
+
end
|
162
|
+
rescue ObjectNotFoundError => e
|
163
|
+
ExceptionQueue.enqueue_exception(e.message)
|
164
|
+
ensure
|
165
|
+
ExceptionQueue.post_exceptions
|
166
|
+
end
|
167
|
+
|
168
|
+
# Perform a swipe gesture in the specified direction. The swipe start point is the center of the screen, and the
|
169
|
+
# swipe end point is the distance specified. A distance of 1 specifies a swipe gesture with a distance that is the
|
170
|
+
# full screen height (vertical swipe), or full screen width (horizontal swipe). A distance of 0.5 specifies a swipe
|
171
|
+
# gesture with a distance that is half the screen width or height.
|
172
|
+
#
|
173
|
+
# @param direction [Symbol] :up, :down, :left, or :right
|
174
|
+
# @param distance [Float] scroll distance relative to the screen height or width
|
175
|
+
# @example
|
176
|
+
# swipe_gesture(direction = :down, distance = 1)
|
177
|
+
#
|
178
|
+
def swipe_gesture(direction, distance = 0.5)
|
179
|
+
raise 'Scroll distance must be between 0 and 1' if (distance < 0 || distance > 1)
|
180
|
+
size = window_size
|
181
|
+
mid_pt = [(size.width * 0.5).to_i, (size.height * 0.5).to_i]
|
182
|
+
top = (mid_pt[1] - ((size.height * distance) * 0.5)).to_i
|
183
|
+
bottom = (mid_pt[1] + ((size.height * distance) * 0.5)).to_i
|
184
|
+
left = (mid_pt[0] - ((size.width * distance) * 0.5)).to_i
|
185
|
+
right = (mid_pt[0] + ((size.width * distance) * 0.5)).to_i
|
186
|
+
|
187
|
+
case direction
|
188
|
+
when :up
|
189
|
+
start_pt = [mid_pt[0], top]
|
190
|
+
end_pt = [mid_pt[0], bottom]
|
191
|
+
when :down
|
192
|
+
start_pt = [mid_pt[0], bottom]
|
193
|
+
end_pt = [mid_pt[0], top]
|
194
|
+
when :left
|
195
|
+
start_pt = [left, mid_pt[1]]
|
196
|
+
end_pt = [right, mid_pt[1]]
|
197
|
+
when :right
|
198
|
+
start_pt = [right, mid_pt[1]]
|
199
|
+
end_pt = [left, mid_pt[1]]
|
200
|
+
end
|
201
|
+
|
202
|
+
puts "Swipe start_pt = #{start_pt} / end_pt = #{end_pt}" if ENV['DEBUG']
|
203
|
+
driver.action
|
204
|
+
.move_to_location(start_pt[0], start_pt[1])
|
205
|
+
.pointer_down
|
206
|
+
.move_to_location(end_pt[0], end_pt[1], duration: 0.25)
|
207
|
+
.release
|
208
|
+
.perform
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|