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.
- checksums.yaml +7 -0
- data/lib/automation_object/blue_print.rb +106 -0
- data/lib/automation_object/blue_print_validation/base_validation.rb +44 -0
- data/lib/automation_object/blue_print_validation/common_methods.rb +106 -0
- data/lib/automation_object/blue_print_validation/element_validation.rb +198 -0
- data/lib/automation_object/blue_print_validation/formatted_errors.rb +41 -0
- data/lib/automation_object/blue_print_validation/hook_validation.rb +393 -0
- data/lib/automation_object/blue_print_validation/key_value_constants.rb +75 -0
- data/lib/automation_object/blue_print_validation/modal_validation.rb +37 -0
- data/lib/automation_object/blue_print_validation/screen_modal_common_methods.rb +119 -0
- data/lib/automation_object/blue_print_validation/screen_validation.rb +21 -0
- data/lib/automation_object/blue_print_validation/validation_object.rb +32 -0
- data/lib/automation_object/driver/anonymous.rb +27 -0
- data/lib/automation_object/driver/driver.rb +281 -0
- data/lib/automation_object/driver/element.rb +243 -0
- data/lib/automation_object/element/element.rb +145 -0
- data/lib/automation_object/element/element_array.rb +12 -0
- data/lib/automation_object/element/element_cell.rb +126 -0
- data/lib/automation_object/element/element_group.rb +33 -0
- data/lib/automation_object/element/element_hash.rb +25 -0
- data/lib/automation_object/element/element_helpers.rb +29 -0
- data/lib/automation_object/element/element_methods.rb +134 -0
- data/lib/automation_object/element/elements_helpers.rb +204 -0
- data/lib/automation_object/framework/events.rb +8 -0
- data/lib/automation_object/framework/helpers.rb +101 -0
- data/lib/automation_object/framework/print_objects.rb +67 -0
- data/lib/automation_object/framework/screen_monitor.rb +55 -0
- data/lib/automation_object/framework/screen_routing.rb +310 -0
- data/lib/automation_object/framework/window_helpers.rb +181 -0
- data/lib/automation_object/framework.rb +408 -0
- data/lib/automation_object/hash.rb +6 -0
- data/lib/automation_object/hook_helpers.rb +27 -0
- data/lib/automation_object/logger.rb +179 -0
- data/lib/automation_object/object.rb +22 -0
- data/lib/automation_object/screen/modal.rb +8 -0
- data/lib/automation_object/screen/screen.rb +209 -0
- data/lib/automation_object/screen/screen_hook_helpers.rb +319 -0
- data/lib/automation_object/screen/screen_modal_helpers.rb +101 -0
- data/lib/automation_object/screen/screen_prompt_helpers.rb +21 -0
- data/lib/automation_object/screen/screen_window_helpers.rb +149 -0
- data/lib/automation_object/version.rb +3 -0
- data/lib/automation_object.rb +80 -0
- 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,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
|