testability-driver 1.0.3 → 1.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/tdriver-devtools/behaviour/xml/rdoc_behaviour_xml_generator.rb +2 -2
- data/lib/tdriver-devtools/tdriver-devtools.rb +1 -1
- data/lib/tdriver-devtools/tests/feature_tests/lib/custom_rdoc_generator.rb +3 -3
- data/lib/tdriver/base/behaviour/behaviours/object_behaviour_composition.rb +6 -1
- data/lib/tdriver/base/behaviour/behaviours/object_behaviour_description.rb +5 -3
- data/lib/tdriver/base/behaviour/behaviours/object_composition.rb +1 -1
- data/lib/tdriver/base/behaviour/factory.rb +225 -225
- data/lib/tdriver/base/errors.rb +1 -1
- data/lib/tdriver/base/state_object.rb +227 -179
- data/lib/tdriver/base/sut/controller.rb +2 -2
- data/lib/tdriver/base/sut/factory.rb +190 -182
- data/lib/tdriver/base/sut/generic/behaviours/application.rb +69 -25
- data/lib/tdriver/base/sut/generic/behaviours/controller.rb +1 -1
- data/lib/tdriver/base/sut/generic/behaviours/find.rb +4 -4
- data/lib/tdriver/base/sut/generic/behaviours/flash_behaviour.rb +3 -3
- data/lib/tdriver/base/sut/generic/behaviours/sut.rb +350 -165
- data/lib/tdriver/base/sut/generic/behaviours/switchbox_behaviour.rb +9 -9
- data/lib/tdriver/base/sut/generic/behaviours/verification.rb +191 -103
- data/lib/tdriver/base/sut/generic/commands/application.rb +1 -1
- data/lib/tdriver/base/sut/generic/commands/key_sequence.rb +1 -1
- data/lib/tdriver/base/sut/generic/commands/screen_capture.rb +1 -1
- data/lib/tdriver/base/sut/generic/plugin.rb +1 -1
- data/lib/tdriver/base/sut/sut.rb +5 -1
- data/lib/tdriver/base/test_object/abstract.rb +136 -151
- data/lib/tdriver/base/test_object/adapter.rb +293 -82
- data/lib/tdriver/base/test_object/behaviours/syncronization.rb +20 -17
- data/lib/tdriver/base/test_object/behaviours/test_object.rb +159 -532
- data/lib/tdriver/base/test_object/cache.rb +1 -1
- data/lib/tdriver/base/test_object/factory.rb +254 -605
- data/lib/tdriver/base/test_object/identificator.rb +1 -1
- data/lib/tdriver/base/test_object/loader.rb +1 -1
- data/lib/tdriver/base/test_object/verification.rb +17 -17
- data/lib/tdriver/loader.rb +20 -9
- data/lib/tdriver/report/report.rb +5 -0
- data/lib/tdriver/report/report_creator.rb +2 -2
- data/lib/tdriver/report/report_cucumber_listener.rb +4 -4
- data/lib/tdriver/report/report_cucumber_reporter.rb +4 -4
- data/lib/tdriver/report/report_execution_statistics.rb +22 -22
- data/lib/tdriver/report/report_grouping.rb +2 -2
- data/lib/tdriver/report/report_javascript.rb +11 -4
- data/lib/tdriver/report/report_test_case_run.rb +2 -2
- data/lib/tdriver/report/report_test_run.rb +5 -5
- data/lib/tdriver/report/report_test_unit.rb +74 -26
- data/lib/tdriver/report/report_writer.rb +70 -13
- data/lib/tdriver/tdriver.rb +17 -8
- data/lib/tdriver/util/common/array.rb +1 -1
- data/lib/tdriver/util/common/crc16.rb +1 -1
- data/lib/tdriver/util/common/environment.rb +1 -1
- data/lib/tdriver/util/common/file.rb +18 -9
- data/lib/tdriver/util/common/gem.rb +1 -1
- data/lib/tdriver/util/common/hash.rb +21 -0
- data/lib/tdriver/util/common/kernel.rb +1 -1
- data/lib/tdriver/util/common/loader.rb +5 -2
- data/lib/tdriver/util/common/numeric.rb +54 -3
- data/lib/tdriver/util/common/retryable.rb +30 -12
- data/lib/tdriver/util/common/stackable.rb +185 -0
- data/lib/tdriver/util/common/string.rb +21 -5
- data/lib/tdriver/util/{dbaccess/dbaccess.rb → database/access.rb} +4 -1
- data/lib/tdriver/util/{dbaccess/dbconnection.rb → database/connection.rb} +3 -0
- data/lib/tdriver/util/{dbaccess → database}/error.rb +0 -1
- data/lib/tdriver/util/{dbaccess → database}/loader.rb +5 -6
- data/lib/tdriver/util/{dynamic_attribute_filter.rb → filters/dynamic_attributes.rb} +1 -1
- data/lib/tdriver/util/hooking/hooking.rb +477 -0
- data/lib/tdriver/util/loader.rb +35 -29
- data/lib/tdriver/util/localisation/error.rb +0 -1
- data/lib/tdriver/util/localisation/loader.rb +1 -4
- data/lib/tdriver/util/localisation/localisation.rb +30 -27
- data/lib/tdriver/util/{common.rb → logger/loader.rb} +2 -4
- data/lib/tdriver/util/logger/logger.rb +574 -0
- data/lib/tdriver/util/operator_data/loader.rb +4 -3
- data/lib/tdriver/util/operator_data/operator_data.rb +5 -5
- data/lib/tdriver/util/parameter/parameter.rb +7 -1
- data/lib/tdriver/util/parameter/parameter_hash.rb +1 -1
- data/lib/tdriver/util/parameter/parameter_template.rb +1 -1
- data/lib/tdriver/util/parameter/parameter_user_api.rb +28 -20
- data/lib/tdriver/util/parameter/parameter_xml.rb +1 -1
- data/lib/tdriver/util/plugin/abstract.rb +1 -1
- data/lib/tdriver/util/plugin/service.rb +1 -1
- data/lib/tdriver/util/{localisation.rb → recorder/loader.rb} +4 -3
- data/lib/tdriver/util/recorder/recorder.rb +66 -0
- data/lib/tdriver/util/recorder/scripter.rb +258 -0
- data/lib/tdriver/util/{stats.rb → statistics/statistics.rb} +7 -8
- data/lib/tdriver/util/user_data/error.rb +0 -1
- data/lib/tdriver/util/user_data/loader.rb +1 -2
- data/lib/tdriver/util/user_data/user_data.rb +6 -6
- data/lib/tdriver/util/video/camera.rb +67 -0
- data/lib/tdriver/util/video/camera_linux.rb +139 -0
- data/lib/tdriver/util/video/camera_windows.rb +174 -0
- data/lib/tdriver/util/video/loader.rb +31 -0
- data/lib/tdriver/util/video/video_utils.rb +139 -0
- data/lib/tdriver/util/xml/abstraction.rb +56 -5
- data/lib/tdriver/util/xml/builder.rb +2 -5
- data/lib/tdriver/util/{parameter.rb → xml/comment.rb} +10 -2
- data/lib/tdriver/util/xml/loader.rb +32 -22
- data/lib/tdriver/util/xml/nil_node.rb +2 -2
- data/lib/tdriver/util/xml/parsers/loader.rb +0 -1
- data/lib/tdriver/util/xml/parsers/nokogiri/abstraction.rb +18 -44
- data/lib/tdriver/util/xml/parsers/nokogiri/attribute.rb +9 -13
- data/lib/tdriver/util/xml/parsers/nokogiri/builder.rb +9 -3
- data/lib/tdriver/util/xml/parsers/nokogiri/comment.rb +39 -0
- data/lib/tdriver/util/xml/parsers/nokogiri/document.rb +6 -11
- data/lib/tdriver/util/xml/parsers/nokogiri/element.rb +2 -122
- data/lib/tdriver/util/xml/parsers/nokogiri/loader.rb +26 -16
- data/lib/tdriver/util/xml/parsers/nokogiri/node.rb +203 -0
- data/lib/tdriver/util/xml/parsers/nokogiri/nodeset.rb +1 -2
- data/lib/tdriver/util/xml/parsers/nokogiri/text.rb +2 -20
- data/lib/tdriver/util/xml/xml.rb +52 -20
- data/lib/tdriver/verify/verify.rb +238 -81
- data/xml/behaviours/generic.xml +12 -10
- metadata +156 -180
- data/lib/tdriver/base/test_object/factory_new.rb +0 -202
- data/lib/tdriver/util/hooking.rb +0 -434
- data/lib/tdriver/util/logger.rb +0 -506
- data/lib/tdriver/util/recorder.rb +0 -297
- data/lib/tdriver/util/video_utils.rb +0 -384
- data/lib/tdriver/util/xml/nil_element.rb +0 -89
@@ -27,96 +27,89 @@ module TDriver
|
|
27
27
|
private
|
28
28
|
|
29
29
|
# special cases: allow partial match when value of type and attribute name matches
|
30
|
-
@@partial_match_allowed = [ 'list_item', 'text' ], ['application', 'fullname' ]
|
30
|
+
@@partial_match_allowed = [ 'list_item', 'text' ], [ 'application', 'fullname' ]
|
31
31
|
|
32
|
+
# TODO: document me
|
32
33
|
def xpath_attributes( attributes, element_attributes, object_type )
|
33
|
-
|
34
|
+
|
35
|
+
# collect attributes
|
34
36
|
attributes = attributes.collect{ | key, values |
|
35
37
|
|
36
|
-
values
|
38
|
+
# allow multiple values options for attribute, e.g. object which 'text' attribute value is either '1' or '2'
|
39
|
+
( values.kind_of?( Array ) ? values : [ values ] ).collect{ | value |
|
37
40
|
|
38
41
|
# concatenate string if it contains single and double quotes, otherwise return as is
|
39
42
|
value = xpath_literal_string( value )
|
40
43
|
|
41
44
|
if @@partial_match_allowed.include?( [ object_type, key ] )
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
else
|
47
|
-
|
48
|
-
# exact match required
|
49
|
-
value = "=#{ value }"
|
50
|
-
|
51
|
-
end
|
52
|
-
|
53
|
-
if element_attributes
|
54
|
-
|
55
|
-
prefix = "@#{key}#{value} or "
|
45
|
+
|
46
|
+
prefix_value = "[contains(.,#{ value })]"
|
47
|
+
attribute_value = "contains(value/text(),#{ value })"
|
56
48
|
|
57
49
|
else
|
58
50
|
|
59
|
-
|
51
|
+
prefix_value = "=#{ value }"
|
52
|
+
attribute_value = "value/text()=#{ value }"
|
60
53
|
|
61
54
|
end
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
55
|
+
|
56
|
+
# construct xpath
|
57
|
+
"(#{ element_attributes ? "@#{ key }#{ prefix_value } or " : "" }attributes/attribute[translate(@name,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')='#{ key }' and #{ attribute_value }])"
|
58
|
+
|
59
|
+
}.join( ' or ' ) # join attribute alternative values
|
66
60
|
|
67
|
-
}
|
61
|
+
}.join( ' and ' ) # join all required attributes
|
62
|
+
|
63
|
+
# return created xpath or nil if no attributes given
|
64
|
+
if attributes.empty?
|
68
65
|
|
69
|
-
|
70
|
-
|
71
|
-
if result.empty?
|
66
|
+
# no attributes given
|
67
|
+
nil
|
72
68
|
|
73
|
-
result = nil
|
74
|
-
|
75
69
|
else
|
76
|
-
|
77
|
-
|
70
|
+
|
71
|
+
# return result
|
72
|
+
attributes
|
78
73
|
|
79
74
|
end
|
80
75
|
|
81
|
-
|
82
|
-
|
83
|
-
end
|
76
|
+
end # xpath_attributes
|
84
77
|
|
85
|
-
|
86
|
-
end
|
78
|
+
end # static
|
87
79
|
|
88
80
|
# TODO: document me
|
89
81
|
def self.xpath_to_object( rules, find_all_children )
|
90
82
|
|
91
83
|
# convert hash keys to downcased string
|
92
|
-
rules = Hash[ rules.collect{ | key, value | [ key.to_s.downcase, value ] } ]
|
84
|
+
rules = Hash[ rules.collect{ | key, value | [ key.to_s.downcase, value.to_s ] } ]
|
93
85
|
|
94
|
-
|
86
|
+
# xpath container array
|
87
|
+
test_object_xpath_array = []
|
95
88
|
|
96
89
|
# store and remove object element attributes from hash
|
97
|
-
object_element_attributes = rules.delete_keys!(
|
90
|
+
object_element_attributes = rules.delete_keys!( 'name', 'type', 'parent', 'id' )
|
98
91
|
|
99
|
-
# TODO: change "any" to "*"
|
100
92
|
# children method may request test objects of any type
|
101
|
-
if object_element_attributes[
|
93
|
+
if object_element_attributes[ 'type' ] == '*'
|
102
94
|
|
103
95
|
# test object with any name, type, parent and id is allowed
|
104
|
-
|
96
|
+
test_object_xpath_array << '@*'
|
105
97
|
|
106
98
|
else
|
107
99
|
|
108
100
|
# required attributes
|
109
|
-
|
101
|
+
test_object_xpath_array << xpath_attributes( object_element_attributes, true, object_element_attributes[ 'type' ] )
|
110
102
|
|
111
103
|
end
|
112
104
|
|
113
105
|
# additional attributes, eg. :text, :x, :y etc.
|
114
|
-
|
106
|
+
test_object_xpath_array << xpath_attributes( rules, false, object_element_attributes[ 'type' ] )
|
115
107
|
|
116
108
|
# join required and additional attribute strings
|
117
|
-
|
109
|
+
test_object_xpath_string = test_object_xpath_array.compact.join( ' and ' )
|
118
110
|
|
119
|
-
|
111
|
+
# return any child element under current node or only immediate child element
|
112
|
+
find_all_children ? "*//object[#{ test_object_xpath_string }]" : "objects[1]/object[#{ test_object_xpath_string }]"
|
120
113
|
|
121
114
|
end
|
122
115
|
|
@@ -183,54 +176,70 @@ module TDriver
|
|
183
176
|
# TODO: document me
|
184
177
|
def self.get_objects( source_data, rules, find_all_children )
|
185
178
|
|
186
|
-
rule = xpath_to_object( rules, find_all_children )
|
187
|
-
|
188
179
|
[
|
189
180
|
# perform xpath to source xml data
|
190
|
-
source_data.xpath( rule ),
|
181
|
+
source_data.xpath( rule = xpath_to_object( rules, find_all_children ) ),
|
182
|
+
|
183
|
+
# return also created xpath
|
191
184
|
rule
|
192
185
|
]
|
193
186
|
|
194
187
|
end
|
195
188
|
|
189
|
+
# TODO: document me
|
196
190
|
def self.test_object_hash( object_id, object_type, object_name )
|
197
191
|
|
192
|
+
# calculate test object hash
|
198
193
|
( ( ( 17 * 37 + object_id ) * 37 + object_type.hash ) * 37 + object_name.hash )
|
199
194
|
|
200
195
|
end
|
201
196
|
|
202
197
|
# Sort XML nodeset of test objects with layout direction
|
203
|
-
def self.sort_elements( nodeset, layout_direction =
|
198
|
+
def self.sort_elements( nodeset, layout_direction = 'LeftToRight' )
|
204
199
|
|
205
|
-
attribute_pattern =
|
200
|
+
attribute_pattern = './attributes/attribute[@name="%s"]/value/text()'
|
206
201
|
|
207
202
|
# collect only nodes that has x_absolute and y_absolute attributes
|
208
203
|
nodeset.collect!{ | node |
|
209
204
|
|
210
|
-
|
211
|
-
|
205
|
+
if node.at_xpath( attribute_pattern % 'x_absolute' ).nil? || node.at_xpath( attribute_pattern % 'y_absolute' ).nil?
|
206
|
+
|
207
|
+
#warn("Warning: Unable to sort object set due to object type of #{ node.attribute( 'type' ).inspect } does not have \"x_absolute\" or \"y_absolute\" attribute")
|
208
|
+
|
209
|
+
return nodeset
|
210
|
+
|
211
|
+
else
|
212
|
+
|
213
|
+
node
|
214
|
+
|
215
|
+
end
|
212
216
|
|
213
217
|
}.compact!.sort!{ | element_a, element_b |
|
214
218
|
|
219
|
+
# retrieve element a's attributes x and y
|
215
220
|
element_a_x = element_a.at_xpath( attribute_pattern % 'x_absolute' ).content.to_i
|
216
221
|
element_a_y = element_a.at_xpath( attribute_pattern % 'y_absolute' ).content.to_i
|
217
222
|
|
223
|
+
# retrieve element b's attributes x and y
|
218
224
|
element_b_x = element_b.at_xpath( attribute_pattern % 'x_absolute' ).content.to_i
|
219
225
|
element_b_y = element_b.at_xpath( attribute_pattern % 'y_absolute' ).content.to_i
|
220
226
|
|
221
227
|
case layout_direction
|
222
228
|
|
223
|
-
when
|
229
|
+
when 'LeftToRight'
|
224
230
|
|
231
|
+
# compare elements
|
225
232
|
( element_a_y == element_b_y ) ? ( element_a_x <=> element_b_x ) : ( element_a_y <=> element_b_y )
|
226
233
|
|
227
|
-
when
|
234
|
+
when 'RightToLeft'
|
228
235
|
|
236
|
+
# compare elements
|
229
237
|
( element_a_y == element_b_y ) ? ( element_b_x <=> element_a_x ) : ( element_a_y <=> element_b_y )
|
230
238
|
|
231
239
|
else
|
232
240
|
|
233
|
-
|
241
|
+
# raise exception if layout direction it not supported
|
242
|
+
Kernel::raise ArgumentError, "Unsupported layout direction #{ layout_direction.inspect }"
|
234
243
|
|
235
244
|
end
|
236
245
|
|
@@ -257,24 +266,32 @@ module TDriver
|
|
257
266
|
end
|
258
267
|
|
259
268
|
# TODO: document me
|
260
|
-
def self.test_object_element_attribute( source_data,
|
269
|
+
def self.test_object_element_attribute( source_data, attribute_name, *default, &block )
|
261
270
|
|
262
|
-
result = source_data.attribute(
|
271
|
+
result = source_data.attribute( attribute_name )
|
263
272
|
|
273
|
+
# if no attribute found call optional code block or raise exception
|
264
274
|
unless result
|
265
275
|
|
266
276
|
if block_given?
|
267
|
-
|
268
|
-
|
277
|
+
|
278
|
+
# pass return value of block as result
|
279
|
+
yield( attribute_name )
|
269
280
|
|
270
281
|
else
|
271
282
|
|
272
|
-
# raise exception if no
|
273
|
-
|
283
|
+
# raise exception if no default value given
|
284
|
+
if default.empty?
|
285
|
+
|
286
|
+
# raise exception if no such attribute found
|
287
|
+
Kernel::raise MobyBase::AttributeNotFoundError, "Could not find test object element attribute #{ attribute_name.inspect }"
|
288
|
+
|
289
|
+
else
|
274
290
|
|
275
|
-
|
276
|
-
|
277
|
-
|
291
|
+
# pass default value as result
|
292
|
+
default.first
|
293
|
+
|
294
|
+
end
|
278
295
|
|
279
296
|
end
|
280
297
|
|
@@ -287,14 +304,14 @@ module TDriver
|
|
287
304
|
end
|
288
305
|
|
289
306
|
# TODO: document me
|
290
|
-
def self.test_object_attribute( source_data, attribute_name, &block )
|
307
|
+
def self.test_object_attribute( source_data, attribute_name, *default, &block )
|
291
308
|
|
292
309
|
# TODO: consider using at_xpath and adding /value/text() to query string; however "downside" is that if multiple matches found only first value will be returned as result
|
293
310
|
|
294
311
|
# retrieve attribute(s) from xml
|
295
312
|
nodeset = source_data.xpath(
|
296
313
|
|
297
|
-
"attributes/attribute[translate(@name,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')='#{ attribute_name.downcase }']"
|
314
|
+
"attributes/attribute[translate(@name,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')='#{ attribute_name.downcase }']"
|
298
315
|
|
299
316
|
)
|
300
317
|
|
@@ -304,20 +321,26 @@ module TDriver
|
|
304
321
|
if block_given?
|
305
322
|
|
306
323
|
# pass return value of block as result
|
307
|
-
yield
|
324
|
+
yield( attribute_name )
|
308
325
|
|
309
326
|
else
|
310
327
|
|
311
|
-
# raise exception if no
|
312
|
-
|
328
|
+
# raise exception if no default value given
|
329
|
+
if default.empty?
|
313
330
|
|
314
|
-
|
315
|
-
|
316
|
-
|
331
|
+
# raise exception if no such attribute found
|
332
|
+
Kernel::raise MobyBase::AttributeNotFoundError, "Could not find attribute #{ attribute_name.inspect }" # for test object of type #{ type.to_s }"
|
333
|
+
|
334
|
+
else
|
317
335
|
|
318
|
-
|
336
|
+
# pass default value as result
|
337
|
+
default.first
|
338
|
+
|
339
|
+
end
|
340
|
+
|
341
|
+
end # block_given?
|
319
342
|
|
320
|
-
else
|
343
|
+
else # not nodeset.empty?
|
321
344
|
|
322
345
|
# attribute(s) found
|
323
346
|
# Need to disable this for now
|
@@ -331,17 +354,33 @@ module TDriver
|
|
331
354
|
end
|
332
355
|
|
333
356
|
# TODO: document me
|
334
|
-
def self.test_object_attributes( source_data )
|
335
|
-
|
357
|
+
def self.test_object_attributes( source_data, inclusive_filter = [] )
|
358
|
+
|
359
|
+
# convert all keys to lowercase
|
360
|
+
inclusive_filter.collect!{ | key | key.to_s.downcase } unless inclusive_filter.empty?
|
361
|
+
|
336
362
|
# return hash of test object attributes
|
337
363
|
Hash[
|
338
364
|
|
339
365
|
# iterate each attribute and collect name and value
|
340
|
-
source_data.xpath( 'attributes/attribute' ).collect{ |
|
366
|
+
source_data.xpath( 'attributes/attribute/value' ).collect{ | value |
|
341
367
|
|
342
|
-
|
368
|
+
# retrieve attribute name
|
369
|
+
name = value.parent.attribute('name').to_s
|
343
370
|
|
344
|
-
|
371
|
+
# collect attribute elements name and content
|
372
|
+
unless inclusive_filter.empty?
|
373
|
+
|
374
|
+
[ name, value.content ] if inclusive_filter.include?( name.downcase )
|
375
|
+
|
376
|
+
else
|
377
|
+
|
378
|
+
# pass the attribute pair - no filtering done
|
379
|
+
[ name, value.content ]
|
380
|
+
|
381
|
+
end
|
382
|
+
|
383
|
+
}
|
345
384
|
|
346
385
|
]
|
347
386
|
|
@@ -372,7 +411,8 @@ module TDriver
|
|
372
411
|
# iterate through each child object type attribute and create accessor method
|
373
412
|
source_data.xpath( 'objects/object/@type' ).each{ | object_type |
|
374
413
|
|
375
|
-
|
414
|
+
# skip if object type value is nil or empty due to child accessor cannot be created
|
415
|
+
next if object_type.nil? || object_type.to_s.empty?
|
376
416
|
|
377
417
|
# convert attribute node value to string
|
378
418
|
object_type = object_type.content
|
@@ -383,7 +423,7 @@ module TDriver
|
|
383
423
|
# create child accessor method to test object unless already exists
|
384
424
|
test_object.instance_eval(
|
385
425
|
|
386
|
-
"def #{object_type}(rules={}); raise TypeError,'parameter <rules> should be hash' unless rules.kind_of?(Hash); rules[:type]=:#{object_type}; child(rules); end;"
|
426
|
+
"def #{ object_type }( rules = {} ); raise TypeError,'parameter <rules> should be hash' unless rules.kind_of?( Hash ); rules[ :type ]=:#{ object_type }; child( rules ); end;"
|
387
427
|
|
388
428
|
) unless object_type.empty?
|
389
429
|
|
@@ -391,8 +431,179 @@ module TDriver
|
|
391
431
|
|
392
432
|
end
|
393
433
|
|
434
|
+
# TODO: document me
|
435
|
+
def self.state_object_xml( source_data, id )
|
436
|
+
|
437
|
+
# collect each object from source xml
|
438
|
+
objects = source_data.xpath( 'tasInfo/object' ).collect{ | element | element.to_s }.join
|
439
|
+
|
440
|
+
# return xml root element
|
441
|
+
MobyUtil::XML.parse_string(
|
442
|
+
"<sut name='sut' type='sut' id='#{ id }'><objects>#{ objects }</objects></sut>"
|
443
|
+
).root
|
444
|
+
|
445
|
+
end
|
446
|
+
|
447
|
+
def self.retrieve_parent_application( xml_source )
|
448
|
+
|
449
|
+
xml_source_iterator = xml_source.clone
|
450
|
+
|
451
|
+
while xml_source_iterator.kind_of?( MobyUtil::XML::Element )
|
452
|
+
|
453
|
+
if ( test_object_element_attribute( xml_source_iterator, 'type' ) == 'application' )
|
454
|
+
|
455
|
+
return xml_source_iterator
|
456
|
+
|
457
|
+
end
|
458
|
+
|
459
|
+
if xml_source_iterator.kind_of?( MobyUtil::XML::Element )
|
460
|
+
|
461
|
+
xml_source_iterator = xml_source_iterator.parent.parent
|
462
|
+
|
463
|
+
else
|
464
|
+
|
465
|
+
# not found from xml tree
|
466
|
+
break
|
467
|
+
|
468
|
+
end
|
469
|
+
|
470
|
+
end
|
471
|
+
|
472
|
+
#warn("warning: unable to retrieve parent application")
|
473
|
+
|
474
|
+
raise MobyBase::TestObjectNotFoundError, "Unable to retrieve parent application"
|
475
|
+
|
476
|
+
# return application object or nil if no parent found
|
477
|
+
# Does is make sense to return nil - shouldn't all test objects belong to an application? Maybe throw exception if application not found
|
478
|
+
|
479
|
+
#nil
|
480
|
+
|
481
|
+
#return @sut.child( :type => 'application' ) rescue nil
|
482
|
+
|
483
|
+
end
|
484
|
+
|
485
|
+
# TODO: document me
|
486
|
+
def self.get_xml_element_for_test_object( test_object )
|
487
|
+
|
488
|
+
# retrieve nodeset from sut xml_data
|
489
|
+
nodeset = test_object.instance_variable_get( :@sut ).xml_data.xpath( test_object.instance_variable_get( :@x_path ) )
|
490
|
+
|
491
|
+
# raise exception if no test objects found
|
492
|
+
Kernel::raise MobyBase::TestObjectNotFoundError if nodeset.empty?
|
493
|
+
|
494
|
+
# return first test object from the nodeset
|
495
|
+
nodeset.first
|
496
|
+
|
497
|
+
end
|
498
|
+
|
499
|
+
# TODO: document me
|
500
|
+
def self.get_test_object_identifiers( xml_source, test_object = nil )
|
501
|
+
|
502
|
+
# retrieve parent xpath if test_object given
|
503
|
+
parent_xpath = test_object ? test_object.instance_variable_get( :@parent ).x_path : ""
|
504
|
+
|
505
|
+
# retrieve type attribute
|
506
|
+
type = xml_source.attribute( 'type' )
|
507
|
+
|
508
|
+
# retrieve id attribute
|
509
|
+
id = xml_source.attribute( 'id' )
|
510
|
+
|
511
|
+
# retrieve env attribute
|
512
|
+
env = xml_source.attribute( 'env' )
|
513
|
+
|
514
|
+
# retrieve test object element attributes and return array containting xpath to test object, name, type and id elements
|
515
|
+
[
|
516
|
+
# x_path to test object
|
517
|
+
test_object ? "#{ parent_xpath }/*//object[@type='#{ type }' and @id='#{ id }']" : nil,
|
518
|
+
|
519
|
+
# test object name
|
520
|
+
xml_source.attribute( 'name' ),
|
521
|
+
|
522
|
+
# test object type
|
523
|
+
type,
|
524
|
+
|
525
|
+
# test object id
|
526
|
+
id,
|
527
|
+
|
528
|
+
env
|
529
|
+
|
530
|
+
]
|
531
|
+
|
532
|
+
end
|
533
|
+
|
534
|
+
# TODO: document me
|
535
|
+
def self.hash_to_element_attributes( hash )
|
536
|
+
|
537
|
+
hash.collect{ | key, value |
|
538
|
+
|
539
|
+
"#{ key.to_s }=\"#{ value.to_s }\""
|
540
|
+
|
541
|
+
}.join(' ')
|
542
|
+
|
543
|
+
end
|
544
|
+
|
545
|
+
# TODO: document me
|
546
|
+
def self.merge_application_elements( xml_string )
|
547
|
+
|
548
|
+
# parse the ui state xml
|
549
|
+
document_root = MobyUtil::XML.parse_string( xml_string ).root
|
550
|
+
|
551
|
+
# retrieve application objects as nodeset
|
552
|
+
nodeset = document_root.xpath('/tasMessage/tasInfo/object')
|
553
|
+
|
554
|
+
# check if multiple application objects found
|
555
|
+
if nodeset.count > 1
|
556
|
+
|
557
|
+
# new header, apply original element attributes
|
558
|
+
new_xml = "<tasMessage #{ hash_to_element_attributes( document_root.attributes ) }><tasInfo #{ hash_to_element_attributes( nodeset.first.parent.attributes ) }>"
|
559
|
+
|
560
|
+
# flag defining that is application element already created
|
561
|
+
application_element_set = false
|
562
|
+
|
563
|
+
# collect environment values
|
564
|
+
environments = document_root.xpath('/tasMessage/tasInfo/object[@type="application"]/@env').collect{ | attribute | attribute.to_s }
|
565
|
+
|
566
|
+
# iterate through each object found in xml
|
567
|
+
nodeset.each{ | object |
|
568
|
+
|
569
|
+
# only one application element
|
570
|
+
unless application_element_set
|
571
|
+
|
572
|
+
#application_objects << object
|
573
|
+
|
574
|
+
# retrieve object attributes
|
575
|
+
attributes = object.attributes
|
576
|
+
|
577
|
+
# merge env to attributes hash
|
578
|
+
attributes['env'] = environments.join(';')
|
579
|
+
|
580
|
+
# add application object xml element to new xml string
|
581
|
+
new_xml << "<object #{ hash_to_element_attributes( attributes ) }>"
|
582
|
+
|
583
|
+
# application element is now set, no need to do it again
|
584
|
+
application_element_set = true
|
585
|
+
|
586
|
+
end
|
587
|
+
|
588
|
+
# append all found elements
|
589
|
+
object.xpath('./*').each{ | object | new_xml << object.to_s }
|
590
|
+
|
591
|
+
}
|
592
|
+
|
593
|
+
# multiple applications found, return merged application xml
|
594
|
+
new_xml << "</object></tasInfo></tasMessage>"
|
595
|
+
|
596
|
+
else
|
597
|
+
|
598
|
+
# only one application found, return data as is
|
599
|
+
xml_string
|
600
|
+
|
601
|
+
end
|
602
|
+
|
603
|
+
end
|
604
|
+
|
394
605
|
# enable hooking for performance measurement & debug logging
|
395
|
-
|
606
|
+
TDriver::Hooking.hook_methods( self ) if defined?( TDriver::Hooking )
|
396
607
|
|
397
608
|
end # TestObjectAdapter
|
398
609
|
|