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,67 @@
|
|
1
|
+
module AutomationObject
|
2
|
+
module FrameworkPrintObjects
|
3
|
+
def print_objects(requested_screen_name = false)
|
4
|
+
puts 'Screens:'.colorize(:green)
|
5
|
+
|
6
|
+
self.instance_variables.each { |automation_variable|
|
7
|
+
automation_variable_value = self.instance_variable_get(automation_variable)
|
8
|
+
next unless automation_variable_value.class == Screen
|
9
|
+
|
10
|
+
screen_name = self.translate_class_to_string(automation_variable).gsub('@', '')
|
11
|
+
|
12
|
+
if requested_screen_name
|
13
|
+
next unless requested_screen_name == screen_name
|
14
|
+
end
|
15
|
+
|
16
|
+
screen_class_symbol = self.translate_string_to_class(screen_name)
|
17
|
+
|
18
|
+
puts "\t#{screen_name}".colorize(:blue)
|
19
|
+
|
20
|
+
self.send(screen_class_symbol).instance_variables.each { |screen_variable|
|
21
|
+
screen_object_name = self.translate_class_to_string(screen_variable).gsub('@', '')
|
22
|
+
screen_object_symbol = self.translate_string_to_class(screen_object_name)
|
23
|
+
|
24
|
+
output = "\t\t#{screen_object_name}".colorize(:magenta)
|
25
|
+
|
26
|
+
begin
|
27
|
+
object_class = self.send(screen_class_symbol).send(screen_object_symbol).class.to_s
|
28
|
+
case object_class
|
29
|
+
when 'AutomationObject::Element'
|
30
|
+
puts output + ' (Element)'.colorize(:green)
|
31
|
+
when 'AutomationObject::ElementHash'
|
32
|
+
puts output + ' (Element Hash)'.colorize(:red)
|
33
|
+
when 'AutomationObject::ElementArray'
|
34
|
+
puts output + ' (Element Array)'.colorize(:blue)
|
35
|
+
when 'AutomationObject::Modal'
|
36
|
+
puts output + ' (Modal)'.colorize(:cyan)
|
37
|
+
|
38
|
+
self.send(screen_class_symbol).send(screen_object_symbol).instance_variables.each { |modal_variable|
|
39
|
+
modal_object_name = self.translate_class_to_string(modal_variable).gsub('@', '')
|
40
|
+
modal_object_symbol = self.translate_string_to_class(modal_object_name)
|
41
|
+
|
42
|
+
modal_output = "\t\t\t#{modal_object_name}".colorize(:magenta)
|
43
|
+
#puts modal_output
|
44
|
+
begin
|
45
|
+
modal_object_class = self.send(screen_class_symbol).send(screen_object_symbol).send(modal_object_symbol).class.to_s
|
46
|
+
|
47
|
+
case modal_object_class
|
48
|
+
when 'AutomationObject::Element'
|
49
|
+
puts modal_output + ' (Element)'.colorize(:green)
|
50
|
+
when 'AutomationObject::ElementHash'
|
51
|
+
puts modal_output + ' (Element Hash)'.colorize(:red)
|
52
|
+
when 'AutomationObject::ElementArray'
|
53
|
+
puts modal_output + ' (Element Array)'.colorize(:blue)
|
54
|
+
end
|
55
|
+
rescue
|
56
|
+
next
|
57
|
+
end
|
58
|
+
}
|
59
|
+
end
|
60
|
+
rescue
|
61
|
+
next
|
62
|
+
end
|
63
|
+
}
|
64
|
+
}
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module AutomationObject
|
2
|
+
module FrameworkScreenMonitor
|
3
|
+
def screen_monitor_thread_method(screen_class_symbol)
|
4
|
+
Thread.abort_on_exception = true
|
5
|
+
|
6
|
+
auto_screens_array = self.send(screen_class_symbol).configuration['automatic_screen_changes']
|
7
|
+
unless auto_screens_array.is_a?(Array)
|
8
|
+
raise "Expecting #{screen_class_symbol} screen to have automatic_screen_changes as an Array"
|
9
|
+
end
|
10
|
+
|
11
|
+
if auto_screens_array.length == 0
|
12
|
+
raise "Expecting #{screen_class_symbol} screen to have automatic_screen_changes count larger than 0"
|
13
|
+
end
|
14
|
+
|
15
|
+
if self.previous_screen_class
|
16
|
+
if self.screen_monitor_thread[self.previous_screen_class].class == Thread
|
17
|
+
AutomationObject::Logger::add("Attempting to kill previous screen threads for screen #{self.previous_screen_class}")
|
18
|
+
|
19
|
+
previous_thread = self.screen_monitor_thread[self.previous_screen_class]
|
20
|
+
Thread.kill(previous_thread)
|
21
|
+
self.screen_monitor_thread[self.previous_screen_class] = nil
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
AutomationObject::Logger::add("Running thread listener for screen #{screen_class_symbol}")
|
26
|
+
|
27
|
+
possible_screen_change_symbol = nil
|
28
|
+
possible_screen_change_name = nil
|
29
|
+
|
30
|
+
screen_live = false
|
31
|
+
|
32
|
+
#Todo: window switching while checking for live?
|
33
|
+
until screen_live
|
34
|
+
self.screen_monitor_mutex_object.synchronize do
|
35
|
+
auto_screens_array.each { |possible_screen_change_name|
|
36
|
+
possible_screen_change_symbol = self.translate_string_to_class(possible_screen_change_name)
|
37
|
+
|
38
|
+
start_time = Time.now.to_f
|
39
|
+
screen_live = self.send(possible_screen_change_symbol).live?
|
40
|
+
end_time = Time.now.to_f
|
41
|
+
|
42
|
+
AutomationObject::Logger::add("Automatic screen check of #{possible_screen_change_name} took (#{end_time-start_time})S")
|
43
|
+
|
44
|
+
break if screen_live
|
45
|
+
}
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
if screen_live
|
50
|
+
AutomationObject::Logger::add("Automatic screen change to #{possible_screen_change_name} found")
|
51
|
+
self.set_current_screen(possible_screen_change_symbol)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,310 @@
|
|
1
|
+
module AutomationObject
|
2
|
+
module FrameworkScreenRouting
|
3
|
+
def route_to_screen(from_screen, to_screen)
|
4
|
+
AutomationObject::Logger::add("Trying to automatically route to screen: #{to_screen}", [from_screen])
|
5
|
+
|
6
|
+
@from_screen = from_screen
|
7
|
+
@to_screen = to_screen
|
8
|
+
#Add @avoid_elements[screen_class_symbol].push(element_name),
|
9
|
+
#to be added later if elements are invisible or disabled
|
10
|
+
#Kind of a fail safe if elements are only sometimes disabled, try to find a new route after in this method if
|
11
|
+
#route found isn't working
|
12
|
+
@avoid_elements = Hash.new
|
13
|
+
@screen_map = self.map_screens
|
14
|
+
@route = nil
|
15
|
+
|
16
|
+
self.recursive_route_map
|
17
|
+
|
18
|
+
unless @route.class == Array
|
19
|
+
AutomationObject::Logger::add("Unable to find route to screen: #{to_screen}", [from_screen])
|
20
|
+
raise "Unable to find route between screen (#{@from_screen}) and screen (#{@to_screen})"
|
21
|
+
end
|
22
|
+
|
23
|
+
route_found = self.execute_route(@route)
|
24
|
+
|
25
|
+
unless route_found
|
26
|
+
@from_screen = self.current_screen_class
|
27
|
+
@screen_map = self.map_screens
|
28
|
+
|
29
|
+
self.recursive_route_map
|
30
|
+
|
31
|
+
unless @route.class == Array
|
32
|
+
raise "Unable to find route between screen (#{@from_screen}) and screen (#{@to_screen})"
|
33
|
+
end
|
34
|
+
|
35
|
+
self.execute_route(@route)
|
36
|
+
end
|
37
|
+
|
38
|
+
#Reset these variables
|
39
|
+
@avoid_elements = nil
|
40
|
+
@from_screen = nil
|
41
|
+
@to_screen = nil
|
42
|
+
@screen_map = nil
|
43
|
+
@route = nil
|
44
|
+
end
|
45
|
+
|
46
|
+
#TODO, enable for all elements, will break except for click, accept, dismiss
|
47
|
+
def execute_route(route)
|
48
|
+
route.each { |direction|
|
49
|
+
screen_configuration = self.send(self.current_screen_class).configuration
|
50
|
+
|
51
|
+
if screen_configuration['accept'].class == Hash
|
52
|
+
possible_change_screen = self.find_possible_change_screen(screen_configuration['accept'])
|
53
|
+
if possible_change_screen == direction
|
54
|
+
self.send(self.current_screen_class).accept
|
55
|
+
next
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
if screen_configuration.has_key?('dismiss')
|
60
|
+
possible_change_screen = self.find_possible_change_screen(screen_configuration['dismiss'])
|
61
|
+
if possible_change_screen == direction
|
62
|
+
self.send(self.current_screen_class).dismiss
|
63
|
+
next
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
route_found = false
|
68
|
+
|
69
|
+
#Try modals
|
70
|
+
if screen_configuration['modals'].is_a?(Hash)
|
71
|
+
screen_configuration['modals'].each { |modal_name, modal_configuration|
|
72
|
+
next unless modal_configuration.is_a?(Hash)
|
73
|
+
next unless modal_configuration['elements'].is_a?(Hash)
|
74
|
+
|
75
|
+
modal_configuration['elements'].each { |element_name, element_configuration|
|
76
|
+
next unless element_configuration.class == Hash
|
77
|
+
next unless element_configuration['click'].class == Hash
|
78
|
+
|
79
|
+
possible_change_screen = self.find_possible_change_screen(element_configuration['click'])
|
80
|
+
if possible_change_screen == direction
|
81
|
+
#If the elements, don't work then don't use them
|
82
|
+
#Will implement method to try to find another way to the screen
|
83
|
+
element_object = self.send(self.current_screen_class).send(modal_name).send(element_name)
|
84
|
+
element_object = element_object.sample if element_object.class == ElementArray
|
85
|
+
element_object = element_object[element_object.keys.sample] if element_object.class == ElementHash
|
86
|
+
|
87
|
+
unless element_object.visible?
|
88
|
+
@avoid_elements[self.current_screen_class] = Array.new unless @avoid_elements[self.current_screen_class].class == Array
|
89
|
+
@avoid_elements[self.current_screen_class].push(element_name)
|
90
|
+
next
|
91
|
+
end
|
92
|
+
|
93
|
+
unless element_object.exists?
|
94
|
+
@avoid_elements[self.current_screen_class] = Array.new unless @avoid_elements[self.current_screen_class].class == Array
|
95
|
+
@avoid_elements[self.current_screen_class].push(element_name)
|
96
|
+
next
|
97
|
+
end
|
98
|
+
|
99
|
+
element_object.click
|
100
|
+
route_found = true
|
101
|
+
break #Stop from looping through other elements
|
102
|
+
end
|
103
|
+
}
|
104
|
+
break if route_found
|
105
|
+
}
|
106
|
+
|
107
|
+
next if route_found
|
108
|
+
end
|
109
|
+
|
110
|
+
next unless screen_configuration['elements'].class == Hash
|
111
|
+
|
112
|
+
screen_configuration['elements'].each { |element_name, element_configuration|
|
113
|
+
next unless element_configuration.class == Hash
|
114
|
+
next unless element_configuration['click'].class == Hash
|
115
|
+
|
116
|
+
possible_change_screen = self.find_possible_change_screen(element_configuration['click'])
|
117
|
+
if possible_change_screen == direction
|
118
|
+
#If the elements, don't work then don't use them
|
119
|
+
#Will implement method to try to find another way to the screen
|
120
|
+
element_object = self.send(self.current_screen_class).send(element_name)
|
121
|
+
element_object = element_object.sample if element_object.class == ElementArray
|
122
|
+
element_object = element_object[element_object.keys.sample] if element_object.class == ElementHash
|
123
|
+
|
124
|
+
unless element_object.visible?
|
125
|
+
@avoid_elements[self.current_screen_class] = Array.new unless @avoid_elements[self.current_screen_class].class == Array
|
126
|
+
@avoid_elements[self.current_screen_class].push(element_name)
|
127
|
+
next
|
128
|
+
end
|
129
|
+
|
130
|
+
unless element_object.exists?
|
131
|
+
@avoid_elements[self.current_screen_class] = Array.new unless @avoid_elements[self.current_screen_class].class == Array
|
132
|
+
@avoid_elements[self.current_screen_class].push(element_name)
|
133
|
+
next
|
134
|
+
end
|
135
|
+
|
136
|
+
element_object.click
|
137
|
+
route_found = true
|
138
|
+
break #Stop from looping through other elements
|
139
|
+
end
|
140
|
+
}
|
141
|
+
|
142
|
+
return route_found unless route_found
|
143
|
+
}
|
144
|
+
|
145
|
+
true
|
146
|
+
end
|
147
|
+
|
148
|
+
def recursive_route_map
|
149
|
+
@depth = 0 unless @depth.class == Fixnum
|
150
|
+
@routes_array = Array.new unless @routes_array
|
151
|
+
|
152
|
+
#Get where we are and start there adding every possible direction to start with
|
153
|
+
if @depth == 0
|
154
|
+
@screen_map[@from_screen].each { |possible_direction|
|
155
|
+
new_route = Array.new
|
156
|
+
new_route.push(possible_direction)
|
157
|
+
@routes_array.push(new_route)
|
158
|
+
}
|
159
|
+
|
160
|
+
@depth += 1
|
161
|
+
end
|
162
|
+
|
163
|
+
#Better Check
|
164
|
+
#Do validation of @routes_array find if route found and break out
|
165
|
+
@routes_array.each { |route|
|
166
|
+
#Get the last direction and see if its the destination
|
167
|
+
if route.last == @to_screen
|
168
|
+
@route = route
|
169
|
+
@depth = nil
|
170
|
+
@routes_array = nil
|
171
|
+
return
|
172
|
+
end
|
173
|
+
}
|
174
|
+
|
175
|
+
tmp_routes_array = Array.new
|
176
|
+
@routes_array.each { |route|
|
177
|
+
last_direction = route.last
|
178
|
+
next unless @screen_map[last_direction]
|
179
|
+
@screen_map[last_direction].each { |possible_direction|
|
180
|
+
#Skip loops?
|
181
|
+
next if route.include?(possible_direction)
|
182
|
+
#Skip from screen
|
183
|
+
next if possible_direction == @from_screen
|
184
|
+
|
185
|
+
new_route = route.clone
|
186
|
+
new_route.push(possible_direction)
|
187
|
+
|
188
|
+
unless @routes_array.include?(new_route)
|
189
|
+
tmp_routes_array.push(new_route)
|
190
|
+
end
|
191
|
+
}
|
192
|
+
|
193
|
+
unless last_direction == @to_screen
|
194
|
+
#@routes_array.delete(route)
|
195
|
+
end
|
196
|
+
}
|
197
|
+
|
198
|
+
@routes_array += tmp_routes_array
|
199
|
+
|
200
|
+
@depth += 1
|
201
|
+
|
202
|
+
if @depth > 100
|
203
|
+
ap @routes_array
|
204
|
+
raise 'Could not complete route, runaway depth for from screen (' + @from_screen.to_s + ') to screen (' + @to_screen.to_s + ')'
|
205
|
+
end
|
206
|
+
|
207
|
+
self.recursive_route_map
|
208
|
+
end
|
209
|
+
|
210
|
+
def map_screens
|
211
|
+
screen_map = Hash.new
|
212
|
+
return screen_map unless self.configuration['screens'].class == Hash
|
213
|
+
|
214
|
+
self.configuration['screens'].each_key { |screen_name|
|
215
|
+
screen_class_symbol = self.translate_string_to_class(screen_name)
|
216
|
+
|
217
|
+
next unless self.respond_to?(screen_class_symbol)
|
218
|
+
next unless self.send(screen_class_symbol).configuration.class == Hash
|
219
|
+
|
220
|
+
screen_map[screen_class_symbol] = Array.new unless screen_map[screen_class_symbol].class == Array
|
221
|
+
|
222
|
+
screen_configuration = self.send(screen_class_symbol).configuration
|
223
|
+
|
224
|
+
if screen_configuration['accept'].class == Hash
|
225
|
+
possible_change_screen = self.find_possible_change_screen(screen_configuration['accept'])
|
226
|
+
screen_map[screen_class_symbol].push(possible_change_screen) if possible_change_screen
|
227
|
+
end
|
228
|
+
|
229
|
+
if screen_configuration.has_key?('dismiss')
|
230
|
+
possible_change_screen = self.find_possible_change_screen(screen_configuration['dismiss'])
|
231
|
+
screen_map[screen_class_symbol].push(possible_change_screen) if possible_change_screen
|
232
|
+
end
|
233
|
+
|
234
|
+
#Check modals
|
235
|
+
if screen_configuration['modals'].is_a?(Hash)
|
236
|
+
screen_configuration['modals'].each { |modal_name, modal_configuration|
|
237
|
+
next unless modal_configuration.is_a?(Hash)
|
238
|
+
next unless modal_configuration['elements'].is_a?(Hash)
|
239
|
+
|
240
|
+
modal_configuration['elements'].each { |element_name, element_configuration|
|
241
|
+
next unless element_configuration.class == Hash
|
242
|
+
#next if not element_configuration['click'].class == Hash
|
243
|
+
|
244
|
+
if @avoid_elements.has_key?(screen_class_symbol)
|
245
|
+
next if @avoid_elements[screen_class_symbol].include?(element_name)
|
246
|
+
end
|
247
|
+
|
248
|
+
element_configuration.each { |key, sub_configuration|
|
249
|
+
next unless sub_configuration.class == Hash
|
250
|
+
next if key == 'custom_methods'
|
251
|
+
next if key == 'xpath'
|
252
|
+
next if key == 'css'
|
253
|
+
next if key == 'multiple'
|
254
|
+
|
255
|
+
possible_change_screen = self.find_possible_change_screen(sub_configuration)
|
256
|
+
screen_map[screen_class_symbol].push(possible_change_screen) if possible_change_screen
|
257
|
+
}
|
258
|
+
}
|
259
|
+
}
|
260
|
+
end
|
261
|
+
|
262
|
+
next unless screen_configuration['elements'].class == Hash
|
263
|
+
|
264
|
+
screen_configuration['elements'].each { |element_name, element_configuration|
|
265
|
+
next unless element_configuration.class == Hash
|
266
|
+
#next if not element_configuration['click'].class == Hash
|
267
|
+
|
268
|
+
if @avoid_elements.has_key?(screen_class_symbol)
|
269
|
+
next if @avoid_elements[screen_class_symbol].include?(element_name)
|
270
|
+
end
|
271
|
+
|
272
|
+
element_configuration.each { |key, sub_configuration|
|
273
|
+
next unless sub_configuration.class == Hash
|
274
|
+
next if key == 'custom_methods'
|
275
|
+
next if key == 'xpath'
|
276
|
+
next if key == 'css'
|
277
|
+
next if key == 'multiple'
|
278
|
+
|
279
|
+
possible_change_screen = self.find_possible_change_screen(sub_configuration)
|
280
|
+
screen_map[screen_class_symbol].push(possible_change_screen) if possible_change_screen
|
281
|
+
}
|
282
|
+
}
|
283
|
+
|
284
|
+
screen_map[screen_class_symbol] = screen_map[screen_class_symbol].uniq
|
285
|
+
}
|
286
|
+
|
287
|
+
screen_map
|
288
|
+
end
|
289
|
+
|
290
|
+
def find_possible_change_screen(configuration)
|
291
|
+
if configuration['before'].class == Hash
|
292
|
+
if configuration['before'].has_key?('change_screen')
|
293
|
+
if configuration['before']['change_screen']
|
294
|
+
return self.translate_string_to_class(configuration['before']['change_screen'])
|
295
|
+
end
|
296
|
+
end
|
297
|
+
end
|
298
|
+
|
299
|
+
if configuration['after'].class == Hash
|
300
|
+
if configuration['after'].has_key?('change_screen')
|
301
|
+
if configuration['after']['change_screen']
|
302
|
+
return self.translate_string_to_class(configuration['after']['change_screen'])
|
303
|
+
end
|
304
|
+
end
|
305
|
+
end
|
306
|
+
|
307
|
+
nil
|
308
|
+
end
|
309
|
+
end
|
310
|
+
end
|
@@ -0,0 +1,181 @@
|
|
1
|
+
module AutomationObject
|
2
|
+
module FrameworkWindowHelpers
|
3
|
+
def get_window_handles
|
4
|
+
window_handles = Array.new
|
5
|
+
return window_handles unless self.is_browser?
|
6
|
+
|
7
|
+
unless self.is_mobile?
|
8
|
+
#Window handles for Selenium are simpler
|
9
|
+
return self.driver_object.window_handles
|
10
|
+
end
|
11
|
+
|
12
|
+
#Remove everything except the WEBVIEW
|
13
|
+
if self.driver_object.device_is_android?
|
14
|
+
window_handles = self.driver_object.window_handles
|
15
|
+
else
|
16
|
+
available_contexts = self.driver_object.available_contexts
|
17
|
+
available_contexts.each { |context|
|
18
|
+
window_handles.push(context) if context.match(/^WEBVIEW_\d+$/)
|
19
|
+
}
|
20
|
+
end
|
21
|
+
|
22
|
+
return window_handles
|
23
|
+
end
|
24
|
+
|
25
|
+
def get_current_window_handle
|
26
|
+
#Selenium
|
27
|
+
unless self.is_mobile?
|
28
|
+
return self.driver_object.window_handle
|
29
|
+
end
|
30
|
+
|
31
|
+
#Appium
|
32
|
+
if self.driver_object.device_is_android?
|
33
|
+
return self.driver_object.window_handle
|
34
|
+
else
|
35
|
+
return self.driver_object.current_context
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def switch_to_window(window_handle)
|
40
|
+
unless self.is_mobile?
|
41
|
+
#Selenium
|
42
|
+
return self.driver_object.switch_to.window(window_handle)
|
43
|
+
end
|
44
|
+
|
45
|
+
#Appium
|
46
|
+
if self.driver_object.device_is_android?
|
47
|
+
return self.driver_object.switch_to.window(window_handle)
|
48
|
+
else
|
49
|
+
return self.driver_object.set_context(window_handle)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def check_closed_windows
|
54
|
+
window_handles = self.get_window_handles
|
55
|
+
|
56
|
+
self.current_screen_hash.each { |current_window_handle, current_screen_symbol|
|
57
|
+
next if window_handles.include?(current_window_handle)
|
58
|
+
|
59
|
+
#Delete current screen hash key
|
60
|
+
self.current_screen_hash.delete(current_window_handle)
|
61
|
+
self.reset_screen(current_screen_symbol)
|
62
|
+
self.previous_screen_hash.delete(current_window_handle)
|
63
|
+
|
64
|
+
if current_screen_symbol == self.current_screen_class
|
65
|
+
self.previous_screen_class = nil
|
66
|
+
end
|
67
|
+
}
|
68
|
+
end
|
69
|
+
|
70
|
+
def wait_for_window_load
|
71
|
+
AutomationObject::Logger::add('Waiting for window to load via document.readyState')
|
72
|
+
loops = 0
|
73
|
+
|
74
|
+
sleep(2)
|
75
|
+
until self.document_complete?
|
76
|
+
loops += 1
|
77
|
+
|
78
|
+
if loops > 30
|
79
|
+
break #Fuck it for now, just see what happens if we don't wait for this
|
80
|
+
raise Net::ReadTimeout, 'Error waiting too long for page to load'
|
81
|
+
end
|
82
|
+
|
83
|
+
sleep(3)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def document_complete?
|
88
|
+
AutomationObject::Logger::add('Running document_complete? command')
|
89
|
+
return self.driver_object.execute_script('return document.readyState;') == 'complete'
|
90
|
+
end
|
91
|
+
|
92
|
+
def wait_for_stable_body_size
|
93
|
+
AutomationObject::Logger::add('Going to wait for body element size to stabilize before continuing')
|
94
|
+
body_element_object = self.driver_object.find_element(:css, 'body')
|
95
|
+
|
96
|
+
begin
|
97
|
+
current_body_size = body_element_object.size
|
98
|
+
rescue Selenium::WebDriver::Error::StaleElementReferenceError, Errno::ECONNREFUSED
|
99
|
+
body_element_object = self.driver_object.find_element(:css, 'body')
|
100
|
+
current_body_size = body_element_object.size
|
101
|
+
end
|
102
|
+
|
103
|
+
previous_width = current_body_size[:width]
|
104
|
+
previous_height = current_body_size[:height]
|
105
|
+
|
106
|
+
sleep(2)
|
107
|
+
|
108
|
+
30.times do
|
109
|
+
sizes_string = "before: #{current_body_size[:width]}x#{current_body_size[:height]}"
|
110
|
+
|
111
|
+
begin
|
112
|
+
current_body_size = body_element_object.size
|
113
|
+
rescue Selenium::WebDriver::Error::StaleElementReferenceError, Errno::ECONNREFUSED
|
114
|
+
body_element_object = self.driver_object.find_element(:css, 'body')
|
115
|
+
current_body_size = body_element_object.size
|
116
|
+
end
|
117
|
+
|
118
|
+
if previous_width == current_body_size[:width] and previous_height == current_body_size[:height]
|
119
|
+
break
|
120
|
+
end
|
121
|
+
|
122
|
+
sizes_string << ", after: #{current_body_size[:width]}x#{current_body_size[:height]}"
|
123
|
+
AutomationObject::Logger::add("Running another loop for body size stabilization. #{sizes_string}")
|
124
|
+
|
125
|
+
previous_width = current_body_size[:width]
|
126
|
+
previous_height = current_body_size[:height]
|
127
|
+
|
128
|
+
sleep(2)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
def set_window_size(x, y)
|
133
|
+
self.driver_object.manage.window.resize_to(x, y)
|
134
|
+
end
|
135
|
+
|
136
|
+
def close_window(screen_name, skip_close = false)
|
137
|
+
AutomationObject::Logger::add("Attempting to close window for screen #{screen_name}")
|
138
|
+
|
139
|
+
screen_class_symbol = self.translate_string_to_class(screen_name)
|
140
|
+
remove_current_handle = nil
|
141
|
+
|
142
|
+
self.current_screen_hash.each { |window_handle, current_screen_symbol|
|
143
|
+
next if current_screen_symbol != screen_class_symbol
|
144
|
+
remove_current_handle = window_handle
|
145
|
+
|
146
|
+
#Kill the thread
|
147
|
+
self.screen_monitor_thread.each { |key, thread|
|
148
|
+
next unless key == screen_class_symbol
|
149
|
+
break unless thread.class == Thread
|
150
|
+
Thread.kill(thread)
|
151
|
+
|
152
|
+
AutomationObject::Logger::add("Killed any threads belonging to window for screen #{screen_name}")
|
153
|
+
break
|
154
|
+
}
|
155
|
+
|
156
|
+
self.screen_monitor_thread[current_screen_symbol] = nil
|
157
|
+
|
158
|
+
#Close the window if needed
|
159
|
+
if skip_close == false
|
160
|
+
self.switch_to_window(window_handle)
|
161
|
+
self.driver_object.close
|
162
|
+
end
|
163
|
+
|
164
|
+
break
|
165
|
+
}
|
166
|
+
|
167
|
+
if remove_current_handle
|
168
|
+
self.current_screen_hash.delete(remove_current_handle)
|
169
|
+
self.screen_history_hash.delete(remove_current_handle)
|
170
|
+
end
|
171
|
+
|
172
|
+
self.current_screen_hash.each { |window_handle, current_screen_symbol|
|
173
|
+
self.switch_to_window(window_handle)
|
174
|
+
self.current_screen_class = current_screen_symbol
|
175
|
+
break
|
176
|
+
}
|
177
|
+
|
178
|
+
self.send(screen_class_symbol).reset_screen
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|