testcentricity 2.3.13

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +11 -0
  3. data/.rspec +3 -0
  4. data/.ruby-gemset +1 -0
  5. data/.ruby-version +1 -0
  6. data/Gemfile +6 -0
  7. data/Gemfile.lock +93 -0
  8. data/LICENSE.txt +28 -0
  9. data/README.md +1634 -0
  10. data/Rakefile +1 -0
  11. data/bin/console +14 -0
  12. data/bin/setup +8 -0
  13. data/lib/devices/devices.yml +344 -0
  14. data/lib/testcentricity.rb +144 -0
  15. data/lib/testcentricity/app_core/appium_connect_helper.rb +154 -0
  16. data/lib/testcentricity/app_core/appium_server.rb +69 -0
  17. data/lib/testcentricity/app_core/screen_objects_helper.rb +180 -0
  18. data/lib/testcentricity/app_core/screen_sections_helper.rb +332 -0
  19. data/lib/testcentricity/app_elements/app_element_helper.rb +293 -0
  20. data/lib/testcentricity/app_elements/button.rb +8 -0
  21. data/lib/testcentricity/app_elements/checkbox.rb +20 -0
  22. data/lib/testcentricity/app_elements/label.rb +8 -0
  23. data/lib/testcentricity/app_elements/list.rb +25 -0
  24. data/lib/testcentricity/app_elements/switch.rb +20 -0
  25. data/lib/testcentricity/app_elements/textfield.rb +12 -0
  26. data/lib/testcentricity/browser_helper.rb +174 -0
  27. data/lib/testcentricity/data_objects/data_objects_helper.rb +78 -0
  28. data/lib/testcentricity/data_objects/environment.rb +281 -0
  29. data/lib/testcentricity/data_objects/excel_helper.rb +242 -0
  30. data/lib/testcentricity/exception_queue_helper.rb +51 -0
  31. data/lib/testcentricity/utility_helpers.rb +28 -0
  32. data/lib/testcentricity/version.rb +3 -0
  33. data/lib/testcentricity/web_core/drag_drop_helper.rb +15 -0
  34. data/lib/testcentricity/web_core/page_objects_helper.rb +669 -0
  35. data/lib/testcentricity/web_core/page_sections_helper.rb +866 -0
  36. data/lib/testcentricity/web_core/webdriver_helper.rb +579 -0
  37. data/lib/testcentricity/web_elements/button.rb +8 -0
  38. data/lib/testcentricity/web_elements/cell_button.rb +8 -0
  39. data/lib/testcentricity/web_elements/cell_checkbox.rb +38 -0
  40. data/lib/testcentricity/web_elements/cell_element.rb +69 -0
  41. data/lib/testcentricity/web_elements/cell_image.rb +8 -0
  42. data/lib/testcentricity/web_elements/cell_radio.rb +31 -0
  43. data/lib/testcentricity/web_elements/checkbox.rb +100 -0
  44. data/lib/testcentricity/web_elements/file_field.rb +45 -0
  45. data/lib/testcentricity/web_elements/image.rb +34 -0
  46. data/lib/testcentricity/web_elements/label.rb +8 -0
  47. data/lib/testcentricity/web_elements/link.rb +8 -0
  48. data/lib/testcentricity/web_elements/list.rb +73 -0
  49. data/lib/testcentricity/web_elements/list_button.rb +8 -0
  50. data/lib/testcentricity/web_elements/list_checkbox.rb +38 -0
  51. data/lib/testcentricity/web_elements/list_element.rb +61 -0
  52. data/lib/testcentricity/web_elements/list_radio.rb +31 -0
  53. data/lib/testcentricity/web_elements/radio.rb +74 -0
  54. data/lib/testcentricity/web_elements/select_list.rb +197 -0
  55. data/lib/testcentricity/web_elements/siebel_open_ui_helper.rb +15 -0
  56. data/lib/testcentricity/web_elements/table.rb +612 -0
  57. data/lib/testcentricity/web_elements/textfield.rb +114 -0
  58. data/lib/testcentricity/web_elements/ui_elements_helper.rb +502 -0
  59. data/lib/testcentricity/world_extensions.rb +26 -0
  60. data/my_templates/default/method_details/setup.rb +3 -0
  61. data/spec/spec_helper.rb +14 -0
  62. data/spec/testcentricity_spec.rb +9 -0
  63. data/testcentricity.gemspec +47 -0
  64. metadata +328 -0
@@ -0,0 +1,293 @@
1
+ require 'test/unit'
2
+
3
+ module TestCentricity
4
+ class AppUIElement
5
+ include Test::Unit::Assertions
6
+
7
+ attr_reader :parent, :strategy, :locator, :context, :type, :name
8
+ attr_accessor :mru_element, :mru_name
9
+
10
+ def initialize(name, parent, strategy, locator, context)
11
+ @name = name
12
+ @parent = parent
13
+ @strategy = strategy.to_sym
14
+ @locator = locator
15
+ @context = context
16
+ @type = nil
17
+ end
18
+
19
+ def get_object_type
20
+ @type
21
+ end
22
+
23
+ def get_locator
24
+ [@strategy.to_sym, @locator]
25
+ end
26
+
27
+ def get_name
28
+ @name
29
+ end
30
+
31
+ def click
32
+ obj = element
33
+ object_not_found_exception(obj)
34
+ obj.click
35
+ end
36
+
37
+ def tap
38
+ obj = element
39
+ object_not_found_exception(obj)
40
+ x = obj.location.x
41
+ y = obj.location.y
42
+ tap_action = Appium::TouchAction.new.tap(element: obj, x: x, y: y)
43
+ tap_action.perform
44
+ end
45
+
46
+ def double_tap
47
+ obj = element
48
+ object_not_found_exception(obj)
49
+ x = obj.location.x
50
+ y = obj.location.y
51
+ tap_action = Appium::TouchAction.new.double_tap(element: obj, x: x, y: y)
52
+ tap_action.perform
53
+ end
54
+
55
+ def set(value)
56
+ obj = element
57
+ object_not_found_exception(obj)
58
+ if value.is_a?(Array)
59
+ obj.send_keys(value[0])
60
+ obj.send_keys(value[1])
61
+ elsif value.is_a?(String)
62
+ obj.send_keys(value)
63
+ end
64
+ end
65
+
66
+ def send_keys(value)
67
+ obj = element
68
+ object_not_found_exception(obj)
69
+ obj.send_keys(value)
70
+ end
71
+
72
+ def clear
73
+ obj = element
74
+ object_not_found_exception(obj)
75
+ obj.clear
76
+ end
77
+
78
+ def get_value
79
+ obj = element
80
+ object_not_found_exception(obj)
81
+ obj.value
82
+ end
83
+
84
+ def get_caption
85
+ obj = element
86
+ object_not_found_exception(obj)
87
+ if obj.tag_name == 'XCUIElementTypeNavigationBar'
88
+ obj.attribute('name')
89
+ else
90
+ obj.attribute('label')
91
+ end
92
+ end
93
+
94
+ def exists?
95
+ begin
96
+ element.displayed?
97
+ rescue
98
+ false
99
+ end
100
+ end
101
+
102
+ def visible?
103
+ if exists?
104
+ element.displayed?
105
+ else
106
+ false
107
+ end
108
+ end
109
+
110
+ def hidden?
111
+ !visible?
112
+ end
113
+
114
+ def enabled?
115
+ obj = element
116
+ object_not_found_exception(obj)
117
+ obj.enabled?
118
+ end
119
+
120
+ def disabled?
121
+ !enabled?
122
+ end
123
+
124
+ def selected?
125
+ obj = element
126
+ object_not_found_exception(obj)
127
+ obj.selected?
128
+ end
129
+
130
+ def tag_name
131
+ obj = element
132
+ object_not_found_exception(obj)
133
+ obj.tag_name
134
+ end
135
+
136
+ def get_attribute(attrib)
137
+ obj = element
138
+ object_not_found_exception(obj)
139
+ obj.attribute(attrib)
140
+ end
141
+
142
+ # Wait until the object exists, or until the specified wait time has expired. If the wait time is nil, then the wait
143
+ # time will be Environ.default_max_wait_time.
144
+ #
145
+ # @param seconds [Integer or Float] wait time in seconds
146
+ # @example
147
+ # run_button.wait_until_exists(0.5)
148
+ #
149
+ def wait_until_exists(seconds = nil)
150
+ timeout = seconds.nil? ? Environ.default_max_wait_time : seconds
151
+ wait = Selenium::WebDriver::Wait.new(timeout: timeout)
152
+ wait.until { exists? }
153
+ rescue
154
+ raise "Could not find UI #{object_ref_message} after #{timeout} seconds" unless exists?
155
+ end
156
+
157
+ # Wait until the object no longer exists, or until the specified wait time has expired. If the wait time is nil, then
158
+ # the wait time will be Environ.default_max_wait_time.
159
+ #
160
+ # @param seconds [Integer or Float] wait time in seconds
161
+ # @example
162
+ # logout_button.wait_until_gone(5)
163
+ #
164
+ def wait_until_gone(seconds = nil)
165
+ timeout = seconds.nil? ? Environ.default_max_wait_time : seconds
166
+ wait = Selenium::WebDriver::Wait.new(timeout: timeout)
167
+ wait.until { !exists? }
168
+ rescue
169
+ raise "UI #{object_ref_message} remained visible after #{timeout} seconds" if exists?
170
+ end
171
+
172
+ # Wait until the object is visible, or until the specified wait time has expired. If the wait time is nil, then the
173
+ # wait time will be Environ.default_max_wait_time.
174
+ #
175
+ # @param seconds [Integer or Float] wait time in seconds
176
+ # @example
177
+ # run_button.wait_until_visible(0.5)
178
+ #
179
+ def wait_until_visible(seconds = nil)
180
+ timeout = seconds.nil? ? Environ.default_max_wait_time : seconds
181
+ wait = Selenium::WebDriver::Wait.new(timeout: timeout)
182
+ wait.until { visible? }
183
+ rescue
184
+ raise "Could not find UI #{object_ref_message} after #{timeout} seconds" unless visible?
185
+ end
186
+
187
+ # Wait until the object is hidden, or until the specified wait time has expired. If the wait time is nil, then the
188
+ # wait time will be Environ.default_max_wait_time.
189
+ #
190
+ # @param seconds [Integer or Float] wait time in seconds
191
+ # @example
192
+ # run_button.wait_until_hidden(10)
193
+ #
194
+ def wait_until_hidden(seconds = nil)
195
+ timeout = seconds.nil? ? Environ.default_max_wait_time : seconds
196
+ wait = Selenium::WebDriver::Wait.new(timeout: timeout)
197
+ wait.until { hidden? }
198
+ rescue
199
+ raise "UI #{object_ref_message} remained visible after #{timeout} seconds" if visible?
200
+ end
201
+
202
+ # Wait until the object's value equals the specified value, or until the specified wait time has expired. If the wait
203
+ # time is nil, then the wait time will be Environ.default_max_wait_time.
204
+ #
205
+ # @param seconds [Integer or Float] wait time in seconds
206
+ # @example
207
+ # card_authorized_label.wait_until_value_is(5, 'Card authorized')
208
+ #
209
+ def wait_until_value_is(value, seconds = nil)
210
+ timeout = seconds.nil? ? Environ.default_max_wait_time : seconds
211
+ wait = Selenium::WebDriver::Wait.new(timeout: timeout)
212
+ wait.until { get_value == value }
213
+ rescue
214
+ raise "Value of UI #{object_ref_message} failed to equal '#{value}' after #{timeout} seconds" unless get_value == value
215
+ end
216
+
217
+ # Wait until the object's value changes to a different value, or until the specified wait time has expired. If the
218
+ # wait time is nil, then the wait time will be Environ.default_max_wait_time.
219
+ #
220
+ # @param seconds [Integer or Float] wait time in seconds
221
+ # @example
222
+ # basket_grand_total_label.wait_until_value_changes(5)
223
+ #
224
+ def wait_until_value_changes(seconds = nil)
225
+ value = get_value
226
+ timeout = seconds.nil? ? Environ.default_max_wait_time : seconds
227
+ wait = Selenium::WebDriver::Wait.new(timeout: timeout)
228
+ wait.until { get_value != value }
229
+ rescue
230
+ raise "Value of UI #{object_ref_message} failed to change from '#{value}' after #{timeout} seconds" if get_value == value
231
+ end
232
+
233
+
234
+ def scroll_into_view
235
+ scroll(:down) unless visible?
236
+ end
237
+
238
+ def scroll(direction)
239
+ execute_script('mobile: scroll', direction: direction.to_s)
240
+ end
241
+
242
+ def swipe(direction)
243
+ execute_script('mobile: swipe', direction: direction.to_s)
244
+ end
245
+
246
+
247
+ private
248
+
249
+ def element
250
+ parent_section = @context == :section
251
+ parent_section ? tries ||= 2 : tries ||= 1
252
+
253
+ if parent_section && tries > 1
254
+ parent_obj = nil
255
+ locators = @parent.get_locator
256
+ locators.each do |parent_locator|
257
+ if parent_obj.nil?
258
+ parent_obj = find_element(parent_locator[0], parent_locator[1])
259
+ else
260
+ parent_obj = parent_obj.find_element(parent_locator[0], parent_locator[1])
261
+ end
262
+ end
263
+
264
+ puts "Found parent object '#{@parent.get_name}' - #{@parent.get_locator}" if ENV['DEBUG']
265
+
266
+
267
+ obj = parent_obj.find_element(@strategy, @locator)
268
+
269
+ puts "Found object '#{@name}' - [:#{@strategy}, #{@locator}]" if ENV['DEBUG']
270
+
271
+ obj
272
+ else
273
+ obj = find_element(@strategy, @locator)
274
+
275
+ puts "Found object '#{@name}' - [:#{@strategy}, #{@locator}]" if ENV['DEBUG']
276
+
277
+ obj
278
+ end
279
+ rescue
280
+ retry if (tries -= 1) > 0
281
+ nil
282
+ end
283
+
284
+ def object_not_found_exception(obj)
285
+ @type.nil? ? object_type = 'Object' : object_type = @type
286
+ raise "#{object_type} named '#{@name}' (#{get_locator}) not found" unless obj
287
+ end
288
+
289
+ def object_ref_message
290
+ "object '#{@name}' (#{get_locator})"
291
+ end
292
+ end
293
+ end
@@ -0,0 +1,8 @@
1
+ module TestCentricity
2
+ class AppButton < AppUIElement
3
+ def initialize(name, parent, strategy, locator, context)
4
+ super
5
+ @type = :button
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,20 @@
1
+ module TestCentricity
2
+ class AppCheckBox < AppUIElement
3
+ def initialize(name, parent, strategy, locator, context)
4
+ super
5
+ @type = :checkbox
6
+ end
7
+
8
+ def checked?
9
+ element.attribute('checked') == 'true'
10
+ end
11
+
12
+ def check
13
+ element.click unless checked?
14
+ end
15
+
16
+ def uncheck
17
+ element.click if checked?
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,8 @@
1
+ module TestCentricity
2
+ class AppLabel < AppUIElement
3
+ def initialize(name, parent, strategy, locator, context)
4
+ super
5
+ @type = :label
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,25 @@
1
+ module TestCentricity
2
+ class AppList < AppUIElement
3
+ def initialize(name, parent, strategy, locator, context)
4
+ super
5
+ @type = :list
6
+ end
7
+
8
+ def get_item_count
9
+ if Environ.device_os == :ios
10
+ items = find_elements(class: 'XCUIElementTypeCell')
11
+ else
12
+ items = find_elements(class: 'android.widget.FrameLayout')
13
+ end
14
+ items.size
15
+ end
16
+
17
+ def get_list_items
18
+
19
+ end
20
+
21
+ def get_list_item(index)
22
+
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,20 @@
1
+ module TestCentricity
2
+ class AppSwitch < AppUIElement
3
+ def initialize(name, parent, strategy, locator, context)
4
+ super
5
+ @type = :switch
6
+ end
7
+
8
+ def on?
9
+ element.get_value == 1
10
+ end
11
+
12
+ def on
13
+ element.click unless on?
14
+ end
15
+
16
+ def off
17
+ element.click if on?
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,12 @@
1
+ module TestCentricity
2
+ class AppTextField < AppUIElement
3
+ def initialize(name, parent, strategy, locator, context)
4
+ super
5
+ @type = :textfield
6
+ end
7
+
8
+ def get_placeholder
9
+ element.text
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,174 @@
1
+ require 'yaml'
2
+
3
+
4
+ module TestCentricity
5
+ module Browsers
6
+ include Capybara::DSL
7
+
8
+ # Sets the size of the browser window.
9
+ #
10
+ # @param resolution [Array] the desired [width, height]
11
+ # @example
12
+ # Browsers.set_browser_window_size([1024, 768])
13
+ #
14
+ def self.set_browser_window_size(resolution)
15
+ resolution = resolution.split(',') if resolution.is_a?(String)
16
+ window = Capybara.current_session.driver.browser.manage.window
17
+ window.resize_to(resolution[0], resolution[1])
18
+ Environ.browser_size = [resolution[0].to_i, resolution[1].to_i]
19
+ end
20
+
21
+ # Maximizes the selenium browser window.
22
+ #
23
+ # @example
24
+ # Browsers.maximize_browser
25
+ #
26
+ def self.maximize_browser
27
+ window = Capybara.current_session.driver.browser.manage.window
28
+ window.maximize
29
+ end
30
+ # Sets the position of the browser window.
31
+ #
32
+ # @param x [Integer] the desired x coordinate
33
+ # @param y [Integer] the desired y coordinate
34
+ # @example
35
+ # Browsers.set_browser_window_position([100, 300])
36
+ #
37
+ def self.set_browser_window_position(x, y)
38
+ window = Capybara.current_session.driver.browser.manage.window
39
+ window.move_to(x, y)
40
+ end
41
+
42
+ # Refreshes the selenium browser.
43
+ #
44
+ # @example
45
+ # Browsers.refresh_browser
46
+ #
47
+ def self.refresh_browser
48
+ Capybara.page.driver.browser.navigate.refresh
49
+ end
50
+
51
+ # Emulates clicking the web browser's Back button. Navigates back by one page on the browser’s history.
52
+ #
53
+ # @example
54
+ # Browsers.navigate_back
55
+ #
56
+ def self.navigate_back
57
+ Capybara.page.driver.browser.navigate.back
58
+ end
59
+
60
+ # Emulates clicking the web browser's Forward button. Navigates forward by one page on the browser’s history.
61
+ #
62
+ # @example
63
+ # Browsers.navigate_forward
64
+ #
65
+ def self.navigate_forward
66
+ Capybara.page.driver.browser.navigate.forward
67
+ end
68
+
69
+ def self.switch_to_new_browser_instance
70
+ Capybara.page.driver.browser.switch_to.window(Capybara.page.driver.browser.window_handles.last)
71
+ end
72
+
73
+ def self.close_all_browser_instances
74
+ Capybara.page.driver.browser.window_handles.each do |handle|
75
+ page.driver.browser.switch_to.window(handle)
76
+ page.driver.browser.close
77
+ end
78
+ end
79
+
80
+ def self.num_browser_instances
81
+ Capybara.page.driver.browser.window_handles.count
82
+ end
83
+
84
+ def self.close_current_browser_instance
85
+ Capybara.page.driver.browser.close
86
+ Capybara.page.driver.browser.switch_to.window(Capybara.page.driver.browser.window_handles.last)
87
+ end
88
+
89
+ def self.close_old_browser_instance
90
+ Capybara.page.driver.browser.switch_to.window(Capybara.page.driver.browser.window_handles.first)
91
+ Capybara.page.driver.browser.close
92
+ Capybara.page.driver.browser.switch_to.window(Capybara.page.driver.browser.window_handles.last)
93
+ end
94
+
95
+ def self.close_named_browser_instance(name)
96
+ Capybara.page.driver.browser.switch_to.window(Capybara.page.driver.find_window(name))
97
+ Capybara.page.driver.browser.close
98
+ Capybara.page.driver.browser.switch_to.window(Capybara.page.driver.browser.window_handles.last)
99
+ end
100
+
101
+ def self.suppress_js_alerts
102
+ Capybara.page.execute_script('window.alert = function() {}')
103
+ end
104
+
105
+ def self.suppress_js_leave_page_modal
106
+ Capybara.page.execute_script('window.onbeforeunload = null')
107
+ end
108
+
109
+ def self.delete_all_cookies
110
+ if Capybara.current_driver == :selenium
111
+ browser = Capybara.current_session.driver.browser
112
+ if browser.respond_to?(:manage) && browser.manage.respond_to?(:delete_all_cookies)
113
+ browser.manage.delete_all_cookies
114
+ else
115
+ raise 'Could not clear cookies.'
116
+ end
117
+ end
118
+ end
119
+
120
+ def self.set_device_orientation(orientation)
121
+ if Environ.is_mobile? && !Environ.is_device?
122
+ Browsers.set_browser_window_size(Browsers.browser_size(Environ.browser.to_s, orientation))
123
+ else
124
+ puts '***** Cannot change device orientation of desktop web browsers or remote devices *****'
125
+ end
126
+ end
127
+
128
+ def self.mobile_device_agent(device)
129
+ device_name = device.gsub(/\s+/, '').downcase.to_sym
130
+ device = get_devices[device_name]
131
+ agent_string = device[:user_agent]
132
+ raise "Device '#{device}' is not defined" unless agent_string
133
+ agent_string
134
+ end
135
+
136
+ def self.mobile_device_name(device)
137
+ device_name = device.gsub(/\s+/, '').downcase.to_sym
138
+ device = get_devices[device_name]
139
+ name = device[:name]
140
+ raise "Device '#{device}' is not defined" unless name
141
+ Environ.device_os = device[:os]
142
+ Environ.device_type = device[:type]
143
+ name
144
+ end
145
+
146
+ def self.browser_size(browser, orientation)
147
+ device_name = browser.gsub(/\s+/, '').downcase.to_sym
148
+ device = get_devices[device_name]
149
+ if device
150
+ width = device[:css_width]
151
+ height = device[:css_height]
152
+ default_orientation = device[:default_orientation].to_sym
153
+ if orientation
154
+ Environ.device_orientation = orientation
155
+ orientation.downcase.to_sym == default_orientation ?
156
+ size = [width, height] :
157
+ size = [height, width]
158
+ else
159
+ Environ.device_orientation = device[:default_orientation]
160
+ size = [width, height]
161
+ end
162
+ else
163
+ size = [1650, 1000]
164
+ end
165
+ size
166
+ end
167
+
168
+ private
169
+
170
+ def self.get_devices
171
+ YAML.load_file File.expand_path('../../devices/devices.yml', __FILE__)
172
+ end
173
+ end
174
+ end