automation_object 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
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
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c36cc7abfa4e9979ce44a0944d93226186e95322
4
+ data.tar.gz: 3c7a3f82d088f77f7fc8decb354eeafa5694632d
5
+ SHA512:
6
+ metadata.gz: c2ece489fe81158e7aa27736e461042c8577180215b24cc0f01d0820e46e163b74b3a594dfb8b886fcdcede3426d84ea15ea7660826934d09311b33f7ae8bc68
7
+ data.tar.gz: 3fbbfa38f5f69f88e21eac36987a9b83f030f769bf211412d97dad5501a3ce6e4e1d65f661fdf731c0242579736134c510fe22565df2830eb19bd7f6ebc5bfb3
@@ -0,0 +1,106 @@
1
+ module AutomationObject
2
+ class BluePrint < Hash
3
+ #Static
4
+ @@max_folder_depth = 10
5
+ @@base_directory = nil
6
+ @@validate_blueprint = false
7
+
8
+ def self.max_folder_depth
9
+ @@max_folder_depth
10
+ end
11
+
12
+ def self.max_folder_depth=(value)
13
+ @@max_folder_depth = value
14
+ end
15
+
16
+ def self.base_directory
17
+ @@base_directory
18
+ end
19
+
20
+ def self.base_directory=(value)
21
+ @@base_directory = value
22
+ end
23
+
24
+ def self.validate_blueprint
25
+ @@validate_blueprint
26
+ end
27
+
28
+ def self.validate_blueprint=(value)
29
+ @@validate_blueprint = value
30
+ end
31
+
32
+ #Instance
33
+ def initialize(path)
34
+ full_path = path
35
+ full_path = File.join(@@base_directory, path) if @@base_directory
36
+
37
+ unless File.directory?(full_path)
38
+ raise ArgumentError, "Blue prints directory doesn't exist: #{full_path}"
39
+ end
40
+
41
+ @configuration = Hash.new
42
+ self.merge_directory(full_path)
43
+
44
+ if @@validate_blueprint
45
+ BluePrintValidation::ValidationObject.new(self)
46
+ end
47
+
48
+ self.merge_views
49
+ end
50
+
51
+ def merge_directory(path, depth = 0)
52
+ raise ArgumentError, "Folder depth breached max depth of #{@@max_folder_depth}" if depth > @@max_folder_depth
53
+
54
+ unless File.directory?(path)
55
+ raise ArgumentError, "Blue print path doesn't exist: #{path}"
56
+ end
57
+
58
+ Dir.foreach(path) do |item|
59
+ next if item == '.' or item == '..'
60
+ next if item[0] == '.'
61
+
62
+ file_path = File.join(path, "#{item}")
63
+ if File.directory?(file_path)
64
+ depth = depth + 1
65
+ self.merge_directory("#{path}/#{item}", depth) #call this method again for the subdirectory
66
+ next
67
+ end
68
+
69
+ next unless self.is_yaml_file?(file_path)
70
+
71
+ file_configuration = YAML.load_file(file_path)
72
+ @configuration = @configuration.deep_merge(file_configuration) if file_configuration.class == Hash
73
+ end
74
+
75
+ @configuration.each { |key, value|
76
+ self[key] = value
77
+ }
78
+ end
79
+
80
+ def is_yaml_file?(file_path)
81
+ return (file_path.match(/\.ya?ml$/)) ? true : false
82
+ end
83
+
84
+ def merge_views
85
+ return unless self['screens'].is_a?(Hash)
86
+ return unless self['views'].is_a?(Hash)
87
+
88
+ self['screens'].each { |screen_name, screen_configuration|
89
+ next unless screen_configuration.is_a?(Hash)
90
+ next unless screen_configuration['included_views'].is_a?(Array)
91
+
92
+ screen_configuration['elements'] = Hash.new unless screen_configuration['elements'].class == Hash
93
+
94
+ screen_configuration['included_views'].each { |view|
95
+ next unless self['views'][view].is_a?(Hash)
96
+ self['views'][view]['elements'] = Hash.new unless self['views'][view]['elements'].is_a?(Hash)
97
+ screen_configuration = screen_configuration.deep_merge(self['views'][view])
98
+ }
99
+
100
+ self['screens'][screen_name] = screen_configuration
101
+ }
102
+
103
+ self.delete('views')
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,44 @@
1
+ module AutomationObject
2
+ module BluePrintValidation
3
+ module BaseValidation
4
+ def validate_base
5
+ error_messages = Array.new
6
+
7
+ self.each { |base_key, base_value|
8
+ #Check if valid base keys
9
+ unless KeyValueConstants::BASE_PAIR_TYPES.keys.include?(base_key)
10
+ error_message = "Base level key (#{base_key}) is not a valid key, available base level keys ("
11
+ error_message << KeyValueConstants::BASE_PAIR_TYPES.keys.join(', ').to_s + ')'
12
+ error_messages.push(FormattedErrors::format_message(error_message))
13
+
14
+ next #skip if not a valid key since we are not going to check value
15
+ end
16
+
17
+ #Skip checking if nil, being nice
18
+ next if base_value == nil
19
+
20
+ unless base_value.is_a?(KeyValueConstants::BASE_PAIR_TYPES[base_key])
21
+ error_message = "Base level key (#{base_key}) has an invalid value type, expecting: ("
22
+ error_message << KeyValueConstants::BASE_PAIR_TYPES[base_key].to_s
23
+ error_message << "), got: (#{base_value.class.to_s})"
24
+ error_messages.push(FormattedErrors::format_message(error_message))
25
+
26
+ next #Skip any additional validation on this
27
+ end
28
+
29
+ case base_key
30
+ when 'default_screen'
31
+ unless self.screen_exists?(self[base_key])
32
+ error_message = "(#{base_key}) value has screen that does not exist (#{self[base_key]}), available screens ("
33
+ error_message << self.get_screens.join(', ').to_s
34
+ error_message << ')'
35
+ error_messages.push(FormattedErrors::format_message(error_message))
36
+ end
37
+ end
38
+ }
39
+
40
+ return error_messages
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,106 @@
1
+ module AutomationObject
2
+ module BluePrintValidation
3
+ module CommonMethods
4
+ def get_screens
5
+ screens = Array.new
6
+ return screens unless self.has_key?('screens')
7
+ return screens unless self['screens'].class == Hash
8
+
9
+ screens = self['screens'].keys
10
+ return screens
11
+ end
12
+
13
+ def screen_exists?(screen_name)
14
+ return self.get_screens.include?(screen_name)
15
+ end
16
+
17
+ def view_has_modal?(view_name, modal_name)
18
+ return false unless self.view_exists?(view_name)
19
+
20
+ view_configuration = self['views'][view_name]
21
+ return self.get_modals(view_configuration).include?(modal_name)
22
+ end
23
+
24
+ def get_view_modals(view_name)
25
+ modals = Array.new
26
+ return modals unless self.has_key?('views')
27
+ return modals unless self['views'].class == Hash
28
+ return modals unless self['views'].has_key?(view_name)
29
+
30
+ view_configuration = self['views'][view_name]
31
+ return self.get_modals(view_configuration)
32
+ end
33
+
34
+ def screen_has_modal?(screen_name, modal_name)
35
+ return false unless self.screen_exists?(screen_name)
36
+
37
+ screen_configuration = self['screens'][screen_name]
38
+ return self.get_modals(screen_configuration).include?(modal_name)
39
+ end
40
+
41
+ def get_screen_modals(screen_name)
42
+ modals = Array.new
43
+ return modals unless self.has_key?('screens')
44
+ return modals unless self['screens'].class == Hash
45
+ return modals unless self['screens'].has_key?(screen_name)
46
+
47
+ screen_configuration = self['screens'][screen_name]
48
+ return self.get_modals(screen_configuration)
49
+ end
50
+
51
+ def get_modals(configuration)
52
+ modals = Array.new
53
+
54
+ return modals unless configuration.class == Hash
55
+ return modals unless configuration.has_key?('modals')
56
+ return modals unless configuration['modals'].class == Hash
57
+
58
+ modals = configuration['modals'].keys
59
+ return modals
60
+ end
61
+
62
+ def screen_has_live?(screen_name)
63
+ return false unless self.screen_exists?(screen_name)
64
+
65
+ screen_configuration = self['screens'][screen_name]
66
+ return false unless screen_configuration.class == Hash
67
+
68
+ if screen_configuration.has_key?('live?')
69
+ return true if screen_configuration['live?'].class == Hash
70
+ return false
71
+ end
72
+
73
+ #Check if has views
74
+ return false unless screen_configuration.has_key?('included_views')
75
+ return false unless screen_configuration['included_views'].class == Array
76
+
77
+ #No need to check if views doesn't exit
78
+ return false unless self.has_key?('views')
79
+ return false unless self['views'].class == Hash
80
+
81
+ screen_configuration['included_views'].each { |included_view|
82
+ return false unless self['views'].has_key?(included_view)
83
+ return false unless self['views'][included_view].class == Hash
84
+
85
+ view_configuration = self['views'][included_view]
86
+ return true if view_configuration.has_key?('live?') and view_configuration['live?'].class == Hash
87
+ }
88
+
89
+ return false
90
+ end
91
+
92
+ def view_exists?(view_name)
93
+ return self.get_views.include?(view_name)
94
+ end
95
+
96
+ def get_views
97
+ views = Array.new
98
+ return views unless self.has_key?('views')
99
+ return views unless self['views'].class == Hash
100
+
101
+ views = self['views'].keys
102
+ return views
103
+ end
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,198 @@
1
+ module AutomationObject
2
+ module BluePrintValidation
3
+ module ElementValidation
4
+ def validate_elements
5
+ error_messages = Array.new
6
+
7
+ elements = self.get_elements
8
+
9
+ elements.each { |element|
10
+ #Set level string and get it out of the way
11
+ level_key_string = ''
12
+ if element[:view_name]
13
+ level_key_string = "(views/#{element[:view_name]}/elements)"
14
+ elsif element[:modal_name]
15
+ level_key_string = "(screens/#{element[:screen_name]}/modals/#{element[:modal_name]}/elements)"
16
+ else
17
+ level_key_string = "(screens/#{element[:screen_name]}/elements)"
18
+ end
19
+
20
+ unless element[:element_name].is_a?(String)
21
+ error_message = "#{level_key_string} level key (#{element[:element_name]}) is an invalid key type, expecting: ("
22
+ error_message << String.to_s
23
+ error_message << "), got: (#{element[:element_name].class.to_s})"
24
+ error_messages.push(FormattedErrors::format_message(error_message))
25
+ end
26
+
27
+ #Skip checking if nil, being nice
28
+ next if element[:configuration] == nil
29
+
30
+ unless element[:configuration].is_a?(Hash)
31
+ error_message = "#{level_key_string} level key (#{element[:element_name]}) is an invalid value type, expecting: ("
32
+ error_message << Hash.to_s
33
+ error_message << "), got: (#{element[:configuration].class.to_s})"
34
+ error_messages.push(FormattedErrors::format_message(error_message))
35
+
36
+ next #Skip any additional validation on this
37
+ end
38
+
39
+ element[:configuration].each { |sub_element_key, sub_element_value|
40
+ #Check if valid element keys
41
+ unless KeyValueConstants::ELEMENT_PAIR_TYPES.keys.include?(sub_element_key)
42
+ error_message = "#{level_key_string} level key (#{element[:element_name]}) sub key (#{sub_element_key}) "
43
+ error_message << 'is not a valid key, available (elements) sub level keys ('
44
+ error_message << KeyValueConstants::ELEMENT_PAIR_TYPES.keys.join(', ').to_s + ')'
45
+ error_messages.push(FormattedErrors::format_message(error_message))
46
+
47
+ next #skip if not a valid key since we are not going to check value
48
+ end
49
+
50
+ #Skip checking if nil, being nice
51
+ next if sub_element_value == nil
52
+
53
+ #Check sub element value
54
+ unless sub_element_value.is_a?(KeyValueConstants::ELEMENT_PAIR_TYPES[sub_element_key])
55
+ error_message = "#{level_key_string} level key (#{element[:element_name]}) sub key (#{sub_element_key}) "
56
+ error_message << 'has an invalid value type, expected: ('
57
+ error_message << KeyValueConstants::SCREEN_PAIR_TYPES[sub_element_key].to_s
58
+ error_message << "), got: (#{sub_element_value.class.to_s})"
59
+ error_messages.push(FormattedErrors::format_message(error_message))
60
+
61
+ next #Skip any additional validation on this
62
+ end
63
+
64
+ case sub_element_key
65
+ when 'define_elements_by'
66
+ valid_element_methods = KeyValueConstants::ELEMENT_KEYS + self.get_element_custom_methods(element[:configuration])
67
+
68
+ unless valid_element_methods.include?(sub_element_value)
69
+ error_message = "#{level_key_string} level key (#{element[:element_name]}) sub key (#{sub_element_key}) "
70
+ error_message << 'is not a valid element methods key. Available keys ('
71
+ error_message << valid_element_methods.join(', ')
72
+ error_message << ')'
73
+ error_messages.push(FormattedErrors::format_message(error_message))
74
+ end
75
+ when 'custom_methods'
76
+ sub_element_value.each { |custom_method_name, custom_method_configuration|
77
+ unless custom_method_name.is_a?(String)
78
+ error_message = "#{level_key_string} level key (#{element[:element_name]}) custom_methods sub key (#{custom_method_name}) "
79
+ error_message << 'is not a valid key type, expected: ('
80
+ error_message << String.to_s
81
+ error_message << "), got: (#{custom_method_name.class.to_s})"
82
+ error_messages.push(FormattedErrors::format_message(error_message))
83
+ end
84
+
85
+ unless custom_method_configuration.is_a?(Hash)
86
+ error_message = "#{level_key_string} level key (#{element[:element_name]}) custom_methods sub key (#{custom_method_name}) "
87
+ error_message << 'is not a valid key value type, expected: ('
88
+ error_message << Hash.to_s
89
+ error_message << "), got: (#{custom_method_configuration.class.to_s})"
90
+ error_messages.push(FormattedErrors::format_message(error_message))
91
+
92
+ next
93
+ end
94
+
95
+ custom_method_configuration.each { |custom_method_key, custom_method_value|
96
+ unless KeyValueConstants::ELEMENT_CUSTOM_METHOD_PAIR_TYPES.keys.include?(custom_method_key)
97
+ error_message = "#{level_key_string} level key (#{element[:element_name]}) custom_methods (#{custom_method_name}) method sub key (#{custom_method_key}) "
98
+ error_message << 'is not a valid key, available (custom_methods) sub level keys ('
99
+ error_message << KeyValueConstants::ELEMENT_CUSTOM_METHOD_PAIR_TYPES.keys.join(', ').to_s + ')'
100
+ error_messages.push(FormattedErrors::format_message(error_message))
101
+
102
+ next #skip if not a valid key since we are not going to check value
103
+ end
104
+
105
+ #Skip checking if nil, being nice
106
+ next if custom_method_value == nil
107
+
108
+ unless custom_method_value.is_a?(KeyValueConstants::ELEMENT_CUSTOM_METHOD_PAIR_TYPES[custom_method_key])
109
+ error_message = "#{level_key_string} level key (#{element[:element_name]}) custom_methods (#{custom_method_name}) method sub key (#{custom_method_key}) "
110
+ error_message << 'has an invalid value type, expected: ('
111
+ error_message << KeyValueConstants::ELEMENT_CUSTOM_METHOD_PAIR_TYPES[custom_method_key].to_s
112
+ error_message << "), got: (#{custom_method_value.class.to_s})"
113
+ error_messages.push(FormattedErrors::format_message(error_message))
114
+
115
+ next #Skip any additional validation on this
116
+ end
117
+
118
+ case custom_method_key
119
+ when 'element_method'
120
+ unless KeyValueConstants::ELEMENT_KEYS.include?(custom_method_value)
121
+ error_message = "#{level_key_string} level key (#{element[:element_name]}) custom_methods (#{custom_method_name}) sub key (#{custom_method_key}) "
122
+ error_message << 'is not a valid elements method. Available element methods ('
123
+ error_message << KeyValueConstants::ELEMENT_KEYS.join(', ')
124
+ error_messages.push(FormattedErrors::format_message(error_message))
125
+ end
126
+ end
127
+ }
128
+ }
129
+ end
130
+ }
131
+ }
132
+
133
+ return error_messages
134
+ end
135
+
136
+ def get_element_custom_methods(configuration)
137
+ custom_methods = Array.new
138
+ return custom_methods unless configuration.class == Hash
139
+ return custom_methods unless configuration.has_key?('custom_methods')
140
+ return custom_methods unless configuration['custom_methods'].class == Hash
141
+
142
+ custom_methods = configuration['custom_methods'].keys
143
+ return custom_methods
144
+ end
145
+
146
+ def get_elements
147
+ elements = Array.new
148
+
149
+ if self.has_key?('views') and self['views'].class == Hash
150
+ self['views'].each { |view_name, view_configuration|
151
+ next unless view_configuration.class == Hash
152
+ next unless view_configuration.has_key?('elements')
153
+ next unless view_configuration['elements'].class == Hash
154
+
155
+ view_configuration['elements'].each { |view_element_name, view_element_configuration|
156
+ element = {:view_name => view_name, :element_name => view_element_name,
157
+ :configuration => view_element_configuration}
158
+ elements.push(element)
159
+ }
160
+ }
161
+ end
162
+
163
+ if self.has_key?('screens') and self['screens'].class == Hash
164
+ self['screens'].each { |screen_name, screen_configuration|
165
+ next unless screen_configuration.class == Hash
166
+
167
+ if screen_configuration.has_key?('elements') and screen_configuration['elements'].class == Hash
168
+ screen_configuration['elements'].each { |screen_element_name, screen_element_configuration|
169
+ element = {:screen_name => screen_name, :element_name => screen_element_name,
170
+ :configuration => screen_element_configuration}
171
+ elements.push(element)
172
+ }
173
+ end
174
+
175
+ #Get elements from modals
176
+ next unless screen_configuration.class == Hash
177
+ next unless screen_configuration.has_key?('modals')
178
+ next unless screen_configuration['modals'].class == Hash
179
+
180
+ screen_configuration['modals'].each { |modal_name, modal_configuration|
181
+ next unless modal_configuration.class == Hash
182
+ next unless modal_configuration.has_key?('elements')
183
+ next unless modal_configuration['elements'].class == Hash
184
+
185
+ modal_configuration['elements'].each { |modal_element_name, modal_element_configuration|
186
+ element = {:screen_name => screen_name, :modal_name => modal_name,
187
+ :element_name => modal_element_name, :configuration => modal_element_configuration}
188
+ elements.push(element)
189
+ }
190
+ }
191
+ }
192
+ end
193
+
194
+ return elements
195
+ end
196
+ end
197
+ end
198
+ end
@@ -0,0 +1,41 @@
1
+ module AutomationObject
2
+ module BluePrintValidation
3
+ class FormattedErrors
4
+ MESSAGE_COLOR = :red
5
+ SPECIFIC_VALUE_COLOR = :blue
6
+
7
+ def self.array_to_message(error_messages)
8
+ error_messages.each_with_index { |raw_message, index|
9
+ error_messages[index] = (((index+1).to_s + '. ').colorize(MESSAGE_COLOR) + raw_message)
10
+ error_messages[index] = "\n" + error_messages[index] if index == 0
11
+ }
12
+
13
+ formatted_message = error_messages.join("\n ----- \n")
14
+ formatted_message << "\n ----- \n"
15
+ return formatted_message
16
+ end
17
+
18
+ def self.format_message(error_message)
19
+ specific_values = error_message.scan(/\([^\)]+\)/)
20
+ replaced_string = error_message.gsub(/\([^\)]+\)/, '######')
21
+ message_array = replaced_string.split('######')
22
+
23
+ return error_message.colorize(MESSAGE_COLOR) if specific_values.length == 0
24
+
25
+ formatted_message = ''
26
+ message_array.each_with_index { |message, index|
27
+ formatted_message << message.colorize(MESSAGE_COLOR)
28
+
29
+ next if specific_values[index] == nil
30
+ stripped_specific_value = specific_values[index].gsub(/\(/, '').gsub(/\)/, '')
31
+ final_specific_value = '('.colorize(MESSAGE_COLOR)
32
+ final_specific_value << stripped_specific_value.colorize(SPECIFIC_VALUE_COLOR)
33
+ final_specific_value << ')'.colorize(MESSAGE_COLOR)
34
+ formatted_message << final_specific_value
35
+ }
36
+
37
+ return formatted_message
38
+ end
39
+ end
40
+ end
41
+ end