automation_object 0.0.4

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 (43) hide show
  1. checksums.yaml +7 -0
  2. data/lib/automation_object/blue_print.rb +106 -0
  3. data/lib/automation_object/blue_print_validation/base_validation.rb +44 -0
  4. data/lib/automation_object/blue_print_validation/common_methods.rb +106 -0
  5. data/lib/automation_object/blue_print_validation/element_validation.rb +198 -0
  6. data/lib/automation_object/blue_print_validation/formatted_errors.rb +41 -0
  7. data/lib/automation_object/blue_print_validation/hook_validation.rb +393 -0
  8. data/lib/automation_object/blue_print_validation/key_value_constants.rb +75 -0
  9. data/lib/automation_object/blue_print_validation/modal_validation.rb +37 -0
  10. data/lib/automation_object/blue_print_validation/screen_modal_common_methods.rb +119 -0
  11. data/lib/automation_object/blue_print_validation/screen_validation.rb +21 -0
  12. data/lib/automation_object/blue_print_validation/validation_object.rb +32 -0
  13. data/lib/automation_object/driver/anonymous.rb +27 -0
  14. data/lib/automation_object/driver/driver.rb +281 -0
  15. data/lib/automation_object/driver/element.rb +243 -0
  16. data/lib/automation_object/element/element.rb +145 -0
  17. data/lib/automation_object/element/element_array.rb +12 -0
  18. data/lib/automation_object/element/element_cell.rb +126 -0
  19. data/lib/automation_object/element/element_group.rb +33 -0
  20. data/lib/automation_object/element/element_hash.rb +25 -0
  21. data/lib/automation_object/element/element_helpers.rb +29 -0
  22. data/lib/automation_object/element/element_methods.rb +134 -0
  23. data/lib/automation_object/element/elements_helpers.rb +204 -0
  24. data/lib/automation_object/framework/events.rb +8 -0
  25. data/lib/automation_object/framework/helpers.rb +101 -0
  26. data/lib/automation_object/framework/print_objects.rb +67 -0
  27. data/lib/automation_object/framework/screen_monitor.rb +55 -0
  28. data/lib/automation_object/framework/screen_routing.rb +310 -0
  29. data/lib/automation_object/framework/window_helpers.rb +181 -0
  30. data/lib/automation_object/framework.rb +408 -0
  31. data/lib/automation_object/hash.rb +6 -0
  32. data/lib/automation_object/hook_helpers.rb +27 -0
  33. data/lib/automation_object/logger.rb +179 -0
  34. data/lib/automation_object/object.rb +22 -0
  35. data/lib/automation_object/screen/modal.rb +8 -0
  36. data/lib/automation_object/screen/screen.rb +209 -0
  37. data/lib/automation_object/screen/screen_hook_helpers.rb +319 -0
  38. data/lib/automation_object/screen/screen_modal_helpers.rb +101 -0
  39. data/lib/automation_object/screen/screen_prompt_helpers.rb +21 -0
  40. data/lib/automation_object/screen/screen_window_helpers.rb +149 -0
  41. data/lib/automation_object/version.rb +3 -0
  42. data/lib/automation_object.rb +80 -0
  43. metadata +279 -0
@@ -0,0 +1,408 @@
1
+ module AutomationObject
2
+ class Framework
3
+ include AutomationObject::FrameworkScreenRouting
4
+ include AutomationObject::FrameworkHelpers
5
+ include AutomationObject::FrameworkWindowHelpers
6
+ include AutomationObject::FrameworkPrintObjects
7
+ include AutomationObject::FrameworkScreenMonitor
8
+
9
+ include EventEmitter
10
+ include AutomationObject::FrameworkEvents
11
+
12
+ attr_accessor :driver_object, :configuration,
13
+ :current_screen_class, :previous_screen_class, #Singular
14
+ :current_screen_hash, :previous_screen_hash, #Multiple, base screens on window_handle
15
+ :screen_history_hash, #keys => window_handles, values => array of screen_class_symbols
16
+ :screen_monitor_thread,
17
+ :screen_monitor_mutex_object
18
+
19
+ def initialize(driver, configuration)
20
+ self.screen_monitor_mutex_object = Mutex.new #Mutex for screen monitor threads, operate one at a time, multiple window edge case
21
+
22
+ #Hash for contained screen monitor threads
23
+ self.screen_monitor_thread = Hash.new
24
+
25
+ self.configuration = configuration
26
+
27
+ #Wrap driver object in our Driver for Thread Safe operations
28
+ self.driver_object = AutomationObject::Driver::Driver.new(driver)
29
+ if self.configuration['throttle_driver_methods']
30
+ AutomationObject::Driver::Driver::throttle_methods = self.configuration['throttle_driver_methods']
31
+ end
32
+ if self.configuration['throttle_element_methods']
33
+ AutomationObject::Driver::Element::throttle_methods = self.configuration['throttle_element_methods']
34
+ end
35
+
36
+ #Support multiple windows for Browser
37
+ if self.is_browser?
38
+ self.current_screen_hash = Hash.new
39
+ self.previous_screen_hash = Hash.new
40
+ self.screen_history_hash = Hash.new
41
+ end
42
+
43
+ #Add Screens
44
+ self.add_screens(configuration['screens']) if configuration['screens']
45
+
46
+ #Set Initial Screen
47
+ self.set_initial_screen
48
+ end
49
+
50
+ def respond_to?(method_symbol, include_private = false)
51
+ #Translate method in possible internal storage attribute
52
+ class_symbol = self.translate_string_to_class(method_symbol)
53
+ instance_symbol = class_symbol.to_s.gsub(/^@/, '')
54
+ instance_symbol = "@#{instance_symbol}".to_sym
55
+
56
+ self.instance_variables.each { |instance_variable|
57
+ return true if instance_variable == instance_symbol
58
+ }
59
+
60
+ #If not then do the super on the method_symbol
61
+ super.respond_to?(method_symbol, include_private)
62
+ end
63
+
64
+ def method_missing(screen_name, *args, &block)
65
+ unless self.current_screen_class #Don't think this happens, but throwing an exception for checking
66
+ raise "No current screen defined when calling the screen (#{screen_name})"
67
+ end
68
+
69
+ #Translate screen name to internal class property
70
+ screen_class_symbol = self.translate_string_to_class(screen_name)
71
+ unless self.respond_to?(screen_class_symbol)
72
+ raise ArgumentError, "Screen called (#{screen_name}) has not been defined"
73
+ end
74
+
75
+ #Check for any closed windows and update accordingly
76
+ #Todo: Important!!!! check if this affects anything negatively
77
+ #self.check_closed_windows if self.is_browser?
78
+
79
+ #Return screen object if it is the current screen
80
+ return self.send(screen_class_symbol, *args, &block) if self.current_screen_class == screen_class_symbol
81
+
82
+ #Check mobile, then just switch_to if the screen is already live
83
+ if self.is_browser?
84
+ self.current_screen_hash.each { |window_handle, current_screen_symbol|
85
+ if current_screen_symbol == screen_class_symbol
86
+ self.switch_to_window(window_handle) unless window_handle == self.get_current_window_handle
87
+
88
+ self.current_screen_class = current_screen_symbol
89
+ return self.send(screen_class_symbol, *args, &block)
90
+ end
91
+ }
92
+ end
93
+
94
+ unless self.is_browser?
95
+ self.route_to_screen(self.current_screen_class, screen_class_symbol)
96
+ return self.send(screen_class_symbol, *args, &block)
97
+ end
98
+
99
+ #Screen is not live, then try to route to it
100
+ routed = false
101
+
102
+ self.current_screen_hash.each { |window_handle, current_screen_symbol|
103
+ self.switch_to_window(window_handle)
104
+ self.current_screen_class = current_screen_symbol
105
+
106
+ begin
107
+ self.route_to_screen(self.current_screen_class, screen_class_symbol)
108
+ routed = true
109
+ break
110
+ rescue Exception => e
111
+ puts "Unable to route under #{self.current_screen_class} and #{screen_class_symbol}".colorize(:red)
112
+ ap e
113
+ ap e.message
114
+ ap e.backtrace
115
+ # ignored
116
+ end
117
+ }
118
+
119
+ unless routed
120
+ #Kind of an edge case but can happen
121
+ if self.current_screen_class != screen_class_symbol
122
+ requested_screen = self.translate_class_to_string(screen_class_symbol)
123
+ current_screen = self.translate_class_to_string(self.current_screen_class)
124
+
125
+ raise "Unable to route to screen from any of the current screens. Current Screen (#{current_screen}), Requested Screen (#{requested_screen})"
126
+ end
127
+ end
128
+
129
+ self.send(screen_class_symbol, *args, &block)
130
+ end
131
+
132
+ def set_initial_screen
133
+ if self.is_browser?
134
+ unless self.configuration['base_url']
135
+ raise ArgumentError, 'base_url is required for Browser configurations'
136
+ end
137
+
138
+ begin
139
+ self.driver_object.navigate.to(self.configuration['base_url'])
140
+ rescue Net::ReadTimeout
141
+ sleep(5)
142
+ self.driver_object.navigate.to(self.configuration['base_url'])
143
+ end
144
+ else
145
+ raise ArgumentError, 'App based configuration should not have base_url in configuration' if self.configuration['base_url']
146
+ end
147
+
148
+ #Skip checking live? configurations if default_screen is set
149
+ if self.configuration['default_screen']
150
+ initial_screen_symbol = self.translate_string_to_class(self.configuration['default_screen'])
151
+
152
+ unless self.respond_to?(initial_screen_symbol)
153
+ raise "Default screen #{self.configuration['default_screen']} has not been defined in configuration"
154
+ end
155
+ else
156
+ initial_screen_symbol = self.find_current_screen
157
+ end
158
+
159
+ unless initial_screen_symbol
160
+ raise 'Unable to find the initial screen via live? configurations or no default screen was specified'
161
+ end
162
+
163
+ AutomationObject::Logger::add("Setting as initial screen #{initial_screen_symbol}")
164
+
165
+ self.set_current_screen(initial_screen_symbol)
166
+ end
167
+
168
+ def find_current_screen
169
+ AutomationObject::Logger::add('Looking for possible current screens through screen live? configurations')
170
+
171
+ return nil unless self.configuration['screens'].class == Hash
172
+
173
+ self.configuration['screens'].each_key { |screen_name|
174
+ screen_class_symbol = self.translate_string_to_class(screen_name)
175
+
176
+ next unless self.configuration['screens'][screen_name].class == Hash
177
+ next unless self.configuration['screens'][screen_name]['live?'].class == Hash
178
+
179
+ if self.current_screen?(screen_name)
180
+ AutomationObject::Logger::add("Found current screen #{screen_name}")
181
+ return screen_class_symbol
182
+ end
183
+ }
184
+
185
+ nil
186
+ end
187
+
188
+ def current_screen?(screen_name)
189
+ screen_class_symbol = self.translate_string_to_class(screen_name)
190
+
191
+ #Raise error if screen doesn't exist, shouldn't be called in the first place if it doesn't
192
+ unless self.respond_to?(screen_class_symbol)
193
+ raise ArgumentError, "Screen has not been defined, #{screen_class_symbol}"
194
+ end
195
+
196
+ #Return true if screen doesn't have live configuration, unable to tell if not so just say yeah
197
+ return true unless self.send(screen_class_symbol).has_live_configuration?
198
+
199
+ self.send(self.translate_string_to_class(screen_name)).live?
200
+ end
201
+
202
+ def add_screens(configuration)
203
+ this = self
204
+ configuration.each { |screen_name, screen_configuration|
205
+ #Change name of screen for class storage, allows for method missing
206
+ screen_class_symbol = self.translate_string_to_class(screen_name)
207
+
208
+ #Add screen class to self
209
+ setter = "#{screen_class_symbol}="
210
+ self.class.send(:attr_accessor, screen_class_symbol) unless self.respond_to?(setter)
211
+
212
+ screen_object_options = {
213
+ :framework_object => self,
214
+ :driver_object => self.driver_object,
215
+ :blue_prints => screen_configuration,
216
+ :screen_name => screen_name
217
+ }
218
+
219
+ send setter, Screen.new(screen_object_options)
220
+
221
+ #Add Listeners
222
+ self.send(screen_class_symbol).on :change_screen do |args|
223
+ this.change_screen_listener(args[:screen_class_symbol], args[:created_window_handle])
224
+ end
225
+
226
+ self.send(screen_class_symbol).on :possible_screen_changes do |args|
227
+ this.possible_change_screen_listener(args[:possible_screens], args[:created_window_handle])
228
+ end
229
+
230
+ self.send(screen_class_symbol).on :close_window do |args|
231
+ this.close_window(args[:screen_name], args[:skip_close])
232
+ end
233
+ }
234
+ end
235
+
236
+ def set_previous_screen
237
+ self.set_current_screen(self.previous_screen_class)
238
+ end
239
+
240
+ def reset_screen(screen_class_symbol)
241
+ unless screen_class_symbol.class == Symbol
242
+ raise ArgumentError, 'You need to provide the screen_class_symbol to Framework.reset_screen method'
243
+ end
244
+
245
+ unless self.respond_to?(screen_class_symbol)
246
+ raise ArgumentError, "Screen class symbol provided (#{screen_class_symbol}) has not been defined"
247
+ end
248
+
249
+ unless self.send(screen_class_symbol).class == Screen
250
+ raise ArgumentError, "Requested symbol (#{screen_class_symbol}) is not a Screen class"
251
+ end
252
+
253
+ #Remove listeners
254
+ self.send(screen_class_symbol).reset_screen
255
+ end
256
+
257
+ def set_current_screen(screen_class_symbol, new_window = false)
258
+ AutomationObject::Logger::add("Going to set current screen #{screen_class_symbol}")
259
+
260
+ #Set current_screen_class to previous_screen_class
261
+ self.previous_screen_class = self.current_screen_class
262
+
263
+ #Reset previous screen if needed
264
+ self.reset_screen(self.previous_screen_class) if self.previous_screen_class
265
+
266
+ #Reset new screen just in case
267
+ self.reset_screen(screen_class_symbol)
268
+
269
+ #Sleep if default sleep
270
+ if self.configuration['screen_transition_sleep']
271
+ transition_sleep = self.configuration['screen_transition_sleep'].to_f
272
+ sleep(transition_sleep)
273
+ end
274
+
275
+ #Reset any active modals in classes underneath
276
+ self.send(self.previous_screen_class).active_modal = nil if self.previous_screen_class
277
+
278
+ #Do multiple set current screens if multiple screens
279
+ if self.is_browser?
280
+ self.set_current_screen_multiple(screen_class_symbol, new_window)
281
+ self.wait_for_window_load
282
+ self.wait_for_stable_body_size
283
+ end
284
+
285
+ #Before Load Event
286
+ self.send(screen_class_symbol).before_load
287
+
288
+ #Set current_screen_class
289
+ self.current_screen_class = screen_class_symbol
290
+
291
+ #Emit Screen Change
292
+ self.emit :change_screen, self.translate_class_to_symbol(screen_class_symbol)
293
+
294
+ #Possible Automatic Screen Changes
295
+ screen_configuration = self.send(screen_class_symbol).configuration
296
+ return unless screen_configuration.is_a?(Hash)
297
+ return unless screen_configuration['automatic_screen_changes'].is_a?(Array)
298
+ return if screen_configuration.length == 0
299
+
300
+ AutomationObject::Logger::add("Adding thread listener for screen #{screen_class_symbol}")
301
+ self.screen_monitor_thread[screen_class_symbol] = Thread.new {
302
+ self.screen_monitor_thread_method(screen_class_symbol)
303
+ }
304
+ end
305
+
306
+ def change_screen_listener(screen_class_symbol, created_window_handle = false)
307
+ self.set_current_screen(screen_class_symbol, created_window_handle)
308
+
309
+ unless self.current_screen?(screen_class_symbol)
310
+ screen_name = self.translate_class_to_string(screen_class_symbol)
311
+ possible_screen_symbol = self.find_current_screen
312
+
313
+ message = "Tried to change screen to (#{screen_name}).
314
+ (#{screen_name}) did not pass live? configuration test. "
315
+
316
+ #If it misses the first time around, no need to error out the screen is should be on anyways
317
+ return if possible_screen_symbol == screen_class_symbol
318
+
319
+ if possible_screen_symbol
320
+ possible_screen_name = self.translate_class_to_string(possible_screen_symbol)
321
+ message << "Got (#{possible_screen_name}) screen instead."
322
+ end
323
+
324
+ raise message
325
+ end
326
+ end
327
+
328
+ def possible_change_screen_listener(possible_screens, created_window_handle = false)
329
+ AutomationObject::Logger::add("Going to try to change to possible screens #{possible_screens}")
330
+
331
+ set_new_screen = false
332
+
333
+ possible_screens.each { |possible_screen_name|
334
+ possible_screen_symbol = self.translate_string_to_class(possible_screen_name)
335
+
336
+ begin
337
+ self.set_current_screen(possible_screen_symbol, created_window_handle)
338
+
339
+ if self.current_screen?(possible_screen_name)
340
+ set_new_screen = true
341
+ break #It worked, screen changed
342
+ end
343
+ rescue
344
+ #Unable to set current screen, don't do much
345
+ end
346
+ }
347
+
348
+ return if set_new_screen
349
+
350
+ #Raise message since unable to change to any of the screens
351
+ raise "Unable to change to any of the possible screens #{possible_screens}"
352
+ end
353
+
354
+ def set_current_screen_multiple(screen_class_symbol, new_window = false)
355
+ unless self.current_screen_class
356
+ current_window_handle = self.get_current_window_handle
357
+
358
+ self.current_screen_hash[current_window_handle] = screen_class_symbol
359
+ self.screen_history_hash[current_window_handle] = Array.new
360
+ self.screen_history_hash[current_window_handle].push(screen_class_symbol)
361
+ self.send(screen_class_symbol).window_handle = current_window_handle
362
+
363
+ return
364
+ end
365
+
366
+ switch_to_window_handle = nil
367
+
368
+ if new_window
369
+ self.current_screen_hash[new_window] = screen_class_symbol
370
+ self.switch_to_window(new_window)
371
+ self.screen_history_hash[new_window] = Array.new
372
+ self.screen_history_hash[new_window].push(screen_class_symbol)
373
+ self.send(screen_class_symbol).window_handle = new_window
374
+
375
+ return
376
+ end
377
+
378
+ #Add previous screen to previous screen hash
379
+ if self.current_screen_class and not new_window
380
+ self.current_screen_hash.each { |window_handle, current_screen_symbol|
381
+ if self.current_screen_class == current_screen_symbol
382
+ self.previous_screen_hash[window_handle] = current_screen_symbol
383
+ self.current_screen_hash[window_handle] = screen_class_symbol
384
+ switch_to_window_handle = window_handle
385
+
386
+ unless self.screen_history_hash[window_handle].class == Array
387
+ self.screen_history_hash[window_handle] = Array.new
388
+ end
389
+
390
+ self.screen_history_hash[window_handle].push(screen_class_symbol)
391
+ self.send(screen_class_symbol).window_handle = window_handle
392
+
393
+ break
394
+ end
395
+ }
396
+ end
397
+
398
+ #Switch to window handle if set
399
+ if switch_to_window_handle
400
+ return if self.current_screen_hash.keys.length == 1
401
+
402
+ if switch_to_window_handle != self.get_current_window_handle
403
+ self.switch_to_window(switch_to_window_handle)
404
+ end
405
+ end
406
+ end
407
+ end
408
+ end
@@ -0,0 +1,6 @@
1
+ class ::Hash
2
+ def deep_merge(second)
3
+ merger = proc { |key, v1, v2| Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : v2 }
4
+ self.merge(second, &merger)
5
+ end
6
+ end
@@ -0,0 +1,27 @@
1
+ module AutomationObject
2
+ module HookHelpers
3
+ def do_hook_action(action, timing, created_window_handle = false)
4
+ self.before_mutex_lock if action == 'before'
5
+
6
+ #Return out if it doesn't meet the given requirements
7
+ return unless self.configuration.class == Hash
8
+ return unless self.configuration[action].class == Hash
9
+ return unless self.configuration[action][timing].class == Hash
10
+
11
+ hook_configuration = self.configuration[action][timing].clone
12
+ self.hook(hook_configuration, created_window_handle)
13
+
14
+ self.after_mutex_lock if action == 'after'
15
+ end
16
+
17
+ def before_mutex_lock
18
+ return unless Thread.current == Thread.main
19
+ self.framework_object.screen_monitor_mutex_object.lock
20
+ end
21
+
22
+ def after_mutex_lock
23
+ return unless Thread.current == Thread.main
24
+ self.framework_object.screen_monitor_mutex_object.unlock
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,179 @@
1
+ module AutomationObject
2
+ class Logger
3
+ @@log = Array.new
4
+
5
+ @@output_message_caller_locations = false
6
+ @@output_driver_caller_locations = false
7
+ @@output_driver_element_caller_locations = false
8
+
9
+ def self.output_message_caller_locations
10
+ @@output_message_caller_locations
11
+ end
12
+
13
+ def self.output_message_caller_locations=(value)
14
+ @@output_message_caller_locations = value
15
+ end
16
+
17
+ def self.output_driver_caller_locations
18
+ @@output_driver_caller_locations
19
+ end
20
+
21
+ def self.output_driver_caller_locations=(value)
22
+ @@output_driver_caller_locations = value
23
+ end
24
+
25
+ def self.output_driver_element_caller_locations
26
+ @@output_driver_element_caller_locations
27
+ end
28
+
29
+ def self.output_driver_element_caller_locations=(value)
30
+ @@output_driver_element_caller_locations = value
31
+ end
32
+
33
+ def self.add(message, location = false)
34
+ called_locations = caller_locations
35
+ parsed_message = self::parse_message(message, called_locations, location)
36
+
37
+ @@log.push(parsed_message)
38
+
39
+ if AutomationObject::debug_mode
40
+ self::output_message(parsed_message)
41
+ end
42
+ end
43
+
44
+ def self.add_driver_message(total_time_taken, called_locations, method_symbol, *arguments, &block)
45
+ parsed_message = self::parse_driver_message(total_time_taken, called_locations, method_symbol, *arguments, &block)
46
+
47
+ @@log.push(parsed_message)
48
+
49
+ if AutomationObject::debug_mode
50
+ self::output_driver_message(parsed_message)
51
+ end
52
+ end
53
+
54
+ def self.add_driver_element_message(total_time_taken, called_locations, method_symbol, *arguments, &block)
55
+ parsed_message = self::parse_driver_element_message(total_time_taken, called_locations, method_symbol, *arguments, &block)
56
+
57
+ @@log.push(parsed_message)
58
+
59
+ if AutomationObject::debug_mode
60
+ self::output_driver_element_message(parsed_message)
61
+ end
62
+ end
63
+
64
+ def self.get_thread_message
65
+ return (Thread.main == Thread.current) ? 'main '.colorize(:black) : 'secondary '.colorize(:light_black)
66
+ end
67
+
68
+ def self.parse_message(message, called_locations, location)
69
+ parsed_message = Hash.new
70
+ parsed_message[:message] = message.to_s
71
+ parsed_message[:called_locations] = called_locations
72
+
73
+ #Add which thread this is under
74
+ parsed_message[:thread_name] = self::get_thread_message
75
+
76
+ parsed_message[:location] = 'framework_object'
77
+ return parsed_message unless location.is_a?(Array)
78
+
79
+ parsed_message[:location] << '.'
80
+ location.each { |part|
81
+ parsed_message[:location] << part.to_s + '.'
82
+ }
83
+ parsed_message[:location].gsub!(/\.$/, '')
84
+
85
+ return parsed_message
86
+ end
87
+
88
+ def self.parse_driver_message(total_time_taken, called_locations, method_symbol, *arguments, &block)
89
+ parsed_message = Hash.new
90
+ parsed_message[:driver_message] = true
91
+
92
+ #Add which thread this is under
93
+ parsed_message[:thread_name] = self::get_thread_message
94
+
95
+ parsed_message[:total_time_taken] = total_time_taken.round(4)
96
+ parsed_message[:method_called] = method_symbol.to_s
97
+ parsed_message[:called_locations] = called_locations
98
+
99
+ parsed_message[:arguments] = arguments.to_s
100
+ parsed_message[:arguments] = parsed_message[:arguments].to_s
101
+ return parsed_message
102
+ end
103
+
104
+ def self.parse_driver_element_message(total_time_taken, called_locations, method_symbol, *arguments, &block)
105
+ parsed_message = Hash.new
106
+ parsed_message[:driver_element_message] = true
107
+
108
+ #Add which thread this is under
109
+ parsed_message[:thread_name] = self::get_thread_message
110
+
111
+ parsed_message[:total_time_taken] = total_time_taken.round(4)
112
+ parsed_message[:method_called] = method_symbol.to_s
113
+ parsed_message[:called_locations] = called_locations
114
+ parsed_message[:arguments] = arguments.to_s
115
+
116
+ return parsed_message
117
+ end
118
+
119
+ def self.format_object_name(object_name)
120
+ return false unless object_name
121
+
122
+ return object_name.to_s.gsub(/_class$/, '')
123
+ end
124
+
125
+ def self.output_messages
126
+ @@log.each { |parsed_message|
127
+ self::output_message(parsed_message)
128
+ }
129
+ end
130
+
131
+ def self.output_message(parsed_message)
132
+ return self::output_driver_message(parsed_message) if parsed_message[:driver_message]
133
+ return self::output_driver_element_message(parsed_message) if parsed_message[:driver_element_message]
134
+
135
+ output_string = 'debug: '.colorize(:black)
136
+ output_string << "thread: ".colorize(:cyan)
137
+ output_string << parsed_message[:thread_name]
138
+ output_string << "location: ".colorize(:cyan)
139
+ output_string << "#{parsed_message[:location]} "
140
+ output_string << "message: ".colorize(:cyan)
141
+ output_string << "#{parsed_message[:message]} "
142
+
143
+ Kernel.puts output_string #Just in case you're running under Cucumber
144
+ if self.output_message_caller_locations
145
+ Kernel.ap parsed_message[:called_locations] if parsed_message[:called_locations]
146
+ end
147
+ end
148
+
149
+ def self.output_driver_message(parsed_message)
150
+ output_string = "driver call (#{parsed_message[:total_time_taken]} S): ".colorize(:light_black)
151
+ output_string << "thread: ".colorize(:cyan)
152
+ output_string << parsed_message[:thread_name]
153
+ output_string << "method: ".colorize(:cyan)
154
+ output_string << "#{parsed_message[:method_called]} "
155
+ output_string << "args: ".colorize(:cyan)
156
+ output_string << "#{parsed_message[:arguments]} "
157
+
158
+ Kernel.puts output_string #Just in case you're running under Cucumber
159
+ if self.output_driver_caller_locations
160
+ Kernel.ap parsed_message[:called_locations] if parsed_message[:called_locations]
161
+ end
162
+ end
163
+
164
+ def self.output_driver_element_message(parsed_message)
165
+ output_string = "driver element call (#{parsed_message[:total_time_taken]} S): ".colorize(:light_black)
166
+ output_string << "thread: ".colorize(:cyan)
167
+ output_string << parsed_message[:thread_name]
168
+ output_string << "method: ".colorize(:cyan)
169
+ output_string << "#{parsed_message[:method_called]} "
170
+ output_string << "args: ".colorize(:cyan)
171
+ output_string << "#{parsed_message[:arguments]} "
172
+
173
+ Kernel.puts output_string #Just in case you're running under Cucumber
174
+ if self.output_driver_element_caller_locations
175
+ Kernel.ap parsed_message[:called_locations] if parsed_message[:called_locations]
176
+ end
177
+ end
178
+ end
179
+ end
@@ -0,0 +1,22 @@
1
+ class ::Object
2
+ def translate_string_to_class(name)
3
+ name_string = name.to_s.gsub('=', '')
4
+
5
+ if name_string.match(/_class$/)
6
+ class_string = name_string
7
+ else
8
+ class_string = name_string + '_class'
9
+ end
10
+
11
+ class_string.to_sym
12
+ end
13
+
14
+ def translate_class_to_string(class_symbol)
15
+ class_symbol.to_s.gsub(/_class$/, '')
16
+ end
17
+
18
+ def translate_class_to_symbol(class_symbol)
19
+ class_string = class_symbol.to_s.gsub(/_class$/, '')
20
+ return class_string.to_sym
21
+ end
22
+ end
@@ -0,0 +1,8 @@
1
+ module AutomationObject
2
+ class Modal < Screen
3
+ def initialize(modal_name, params)
4
+ super(params)
5
+ self.framework_location = self.framework_location + ".#{modal_name}"
6
+ end
7
+ end
8
+ end