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.
Files changed (31) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +3 -0
  3. data/CHANGELOG.md +193 -0
  4. data/LICENSE.md +27 -0
  5. data/README.md +2297 -0
  6. data/lib/testcentricity_apps/app_core/appium_connect_helper.rb +667 -0
  7. data/lib/testcentricity_apps/app_core/screen_object.rb +494 -0
  8. data/lib/testcentricity_apps/app_core/screen_objects_helper.rb +211 -0
  9. data/lib/testcentricity_apps/app_core/screen_section.rb +669 -0
  10. data/lib/testcentricity_apps/app_elements/alert.rb +152 -0
  11. data/lib/testcentricity_apps/app_elements/app_element.rb +728 -0
  12. data/lib/testcentricity_apps/app_elements/button.rb +10 -0
  13. data/lib/testcentricity_apps/app_elements/checkbox.rb +61 -0
  14. data/lib/testcentricity_apps/app_elements/image.rb +10 -0
  15. data/lib/testcentricity_apps/app_elements/label.rb +10 -0
  16. data/lib/testcentricity_apps/app_elements/list.rb +188 -0
  17. data/lib/testcentricity_apps/app_elements/menu.rb +159 -0
  18. data/lib/testcentricity_apps/app_elements/menubar.rb +78 -0
  19. data/lib/testcentricity_apps/app_elements/radio.rb +61 -0
  20. data/lib/testcentricity_apps/app_elements/selectlist.rb +126 -0
  21. data/lib/testcentricity_apps/app_elements/switch.rb +66 -0
  22. data/lib/testcentricity_apps/app_elements/textfield.rb +51 -0
  23. data/lib/testcentricity_apps/appium_server.rb +76 -0
  24. data/lib/testcentricity_apps/data_objects/data_objects_helper.rb +100 -0
  25. data/lib/testcentricity_apps/data_objects/environment.rb +423 -0
  26. data/lib/testcentricity_apps/exception_queue_helper.rb +160 -0
  27. data/lib/testcentricity_apps/utility_helpers.rb +48 -0
  28. data/lib/testcentricity_apps/version.rb +3 -0
  29. data/lib/testcentricity_apps/world_extensions.rb +61 -0
  30. data/lib/testcentricity_apps.rb +103 -0
  31. 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