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,393 @@
1
+ module AutomationObject
2
+ module BluePrintValidation
3
+ module HookValidation
4
+ def validate_hooks
5
+ error_messages = Array.new
6
+
7
+ hooks = self.get_hooks
8
+ hooks.each { |hook|
9
+ #Set level string and get it out of the way
10
+ level_key_string = self.get_hook_level(hook)
11
+
12
+ #Skip checking if nil, being nice
13
+ next if hook[:configuration] == nil
14
+
15
+ unless hook[:configuration].is_a?(Hash)
16
+ error_message = "(#{level_key_string}) hook key (#{hook[:hook_name]}) is an invalid value type, expecting: ("
17
+ error_message << Hash.to_s
18
+ error_message << "), got: (#{hook[:configuration].class.to_s})"
19
+ error_messages.push(FormattedErrors::format_message(error_message))
20
+
21
+ next #Skip any additional validation on this
22
+ end
23
+
24
+ #before_load has no sub actions so go straight to validate_hook_action and skip this validation
25
+ if hook[:hook_name] == 'before_load'
26
+ error_messages += self.validate_hook_action(hook, hook[:hook_name], hook[:configuration])
27
+ next
28
+ end
29
+
30
+ hook[:configuration].each { |hook_action, hook_action_configuration|
31
+ #Check if valid element keys
32
+ hook_pair_types = KeyValueConstants::HOOK_PAIR_TYPES.clone
33
+ hook_pair_types.delete('elements') unless hook[:hook_name] == 'live?'
34
+
35
+ unless hook_pair_types.keys.include?(hook_action)
36
+ error_message = "(#{level_key_string}) level key (#{hook[:hook_name]}) sub key (#{hook_action}) "
37
+ error_message << 'is not a valid key, available hook sub level keys ('
38
+ error_message << hook_pair_types.keys.join(', ').to_s + ')'
39
+ error_messages.push(FormattedErrors::format_message(error_message))
40
+
41
+ next #skip if not a valid key since we are not going to check value
42
+ end
43
+
44
+ #Skip checking if nil, being nice
45
+ next if hook_action_configuration == nil
46
+
47
+ #Check sub element value
48
+ unless hook_action_configuration.is_a?(KeyValueConstants::HOOK_PAIR_TYPES[hook_action])
49
+ error_message = "(#{level_key_string}) level key (#{hook[:hook_name]}) sub key (#{hook_action}) "
50
+ error_message << 'has an invalid value type, expected: ('
51
+ error_message << KeyValueConstants::HOOK_PAIR_TYPES[hook_action].to_s
52
+ error_message << "), got: (#{hook_action_configuration.class.to_s})"
53
+ error_messages.push(FormattedErrors::format_message(error_message))
54
+
55
+ next #Skip any additional validation on this
56
+ end
57
+
58
+ error_messages += self.validate_hook_action(hook, hook_action, hook_action_configuration)
59
+ }
60
+ }
61
+
62
+ return error_messages
63
+ end
64
+
65
+ def validate_hook_action(hook, action, hook_action_configuration)
66
+ error_messages = Array.new
67
+ return error_messages if hook_action_configuration == nil #Being nice
68
+
69
+ level_key_string = self.get_hook_level(hook, action)
70
+
71
+ #Skip if elements action and use validate_elements_hook
72
+ if action == 'elements'
73
+ return self.validate_elements_hook(hook, action, hook_action_configuration)
74
+ end
75
+
76
+ unless hook_action_configuration.is_a?(Hash)
77
+ error_message = "(#{level_key_string}) hook action is an invalid value type, expecting: ("
78
+ error_message << Hash.to_s
79
+ error_message << "), got: (#{hook_action_configuration.class.to_s})"
80
+ error_messages.push(FormattedErrors::format_message(error_message))
81
+
82
+ return error_messages #Skip any additional validation on this
83
+ end
84
+
85
+ hook_action_configuration.each { |sub_action_key, sub_action_value|
86
+ #Check if valid sub hook action keys
87
+ unless KeyValueConstants::HOOK_ACTION_PAIR_TYPES.keys.include?(sub_action_key)
88
+ error_message = "(#{level_key_string}) level sub key (#{sub_action_key}) "
89
+ error_message << 'is not a valid key, available (hook action) sub level keys ('
90
+ error_message << KeyValueConstants::HOOK_ACTION_PAIR_TYPES.keys.join(', ').to_s + ')'
91
+ error_messages.push(FormattedErrors::format_message(error_message))
92
+
93
+ next #skip if not a valid key since we are not going to check value
94
+ end
95
+
96
+ #Skip checking if nil, being nice
97
+ next if sub_action_value == nil
98
+
99
+ #Check sub hook action value
100
+ unless sub_action_value.is_a?(KeyValueConstants::HOOK_ACTION_PAIR_TYPES[sub_action_key])
101
+ error_message = "(#{level_key_string}) level sub key (#{sub_action_key}) "
102
+ error_message << 'has an invalid value type, expected: ('
103
+ error_message << KeyValueConstants::HOOK_ACTION_PAIR_TYPES[sub_action_key].to_s
104
+ error_message << "), got: (#{sub_action_key.class.to_s})"
105
+ error_messages.push(FormattedErrors::format_message(error_message))
106
+
107
+ next #Skip any additional validation on this
108
+ end
109
+
110
+ #wait_for_elements test with validate_elements_hook, same set up as live?/elements
111
+ if sub_action_key == 'wait_for_elements'
112
+ error_messages += self.validate_elements_hook(hook, action, sub_action_key, sub_action_value)
113
+ next
114
+ end
115
+
116
+ case sub_action_key
117
+ when 'show_modal'
118
+ if hook[:view_name]
119
+ modal_exists = self.view_has_modal?(hook[:view_name], sub_action_value)
120
+ else
121
+ modal_exists = self.screen_has_modal?(hook[:screen_name], sub_action_value)
122
+ end
123
+
124
+ unless modal_exists
125
+ error_message = "(#{level_key_string}) level sub key (#{sub_action_key}) value (#{sub_action_value}) "
126
+ error_message << 'modal does not exist in '
127
+
128
+ if hook[:view_name]
129
+ error_message << "view (#{hook[:view_name]}), available modals ("
130
+ error_message << self.get_view_modals(hook[:view_name]).join(', ')
131
+ error_message << ')'
132
+ else
133
+ error_message << "screen (#{hook[:screen_name]}), available modals ("
134
+ error_message << self.get_screen_modals(hook[:screen_name]).join(', ')
135
+ error_message << ')'
136
+ end
137
+
138
+ error_messages.push(FormattedErrors::format_message(error_message))
139
+ end
140
+ when 'change_screen'
141
+ unless self.screen_exists?(sub_action_value)
142
+ error_message = "(#{level_key_string}/#{sub_action_key}) value (#{sub_action_value}) is not a defined screen. Available screens ("
143
+ error_message << self.get_screens.join(', ')
144
+ error_message << ')'
145
+ error_messages.push(FormattedErrors::format_message(error_message))
146
+ end
147
+ end
148
+ }
149
+
150
+ return error_messages
151
+ end
152
+
153
+ def validate_elements_hook(hook, action, sub_action_key = false, hook_action_configuration)
154
+ error_messages = Array.new
155
+ return error_messages if hook_action_configuration == nil
156
+
157
+ if action == 'before_load'
158
+ action = "#{sub_action_key}" if sub_action_key.is_a?(String)
159
+ else
160
+ action = action + "/#{sub_action_key}" if sub_action_key.is_a?(String)
161
+ end
162
+
163
+ level_key_string = self.get_hook_level(hook, action)
164
+
165
+ unless hook_action_configuration.is_a?(Array)
166
+ error_message = "(#{level_key_string}) level key is an invalid value type, expecting: ("
167
+ error_message << Array.to_s
168
+ error_message << "), got: (#{hook_action_configuration.class.to_s})"
169
+ error_messages.push(FormattedErrors::format_message(error_message))
170
+
171
+ return error_messages #Skip any further validation
172
+ end
173
+
174
+ hook_action_configuration.each_with_index { |element_hash, index|
175
+ unless element_hash.is_a?(Hash)
176
+ error_message = "(#{level_key_string}/#{index.to_s}) level key is an invalid value type, expecting: ("
177
+ error_message << Hash.to_s
178
+ error_message << "), got: (#{element_hash.class.to_s})"
179
+ error_messages.push(FormattedErrors::format_message(error_message))
180
+
181
+ next #Skip any additional validation on this
182
+ end
183
+
184
+ unless element_hash.has_key?('element_name')
185
+ error_message = "(#{level_key_string}/#{index.to_s}) level key Hash requires the element_name key"
186
+ error_message << Hash.to_s
187
+ error_message << "), got: (#{element_hash.class.to_s})"
188
+ error_messages.push(FormattedErrors::format_message(error_message))
189
+ end
190
+
191
+ acceptable_keys = KeyValueConstants::ELEMENT_KEYS + ['element_name']
192
+ acceptable_keys += self.get_element_custom_methods_via_hook(hook, element_hash['element_name'])
193
+ element_hash.each { |sub_element_key, sub_element_value|
194
+ unless acceptable_keys.include?(sub_element_key)
195
+ error_message = "(#{level_key_string}/#{index.to_s}) level sub key (#{sub_element_key}) "
196
+ error_message << 'is not a valid key, available sub level keys ('
197
+ error_message << acceptable_keys.join(', ').to_s + ')'
198
+ error_messages.push(FormattedErrors::format_message(error_message))
199
+
200
+ next #skip if not a valid key since we are not going to check value
201
+ end
202
+ }
203
+ }
204
+
205
+ return error_messages
206
+ end
207
+
208
+ def get_element_custom_methods_via_hook(hook, element_name)
209
+ custom_methods = Array.new
210
+
211
+ if hook[:screen_name]
212
+ return custom_methods unless self.has_key?('screens')
213
+ return custom_methods unless self['screens'].class == Hash
214
+ return custom_methods unless self['screens'].has_key?(hook[:screen_name])
215
+
216
+ configuration = self['screens'][hook[:screen_name]]
217
+ else
218
+ return custom_methods unless self.has_key?('views')
219
+ return custom_methods unless self['views'].class == Hash
220
+ return custom_methods unless self['views'].has_key?(hook[:view_name])
221
+
222
+ configuration = self['views'][hook[:view_name]]
223
+ end
224
+
225
+ if hook[:modals]
226
+ return custom_methods unless configuration.has_key?('modals')
227
+ return custom_methods unless configuration['modals'].class == Hash
228
+ return custom_methods unless configuration['modals'].has_key?(hook[:modal_name])
229
+
230
+ configuration = configuration['modals'][hook[:modal_name]]
231
+ end
232
+
233
+ return custom_methods unless configuration.class == Hash
234
+ return custom_methods unless configuration.has_key?('elements')
235
+ return custom_methods unless configuration['elements'].class == Hash
236
+ return custom_methods unless configuration['elements'].has_key?(element_name)
237
+
238
+ element_configuration = configuration['elements'][element_name]
239
+
240
+ return custom_methods unless element_configuration.class == Hash
241
+ return custom_methods unless element_configuration.has_key?('custom_methods')
242
+ return custom_methods unless element_configuration['custom_methods'].class == Hash
243
+
244
+ return element_configuration['custom_methods'].keys
245
+ end
246
+
247
+ def get_hook_level(hook, hook_action = false)
248
+ level_key_string = ''
249
+ if hook[:view_name]
250
+ level_key_string << "views/#{hook[:view_name]}"
251
+ else
252
+ level_key_string << "screens/#{hook[:screen_name]}"
253
+ end
254
+
255
+ level_key_string << "/modals/#{hook[:modal_name]}" if hook[:modal_name]
256
+ level_key_string << "/elements/#{hook[:element_name]}" if hook[:element_name]
257
+
258
+ level_key_string << "/#{hook[:hook_name]}" if hook[:hook_name]
259
+ level_key_string << "/#{hook_action}" if hook_action and hook_action != 'before_load'
260
+
261
+ return level_key_string
262
+ end
263
+
264
+ def get_hooks
265
+ hooks = Array.new
266
+
267
+ if self.has_key?('views') and self['views'].class == Hash
268
+ self['views'].each { |view_name, view_configuration|
269
+ next unless view_configuration.class == Hash
270
+
271
+ view_configuration.each { |sub_view_key, sub_view_configuration|
272
+ next unless KeyValueConstants::HOOK_KEYS.include?(sub_view_key)
273
+
274
+ hook = {:view_name => view_name, :hook_name => sub_view_key, :configuration => sub_view_configuration}
275
+ hooks.push(hook)
276
+ }
277
+
278
+ #Check for Modals
279
+ if view_configuration.has_key?('modals') and view_configuration['modals'].class == Hash
280
+ view_configuration['modals'].each { |modal_name, modal_configuration|
281
+ next unless modal_configuration.class == Hash
282
+
283
+ modal_configuration.each { |sub_modal_key, sub_modal_configuration|
284
+ next unless KeyValueConstants::HOOK_KEYS.include?(sub_modal_key)
285
+
286
+ hook = {:view_name => view_name, :modal_name => modal_name,
287
+ :hook_name => sub_modal_key, :configuration => sub_modal_configuration}
288
+ hooks.push(hook)
289
+ }
290
+
291
+ next unless modal_configuration.has_key?('elements')
292
+ next unless modal_configuration['elements'].class == Hash
293
+
294
+ modal_configuration['elements'].each { |modal_element_name, modal_element_configuration|
295
+ next unless modal_element_configuration.class == Hash
296
+
297
+ modal_element_configuration.each { |sub_modal_element_key, sub_modal_element_configuration|
298
+ next unless KeyValueConstants::ELEMENT_KEYS.include?(sub_modal_element_key)
299
+
300
+ hook = {:view_name => view_name, :modal_name => modal_name,
301
+ :element_name => modal_element_name, :hook_name => sub_modal_element_key,
302
+ :configuration => sub_modal_element_configuration}
303
+ hooks.push(hook)
304
+ }
305
+ }
306
+ }
307
+ end
308
+
309
+ #Check for element hooks
310
+ next unless view_configuration.has_key?('elements')
311
+ next unless view_configuration['elements'].class == Hash
312
+
313
+ view_configuration['elements'].each { |element_name, element_configuration|
314
+ next unless element_configuration.class == Hash
315
+
316
+ element_configuration.each { |sub_element_key, sub_element_configuration|
317
+ next unless KeyValueConstants::ELEMENT_KEYS.include?(sub_element_key)
318
+
319
+ hook = {:view_name => view_name, :element_name => element_name,
320
+ :hook_name => sub_element_key, :configuration => sub_element_configuration}
321
+ hooks.push(hook)
322
+ }
323
+ }
324
+ }
325
+ end
326
+
327
+ return hooks unless self.has_key?('screens')
328
+ return hooks unless self['screens'].class == Hash
329
+
330
+ self['screens'].each { |screen_name, screen_configuration|
331
+ next unless screen_configuration.class == Hash
332
+
333
+ screen_configuration.each { |sub_screen_key, sub_screen_configuration|
334
+ next unless KeyValueConstants::HOOK_KEYS.include?(sub_screen_key)
335
+
336
+ hook = {:screen_name => screen_name, :hook_name => sub_screen_key,
337
+ :configuration => sub_screen_configuration}
338
+ hooks.push(hook)
339
+ }
340
+
341
+ #Check for Modals
342
+ if screen_configuration.has_key?('modals') and screen_configuration['modals'].class == Hash
343
+ screen_configuration['modals'].each { |modal_name, modal_configuration|
344
+ next unless modal_configuration.class == Hash
345
+
346
+ modal_configuration.each { |sub_modal_key, sub_modal_configuration|
347
+ next unless KeyValueConstants::HOOK_KEYS.include?(sub_modal_key)
348
+
349
+ hook = {:screen_name => screen_name, :modal_name => modal_name,
350
+ :hook_name => sub_modal_key, :configuration => sub_modal_configuration}
351
+ hooks.push(hook)
352
+ }
353
+
354
+ next unless modal_configuration.has_key?('elements')
355
+ next unless modal_configuration['elements'].class == Hash
356
+
357
+ modal_configuration['elements'].each { |modal_element_name, modal_element_configuration|
358
+ next unless modal_element_configuration.class == Hash
359
+
360
+ modal_element_configuration.each { |sub_modal_element_key, sub_modal_element_configuration|
361
+ next unless KeyValueConstants::ELEMENT_KEYS.include?(sub_modal_element_key)
362
+
363
+ hook = {:screen_name => screen_name, :modal_name => modal_name,
364
+ :element_name => modal_element_name, :hook_name => sub_modal_element_key,
365
+ :configuration => sub_modal_element_configuration}
366
+ hooks.push(hook)
367
+ }
368
+ }
369
+ }
370
+ end
371
+
372
+ #Check for element hooks
373
+ next unless screen_configuration.has_key?('elements')
374
+ next unless screen_configuration['elements'].class == Hash
375
+
376
+ screen_configuration['elements'].each { |element_name, element_configuration|
377
+ next unless element_configuration.class == Hash
378
+
379
+ element_configuration.each { |sub_element_key, sub_element_configuration|
380
+ next unless KeyValueConstants::ELEMENT_KEYS.include?(sub_element_key)
381
+
382
+ hook = {:screen_name => screen_name, :element_name => element_name,
383
+ :hook_name => sub_element_key, :configuration => sub_element_configuration}
384
+ hooks.push(hook)
385
+ }
386
+ }
387
+ }
388
+
389
+ return hooks
390
+ end
391
+ end
392
+ end
393
+ end
@@ -0,0 +1,75 @@
1
+ module AutomationObject
2
+ module BluePrintValidation
3
+ module KeyValueConstants
4
+ ELEMENT_KEYS = ['length', 'exists?', 'click', 'visible?', 'invisible?',
5
+ 'id', 'href', 'scroll_to_view', 'x', 'y', 'width', 'height', 'drag_to_element',
6
+ 'get_element_center', 'name', 'value', 'type', 'clear', 'tag_name', 'text',
7
+ 'size', 'location', 'rel_location', 'send_keys', 'set_value', 'displayed?', 'selected?',
8
+ 'attribute', 'clear', 'attribute', 'click', 'css_value', 'displayed?', 'enabled?',
9
+ 'location', 'location_once_scrolled_into_view', 'ref', 'selected?', 'send_keys',
10
+ 'size', 'submit', 'tag_name', 'text', 'content']
11
+
12
+ HOOK_KEYS = ['live?', 'before_load', 'accept', 'dismiss', 'scroll_up', 'scroll_down', 'scroll_right', 'scroll_left']
13
+
14
+ BASE_PAIR_TYPES = {
15
+ 'base_url' => String,
16
+ 'default_screen' => String,
17
+ 'throttle_element_interactions' => Hash,
18
+ 'throttle_element_methods' => Hash,
19
+ 'throttle_driver_methods' => Hash,
20
+ 'screen_transition_sleep' => Numeric,
21
+ 'views' => Hash,
22
+ 'screens' => Hash
23
+ }
24
+
25
+ THROTTLE_ELEMENT_PAIR_TYPES = Hash[*ELEMENT_KEYS.collect { |v| [v, Numeric] }.flatten]
26
+
27
+ SCREEN_PAIR_TYPES = {
28
+ 'modals' => Hash,
29
+ 'included_views' => Array,
30
+ 'automatic_screen_changes' => Array,
31
+ 'elements' => Hash,
32
+ 'element_groups' => Hash
33
+ }.merge(Hash[*HOOK_KEYS.collect { |v| [v, Hash] }.flatten])
34
+
35
+ MODAL_PAIR_TYPES = SCREEN_PAIR_TYPES
36
+
37
+ ELEMENT_PAIR_TYPES = {
38
+ 'in_iframe' => String,
39
+ 'css' => String,
40
+ 'xpath' => String,
41
+ 'multiple' => TrueClass,
42
+ 'multiple_ios_fix' => TrueClass,
43
+ 'define_elements_by' => String,
44
+ 'custom_methods' => Hash,
45
+ 'custom_range' => Hash,
46
+ 'remove_duplicates' => String
47
+ }.merge(Hash[*ELEMENT_KEYS.collect { |v| [v, Hash] }.flatten])
48
+
49
+ ELEMENT_CUSTOM_METHOD_PAIR_TYPES = {
50
+ 'element_method' => String,
51
+ 'evaluate' => String
52
+ }
53
+
54
+ HOOK_PAIR_TYPES = {
55
+ 'before' => Hash,
56
+ 'after' => Hash,
57
+ 'elements' => Array
58
+ }
59
+
60
+ HOOK_ACTION_PAIR_TYPES = {
61
+ 'wait_for_new_window' => TrueClass,
62
+ 'show_modal' => String,
63
+ 'close_window' => TrueClass,
64
+ 'change_screen' => String,
65
+ 'sleep' => Numeric,
66
+ 'wait_for_elements' => Array,
67
+ 'change_to_previous_screen' => TrueClass,
68
+ 'close_modal' => TrueClass,
69
+ 'automatic_onload_modals' => Array,
70
+ 'reset_screen' => TrueClass,
71
+ 'possible_screen_changes' => Array
72
+ }
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,37 @@
1
+ module AutomationObject
2
+ module BluePrintValidation
3
+ module ModalValidation
4
+ include ScreenModalCommonMethods
5
+
6
+ def validate_modals
7
+ error_messages = Array.new
8
+
9
+ self.get_all_modals.each { |modal|
10
+ error_messages += self.validate_screen_modal(modal[:screen_name], modal[:modal_name], modal[:configuration])
11
+ }
12
+
13
+ return error_messages
14
+ end
15
+
16
+ def get_all_modals
17
+ modals = Array.new
18
+ return modals unless self.has_key?('screens')
19
+ return modals unless self['screens'].class == Hash
20
+
21
+ self['screens'].each { |screen_name, screen_configuration|
22
+ next unless screen_configuration.class == Hash
23
+ next unless screen_configuration.has_key?('modals')
24
+ next unless screen_configuration['modals'].class == Hash
25
+
26
+ screen_configuration['modals'].each { |modal_name, modal_configuration|
27
+ next if modal_configuration == nil
28
+ modal = {:screen_name => screen_name, :modal_name => modal_name, :configuration => modal_configuration}
29
+ modals.push(modal)
30
+ }
31
+ }
32
+
33
+ return modals
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,119 @@
1
+ module AutomationObject
2
+ module BluePrintValidation
3
+ module ScreenModalCommonMethods
4
+ def validate_screen_modal(screen_name, modal_name = false, configuration)
5
+ error_messages = Array.new
6
+
7
+ if modal_name == false #Skip multiple errors
8
+ unless screen_name.is_a?(String)
9
+ error_message = "(screens) level key (#{screen_name}) is an invalid key type, expecting: ("
10
+ error_message << String.to_s
11
+ error_message << "), got: (#{screen_name.class.to_s})"
12
+ error_messages.push(FormattedErrors::format_message(error_message))
13
+ end
14
+ else
15
+ unless modal_name.is_a?(String)
16
+ error_message = "(screens/#{screen_name}/modals) level key (#{modal_name}) is an invalid key type, expecting: ("
17
+ error_message << String.to_s
18
+ error_message << "), got: (#{modal_name.class.to_s})"
19
+ error_messages.push(FormattedErrors::format_message(error_message))
20
+ end
21
+ end
22
+
23
+ return error_messages if configuration == nil
24
+
25
+ unless configuration.is_a?(Hash)
26
+ if modal_name == false
27
+ error_message = "(screens) level key (#{screen_name}) has an invalid value type, expecting: ("
28
+ else
29
+ error_message = "(screens/#{screen_name}/modals) level key (#{modal_name}) has an invalid value type, expecting: ("
30
+ end
31
+
32
+ error_message << Hash.to_s
33
+ error_message << "), got: (#{configuration.class.to_s})"
34
+ error_messages.push(FormattedErrors::format_message(error_message))
35
+
36
+ return error_messages
37
+ end
38
+
39
+ configuration.each { |sub_screen_key, sub_screen_value|
40
+ #Check if valid screen keys
41
+ unless KeyValueConstants::SCREEN_PAIR_TYPES.keys.include?(sub_screen_key)
42
+ if modal_name == false
43
+ error_message = "(screens) level key (#{screen_name}) sub key (#{sub_screen_key}) "
44
+ else
45
+ error_message = "(screens/#{screen_name}/modals) level key (#{modal_name}) sub key (#{sub_screen_key}) "
46
+ end
47
+
48
+ error_message << 'is not a valid key, available (screens) sub level keys ('
49
+ error_message << KeyValueConstants::SCREEN_PAIR_TYPES.keys.join(', ').to_s + ')'
50
+ error_messages.push(FormattedErrors::format_message(error_message))
51
+
52
+ next #skip if not a valid key since we are not going to check value
53
+ end
54
+
55
+ #Skip checking if nil, being nice
56
+ next if sub_screen_value == nil
57
+
58
+ #Check sub screen value
59
+ unless sub_screen_value.is_a?(KeyValueConstants::SCREEN_PAIR_TYPES[sub_screen_key])
60
+ if modal_name == false
61
+ error_message = "(screens) level key (#{screen_name}) sub key (#{sub_screen_key}) "
62
+ else
63
+ error_message = "(screens/#{screen_name}/modals) level key (#{screen_name}) sub key (#{sub_screen_key}) "
64
+ end
65
+
66
+ error_message << 'has an invalid value type, expected: ('
67
+ error_message << KeyValueConstants::SCREEN_PAIR_TYPES[sub_screen_key].to_s
68
+ error_message << "), got: (#{sub_screen_value.class.to_s})"
69
+ error_messages.push(FormattedErrors::format_message(error_message))
70
+
71
+ next #Skip any additional validation on this
72
+ end
73
+
74
+ #More complex validation
75
+ case sub_screen_key
76
+ when 'included_views'
77
+ sub_screen_value.each { |included_view|
78
+ unless self.view_exists?(included_view)
79
+ if modal_name == false
80
+ error_message = "(screens) level key (#{screen_name}) sub key (#{sub_screen_key}) "
81
+ else
82
+ error_message = "(screens/#{screen_name}/modals) level key (#{screen_name}) sub key (#{sub_screen_key}) "
83
+ end
84
+
85
+ error_message << "included_view (#{included_view}) does not exist. Available views ("
86
+ error_message << self.get_views.join(', ')
87
+ error_message << ')'
88
+ error_messages.push(FormattedErrors::format_message(error_message))
89
+ end
90
+ }
91
+ when 'automatic_screen_changes'
92
+ sub_screen_value.each { |automatic_screen_change|
93
+ unless self.screen_exists?(automatic_screen_change)
94
+ error_message = "(screens) level key (#{screen_name}) sub key (#{sub_screen_key}) "
95
+ error_message << "screen (#{automatic_screen_change}) does not exist. Available screens ("
96
+ error_message << self.get_screens.join(', ')
97
+ error_message << ')'
98
+ error_messages.push(FormattedErrors::format_message(error_message))
99
+
100
+ next
101
+ end
102
+
103
+ unless self.screen_has_live?(automatic_screen_change)
104
+ error_message = "(screens) level key (#{screen_name}) sub key (#{sub_screen_key}) "
105
+ error_message << "screen (#{automatic_screen_change}) does not have live? configuration. "
106
+ error_message << 'Automatic screen changes need to have associated live? configurations.'
107
+ error_messages.push(FormattedErrors::format_message(error_message))
108
+
109
+ next
110
+ end
111
+ }
112
+ end
113
+ }
114
+
115
+ return error_messages
116
+ end
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,21 @@
1
+ module AutomationObject
2
+ module BluePrintValidation
3
+ module ScreenValidation
4
+ include ScreenModalCommonMethods
5
+
6
+ def validate_screens
7
+ error_messages = Array.new
8
+ return error_messages unless self.has_key?('screens')
9
+ return error_messages unless self['screens'].class == Hash
10
+
11
+ error_messages = Array.new
12
+
13
+ self['screens'].each { |screen_name, screen_configuration|
14
+ error_messages += self.validate_screen_modal(screen_name, screen_configuration)
15
+ }
16
+
17
+ return error_messages
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,32 @@
1
+ module AutomationObject
2
+ module BluePrintValidation
3
+ class ValidationObject < Hash
4
+ include CommonMethods
5
+ include BaseValidation
6
+ include ScreenValidation
7
+ include ModalValidation
8
+ include ElementValidation
9
+ include HookValidation
10
+
11
+ def initialize(blue_print_object)
12
+ #Figured on cloning the Hash Object, probably not needed
13
+ blue_print_object_cloned = blue_print_object.clone
14
+
15
+ blue_print_object_cloned.each { |key, value|
16
+ self[key] = value
17
+ }
18
+
19
+ error_messages = Array.new
20
+ error_messages += self.validate_base #BaseValidation Module
21
+ error_messages += self.validate_screens #ScreenValidation Module
22
+ error_messages += self.validate_modals
23
+ error_messages += self.validate_elements
24
+ error_messages += self.validate_hooks
25
+
26
+ if error_messages.length > 0
27
+ raise FormattedErrors::array_to_message(error_messages)
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end