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,154 @@
1
+ require 'appium_lib'
2
+
3
+
4
+ module TestCentricity
5
+ module AppiumConnect
6
+
7
+ attr_accessor :running
8
+ attr_accessor :config_file
9
+
10
+ def self.initialize_appium(project_path = nil)
11
+ Environ.platform = :mobile
12
+ Environ.driver = :appium
13
+ Environ.device_type = ENV['DEVICE_TYPE'] if ENV['DEVICE_TYPE']
14
+
15
+ @config_file = project_path
16
+
17
+ if project_path.nil?
18
+ Environ.device_name = ENV['APP_DEVICE']
19
+ Environ.device_os = ENV['APP_PLATFORM_NAME']
20
+ Environ.device_orientation = ENV['ORIENTATION'] if ENV['ORIENTATION']
21
+ if ENV['UDID']
22
+ Environ.device = :device
23
+ else
24
+ Environ.device = :simulator
25
+ end
26
+ end
27
+ @running = false
28
+ end
29
+
30
+ def self.start_driver
31
+ if @config_file.nil?
32
+ desired_capabilities = {
33
+ caps: {
34
+ platformName: ENV['APP_PLATFORM_NAME'],
35
+ platformVersion: ENV['APP_VERSION'],
36
+ deviceName: ENV['APP_DEVICE'],
37
+ automationName: ENV['AUTOMATION_ENGINE']
38
+ }
39
+ }
40
+ capabilities = desired_capabilities[:caps]
41
+ capabilities[:avd] = ENV['APP_DEVICE'] if ENV['APP_PLATFORM_NAME'].downcase.to_sym == :android
42
+ capabilities[:orientation] = ENV['ORIENTATION'].upcase if ENV['ORIENTATION']
43
+ capabilities[:language] = ENV['LANGUAGE'] if ENV['LANGUAGE']
44
+ capabilities[:locale] = ENV['LOCALE'].gsub('-', '_') if ENV['LOCALE']
45
+ capabilities[:newCommandTimeout] = ENV['NEW_COMMAND_TIMEOUT'] if ENV['NEW_COMMAND_TIMEOUT']
46
+ capabilities[:noReset] = ENV['APP_NO_RESET'] if ENV['APP_NO_RESET']
47
+ capabilities[:fullReset] = ENV['APP_FULL_RESET'] if ENV['APP_FULL_RESET']
48
+ if ENV['UDID']
49
+ capabilities[:udid] = ENV['UDID']
50
+ capabilities[:bundleId] = ENV['BUNDLE_ID'] if ENV['BUNDLE_ID']
51
+ capabilities[:xcodeOrgId] = ENV['TEAM_ID'] if ENV['TEAM_ID']
52
+ capabilities[:xcodeSigningId] = ENV['TEAM_NAME'] if ENV['TEAM_NAME']
53
+ capabilities[:appActivity] = ENV['APP_ACTIVITY'] if ENV['APP_ACTIVITY']
54
+ capabilities[:appPackage] = ENV['APP_PACKAGE'] if ENV['APP_PACKAGE']
55
+ end
56
+
57
+ if ENV['APP']
58
+ capabilities[:app] = ENV['APP']
59
+ else
60
+ if Environ.is_android?
61
+ capabilities[:app] = Environ.current.android_apk_path
62
+ elsif Environ.is_ios?
63
+ if Environ.is_device?
64
+ capabilities[:app] = Environ.current.ios_ipa_path
65
+ else
66
+ capabilities[:app] = Environ.current.ios_app_path
67
+ end
68
+ end
69
+ end
70
+
71
+ else
72
+ base_path = 'config'
73
+ unless File.directory?(File.join(@config_file, base_path))
74
+ raise 'Could not find appium.txt files in /config folder'
75
+ end
76
+ appium_caps = File.join(@config_file, base_path, 'appium.txt')
77
+ desired_capabilities = Appium.load_appium_txt file: appium_caps
78
+ end
79
+ Appium::Driver.new(desired_capabilities).start_driver
80
+ @running = true
81
+ Appium.promote_appium_methods TestCentricity::ScreenObject
82
+ Appium.promote_appium_methods TestCentricity::AppUIElement
83
+ end
84
+
85
+ def self.quit_driver
86
+ if @running
87
+ $driver.driver_quit
88
+ @running = false
89
+ end
90
+ end
91
+
92
+ def self.driver
93
+ $driver
94
+ end
95
+
96
+ def self.take_screenshot(png_save_path)
97
+ FileUtils.mkdir_p(File.dirname(png_save_path))
98
+ $driver.driver.save_screenshot(png_save_path)
99
+ end
100
+
101
+ def self.install_app(app_path)
102
+ $driver.install_app(app_path)
103
+ end
104
+
105
+ def self.app_installed?(bundle_id)
106
+ $driver.app_installed?(bundle_id)
107
+ end
108
+
109
+ def self.launch_app
110
+ $driver.launch_app
111
+ end
112
+
113
+ def self.close_app
114
+ $driver.close_app
115
+ end
116
+
117
+ def self.reset_app
118
+ $driver.reset
119
+ end
120
+
121
+ def self.remove_app(bundle_id)
122
+ $driver.remove_app(bundle_id)
123
+ end
124
+
125
+ def self.implicit_wait(timeout)
126
+ $driver.manage.timeouts.implicit_wait = timeout
127
+ end
128
+
129
+ def self.hide_keyboard
130
+ $driver.hide_keyboard
131
+ end
132
+
133
+ def self.keyboard_shown?
134
+ $driver.is_keyboard_shown
135
+ end
136
+
137
+ def self.set_geolocation(latitude, longitude, altitude)
138
+ $driver.set_location(latitude, longitude, altitude)
139
+ end
140
+
141
+ def self.current_context
142
+ $driver.current_context
143
+ end
144
+
145
+ def self.set_context(context)
146
+ $driver.set_context(context)
147
+ end
148
+
149
+ def self.available_contexts
150
+ $driver.available_contexts
151
+ end
152
+ end
153
+ end
154
+
@@ -0,0 +1,69 @@
1
+ require 'childprocess'
2
+
3
+ #
4
+ # This class is designed to start and stop the Appium Server process. In order to use it you must have Appium
5
+ # and node installed on your computer. You can pass parameters to Appium at startup via the constructor.
6
+ #
7
+ module TestCentricity
8
+ class AppiumServer
9
+
10
+ attr_accessor :process
11
+
12
+ def initialize(params={})
13
+ @params = params
14
+ end
15
+
16
+ #
17
+ # Start the Appium Server
18
+ #
19
+ def start
20
+ # terminate any currently running Appium Server
21
+ if running?
22
+ system('killall -9 node')
23
+ puts 'Terminating existing Appium Server'
24
+ sleep(5)
25
+ puts 'Appium Server is being restarted'
26
+ else
27
+ puts 'Appium Server is being started'
28
+ end
29
+ # start new Appium Server
30
+ @process = ChildProcess.build(*parameters)
31
+ process.start
32
+ # wait until confirmation that Appium Server is running
33
+ wait = Selenium::WebDriver::Wait.new(timeout: 30)
34
+ wait.until { running? }
35
+ puts "Appium Server is running - PID = #{process.pid}"
36
+ end
37
+
38
+ #
39
+ # Check to see if Appium Server is running
40
+ #
41
+ def running?
42
+ response = nil
43
+ begin
44
+ response = Net::HTTP.get_response(URI('http://127.0.0.1:4723/wd/hub/sessions'))
45
+ rescue
46
+ end
47
+ response && response.code_type == Net::HTTPOK
48
+ end
49
+
50
+ #
51
+ # Stop the Appium Server
52
+ #
53
+ def stop
54
+ process.stop
55
+ puts 'Appium Server has been terminated'
56
+ end
57
+
58
+ private
59
+
60
+ def parameters
61
+ cmd = ['appium']
62
+ @params.each do |key, value|
63
+ cmd << '--' + key.to_s
64
+ cmd << value.to_s if not value.nil? and value.size > 0
65
+ end
66
+ cmd
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,180 @@
1
+ require 'test/unit'
2
+
3
+ module TestCentricity
4
+ class ScreenObject
5
+ include Test::Unit::Assertions
6
+
7
+ attr_reader :strategy, :locator
8
+
9
+ def initialize
10
+ raise "Screen object #{self.class.name} does not have a page_locator trait defined" unless defined?(page_locator)
11
+ @strategy = page_locator[0].to_sym
12
+ @locator = page_locator[1]
13
+ end
14
+
15
+ def self.trait(trait_name, &block)
16
+ define_method(trait_name.to_s, &block)
17
+ end
18
+
19
+ def self.element(element_name, strategy, locator)
20
+ class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::AppUIElement.new("#{element_name}", self, "#{strategy}", "#{locator}", :page);end))
21
+ end
22
+
23
+ def self.button(element_name, strategy, locator)
24
+ class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::AppButton.new("#{element_name}", self, "#{strategy}", "#{locator}", :page);end))
25
+ end
26
+
27
+ def self.textfield(element_name, strategy, locator)
28
+ class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::AppTextField.new("#{element_name}", self, "#{strategy}", "#{locator}", :page);end))
29
+ end
30
+
31
+ def self.switch(element_name, strategy, locator)
32
+ class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::AppSwitch.new("#{element_name}", self, "#{strategy}", "#{locator}", :page);end))
33
+ end
34
+
35
+ def self.checkbox(element_name, strategy, locator)
36
+ class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::AppCheckBox.new("#{element_name}", self, "#{strategy}", "#{locator}", :page);end))
37
+ end
38
+
39
+ def self.label(element_name, strategy, locator)
40
+ class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::AppLabel.new("#{element_name}", self, "#{strategy}", "#{locator}", :page);end))
41
+ end
42
+
43
+ def self.list(element_name, strategy, locator)
44
+ class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::AppList.new("#{element_name}", self, "#{strategy}", "#{locator}", :page);end))
45
+ end
46
+
47
+ def self.section(section_name, class_name)
48
+ class_eval(%(def #{section_name};@#{section_name} ||= #{class_name}.new("#{section_name}", self, :page);end))
49
+ end
50
+
51
+ def open_portal
52
+ environment = Environ.current
53
+
54
+ Environ.portal_state = :open
55
+ end
56
+
57
+ def verify_page_exists
58
+ wait = Selenium::WebDriver::Wait.new(timeout: Environ.default_max_wait_time)
59
+ wait.until { $driver.find_element(@strategy.to_sym, @locator).displayed? }
60
+ PageManager.current_page = self
61
+ rescue
62
+ raise "Could not find page_locator for screen object '#{self.class.name}' (:#{@strategy}, #{@locator}) after #{Environ.default_max_wait_time} seconds"
63
+ end
64
+
65
+ def navigate_to; end
66
+
67
+ def verify_page_ui; end
68
+
69
+ def load_page
70
+ verify_page_exists
71
+ PageManager.current_page = self
72
+ end
73
+
74
+
75
+
76
+ def verify_ui_states(ui_states)
77
+ ui_states.each do |ui_object, object_states|
78
+ object_states.each do |property, state|
79
+
80
+
81
+ puts "#{ui_object.get_name} - #{property} = #{state}" if ENV['DEBUG']
82
+
83
+
84
+ case property
85
+ when :exists
86
+ actual = ui_object.exists?
87
+ when :enabled
88
+ actual = ui_object.enabled?
89
+ when :disabled
90
+ actual = ui_object.disabled?
91
+ when :visible
92
+ actual = ui_object.visible?
93
+ when :hidden
94
+ actual = ui_object.hidden?
95
+ when :checked
96
+ actual = ui_object.checked?
97
+ when :selected
98
+ actual = ui_object.selected?
99
+ when :value
100
+ actual = ui_object.get_value
101
+ when :caption
102
+ actual = ui_object.get_caption
103
+ when :name
104
+ actual = ui_object.tag_name
105
+ when :placeholder
106
+ actual = ui_object.get_placeholder
107
+ when :items
108
+ actual = ui_object.get_list_items
109
+ when :itemcount
110
+ actual = ui_object.get_item_count
111
+ end
112
+
113
+ if state.is_a?(Hash) && state.length == 1
114
+ error_msg = "Expected UI object '#{ui_object.get_name}' (#{ui_object.get_locator}) #{property} property to"
115
+ state.each do |key, value|
116
+ case key
117
+ when :lt, :less_than
118
+ ExceptionQueue.enqueue_exception("#{error_msg} be less than #{value} but found '#{actual}'") unless actual < value
119
+ when :lt_eq, :less_than_or_equal
120
+ ExceptionQueue.enqueue_exception("#{error_msg} be less than or equal to #{value} but found '#{actual}'") unless actual <= value
121
+ when :gt, :greater_than
122
+ ExceptionQueue.enqueue_exception("#{error_msg} be greater than #{value} but found '#{actual}'") unless actual > value
123
+ when :gt_eq, :greater_than_or_equal
124
+ ExceptionQueue.enqueue_exception("#{error_msg} be greater than or equal to #{value} but found '#{actual}'") unless actual >= value
125
+ when :starts_with
126
+ ExceptionQueue.enqueue_exception("#{error_msg} start with '#{value}' but found '#{actual}'") unless actual.start_with?(value)
127
+ when :ends_with
128
+ ExceptionQueue.enqueue_exception("#{error_msg} end with '#{value}' but found '#{actual}'") unless actual.end_with?(value)
129
+ when :contains
130
+ ExceptionQueue.enqueue_exception("#{error_msg} contain '#{value}' but found '#{actual}'") unless actual.include?(value)
131
+ when :not_contains, :does_not_contain
132
+ ExceptionQueue.enqueue_exception("#{error_msg} not contain '#{value}' but found '#{actual}'") if actual.include?(value)
133
+ when :not_equal
134
+ ExceptionQueue.enqueue_exception("#{error_msg} not equal '#{value}' but found '#{actual}'") if actual == value
135
+ when :like, :is_like
136
+ actual_like = actual.delete("\n")
137
+ actual_like = actual_like.delete("\r")
138
+ actual_like = actual_like.delete("\t")
139
+ actual_like = actual_like.delete(' ')
140
+ actual_like = actual_like.downcase
141
+ expected = value.delete("\n")
142
+ expected = expected.delete("\r")
143
+ expected = expected.delete("\t")
144
+ expected = expected.delete(' ')
145
+ expected = expected.downcase
146
+ ExceptionQueue.enqueue_exception("#{error_msg} be like '#{value}' but found '#{actual}'") unless actual_like.include?(expected)
147
+ when :translate
148
+ expected = I18n.t(value)
149
+ ExceptionQueue.enqueue_assert_equal(expected, actual, "Expected UI object '#{ui_object.get_name}' (#{ui_object.get_locator}) translated #{property} property")
150
+ end
151
+ end
152
+ else
153
+ ExceptionQueue.enqueue_assert_equal(state, actual, "Expected UI object '#{ui_object.get_name}' (#{ui_object.get_locator}) #{property} property")
154
+ end
155
+ end
156
+ end
157
+ ExceptionQueue.post_exceptions
158
+ end
159
+
160
+ def populate_data_fields(data, wait_time = nil)
161
+ timeout = wait_time.nil? ? 5 : wait_time
162
+ data.each do |data_field, data_param|
163
+ unless data_param.blank?
164
+ # make sure the intended UI target element is visible before trying to set its value
165
+ data_field.wait_until_visible(timeout)
166
+ if data_param == '!DELETE'
167
+ data_field.clear
168
+ else
169
+ case data_field.get_object_type
170
+ when :checkbox
171
+ data_field.set_checkbox_state(data_param.to_bool)
172
+ when :textfield
173
+ data_field.set("#{data_param}\t")
174
+ end
175
+ end
176
+ end
177
+ end
178
+ end
179
+ end
180
+ end
@@ -0,0 +1,332 @@
1
+ require 'test/unit'
2
+
3
+ module TestCentricity
4
+ class ScreenSection
5
+ include Test::Unit::Assertions
6
+
7
+ attr_reader :context, :name
8
+ attr_accessor :locator
9
+ attr_accessor :parent
10
+ attr_accessor :strategy
11
+ attr_accessor :parent_list
12
+ attr_accessor :list_index
13
+
14
+ def initialize(name, parent, context)
15
+ @name = name
16
+ @parent = parent
17
+ @context = context
18
+ @parent_list = nil
19
+ @list_index = nil
20
+ @strategy = nil
21
+ @locator = nil
22
+ end
23
+
24
+ def get_locator
25
+ if @locator.nil? && defined?(section_locator)
26
+ @strategy = section_locator[0]
27
+ @locator = section_locator[1]
28
+ end
29
+
30
+ locators = []
31
+ if @context == :section && !@parent.nil?
32
+ parent_strategy, parent_locator = @parent.get_locator
33
+ end
34
+
35
+ if @parent_list.nil?
36
+ if parent_strategy == @strategy
37
+ locators.push([@strategy, @locator])
38
+ else
39
+ locators.push([parent_strategy, parent_locator]) unless parent_strategy.nil?
40
+ locators.push([@strategy, "#{parent_locator}#{@locator}"])
41
+ end
42
+ else
43
+ list_strategy, list_locator = @parent_list.get_locator
44
+ if parent_strategy == list_strategy
45
+ list_locator = "#{parent_locator}#{list_locator}"
46
+ else
47
+ locators.push([parent_strategy, parent_locator]) unless parent_strategy.nil?
48
+ end
49
+ if list_strategy == @strategy
50
+ obj_locator = "#{list_locator}#{@locator}"
51
+ else
52
+ obj_locator = @locator
53
+ locators.push([list_strategy, list_locator])
54
+ end
55
+ unless @list_index.nil?
56
+ obj_locator = "#{obj_locator}[#{@list_index}]"
57
+ end
58
+ locators.push([@strategy, obj_locator])
59
+ end
60
+ locators
61
+ end
62
+
63
+
64
+ def set_list_index(list, index = 1)
65
+ @parent_list = list unless list.nil?
66
+ @list_index = index
67
+ end
68
+
69
+ def get_item_count
70
+ raise 'No parent list defined' if @parent_list.nil?
71
+ @parent_list.get_item_count
72
+ end
73
+
74
+ def get_list_items
75
+ items = []
76
+ (1..get_item_count).each do |item|
77
+ set_list_index(nil, item)
78
+ items.push(get_value)
79
+ end
80
+ items
81
+ end
82
+
83
+ def get_object_type
84
+ :section
85
+ end
86
+
87
+ def get_name
88
+ @name
89
+ end
90
+
91
+ def set_parent(parent)
92
+ @parent = parent
93
+ end
94
+
95
+
96
+ def self.trait(trait_name, &block)
97
+ define_method(trait_name.to_s, &block)
98
+ end
99
+
100
+ def self.element(element_name, strategy, locator)
101
+ class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::AppUIElement.new("#{element_name}", self, "#{strategy}", "#{locator}", :section);end))
102
+ end
103
+
104
+ def self.button(element_name, strategy, locator)
105
+ class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::AppButton.new("#{element_name}", self, "#{strategy}", "#{locator}", :section);end))
106
+ end
107
+
108
+ def self.textfield(element_name, strategy, locator)
109
+ class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::AppTextField.new("#{element_name}", self, "#{strategy}", "#{locator}", :section);end))
110
+ end
111
+
112
+ def self.switch(element_name, strategy, locator)
113
+ class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::AppSwitch.new("#{element_name}", self, "#{strategy}", "#{locator}", :section);end))
114
+ end
115
+
116
+ def self.checkbox(element_name, strategy, locator)
117
+ class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::AppCheckBox.new("#{element_name}", self, "#{strategy}", "#{locator}", :section);end))
118
+ end
119
+
120
+ def self.label(element_name, strategy, locator)
121
+ class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::AppLabel.new("#{element_name}", self, "#{strategy}", "#{locator}", :section);end))
122
+ end
123
+
124
+ def self.list(element_name, strategy, locator)
125
+ class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::AppList.new("#{element_name}", self, "#{strategy}", "#{locator}", :section);end))
126
+ end
127
+
128
+ def self.section(section_name, class_name)
129
+ class_eval(%(def #{section_name};@#{section_name} ||= #{class_name}.new("#{section_name}", self, :section);end))
130
+ end
131
+
132
+
133
+
134
+ def click
135
+ section = find_section
136
+ raise "Section object '#{get_name}' (#{get_locator}) not found" unless section
137
+ section.click
138
+ end
139
+
140
+ def tap
141
+ section = find_section
142
+ raise "Section object '#{get_name}' (#{get_locator}) not found" unless section
143
+ x = section.location.x
144
+ y = section.location.y
145
+ tap_action = Appium::TouchAction.new.tap(element: section, x: x, y: y)
146
+ tap_action.perform
147
+ end
148
+
149
+ def double_tap
150
+ section = find_section
151
+ raise "Section object '#{get_name}' (#{get_locator}) not found" unless section
152
+ x = section.location.x
153
+ y = section.location.y
154
+ tap_action = Appium::TouchAction.new.double_tap(element: section, x: x, y: y)
155
+ tap_action.perform
156
+ end
157
+
158
+ def exists?
159
+ section = find_section
160
+ section != nil
161
+ end
162
+
163
+ def enabled?
164
+ section = find_section
165
+ raise "Section object '#{get_name}' (#{get_locator}) not found" unless section
166
+ section.enabled?
167
+ end
168
+
169
+ def disabled?
170
+ section = find_section
171
+ raise "Section object '#{get_name}' (#{get_locator}) not found" unless section
172
+ section.enabled?
173
+ end
174
+
175
+ def visible?
176
+ if exists?
177
+ section.displayed?
178
+ else
179
+ false
180
+ end
181
+ end
182
+
183
+ def hidden?
184
+ !visible?
185
+ end
186
+
187
+ def wait_until_exists(seconds = nil)
188
+ timeout = seconds.nil? ? Environ.default_max_wait_time : seconds
189
+ wait = Selenium::WebDriver::Wait.new(timeout: timeout)
190
+ wait.until { exists? }
191
+ rescue
192
+ raise "Could not find Section object '#{get_name}' (#{get_locator}) after #{timeout} seconds" unless exists?
193
+ end
194
+
195
+ def wait_until_gone(seconds = nil)
196
+ timeout = seconds.nil? ? Environ.default_max_wait_time : seconds
197
+ wait = Selenium::WebDriver::Wait.new(timeout: timeout)
198
+ wait.until { !exists? }
199
+ rescue
200
+ raise "Section object '#{get_name}' (#{get_locator}) remained visible after #{timeout} seconds" if exists?
201
+ end
202
+
203
+ def wait_until_visible(seconds = nil)
204
+ timeout = seconds.nil? ? Environ.default_max_wait_time : seconds
205
+ wait = Selenium::WebDriver::Wait.new(timeout: timeout)
206
+ wait.until { visible? }
207
+ rescue
208
+ raise "Could not find Section object '#{get_name}' (#{get_locator}) after #{timeout} seconds" unless visible?
209
+ end
210
+
211
+ def wait_until_hidden(seconds = nil)
212
+ timeout = seconds.nil? ? Environ.default_max_wait_time : seconds
213
+ wait = Selenium::WebDriver::Wait.new(timeout: timeout)
214
+ wait.until { hidden? }
215
+ rescue
216
+ raise "Section object '#{get_name}' (#{get_locator}) remained visible after #{timeout} seconds" if visible?
217
+ end
218
+
219
+
220
+ def verify_ui_states(ui_states)
221
+ ui_states.each do |ui_object, object_states|
222
+ object_states.each do |property, state|
223
+
224
+
225
+ puts "#{ui_object.get_name} - #{property} = #{state}" if ENV['DEBUG']
226
+
227
+
228
+ case property
229
+ when :exists
230
+ actual = ui_object.exists?
231
+ when :enabled
232
+ actual = ui_object.enabled?
233
+ when :disabled
234
+ actual = ui_object.disabled?
235
+ when :visible
236
+ actual = ui_object.visible?
237
+ when :hidden
238
+ actual = ui_object.hidden?
239
+ when :checked
240
+ actual = ui_object.checked?
241
+ when :selected
242
+ actual = ui_object.selected?
243
+ when :value
244
+ actual = ui_object.get_value
245
+ when :caption
246
+ actual = ui_object.get_caption
247
+ when :name
248
+ actual = ui_object.tag_name
249
+ when :placeholder
250
+ actual = ui_object.get_placeholder
251
+ when :items
252
+ actual = ui_object.get_list_items
253
+ when :itemcount
254
+ actual = ui_object.get_item_count
255
+ end
256
+
257
+ if state.is_a?(Hash) && state.length == 1
258
+ error_msg = "Expected UI object '#{ui_object.get_name}' (#{ui_object.get_locator}) #{property} property to"
259
+ state.each do |key, value|
260
+ case key
261
+ when :lt, :less_than
262
+ ExceptionQueue.enqueue_exception("#{error_msg} be less than #{value} but found '#{actual}'") unless actual < value
263
+ when :lt_eq, :less_than_or_equal
264
+ ExceptionQueue.enqueue_exception("#{error_msg} be less than or equal to #{value} but found '#{actual}'") unless actual <= value
265
+ when :gt, :greater_than
266
+ ExceptionQueue.enqueue_exception("#{error_msg} be greater than #{value} but found '#{actual}'") unless actual > value
267
+ when :gt_eq, :greater_than_or_equal
268
+ ExceptionQueue.enqueue_exception("#{error_msg} be greater than or equal to #{value} but found '#{actual}'") unless actual >= value
269
+ when :starts_with
270
+ ExceptionQueue.enqueue_exception("#{error_msg} start with '#{value}' but found '#{actual}'") unless actual.start_with?(value)
271
+ when :ends_with
272
+ ExceptionQueue.enqueue_exception("#{error_msg} end with '#{value}' but found '#{actual}'") unless actual.end_with?(value)
273
+ when :contains
274
+ ExceptionQueue.enqueue_exception("#{error_msg} contain '#{value}' but found '#{actual}'") unless actual.include?(value)
275
+ when :not_contains, :does_not_contain
276
+ ExceptionQueue.enqueue_exception("#{error_msg} not contain '#{value}' but found '#{actual}'") if actual.include?(value)
277
+ when :not_equal
278
+ ExceptionQueue.enqueue_exception("#{error_msg} not equal '#{value}' but found '#{actual}'") if actual == value
279
+ when :like, :is_like
280
+ actual_like = actual.delete("\n")
281
+ actual_like = actual_like.delete("\r")
282
+ actual_like = actual_like.delete("\t")
283
+ actual_like = actual_like.delete(' ')
284
+ actual_like = actual_like.downcase
285
+ expected = value.delete("\n")
286
+ expected = expected.delete("\r")
287
+ expected = expected.delete("\t")
288
+ expected = expected.delete(' ')
289
+ expected = expected.downcase
290
+ ExceptionQueue.enqueue_exception("#{error_msg} be like '#{value}' but found '#{actual}'") unless actual_like.include?(expected)
291
+ when :translate
292
+ expected = I18n.t(value)
293
+ ExceptionQueue.enqueue_assert_equal(expected, actual, "Expected UI object '#{ui_object.get_name}' (#{ui_object.get_locator}) translated #{property} property")
294
+ end
295
+ end
296
+ else
297
+ ExceptionQueue.enqueue_assert_equal(state, actual, "Expected UI object '#{ui_object.get_name}' (#{ui_object.get_locator}) #{property} property")
298
+ end
299
+ end
300
+ end
301
+ ExceptionQueue.post_exceptions
302
+ end
303
+
304
+ def populate_data_fields(data, wait_time = nil)
305
+ timeout = wait_time.nil? ? 5 : wait_time
306
+ data.each do |data_field, data_param|
307
+ unless data_param.blank?
308
+ # make sure the intended UI target element is visible before trying to set its value
309
+ data_field.wait_until_visible(timeout)
310
+ if data_param == '!DELETE'
311
+ data_field.clear
312
+ else
313
+ case data_field.get_object_type
314
+ when :checkbox
315
+ data_field.set_checkbox_state(data_param.to_bool)
316
+ when :textfield
317
+ data_field.set("#{data_param}\t")
318
+ end
319
+ end
320
+ end
321
+ end
322
+ end
323
+
324
+ private
325
+
326
+ def find_section
327
+ find_element(@strategy, @locator)
328
+ rescue
329
+ nil
330
+ end
331
+ end
332
+ end