testability-driver 1.0.3 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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