testability-driver 0.9.2

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 (214) hide show
  1. data/README +1 -0
  2. data/bin/start_app_perf +199 -0
  3. data/bin/tdriver-devtools +3 -0
  4. data/config/sut_parameters.rb +39 -0
  5. data/ext/extconf.rb +67 -0
  6. data/ext/native_extensions.c +70 -0
  7. data/lib/matti.rb +30 -0
  8. data/lib/tdriver-devtools/behaviour/old/xml/example/flick-example.rb +223 -0
  9. data/lib/tdriver-devtools/behaviour/old/xml/example/impl.rb_invalid +194 -0
  10. data/lib/tdriver-devtools/behaviour/old/xml/generate_behaviour_xml.rb +95 -0
  11. data/lib/tdriver-devtools/behaviour/old/xml/lib/tdriver_generator.rb +722 -0
  12. data/lib/tdriver-devtools/behaviour/old/xml/qdoc_generator.rb +321 -0
  13. data/lib/tdriver-devtools/behaviour/old/xml/templates/behaviour.method.template +43 -0
  14. data/lib/tdriver-devtools/behaviour/old/xml/templates/behaviour.module.template +54 -0
  15. data/lib/tdriver-devtools/behaviour/old/xml/templates/behaviour.xml.argument.template +7 -0
  16. data/lib/tdriver-devtools/behaviour/old/xml/templates/behaviour.xml.argument_type.template +7 -0
  17. data/lib/tdriver-devtools/behaviour/old/xml/templates/behaviour.xml.exception.template +5 -0
  18. data/lib/tdriver-devtools/behaviour/old/xml/templates/behaviour.xml.howto.line.template +2 -0
  19. data/lib/tdriver-devtools/behaviour/old/xml/templates/behaviour.xml.howto.template +5 -0
  20. data/lib/tdriver-devtools/behaviour/old/xml/templates/behaviour.xml.method.template +23 -0
  21. data/lib/tdriver-devtools/behaviour/old/xml/templates/behaviour.xml.template +14 -0
  22. data/lib/tdriver-devtools/behaviour/old/xml/update +3 -0
  23. data/lib/tdriver-devtools/behaviour/xml/generate.rb +88 -0
  24. data/lib/tdriver-devtools/behaviour/xml/rdoc_behaviour_xml_generator.rb +1924 -0
  25. data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.argument.default.template +1 -0
  26. data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.argument.template +3 -0
  27. data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.argument_type.template +4 -0
  28. data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.exception.template +4 -0
  29. data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.method.arguments.template +4 -0
  30. data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.method.deprecated.template +3 -0
  31. data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.method.exceptions.template +3 -0
  32. data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.method.info.template +1 -0
  33. data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.method.returns.template +3 -0
  34. data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.method.tables.template +3 -0
  35. data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.method.template +12 -0
  36. data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.returns.template +5 -0
  37. data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.table.item.template +1 -0
  38. data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.table.row.template +2 -0
  39. data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.table.template +8 -0
  40. data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.template +14 -0
  41. data/lib/tdriver-devtools/behaviour/xml_generator/example/flick-example.rb +245 -0
  42. data/lib/tdriver-devtools/behaviour/xml_generator/example/sut.rb +964 -0
  43. data/lib/tdriver-devtools/behaviour/xml_generator/generate.rb +68 -0
  44. data/lib/tdriver-devtools/behaviour/xml_generator/lib/custom_rdoc_generator.rb +1865 -0
  45. data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.argument.default.template +1 -0
  46. data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.argument.template +3 -0
  47. data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.argument_type.template +4 -0
  48. data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.exception.template +4 -0
  49. data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.method.arguments.template +4 -0
  50. data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.method.deprecated.template +3 -0
  51. data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.method.exceptions.template +3 -0
  52. data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.method.info.template +1 -0
  53. data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.method.returns.template +3 -0
  54. data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.method.tables.template +3 -0
  55. data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.method.template +12 -0
  56. data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.returns.template +5 -0
  57. data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.table.item.template +1 -0
  58. data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.table.row.template +2 -0
  59. data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.table.template +7 -0
  60. data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.template +14 -0
  61. data/lib/tdriver-devtools/behaviour/xml_generator/update +3 -0
  62. data/lib/tdriver-devtools/doc/behaviour_xml/QtExampleGestureBehaviour.xml +138 -0
  63. data/lib/tdriver-devtools/doc/behaviour_xml/created.rid +1 -0
  64. data/lib/tdriver-devtools/doc/behaviour_xml/tdriver.hash +1 -0
  65. data/lib/tdriver-devtools/doc/feature_xml/qt_widget_hold.feature.xml +9 -0
  66. data/lib/tdriver-devtools/doc/feature_xml/qt_widget_tap.feature.xml +9 -0
  67. data/lib/tdriver-devtools/doc/generate.rb +892 -0
  68. data/lib/tdriver-devtools/doc/update +1 -0
  69. data/lib/tdriver-devtools/doc/xslt/html.rb +7 -0
  70. data/lib/tdriver-devtools/doc/xslt/template.xsl +1861 -0
  71. data/lib/tdriver-devtools/doc/xslt/update +3 -0
  72. data/lib/tdriver-devtools/plugin/placeholder.txt +1 -0
  73. data/lib/tdriver-devtools/tdriver-devtools.rb +404 -0
  74. data/lib/tdriver-devtools/tests/feature_tests/example/flick-example.rb +233 -0
  75. data/lib/tdriver-devtools/tests/feature_tests/example/impl.rb +194 -0
  76. data/lib/tdriver-devtools/tests/feature_tests/generate.rb +82 -0
  77. data/lib/tdriver-devtools/tests/feature_tests/lib/custom_rdoc_generator.rb +468 -0
  78. data/lib/tdriver-devtools/tests/feature_tests/templates/feature_attribute.template +5 -0
  79. data/lib/tdriver-devtools/tests/feature_tests/templates/feature_method.template +5 -0
  80. data/lib/tdriver-devtools/tests/feature_tests/templates/scenario_attribute.template +5 -0
  81. data/lib/tdriver-devtools/tests/feature_tests/templates/scenario_method.template +5 -0
  82. data/lib/tdriver-devtools/tests/feature_tests/update +3 -0
  83. data/lib/tdriver.rb +26 -0
  84. data/lib/tdriver/base/behaviour/behaviour.rb +32 -0
  85. data/lib/tdriver/base/behaviour/behaviours/object_behaviour_composition.rb +94 -0
  86. data/lib/tdriver/base/behaviour/behaviours/object_behaviour_description.rb +262 -0
  87. data/lib/tdriver/base/behaviour/behaviours/object_composition.rb +111 -0
  88. data/lib/tdriver/base/behaviour/factory.rb +380 -0
  89. data/lib/tdriver/base/behaviour/loader.rb +28 -0
  90. data/lib/tdriver/base/command_data/command_data.rb +51 -0
  91. data/lib/tdriver/base/command_data/loader.rb +25 -0
  92. data/lib/tdriver/base/errors.rb +131 -0
  93. data/lib/tdriver/base/loader.rb +38 -0
  94. data/lib/tdriver/base/state_object.rb +270 -0
  95. data/lib/tdriver/base/sut/adapter.rb +28 -0
  96. data/lib/tdriver/base/sut/controller.rb +119 -0
  97. data/lib/tdriver/base/sut/factory.rb +287 -0
  98. data/lib/tdriver/base/sut/generic/behaviours/application.rb +243 -0
  99. data/lib/tdriver/base/sut/generic/behaviours/controller.rb +67 -0
  100. data/lib/tdriver/base/sut/generic/behaviours/find.rb +96 -0
  101. data/lib/tdriver/base/sut/generic/behaviours/flash_behaviour.rb +346 -0
  102. data/lib/tdriver/base/sut/generic/behaviours/sut.rb +1268 -0
  103. data/lib/tdriver/base/sut/generic/behaviours/switchbox_behaviour.rb +182 -0
  104. data/lib/tdriver/base/sut/generic/behaviours/verification.rb +119 -0
  105. data/lib/tdriver/base/sut/generic/commands/application.rb +219 -0
  106. data/lib/tdriver/base/sut/generic/commands/key_sequence.rb +82 -0
  107. data/lib/tdriver/base/sut/generic/commands/screen_capture.rb +58 -0
  108. data/lib/tdriver/base/sut/generic/plugin.rb +96 -0
  109. data/lib/tdriver/base/sut/loader.rb +35 -0
  110. data/lib/tdriver/base/sut/sut.rb +67 -0
  111. data/lib/tdriver/base/test_object/abstract.rb +179 -0
  112. data/lib/tdriver/base/test_object/behaviours/syncronization.rb +94 -0
  113. data/lib/tdriver/base/test_object/behaviours/test_object.rb +787 -0
  114. data/lib/tdriver/base/test_object/factory.rb +618 -0
  115. data/lib/tdriver/base/test_object/identificator.rb +511 -0
  116. data/lib/tdriver/base/test_object/loader.rb +37 -0
  117. data/lib/tdriver/env.rb +21 -0
  118. data/lib/tdriver/loader.rb +36 -0
  119. data/lib/tdriver/matti.rb +35 -0
  120. data/lib/tdriver/report/error_recovery/tdriver_custom_error_recovery.rb +83 -0
  121. data/lib/tdriver/report/error_recovery/tdriver_error_recovery.rb +158 -0
  122. data/lib/tdriver/report/error_recovery/tdriver_error_recovery_settings.rb +98 -0
  123. data/lib/tdriver/report/report.rb +47 -0
  124. data/lib/tdriver/report/report_api.rb +207 -0
  125. data/lib/tdriver/report/report_combine.rb +86 -0
  126. data/lib/tdriver/report/report_crash_file_capture.rb +167 -0
  127. data/lib/tdriver/report/report_creator.rb +571 -0
  128. data/lib/tdriver/report/report_cucumber.rb +158 -0
  129. data/lib/tdriver/report/report_cucumber_listener.rb +337 -0
  130. data/lib/tdriver/report/report_cucumber_reporter.rb +335 -0
  131. data/lib/tdriver/report/report_data_presentation.rb +152 -0
  132. data/lib/tdriver/report/report_data_table.rb +64 -0
  133. data/lib/tdriver/report/report_execution_statistics.rb +284 -0
  134. data/lib/tdriver/report/report_file_capture.rb +159 -0
  135. data/lib/tdriver/report/report_grouping.rb +539 -0
  136. data/lib/tdriver/report/report_junit_xml.rb +147 -0
  137. data/lib/tdriver/report/report_rspec.rb +108 -0
  138. data/lib/tdriver/report/report_test_case_run.rb +621 -0
  139. data/lib/tdriver/report/report_test_run.rb +1286 -0
  140. data/lib/tdriver/report/report_test_unit.rb +175 -0
  141. data/lib/tdriver/report/report_writer.rb +1405 -0
  142. data/lib/tdriver/tdriver.rb +158 -0
  143. data/lib/tdriver/util/common.rb +24 -0
  144. data/lib/tdriver/util/common/array.rb +39 -0
  145. data/lib/tdriver/util/common/crc16.rb +100 -0
  146. data/lib/tdriver/util/common/environment.rb +153 -0
  147. data/lib/tdriver/util/common/error.rb +39 -0
  148. data/lib/tdriver/util/common/file.rb +315 -0
  149. data/lib/tdriver/util/common/gem.rb +108 -0
  150. data/lib/tdriver/util/common/kernel.rb +189 -0
  151. data/lib/tdriver/util/common/loader.rb +39 -0
  152. data/lib/tdriver/util/common/retryable.rb +98 -0
  153. data/lib/tdriver/util/common/string.rb +77 -0
  154. data/lib/tdriver/util/dbaccess/dbaccess.rb +188 -0
  155. data/lib/tdriver/util/dbaccess/dbconnection.rb +41 -0
  156. data/lib/tdriver/util/dbaccess/error.rb +35 -0
  157. data/lib/tdriver/util/dbaccess/loader.rb +29 -0
  158. data/lib/tdriver/util/dynamic_attribute_filter.rb +182 -0
  159. data/lib/tdriver/util/hooking.rb +434 -0
  160. data/lib/tdriver/util/loader.rb +65 -0
  161. data/lib/tdriver/util/localisation.rb +24 -0
  162. data/lib/tdriver/util/localisation/error.rb +32 -0
  163. data/lib/tdriver/util/localisation/loader.rb +28 -0
  164. data/lib/tdriver/util/localisation/localisation.rb +479 -0
  165. data/lib/tdriver/util/logger.rb +377 -0
  166. data/lib/tdriver/util/operator_data/error.rb +29 -0
  167. data/lib/tdriver/util/operator_data/loader.rb +26 -0
  168. data/lib/tdriver/util/operator_data/operator_data.rb +93 -0
  169. data/lib/tdriver/util/other/config.rb +221 -0
  170. data/lib/tdriver/util/parameter.rb +24 -0
  171. data/lib/tdriver/util/parameter/error.rb +45 -0
  172. data/lib/tdriver/util/parameter/loader.rb +37 -0
  173. data/lib/tdriver/util/parameter/parameter.rb +285 -0
  174. data/lib/tdriver/util/parameter/parameter_hash.rb +101 -0
  175. data/lib/tdriver/util/parameter/parameter_template.rb +120 -0
  176. data/lib/tdriver/util/parameter/parameter_user_api.rb +84 -0
  177. data/lib/tdriver/util/parameter/parameter_xml.rb +247 -0
  178. data/lib/tdriver/util/plugin/abstract.rb +60 -0
  179. data/lib/tdriver/util/plugin/error.rb +25 -0
  180. data/lib/tdriver/util/plugin/loader.rb +28 -0
  181. data/lib/tdriver/util/plugin/service.rb +200 -0
  182. data/lib/tdriver/util/recorder.rb +292 -0
  183. data/lib/tdriver/util/stats.rb +90 -0
  184. data/lib/tdriver/util/user_data/error.rb +29 -0
  185. data/lib/tdriver/util/user_data/loader.rb +26 -0
  186. data/lib/tdriver/util/user_data/user_data.rb +103 -0
  187. data/lib/tdriver/util/video_rec.rb +264 -0
  188. data/lib/tdriver/util/xml/abstraction.rb +47 -0
  189. data/lib/tdriver/util/xml/builder.rb +54 -0
  190. data/lib/tdriver/util/xml/document.rb +32 -0
  191. data/lib/tdriver/util/xml/element.rb +32 -0
  192. data/lib/tdriver/util/xml/error.rb +46 -0
  193. data/lib/tdriver/util/xml/loader.rb +46 -0
  194. data/lib/tdriver/util/xml/nil_element.rb +89 -0
  195. data/lib/tdriver/util/xml/nodeset.rb +32 -0
  196. data/lib/tdriver/util/xml/parsers/libxml/libxml.rb +140 -0
  197. data/lib/tdriver/util/xml/parsers/loader.rb +22 -0
  198. data/lib/tdriver/util/xml/parsers/nokogiri/abstraction.rb +111 -0
  199. data/lib/tdriver/util/xml/parsers/nokogiri/attribute.rb +54 -0
  200. data/lib/tdriver/util/xml/parsers/nokogiri/builder.rb +58 -0
  201. data/lib/tdriver/util/xml/parsers/nokogiri/document.rb +58 -0
  202. data/lib/tdriver/util/xml/parsers/nokogiri/element.rb +147 -0
  203. data/lib/tdriver/util/xml/parsers/nokogiri/loader.rb +42 -0
  204. data/lib/tdriver/util/xml/parsers/nokogiri/nodeset.rb +187 -0
  205. data/lib/tdriver/util/xml/xml.rb +170 -0
  206. data/lib/tdriver/verify/verify.rb +687 -0
  207. data/lib/tdriver/verify/verify.rb_org +630 -0
  208. data/lib/tdriver/version.rb +21 -0
  209. data/xml/behaviours/generic.xml +495 -0
  210. data/xml/defaults/generic.xml +97 -0
  211. data/xml/defaults/sut_generic.xml +36 -0
  212. data/xml/parameters/tdriver_parameters.xml +23 -0
  213. data/xml/templates/generic.xml +227 -0
  214. metadata +327 -0
@@ -0,0 +1,511 @@
1
+ ############################################################################
2
+ ##
3
+ ## Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4
+ ## All rights reserved.
5
+ ## Contact: Nokia Corporation (testabilitydriver@nokia.com)
6
+ ##
7
+ ## This file is part of Testability Driver.
8
+ ##
9
+ ## If you have questions regarding the use of this file, please contact
10
+ ## Nokia at testabilitydriver@nokia.com .
11
+ ##
12
+ ## This library is free software; you can redistribute it and/or
13
+ ## modify it under the terms of the GNU Lesser General Public
14
+ ## License version 2.1 as published by the Free Software Foundation
15
+ ## and appearing in the file LICENSE.LGPL included in the packaging
16
+ ## of this file.
17
+ ##
18
+ ############################################################################
19
+
20
+ module MobyBase
21
+
22
+ # Class to represent TestObjectIdentificator
23
+ # TestObjectIdentificator identifies TestObject representation from a TasMessage xml document.
24
+ class TestObjectIdentificator
25
+
26
+ attr_accessor :dynamic_attributes
27
+
28
+ @@required_attributes = [ :type, :id, :name, :parent ]
29
+
30
+ # special cases: allow partial match when value of :type and attribute name matches
31
+ @@partial_match_allowed = [ [ :list_item, :Text ], [ 'list_item', :Text ], [ :application, :FullName ], ['application', :FullName ] ]
32
+
33
+ # Creating new TestObjectIdentificator gets one argument as a Hash
34
+ # The hash contains rules with which xml fragments are identified within the scope.
35
+ # The scope can be either whole UI dump, or a TestObject containing child objects
36
+ #
37
+ # Usage: @test_object_identificator.new (:type => :softkey, :Text => Options)
38
+ # ==> tries to find 'softkey' TestObject, which has an attribute 'Text' with value 'Options'
39
+ # Usage: @test_object_identificator.new (:type => :list)
40
+ # ==> tries to identify the only list currently seen in the scope
41
+ #
42
+ # == params
43
+ # hash_rules:: hash containing rules to identify.
44
+ # NOTE: the hash_rule MUST contain either mapping from
45
+ # :type => <some_type> OR
46
+ # :id => <some id>
47
+ # == return
48
+ # TestObjectIdentificator:: set with specific rules
49
+ # == raises
50
+ # ArgumentError:: if hash_rules does not contain either :type or :id
51
+ def initialize( hash_rules = {} )
52
+
53
+ # Relaxing conditoins of search, no need for mandatory :name, :type or :id rule
54
+ #Kernel::raise ArgumentError.new('Cannot create a TestObjectIdentifier without :name, :type or :id rule') unless ( hash_rules.has_key?( :type ) or hash_rules.has_key?( :id ) or hash_rules.has_key?( :name ) )
55
+
56
+ # ensure that each attribute keys used for object identification are type of Symbol
57
+ @_attributes_used_to_identify_object = Hash[ hash_rules.collect{ | key, value | [ key.to_sym, value ] } ]
58
+
59
+ @dynamic_attributes = Hash[ hash_rules.select{ | key, value | key.to_s =~ /^__/ } ]
60
+
61
+ @insignificant_attributes = @@required_attributes + [ :__index ] + [ :__xy_sorting ] + [ :__fname ] + [ :__plurality ] + [ :__numerus ] + [ :__lengthvariant ]
62
+
63
+ end
64
+
65
+ # TODO: Documentation
66
+ def find_objects( from_xml_element, find_all_children )
67
+
68
+ [ from_xml_element.xpath( rule = xpath_to_identify( find_all_children ) ), rule ]
69
+
70
+ end
71
+
72
+ # getter to return the rules used in identification
73
+ # == returns
74
+ # Hash:: Hash object containing the rules
75
+ def get_identification_rules
76
+
77
+ @_attributes_used_to_identify_object
78
+
79
+ end
80
+
81
+ # Sort XML nodeset of test objects with layout direction
82
+ def sort_elements_by_xy_layout!( nodeset, layout_direction = "LeftToRight" )
83
+
84
+ attribute_pattern = "./attributes/attribute[@name='%s']/value"
85
+
86
+ # collect only nodes that has x_absolute and y_absolute attributes
87
+ nodeset.collect!{ | node |
88
+
89
+ node unless node.xpath( attribute_pattern % 'x_absolute' ).empty? || node.xpath( attribute_pattern % 'y_absolute' ).empty?
90
+
91
+ }.compact!.sort!{ | a, b |
92
+
93
+ a_x = a.xpath( attribute_pattern % 'x_absolute' ).first.content.to_i
94
+ a_y = a.xpath( attribute_pattern % 'y_absolute' ).first.content.to_i
95
+
96
+ b_x = b.xpath( attribute_pattern % 'x_absolute' ).first.content.to_i
97
+ b_y = b.xpath( attribute_pattern % 'y_absolute' ).first.content.to_i
98
+
99
+ if ( layout_direction =~ /LeftToRight/i )
100
+
101
+ ( a_y == b_y ) ? ( a_x <=> b_x ) : ( a_y <=> b_y )
102
+
103
+ elsif ( layout_direction =~ /RightToLeft/i )
104
+
105
+ ( a_y == b_y ) ? ( b_x <=> a_x ) : ( a_y <=> b_y )
106
+
107
+ else
108
+
109
+ Kernel::raise ArgumentError.new( "Unexpected layout direction: %s" % layout_direction )
110
+
111
+ end
112
+
113
+ }
114
+
115
+ end
116
+
117
+ private
118
+
119
+
120
+ # function create x_path that included required attributes type, id and/or name
121
+ # == returns
122
+ # String:: x_path containing required attributes
123
+ def create_xpath_from_required_attributes
124
+
125
+ return "@*" if @_attributes_used_to_identify_object[ :type ].to_s == "any"
126
+
127
+ xpath = ""
128
+
129
+ pattern = "@%s=%s or attributes/attribute[translate(@name,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')=%s]/value=%s"
130
+
131
+ @_attributes_used_to_identify_object.each_pair{ | attribute_name, attribute_value |
132
+
133
+ next unless @@required_attributes.include?( attribute_name )
134
+
135
+ xpath << ' and ' unless xpath.empty?
136
+
137
+ xpath << '('
138
+
139
+ if attribute_value.kind_of?( Array )
140
+
141
+ # multiple (optional) attributes for object identification
142
+ attribute_value.each_with_index{ | attribute_value_option, index |
143
+
144
+ xpath << ' or ' unless index.zero?
145
+
146
+ a_v_o = convertToXPathLiteral( attribute_value_option )
147
+
148
+ xpath << pattern % [
149
+ attribute_name,
150
+ a_v_o,
151
+ convertToXPathLiteral( attribute_name.to_s.downcase),
152
+ a_v_o
153
+ ]
154
+
155
+ }
156
+
157
+ else
158
+
159
+ a_v = convertToXPathLiteral( attribute_value )
160
+
161
+ # one attribute used for object identification
162
+ xpath << "%s" % [
163
+ pattern % [
164
+ attribute_name,
165
+ a_v,
166
+ convertToXPathLiteral( attribute_name.to_s.downcase),
167
+ a_v
168
+ ]
169
+ ]
170
+
171
+ end
172
+
173
+ xpath << ')'
174
+
175
+ }
176
+
177
+ xpath
178
+
179
+ end
180
+
181
+ # Private function to define rule for a given MobyUtil::XML::Element element.
182
+ # Uses xml_elements namespace in the rule.
183
+ # Uses private instance variable to define the actual rule. Instance variable is set in constructor
184
+ # == params
185
+ # xml_element:: MobyUtil::XML::Element element frow which objects are being identified
186
+ # == returns
187
+ # Array (<String>, Array(<String>) ):: returns array of two element as defined below
188
+ # String:: Rule to be used in xpath
189
+ def xpath_to_identify( get_all_children = true )
190
+
191
+ xpath = create_xpath_from_required_attributes
192
+
193
+ pattern = "attributes/attribute[translate(@name,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')=%s]/"
194
+
195
+ @_attributes_used_to_identify_object.each_pair do | attribute_key, attribute_value |
196
+
197
+ # Relaxing conditions, no need for mandatory :name, :type, :parent, :id or :__index. See class instance constructor.
198
+ next if @insignificant_attributes.include?( attribute_key )
199
+
200
+ xpath << ' and ' unless xpath.empty?
201
+
202
+ xpath << pattern % convertToXPathLiteral( attribute_key.to_s.downcase )
203
+
204
+ # convert single value to array, due to value can contain multiple values and no use to have duplicate code for processing
205
+ attribute_value = [ attribute_value ] unless attribute_value.kind_of?( Array )
206
+
207
+ attribute_value.each_with_index do | value, index |
208
+
209
+ xpath << " or " unless index.zero?
210
+
211
+ # allow partial match when value of :type and attribute name matches. see class instance constructor.
212
+ if @@partial_match_allowed.include?( [ @_attributes_used_to_identify_object[ :type ], attribute_key ] )
213
+
214
+ xpath << "value[contains(.,%s)]" % convertToXPathLiteral( value )
215
+
216
+ else
217
+
218
+ xpath << "value=%s" % convertToXPathLiteral( value )
219
+
220
+
221
+ end
222
+ end
223
+
224
+ end
225
+
226
+ ( get_all_children ? "*//object[%s]" : "objects[1]/object[%s]" ) % xpath
227
+
228
+ end
229
+
230
+ # TODO: This method needs to refactored
231
+ # function to deal with case where string literals in XPath expressions contains single or double quotes
232
+ # If string literal value contain only one type - double or single, then delimit with the other.
233
+ # E.g. "'" or '"'
234
+ # If value contains both then you can not do it directly in a string literal but need to construct the string using
235
+ # concat("'",'"')
236
+ def convertToXPathLiteral( value )
237
+
238
+ # convert to string if needed
239
+ value_string = value.kind_of?( String ) ? value : value.to_s
240
+
241
+ if !value_string.include?("\'")
242
+
243
+ # return value
244
+ "\'%s\'" % value_string
245
+
246
+ elsif !value_string.include?("\"")
247
+
248
+ # return value
249
+ "\"%s\"" % value_string
250
+
251
+ else
252
+
253
+ result = ""
254
+
255
+ substrings = value_string.split( "\"" )
256
+
257
+ substrings.each_with_index do | s, i |
258
+
259
+ needComma = true if i > 0
260
+
261
+ unless s.empty?
262
+
263
+ result << ", " if i > 0
264
+
265
+ result << "\"%s\"" % s
266
+
267
+ needComma = true
268
+
269
+ end
270
+
271
+ # other than last one
272
+ if i < substrings.length - 1
273
+
274
+ result << ", " if needComma
275
+
276
+ result << "'\"'"
277
+
278
+ end
279
+
280
+ end
281
+
282
+ # return value
283
+ "concat(%s)" % result
284
+
285
+ end
286
+
287
+ end
288
+
289
+ public # deprecated
290
+
291
+ # function create x_path that included required attributes type, id and/or name
292
+ # == returns
293
+ # String:: x_path containing required attributes
294
+ def create_x_path_from_required_attributes
295
+
296
+ return "@*" if @_attributes_used_to_identify_object[ :type ].to_s == "any"
297
+
298
+ xpath = ""
299
+
300
+ pattern = "@%s=%s or attributes/attribute[translate(@name,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')=%s]/value=%s"
301
+
302
+ @_attributes_used_to_identify_object.each_pair{ | attribute_name, attribute_value |
303
+
304
+ next unless @@required_attributes.include?( attribute_name )
305
+
306
+ xpath << ' and ' unless xpath.empty?
307
+
308
+ xpath << '('
309
+
310
+ if attribute_value.kind_of?( Array )
311
+
312
+ # multiple (optional) attributes for object identification
313
+ attribute_value.each_with_index{ | attribute_value_option, index |
314
+
315
+ xpath << ' or ' unless index.zero?
316
+
317
+ xpath << pattern % [
318
+ attribute_name,
319
+ convertToXPathLiteral( attribute_value_option),
320
+ convertToXPathLiteral( attribute_name.to_s.downcase),
321
+ convertToXPathLiteral( attribute_value_option)
322
+ ]
323
+
324
+ }
325
+
326
+ else
327
+
328
+ # one attribute used for object identification
329
+ xpath << "%s" % [
330
+ pattern % [
331
+ attribute_name,
332
+ convertToXPathLiteral( attribute_value),
333
+ convertToXPathLiteral( attribute_name.to_s.downcase),
334
+ convertToXPathLiteral( attribute_value)
335
+ ]
336
+ ]
337
+
338
+ end
339
+
340
+ xpath << ')'
341
+
342
+ }
343
+
344
+ xpath
345
+
346
+ end
347
+
348
+ # Private function to define rule for a given MobyUtil::XML::Element element.
349
+ # Uses xml_elements namespace in the rule.
350
+ # Uses private instance variable to define the actual rule. Instance variable is set in constructor
351
+ # == params
352
+ # xml_element:: MobyUtil::XML::Element element frow which objects are being identified
353
+ # == returns
354
+ # Array (<String>, Array(<String>) ):: returns array of two element as defined below
355
+ # String:: Rule to be used in xpath
356
+ def get_xpath_to_identify( from_xml_element, namespace = nil, get_all_children= true )
357
+
358
+ xpath = create_x_path_from_required_attributes
359
+ pattern = "attributes/attribute[translate(@name,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')=%s]/"
360
+
361
+ @_attributes_used_to_identify_object.each_pair do | attribute_key, attribute_value |
362
+
363
+ # Relaxing conditions, no need for mandatory :name, :type, :parent, :id or :__index. See class instance constructor.
364
+ next if @insignificant_attributes.include?( attribute_key )
365
+
366
+ xpath << ' and ' unless xpath.empty?
367
+
368
+ xpath << pattern % convertToXPathLiteral( attribute_key.to_s.downcase )
369
+
370
+ # convert single value to array, due to value can contain multiple values and no use to have duplicate code for processing
371
+ attribute_value = [ attribute_value ] unless attribute_value.kind_of?( Array )
372
+
373
+ attribute_value.each_with_index do | value, index |
374
+
375
+ xpath << " or " unless index.zero?
376
+
377
+ # allow partial match when value of :type and attribute name matches. see class instance constructor.
378
+ if @@partial_match_allowed.include?( [ @_attributes_used_to_identify_object[ :type ], attribute_key ] )
379
+
380
+ xpath << "value[contains(.,%s)]" % convertToXPathLiteral( value )
381
+
382
+ else
383
+
384
+ xpath << "value=%s" % convertToXPathLiteral( value )
385
+
386
+
387
+ end
388
+ end
389
+
390
+ end
391
+
392
+ ( get_all_children ? "*//object[%s]" : "objects[1]/object[%s]" ) % xpath
393
+
394
+ end
395
+
396
+ ## Returns array of element nodes
397
+ def sort_elements_by_xy_layout( element_set, layout_direction = "LeftToRight" )
398
+
399
+ # MobyUtil::XML::NodeSet and Elements
400
+ # Take out all test_objects with no x_absolute or y_absolute
401
+ to_delete = []
402
+ element_set.each do |node|
403
+ begin
404
+ node.xpath("./attributes/attribute[@name = 'x_absolute']/value").first.content
405
+ node.xpath("./attributes/attribute[@name = 'y_absolute']/value").first.content
406
+ rescue
407
+ to_delete << node
408
+ end
409
+ end
410
+ to_delete.each do |node|
411
+ element_set.delete(node)
412
+ end
413
+ # Sort remaining by layout direction and up to down
414
+ # Requires .to_a to return an array of MobyUtil::XML::Elements
415
+ element_set.to_a.sort!{ |a, b|
416
+ a_x = a.xpath("./attributes/attribute[@name = 'x_absolute']/value").first.content.to_i
417
+ a_y = a.xpath("./attributes/attribute[@name = 'y_absolute']/value").first.content.to_i
418
+ b_x = b.xpath("./attributes/attribute[@name = 'x_absolute']/value").first.content.to_i
419
+ b_y = b.xpath("./attributes/attribute[@name = 'y_absolute']/value").first.content.to_i
420
+ if ( layout_direction.downcase == "LeftToRight".downcase )
421
+ ( a_y == b_y ) ? ( a_x <=> b_x ) : ( a_y <=> b_y )
422
+ elsif ( layout_direction.downcase == "RightToLeft".downcase )
423
+ ( a_y == b_y ) ? ( b_x <=> a_x ) : ( a_y <=> b_y )
424
+ else
425
+ Kernel::raise ArgumentError.new("Unexpected layout direction: " + layout_direction)
426
+ end
427
+ }
428
+ end
429
+
430
+ # Function to identify an object from tasMessage xml content
431
+ #
432
+ # == params
433
+ # from_xml_element: MobyUtil::XML::Element XML element for TestObject object containing the information from which a child test object is to be identified
434
+ # == return
435
+ # MobyUtil::XML::Element:: found XML fragment, if any
436
+ # == raise
437
+ # MultipleTestObjectsIdentifiedError:: if multiple test objects are identified
438
+ # TestObjectNotFoundError:: if no TestObject can be identified
439
+ # ArgumentError:: if 'from_xml_element' is not of type MobyUtil::XML::Element
440
+ def find_object_data( from_xml_element, layout_direction = nil )
441
+
442
+ Kernel::raise ArgumentError.new( "Wrong argument type %s for argument 'xml_element' (expected MobyUtil::XML::Element)" % from_xml_element.class ) unless from_xml_element.kind_of?( MobyUtil::XML::Element )
443
+
444
+ xpath = get_xpath_to_identify( from_xml_element )
445
+
446
+ element_set = from_xml_element.xpath( xpath )
447
+
448
+ if @_attributes_used_to_identify_object[ :__xy_sorting ] == "true"
449
+ begin
450
+ #layout_direction = parent_test_object.sut.application( :id => parent_test_object.get_application_id ).attribute("layoutDirection")
451
+ element_set = sort_elements_by_xy_layout( element_set, layout_direction )
452
+ rescue MobyBase::AttributeNotFoundError
453
+ element_set = sort_elements_by_xy_layout( element_set)
454
+ end
455
+ end
456
+
457
+ ret, size = ( (size = element_set.size).zero? ) ? [ nil, 0 ] : [ element_set[ ( ( index = @_attributes_used_to_identify_object[ :__index ] ) || 0 ).to_i ], ( index.nil? ? size : 1 ) ]
458
+
459
+ Kernel::raise MobyBase::MultipleTestObjectsIdentifiedError.new( "Multiple test objects found with rule:\n#{ xpath }" ) if ( size > 1 )
460
+
461
+ Kernel::raise MobyBase::TestObjectNotFoundError.new( "Cannot find object with rule:\n%s" % [ xpath ] ) if ( size.zero? || ret.nil? )
462
+
463
+ ret
464
+
465
+ end
466
+
467
+ # Function to identify all object from tasMessage xml content
468
+ #
469
+ # == params
470
+ # from_xml_element: MobyUtil::XML::Element XML element for TestObject object containing the information from which a children test object is to be identified
471
+ # find_all_children:: Boolean specifying whether all children under the test node or just immediate children should be retreived.
472
+ # == return
473
+ # MobyUtil::XML::Element:: found XML fragment, if any
474
+ # == raise
475
+ # TestObjectNotFoundError:: if no TestObject can be identified
476
+ # ArgumentError:: if 'from_xml_element' is not of type MobyUtil::XML::Element
477
+ def find_multiple_object_data( from_xml_element, find_all_children, layout_direction = nil )
478
+ Kernel::raise ArgumentError.new( "Wrong argument type %s for argument 'xml_element' (expected MobyUtil::XML::Element)" % from_xml_element.class ) unless from_xml_element.kind_of?( MobyUtil::XML::Element )
479
+
480
+ element_set = from_xml_element.xpath( xpath = get_xpath_to_identify( from_xml_element ,nil,find_all_children) )
481
+ ret = Array.new
482
+
483
+ if @_attributes_used_to_identify_object[ :__xy_sorting ] == "true"
484
+ begin
485
+ #layout_direction = parent_test_object.sut.application( :id => parent_test_object.get_application_id ).attribute("layoutDirection")
486
+ element_set = sort_elements_by_xy_layout( element_set, layout_direction )
487
+ rescue MobyBase::AttributeNotFoundError
488
+ element_set = sort_elements_by_xy_layout( element_set)
489
+ end
490
+ end
491
+
492
+ if @_attributes_used_to_identify_object.has_key?( :__index ) && element_set.size > 1
493
+ ret << element_set[ @_attributes_used_to_identify_object[ :__index ].to_i ]
494
+ size = 1
495
+ else
496
+ ret = element_set
497
+ size = element_set.size
498
+ end
499
+
500
+ Kernel::raise MobyBase::TestObjectNotFoundError.new( "Cannot find object with rule:\n#{ xpath }" ) if ( size == 0 or ret == nil)
501
+
502
+ ret
503
+
504
+ end
505
+
506
+ # enable hooking for performance measurement & debug logging
507
+ MobyUtil::Hooking.instance.hook_methods( self ) if defined?( MobyUtil::Hooking )
508
+
509
+ end # TestObjectIdentificator
510
+
511
+ end # MobyBase