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.
Files changed (116) hide show
  1. data/lib/tdriver-devtools/behaviour/xml/rdoc_behaviour_xml_generator.rb +2 -2
  2. data/lib/tdriver-devtools/tdriver-devtools.rb +1 -1
  3. data/lib/tdriver-devtools/tests/feature_tests/lib/custom_rdoc_generator.rb +3 -3
  4. data/lib/tdriver/base/behaviour/behaviours/object_behaviour_composition.rb +6 -1
  5. data/lib/tdriver/base/behaviour/behaviours/object_behaviour_description.rb +5 -3
  6. data/lib/tdriver/base/behaviour/behaviours/object_composition.rb +1 -1
  7. data/lib/tdriver/base/behaviour/factory.rb +225 -225
  8. data/lib/tdriver/base/errors.rb +1 -1
  9. data/lib/tdriver/base/state_object.rb +227 -179
  10. data/lib/tdriver/base/sut/controller.rb +2 -2
  11. data/lib/tdriver/base/sut/factory.rb +190 -182
  12. data/lib/tdriver/base/sut/generic/behaviours/application.rb +69 -25
  13. data/lib/tdriver/base/sut/generic/behaviours/controller.rb +1 -1
  14. data/lib/tdriver/base/sut/generic/behaviours/find.rb +4 -4
  15. data/lib/tdriver/base/sut/generic/behaviours/flash_behaviour.rb +3 -3
  16. data/lib/tdriver/base/sut/generic/behaviours/sut.rb +350 -165
  17. data/lib/tdriver/base/sut/generic/behaviours/switchbox_behaviour.rb +9 -9
  18. data/lib/tdriver/base/sut/generic/behaviours/verification.rb +191 -103
  19. data/lib/tdriver/base/sut/generic/commands/application.rb +1 -1
  20. data/lib/tdriver/base/sut/generic/commands/key_sequence.rb +1 -1
  21. data/lib/tdriver/base/sut/generic/commands/screen_capture.rb +1 -1
  22. data/lib/tdriver/base/sut/generic/plugin.rb +1 -1
  23. data/lib/tdriver/base/sut/sut.rb +5 -1
  24. data/lib/tdriver/base/test_object/abstract.rb +136 -151
  25. data/lib/tdriver/base/test_object/adapter.rb +293 -82
  26. data/lib/tdriver/base/test_object/behaviours/syncronization.rb +20 -17
  27. data/lib/tdriver/base/test_object/behaviours/test_object.rb +159 -532
  28. data/lib/tdriver/base/test_object/cache.rb +1 -1
  29. data/lib/tdriver/base/test_object/factory.rb +254 -605
  30. data/lib/tdriver/base/test_object/identificator.rb +1 -1
  31. data/lib/tdriver/base/test_object/loader.rb +1 -1
  32. data/lib/tdriver/base/test_object/verification.rb +17 -17
  33. data/lib/tdriver/loader.rb +20 -9
  34. data/lib/tdriver/report/report.rb +5 -0
  35. data/lib/tdriver/report/report_creator.rb +2 -2
  36. data/lib/tdriver/report/report_cucumber_listener.rb +4 -4
  37. data/lib/tdriver/report/report_cucumber_reporter.rb +4 -4
  38. data/lib/tdriver/report/report_execution_statistics.rb +22 -22
  39. data/lib/tdriver/report/report_grouping.rb +2 -2
  40. data/lib/tdriver/report/report_javascript.rb +11 -4
  41. data/lib/tdriver/report/report_test_case_run.rb +2 -2
  42. data/lib/tdriver/report/report_test_run.rb +5 -5
  43. data/lib/tdriver/report/report_test_unit.rb +74 -26
  44. data/lib/tdriver/report/report_writer.rb +70 -13
  45. data/lib/tdriver/tdriver.rb +17 -8
  46. data/lib/tdriver/util/common/array.rb +1 -1
  47. data/lib/tdriver/util/common/crc16.rb +1 -1
  48. data/lib/tdriver/util/common/environment.rb +1 -1
  49. data/lib/tdriver/util/common/file.rb +18 -9
  50. data/lib/tdriver/util/common/gem.rb +1 -1
  51. data/lib/tdriver/util/common/hash.rb +21 -0
  52. data/lib/tdriver/util/common/kernel.rb +1 -1
  53. data/lib/tdriver/util/common/loader.rb +5 -2
  54. data/lib/tdriver/util/common/numeric.rb +54 -3
  55. data/lib/tdriver/util/common/retryable.rb +30 -12
  56. data/lib/tdriver/util/common/stackable.rb +185 -0
  57. data/lib/tdriver/util/common/string.rb +21 -5
  58. data/lib/tdriver/util/{dbaccess/dbaccess.rb → database/access.rb} +4 -1
  59. data/lib/tdriver/util/{dbaccess/dbconnection.rb → database/connection.rb} +3 -0
  60. data/lib/tdriver/util/{dbaccess → database}/error.rb +0 -1
  61. data/lib/tdriver/util/{dbaccess → database}/loader.rb +5 -6
  62. data/lib/tdriver/util/{dynamic_attribute_filter.rb → filters/dynamic_attributes.rb} +1 -1
  63. data/lib/tdriver/util/hooking/hooking.rb +477 -0
  64. data/lib/tdriver/util/loader.rb +35 -29
  65. data/lib/tdriver/util/localisation/error.rb +0 -1
  66. data/lib/tdriver/util/localisation/loader.rb +1 -4
  67. data/lib/tdriver/util/localisation/localisation.rb +30 -27
  68. data/lib/tdriver/util/{common.rb → logger/loader.rb} +2 -4
  69. data/lib/tdriver/util/logger/logger.rb +574 -0
  70. data/lib/tdriver/util/operator_data/loader.rb +4 -3
  71. data/lib/tdriver/util/operator_data/operator_data.rb +5 -5
  72. data/lib/tdriver/util/parameter/parameter.rb +7 -1
  73. data/lib/tdriver/util/parameter/parameter_hash.rb +1 -1
  74. data/lib/tdriver/util/parameter/parameter_template.rb +1 -1
  75. data/lib/tdriver/util/parameter/parameter_user_api.rb +28 -20
  76. data/lib/tdriver/util/parameter/parameter_xml.rb +1 -1
  77. data/lib/tdriver/util/plugin/abstract.rb +1 -1
  78. data/lib/tdriver/util/plugin/service.rb +1 -1
  79. data/lib/tdriver/util/{localisation.rb → recorder/loader.rb} +4 -3
  80. data/lib/tdriver/util/recorder/recorder.rb +66 -0
  81. data/lib/tdriver/util/recorder/scripter.rb +258 -0
  82. data/lib/tdriver/util/{stats.rb → statistics/statistics.rb} +7 -8
  83. data/lib/tdriver/util/user_data/error.rb +0 -1
  84. data/lib/tdriver/util/user_data/loader.rb +1 -2
  85. data/lib/tdriver/util/user_data/user_data.rb +6 -6
  86. data/lib/tdriver/util/video/camera.rb +67 -0
  87. data/lib/tdriver/util/video/camera_linux.rb +139 -0
  88. data/lib/tdriver/util/video/camera_windows.rb +174 -0
  89. data/lib/tdriver/util/video/loader.rb +31 -0
  90. data/lib/tdriver/util/video/video_utils.rb +139 -0
  91. data/lib/tdriver/util/xml/abstraction.rb +56 -5
  92. data/lib/tdriver/util/xml/builder.rb +2 -5
  93. data/lib/tdriver/util/{parameter.rb → xml/comment.rb} +10 -2
  94. data/lib/tdriver/util/xml/loader.rb +32 -22
  95. data/lib/tdriver/util/xml/nil_node.rb +2 -2
  96. data/lib/tdriver/util/xml/parsers/loader.rb +0 -1
  97. data/lib/tdriver/util/xml/parsers/nokogiri/abstraction.rb +18 -44
  98. data/lib/tdriver/util/xml/parsers/nokogiri/attribute.rb +9 -13
  99. data/lib/tdriver/util/xml/parsers/nokogiri/builder.rb +9 -3
  100. data/lib/tdriver/util/xml/parsers/nokogiri/comment.rb +39 -0
  101. data/lib/tdriver/util/xml/parsers/nokogiri/document.rb +6 -11
  102. data/lib/tdriver/util/xml/parsers/nokogiri/element.rb +2 -122
  103. data/lib/tdriver/util/xml/parsers/nokogiri/loader.rb +26 -16
  104. data/lib/tdriver/util/xml/parsers/nokogiri/node.rb +203 -0
  105. data/lib/tdriver/util/xml/parsers/nokogiri/nodeset.rb +1 -2
  106. data/lib/tdriver/util/xml/parsers/nokogiri/text.rb +2 -20
  107. data/lib/tdriver/util/xml/xml.rb +52 -20
  108. data/lib/tdriver/verify/verify.rb +238 -81
  109. data/xml/behaviours/generic.xml +12 -10
  110. metadata +156 -180
  111. data/lib/tdriver/base/test_object/factory_new.rb +0 -202
  112. data/lib/tdriver/util/hooking.rb +0 -434
  113. data/lib/tdriver/util/logger.rb +0 -506
  114. data/lib/tdriver/util/recorder.rb +0 -297
  115. data/lib/tdriver/util/video_utils.rb +0 -384
  116. 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 = ( values.kind_of?( Array ) ? values : [ values ] ).collect{ | value |
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
- # partial match allowed
44
- value = "[contains(.,#{ value })]"
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
- prefix = ""
51
+ prefix_value = "=#{ value }"
52
+ attribute_value = "value/text()=#{ value }"
60
53
 
61
54
  end
62
-
63
- "#{ prefix }attributes/attribute[translate(@name,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')='#{key}' and .#{value}]"
64
-
65
- }.join( " or " )
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
- result = attributes.join(' and ')
70
-
71
- if result.empty?
66
+ # no attributes given
67
+ nil
72
68
 
73
- result = nil
74
-
75
69
  else
76
-
77
- result = "(#{ result })" if element_attributes
70
+
71
+ # return result
72
+ attributes
78
73
 
79
74
  end
80
75
 
81
- result
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
- test_object_identification_attributes_array = []
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!( "name", "type", "parent", "id" )
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[ "type" ] == 'any'
93
+ if object_element_attributes[ 'type' ] == '*'
102
94
 
103
95
  # test object with any name, type, parent and id is allowed
104
- test_object_identification_attributes_array << '@*'
96
+ test_object_xpath_array << '@*'
105
97
 
106
98
  else
107
99
 
108
100
  # required attributes
109
- test_object_identification_attributes_array << xpath_attributes( object_element_attributes, true, object_element_attributes[ "type" ] )
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
- test_object_identification_attributes_array << xpath_attributes( rules, false, object_element_attributes[ "type" ] )
106
+ test_object_xpath_array << xpath_attributes( rules, false, object_element_attributes[ 'type' ] )
115
107
 
116
108
  # join required and additional attribute strings
117
- test_object_identification_attributes = test_object_identification_attributes_array.compact.join(" and ")
109
+ test_object_xpath_string = test_object_xpath_array.compact.join( ' and ' )
118
110
 
119
- find_all_children ? "*//object[#{ test_object_identification_attributes }]" : "objects[1]/object[#{ test_object_identification_attributes }]"
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 = "LeftToRight" )
198
+ def self.sort_elements( nodeset, layout_direction = 'LeftToRight' )
204
199
 
205
- attribute_pattern = "./attributes/attribute[@name='%s']/value/text()"
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
- #node unless node.at_xpath( attribute_pattern % 'x_absolute' ).to_s.empty? || node.at_xpath( attribute_pattern % 'y_absolute' ).to_s.empty?
211
- node unless node.at_xpath( attribute_pattern % 'x_absolute' ).nil? || node.at_xpath( attribute_pattern % 'y_absolute' ).nil?
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 "LeftToRight"
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 "RightToLeft"
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
- Kernel::raise ArgumentError.new( "Unsupported layout direction #{ layout_direction.inspect }" )
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, name, &block )
269
+ def self.test_object_element_attribute( source_data, attribute_name, *default, &block )
261
270
 
262
- result = source_data.attribute( name )
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
- yield
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 such attribute found
273
- Kernel::raise MobyBase::AttributeNotFoundError.new(
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
- "Could not find test object element attribute #{ attribute_name.inspect }"
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 }']" # /value/text()"
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 such attribute found
312
- Kernel::raise MobyBase::AttributeNotFoundError.new(
328
+ # raise exception if no default value given
329
+ if default.empty?
313
330
 
314
- "Could not find attribute #{ attribute_name.inspect }" # for test object of type #{ type.to_s }"
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
- end
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{ | test_object |
366
+ source_data.xpath( 'attributes/attribute/value' ).collect{ | value |
341
367
 
342
- [ test_object.attribute( 'name' ), test_object.at_xpath( 'value/text()' ).to_s ]
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
- next if object_type.nil?
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
- MobyUtil::Hooking.instance.hook_methods( self ) if defined?( MobyUtil::Hooking )
606
+ TDriver::Hooking.hook_methods( self ) if defined?( TDriver::Hooking )
396
607
 
397
608
  end # TestObjectAdapter
398
609