testability-driver 0.9.2 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (108) hide show
  1. data/lib/tdriver/base/behaviour/behaviours/object_behaviour_composition.rb +1 -1
  2. data/lib/tdriver/base/behaviour/behaviours/object_behaviour_description.rb +11 -7
  3. data/lib/tdriver/base/behaviour/behaviours/object_composition.rb +8 -0
  4. data/lib/tdriver/base/behaviour/factory.rb +229 -209
  5. data/lib/tdriver/base/errors.rb +3 -0
  6. data/lib/tdriver/base/state_object.rb +11 -20
  7. data/lib/tdriver/base/sut/controller.rb +4 -4
  8. data/lib/tdriver/base/sut/factory.rb +205 -170
  9. data/lib/tdriver/base/sut/generic/behaviours/application.rb +256 -174
  10. data/lib/tdriver/base/sut/generic/behaviours/find.rb +17 -11
  11. data/lib/tdriver/base/sut/generic/behaviours/flash_behaviour.rb +57 -66
  12. data/lib/tdriver/base/sut/generic/behaviours/sut.rb +578 -497
  13. data/lib/tdriver/base/sut/generic/behaviours/switchbox_behaviour.rb +41 -15
  14. data/lib/tdriver/base/sut/generic/behaviours/verification.rb +48 -19
  15. data/lib/tdriver/base/sut/generic/commands/fixture.rb +47 -0
  16. data/lib/tdriver/base/sut/generic/commands/key_sequence.rb +25 -13
  17. data/lib/tdriver/base/sut/generic/commands/screen_capture.rb +16 -10
  18. data/lib/tdriver/base/sut/generic/plugin.rb +9 -3
  19. data/lib/tdriver/base/sut/sut.rb +41 -33
  20. data/lib/tdriver/base/test_object/abstract.rb +26 -3
  21. data/lib/tdriver/base/test_object/adapter.rb +399 -0
  22. data/lib/tdriver/base/test_object/behaviours/syncronization.rb +56 -14
  23. data/lib/tdriver/base/test_object/behaviours/test_object.rb +663 -197
  24. data/lib/tdriver/base/test_object/cache.rb +132 -0
  25. data/lib/tdriver/base/test_object/factory.rb +677 -426
  26. data/lib/tdriver/base/test_object/factory_new.rb +202 -0
  27. data/lib/tdriver/base/test_object/identificator.rb +24 -17
  28. data/lib/tdriver/base/test_object/loader.rb +9 -3
  29. data/lib/tdriver/base/test_object/verification.rb +181 -0
  30. data/lib/tdriver/loader.rb +1 -1
  31. data/lib/tdriver/report/report.rb +2 -0
  32. data/lib/tdriver/report/report_api.rb +4 -4
  33. data/lib/tdriver/report/report_creator.rb +29 -3
  34. data/lib/tdriver/report/report_data_presentation.rb +7 -3
  35. data/lib/tdriver/report/report_execution_statistics.rb +80 -21
  36. data/lib/tdriver/report/report_javascript.rb +192 -0
  37. data/lib/tdriver/report/report_test_case_run.rb +22 -0
  38. data/lib/tdriver/report/report_test_run.rb +62 -55
  39. data/lib/tdriver/report/report_writer.rb +57 -56
  40. data/lib/tdriver/tdriver.rb +14 -41
  41. data/lib/tdriver/util/common/error.rb +1 -0
  42. data/lib/tdriver/util/common/exceptions.rb +12 -0
  43. data/lib/tdriver/util/common/file.rb +12 -6
  44. data/lib/tdriver/util/common/gem.rb +2 -1
  45. data/lib/tdriver/util/common/hash.rb +152 -0
  46. data/lib/tdriver/util/common/kernel.rb +49 -34
  47. data/lib/tdriver/util/common/loader.rb +21 -17
  48. data/lib/tdriver/util/common/numeric.rb +39 -0
  49. data/lib/tdriver/util/common/object.rb +115 -0
  50. data/lib/tdriver/util/common/string.rb +55 -2
  51. data/lib/tdriver/util/dbaccess/dbaccess.rb +194 -161
  52. data/lib/tdriver/util/dynamic_attribute_filter.rb +6 -0
  53. data/lib/tdriver/util/hooking.rb +2 -2
  54. data/lib/tdriver/util/loader.rb +2 -2
  55. data/lib/tdriver/util/localisation/localisation.rb +277 -18
  56. data/lib/tdriver/util/logger.rb +142 -13
  57. data/lib/tdriver/util/parameter/parameter_hash.rb +8 -5
  58. data/lib/tdriver/util/parameter/parameter_xml.rb +18 -2
  59. data/lib/tdriver/util/recorder.rb +17 -12
  60. data/lib/tdriver/util/user_data/user_data.rb +3 -2
  61. data/lib/tdriver/util/{video_rec.rb → video_utils.rb} +136 -16
  62. data/lib/tdriver/util/xml/abstraction.rb +7 -0
  63. data/lib/tdriver/util/xml/attribute.rb +32 -0
  64. data/lib/tdriver/util/xml/loader.rb +8 -2
  65. data/lib/tdriver/util/xml/nil_node.rb +95 -0
  66. data/lib/tdriver/util/xml/parsers/nokogiri/abstraction.rb +46 -7
  67. data/lib/tdriver/util/xml/parsers/nokogiri/attribute.rb +19 -9
  68. data/lib/tdriver/util/xml/parsers/nokogiri/document.rb +1 -1
  69. data/lib/tdriver/util/xml/parsers/nokogiri/element.rb +13 -1
  70. data/lib/tdriver/util/xml/parsers/nokogiri/loader.rb +6 -0
  71. data/lib/tdriver/util/xml/parsers/nokogiri/nodeset.rb +27 -15
  72. data/lib/tdriver/util/xml/parsers/nokogiri/text.rb +57 -0
  73. data/lib/tdriver/util/xml/text.rb +32 -0
  74. data/lib/tdriver/util/xml/xml.rb +35 -22
  75. data/lib/tdriver/version.rb +1 -1
  76. data/lib/tdriver-devtools/behaviour/xml/rdoc_behaviour_xml_generator.rb +41 -34
  77. data/lib/tdriver-devtools/doc/generate.rb +31 -6
  78. data/lib/tdriver-devtools/doc/xslt/template.xsl +46 -25
  79. data/lib/tdriver-devtools/tests/feature_tests/example/behaviour_example.rb +100 -0
  80. data/lib/tdriver-devtools/tests/feature_tests/update +1 -1
  81. data/lib/tdriver.rb +0 -3
  82. data/xml/behaviours/generic.xml +1 -1
  83. data/xml/defaults/generic.xml +4 -90
  84. data/xml/templates/generic.xml +33 -25
  85. metadata +21 -29
  86. data/lib/tdriver-devtools/behaviour/xml_generator/example/flick-example.rb +0 -245
  87. data/lib/tdriver-devtools/behaviour/xml_generator/example/sut.rb +0 -964
  88. data/lib/tdriver-devtools/behaviour/xml_generator/generate.rb +0 -68
  89. data/lib/tdriver-devtools/behaviour/xml_generator/lib/custom_rdoc_generator.rb +0 -1865
  90. data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.argument.default.template +0 -1
  91. data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.argument.template +0 -3
  92. data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.argument_type.template +0 -4
  93. data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.exception.template +0 -4
  94. data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.method.arguments.template +0 -4
  95. data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.method.deprecated.template +0 -3
  96. data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.method.exceptions.template +0 -3
  97. data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.method.info.template +0 -1
  98. data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.method.returns.template +0 -3
  99. data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.method.tables.template +0 -3
  100. data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.method.template +0 -12
  101. data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.returns.template +0 -5
  102. data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.table.item.template +0 -1
  103. data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.table.row.template +0 -2
  104. data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.table.template +0 -7
  105. data/lib/tdriver-devtools/behaviour/xml_generator/templates/behaviour.xml.template +0 -14
  106. data/lib/tdriver-devtools/behaviour/xml_generator/update +0 -3
  107. data/lib/tdriver-devtools/tests/feature_tests/example/flick-example.rb +0 -233
  108. data/lib/tdriver-devtools/tests/feature_tests/example/impl.rb +0 -194
@@ -1,964 +0,0 @@
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 MobyBehaviour
21
-
22
- # Describes the behaviour of SUT, aka the methods that can be used to control SUT
23
- module SUT
24
-
25
- include MobyBehaviour::Behaviour
26
-
27
- attr_accessor(
28
-
29
- :dump_count, # number of UI dump requests done to current SUT
30
- :current_application_id, # id of the current appication if set
31
- :input, # the input method used for interacting with this sut as a symbol, eg. :key or :touch.
32
- :refresh_tries, # number of retries for ui dump on error case
33
- :refresh_timeout # timeout between timeout retry
34
-
35
- )
36
-
37
- attr_reader(
38
-
39
- :xml_data, # sut xml_data
40
- :x_path, # x_path pattern for xml_data
41
- :ui_type, # type of the UI used on the sut, ie. s60, qt, windows
42
- :ui_version, # version of the ui used on the sut, ie 3.2.3
43
- :frozen, # flag that tells if the ui dump getting is disabled
44
- :xml_data_crc, # crc of the previous ui state message
45
- :verify_blocks # verify blocks
46
-
47
- )
48
-
49
- #TODO: document
50
- def connect( id )
51
-
52
- @_sutController.connect( id )
53
-
54
- end
55
-
56
- # Disconnects connection to sut (e.g. closes open socket)
57
- # == examples
58
- # @sut.disconnect
59
- def disconnect
60
-
61
- @_sutController.disconnect
62
-
63
- end
64
-
65
- # function to disable taking ui dumps from target for a moment
66
- # user must remember to enable ui dumps again using unfreeze
67
- def freeze
68
-
69
- @frozen = true
70
-
71
- end
72
-
73
- # function to enable taking ui dumps from target
74
- def unfreeze
75
-
76
- @frozen = false
77
-
78
- end
79
-
80
- # function to get TestObject
81
- # TODO: Still under construction. Should be able to create single descendant of the SUT
82
- # Then is Should create path (parent-child-child-child...) until reaching the particular TestObject
83
- # TODO: Document me when I'm ready
84
- def get_object( object_id )
85
-
86
- test_object = @test_object_factory.make( self, MobyBase::TestObjectIdentificator.new( object_id ) )
87
-
88
- end
89
-
90
- # Force to use user defined ui state (e.g. for debugging purposes)
91
- #
92
- # Freezes the SUT xml_data, until unfreezed or set to nil.
93
- # == params
94
- # xml:: String, MobyUtil::XML::Element or NilClass
95
- # == examples
96
- # @sut.xml_data = "<tasMessage>.....</tasMessage>"
97
- # @sut.xml_data = xml_element
98
- # @sut.xml_data = nil
99
- # == raises
100
- # ArgumentError:: Unexpected argument type (%s) for xml, expected: %s
101
- def xml_data=( xml )
102
-
103
- if xml.kind_of?( MobyUtil::XML::Element )
104
-
105
- @xml_data = xml
106
-
107
- elsif xml.kind_of?( String )
108
-
109
- @xml_data = MobyUtil::XML.parse_string( xml ).root
110
-
111
- elsif xml.nil?
112
-
113
- @xml_data = nil
114
-
115
- @frozen = false
116
-
117
- else
118
-
119
- Kernel::raise ArgumentError.new( "Unexpected argument type (%s) for xml, expected: %s" % [ xml.class, "MobyUtil::XML::Element or String"] )
120
-
121
- end
122
-
123
- # freeze sut - xml won't be updated unless unfreezed first
124
- @frozen = true unless xml.nil?
125
-
126
- end
127
-
128
- # Function asks for fresh xml ui data from the device and stores the result
129
- # == returns
130
- # MobyUtil::XML::Element:: xml document containing valid xml fragment describing the current state of the device
131
- def refresh_ui_dump( refresh_args = {} )
132
-
133
- current_time = Time.now
134
-
135
- if !@frozen && ( @_previous_refresh.nil? || ( current_time - @_previous_refresh ).to_f > @refresh_interval )
136
-
137
- MobyUtil::Retryable.while(
138
- :tries => @refresh_tries,
139
- :interval => @refresh_interval,
140
- :unless => [ MobyBase::ControllerNotFoundError, MobyBase::CommandNotFoundError ] ) {
141
-
142
- new_xml_data, crc = execute_command(
143
-
144
- MobyCommand::Application.new(
145
- :State,
146
- ( refresh_args[ :FullName ] || refresh_args[ :name ] ),
147
- refresh_args[ :id ],
148
- self
149
- )
150
-
151
- )
152
-
153
- # remove timestamp from the beginning of tasMessage, parse if not same as previous ui state
154
- if ( xml_data_no_timestamp = new_xml_data.split( ">", 2 ).last ) != @last_xml_data
155
-
156
- @xml_data, @childs_updated = MobyUtil::XML.parse_string( new_xml_data ).root, false
157
-
158
- @last_xml_data = xml_data_no_timestamp
159
-
160
- end
161
-
162
-
163
- # if ( @xml_data_crc == 0 || crc != @xml_data_crc || crc.nil? )
164
- # @xml_data, @xml_data_crc, @childs_updated = MobyUtil::XML.parse_string( new_xml_data ).root, crc, false
165
-
166
- # end
167
-
168
- @dump_count += 1
169
-
170
- @_previous_refresh = current_time
171
-
172
- }
173
-
174
-
175
-
176
-
177
- end
178
-
179
- @xml_data = fetch_references( @xml_data )
180
-
181
- @xml_data
182
-
183
- end
184
-
185
- # Creates a test object that belongs to this SUT.
186
- # Usually it is 'Application' TestObject
187
- # Associates child object as current object's child.
188
- # and associates self as child object's parent.
189
- #
190
- # NOTE:
191
- # Subsequent calls to SUT#child(rule) always returns reference to same Testobject:
192
- # a = sut.child(rule) ; b = sut.child(rule) ; a.equal?( b ); # => true
193
- # note the usage of equal? above instead of normally used eql?. Please refer to Ruby manual for more information.
194
- #
195
- # == params
196
- # hash_rule:: Hash object holding information for identifying which child to create, eg. :type => :application
197
- # == returns
198
- # TestObject:: new child test object or reference to existing child
199
- def child( hash_rule )
200
-
201
- creation_hash = hash_rule.clone
202
-
203
- initial_timeout = @test_object_factory.timeout unless ( custom_timeout = creation_hash.delete( :__timeout ) ).nil?
204
-
205
- logging_enabled = MobyUtil::Logger.instance.enabled
206
- MobyUtil::Logger.instance.enabled = false if ( creation_hash.delete( :__logging ) == 'false' )
207
-
208
- begin
209
-
210
- @test_object_factory.timeout = custom_timeout unless custom_timeout.nil?
211
- child_test_object = @test_object_factory.make( self, MobyBase::TestObjectIdentificator.new( creation_hash ) )
212
-
213
- rescue MobyBase::MultipleTestObjectsIdentifiedError => exception
214
-
215
- MobyUtil::Logger.instance.log "behaviour", "FAIL;Multiple child objects matched criteria.;#{ id };sut;{};child;#{ hash_rule.inspect }"
216
- Kernel::raise exception
217
-
218
- rescue MobyBase::TestObjectNotFoundError => exception
219
-
220
- MobyUtil::Logger.instance.log "behaviour", "FAIL;The child object could not be found.;#{ id };sut;{};child;#{ hash_rule.inspect }"
221
- Kernel::raise exception
222
-
223
- rescue Exception => exception
224
-
225
- MobyUtil::Logger.instance.log "behaviour", "FAIL;Failed when trying to find child object.;#{ id };sut;{};child;#{ hash_rule.inspect }"
226
- Kernel::raise exception
227
-
228
- ensure
229
-
230
- @test_object_factory.timeout = initial_timeout unless custom_timeout.nil?
231
- MobyUtil::Logger.instance.enabled = logging_enabled
232
-
233
- end
234
-
235
- # return already existing child TestObject so that there is references to only one TestObject
236
- child_test_object.add_parent( self )
237
-
238
- # Type information is stored in a separate member, not in the Hash
239
- creation_hash.delete( :type )
240
-
241
- @_child_object_cache.each_value do | _child |
242
-
243
- if _child.eql?( child_test_object )
244
-
245
- # Update the attributes that were used to create the child object.
246
- _child.creation_attributes = creation_hash
247
-
248
- return _child
249
-
250
- end
251
-
252
- end
253
-
254
- =begin
255
- @_child_objects.each do | _child |
256
-
257
- if _child.eql? child_test_object
258
-
259
- # Update the attributes that were used to create the child object.
260
- _child.creation_attributes = creation_hash
261
- return _child
262
-
263
- end
264
-
265
- end
266
- =end
267
- # Store the attributes that were used to create the child object.
268
- child.creation_attributes = creation_hash
269
-
270
- add_child( child_test_object )
271
-
272
- child_test_object
273
-
274
- end
275
-
276
- # Returns a StateObject containing the current state of this sut object as XML.
277
- # The state object is static and thus is not refreshed or synchronized etc.
278
- #
279
- # === returns
280
- # StateObject:: State of this SUT object
281
- def state
282
-
283
- # refresh if xml data is empty
284
- self.refresh if @xml_data.empty?
285
-
286
- Kernel::raise RuntimeError.new( "Can not create state object of SUT with id '%s', no XML content or SUT not initialized properly." % @id ) if @xml_data.empty?
287
-
288
- MobyBase::StateObject.new(
289
-
290
- MobyUtil::XML.parse_string(
291
-
292
- "<sut name='sut' type='sut' id='%s'><objects>%s</objects></sut>" % [ @id, xml_data.xpath("tasInfo/object").collect{ | element | element.to_s }.join ]
293
-
294
- ).root,
295
- self
296
-
297
- )
298
-
299
- end
300
-
301
- # Returns the current foreground application
302
- #
303
- # === params
304
- # attributes:: (optional) Hash defining required expected attributes of the application
305
- # === returns
306
- # TestObject:: Current foreground application
307
- # === raises
308
- # ArgumentError:: The attributes argument was not a Hash
309
- # === examples
310
- # fg_app = @sut.application # retrieves foreground application info and stores it in fg_app-object
311
- def application( attributes = {} )
312
-
313
- begin
314
-
315
- raise TypeError.new( "Input parameter not of Type: Hash.\nIt is: #{ attributes.class }" ) unless attributes.kind_of?( Hash )
316
- get_default_app = attributes.empty?
317
- attributes[ :type ] = 'application'
318
- current_application_id = nil if attributes[ :id ].nil?
319
-
320
-
321
- app_child = child( attributes )
322
-
323
- rescue Exception => e
324
-
325
- MobyUtil::Logger.instance.log "behaviour" , "FAIL;Failed to find application.;#{id.to_s};sut;{};application;" << (attributes.kind_of?(Hash) ? attributes.inspect : attributes.class.to_s)
326
- Kernel::raise e
327
-
328
- end
329
-
330
- MobyUtil::Logger.instance.log "behaviour" , "PASS;Application found.;#{id.to_s};sut;{};application;" << attributes.inspect
331
-
332
- app_child
333
-
334
- end
335
-
336
- # Screen capture function to take snapshot of SUTs current display view
337
- # === params
338
- # arguments:: Hash containing settings to be used in screen capture from device
339
- # Following symbols are supported:
340
- # [:Filename] (Required) String representing the output filename. When no path given current working directory will be used.
341
- # === returns
342
- # nil
343
- # === raises
344
- # ArgumentError:: Wrong argument type %s (Expected Hash)
345
- # ArgumentError:: Symbol %s expected in argument(s)
346
- # ArgumentError:: Invalid string length for output filename: '%s'
347
- # === examples
348
- # @sut.capture_screen( :Filename => 'screen.png' ) # captures current screen and stores it to working directory/screen.png
349
- # @sut.capture_screen( :Filename => 'c:/screen.png' ) # captures current screen and stores it to c:/screen.png
350
- def capture_screen( arguments )
351
-
352
- begin
353
-
354
- MobyBase::Error.raise( :WrongArgumentType, arguments.class, "Hash" ) unless arguments.kind_of?( Hash )
355
- MobyBase::Error.raise( :ArgumentSymbolExpected, ":Filename" ) unless arguments.include?( :Filename )
356
- MobyBase::Error.raise( :WrongArgumentTypeFor, arguments[ :Filename ].class, "output filename", "String" ) unless arguments[:Filename].kind_of?( String )
357
- MobyBase::Error.raise( :InvalidStringLengthFor, arguments[ :Filename ].length, "output filename", ">=1" ) unless arguments[:Filename].length > 0
358
-
359
- screen_capture_command_object = MobyCommand::ScreenCapture.new()
360
- screen_capture_command_object.redraw = arguments[ :Redraw ] if arguments[ :Redraw ]
361
- image_binary = execute_command( screen_capture_command_object )
362
-
363
- File.open( arguments[ :Filename ], 'wb:binary'){ | image_file | image_file << image_binary }
364
-
365
- rescue Exception => e
366
-
367
- MobyUtil::Logger.instance.log "behaviour" , "FAIL;Failed to capture screen.;#{id.to_s};sut;{};capture_screen;" << (arguments.kind_of?( Hash ) ? arguments.inspect : arguments.class.to_s )
368
- Kernel::raise e
369
-
370
- end
371
-
372
- MobyUtil::Logger.instance.log "behaviour" , "PASS;Screen was captured successfully.;#{id.to_s};sut;{};capture_screen;" << arguments.inspect
373
-
374
- nil
375
-
376
- end
377
-
378
- # Instructs the SUT to start the specified application if it is not currenly being executed
379
- # The application will also be brought to the foregound.
380
- # === params
381
- # target:: Hash, used to indetify the application to be executed. All symbols defined in the hash
382
- # must match with the launched application.
383
- # The following symbols can be defined in the hash, at least one them must be included:
384
- # [:uid] = String or Integer, uid of the application (268458181)
385
- # [:name] = String, executable name of the application ('Mce.exe')
386
- # [:arguments] = Comma separated list of arguments passed to application when starting. ('--nogui,-v')
387
- # Examples:
388
- # @sut.run(:name => 'Mce.exe')
389
- # @sut.run(:name => 'Mce.exe', :uid => 268458181)
390
- # @sut.run(:name => 'demoapp.exe', :arguments => '--nogui')
391
- # === returns
392
- # TestObject:: Test object of the started application
393
- # === raises
394
- # ArgumentError:: If no Hash is provided as argument or the Hash does not contain at least a valid :uid or :name
395
- # VerificationError:: If no application test object can be found after starting the application, or the found object does not match the launched application
396
- def run( target )
397
-
398
- begin
399
- # set the refresh interval to zero while the application is launched
400
- #orig_interval = MobyUtil::Parameter[ @id ][ :refresh_interval ]
401
- #MobyUtil::Parameter[ @id ][ :refresh_interval ] = '0'
402
-
403
- # raise exception if argument type other than hash
404
- Kernel::raise ArgumentError.new( "Wrong argument type %s) for %s (Expected: %s)" % [ target.class, "run method", "Hash" ]) unless target.instance_of?( Hash )
405
-
406
- # default value for keys that does not exist in hash
407
- target.default = nil
408
-
409
- Kernel::raise ArgumentError.new( "Argument hash must contain at least :uid or :name" ) unless target[ :uid ] || target[ :name ]
410
-
411
- # nils are valid arguments here, at least one of :name, :id has been verified to not be nil
412
- # ArgumentError is raised by MobyCommnand::Application if the parameters are not valid
413
- sleep_time = target[ :sleep_after_launch ].to_i #( target[ :sleep_after_launch ] == nil ? 0 : target[ :sleep_after_launch ].to_i)
414
-
415
- #Kernel::raise ArgumentError.new( "Sleep time need to be Integer >= 0" ) unless sleep_time.kind_of? Numeric #instance_of?( Fixnum )
416
- Kernel::raise ArgumentError.new( "Sleep time need to be >= 0" ) unless sleep_time >= 0
417
-
418
-
419
- # try to find an existing app with the current arguments
420
- if target[ :try_attach ]
421
-
422
- app_list = MobyBase::StateObject.new( self.list_apps() )
423
-
424
- # either ID or NAME have been passed to identify the application
425
- # raise exception if more than one app has been found for this id/name
426
- # otherwhise attempt to get the application test object
427
- app_info = find_app(app_list, {:id => target[ :uid ]}) if target[ :uid ] != nil
428
- app_info = find_app(app_list, {:name => target[ :name ]}) unless app_info
429
- app = self.application(:id => app_info.id) if app_info
430
- if app
431
- begin
432
- app.bring_to_foreground
433
- rescue Exception => e
434
- MobyUtil::Logger.instance.log "WARNING", "Could not bring app to foreground"
435
- end
436
- return app
437
- end
438
- end
439
-
440
- if ( target[ :start_command ] != nil )
441
- Kernel::raise MobyBase::BehaviourError.new("Run", "Failed to load execute_shell_method") unless self.respond_to?("execute_shell_command")
442
- execute_shell_command( target[ :start_command ], :detached => "true" )
443
- else
444
- run_command = MobyCommand::Application.new(
445
- :Run,
446
- target[ :name ],
447
- target[ :uid ],
448
- self,
449
- target[ :arguments ],
450
- target[ :environment ],
451
- target[ :events_to_listen ],
452
- target[ :signals_to_listen ]
453
- )
454
-
455
- # execute the application control service request
456
- execute_command( run_command )
457
-
458
- end
459
-
460
- # do not remove this, unless qttas server & plugin handles the syncronization between plugin registration & first ui state request
461
- # first ui dump is requested too early and target/server seems not be ready...
462
- #sleep 0.100
463
-
464
- sleep sleep_time if sleep_time > 0
465
-
466
- #TODO: Refresh should be initiated by sut_controller
467
- #PKI: one refresh might not be enough as application launch takes more time sometimes
468
- #PKI: added artificial wait for now until this has been refactored
469
-
470
- expected_attributes = Hash.new
471
-
472
- expected_attributes[ :type ] = 'application'
473
-
474
- expected_attributes[ :id ] = target[ :uid ] unless target[ :uid ].nil?
475
- expected_attributes[ :FullName ] = target[ :name ] unless target[ :name ].nil?
476
-
477
- error_details = target[ :name ].nil? ? "" : "name: " << target[ :name ].to_s
478
-
479
- error_details << ( error_details.empty? ? "" : ", ") << "id: " << target[ :uid ].to_s if !target[ :uid ].nil?
480
-
481
- if( self.ui_type.downcase.include?( 'qt' ) && !expected_attributes[ :FullName ].nil? )
482
-
483
- if( expected_attributes[ :FullName ].include?('/') )
484
-
485
- app_name = expected_attributes[ :FullName ].split('/')[ expected_attributes[ :FullName ].split( '/' ).size-1 ]
486
- app_name.slice!( ".exe" )
487
- expected_attributes[ :name ] = app_name
488
-
489
- elsif( expected_attributes[ :FullName ].include?("\\") )
490
-
491
- app_name = expected_attributes[ :FullName ].split("\\")[ expected_attributes[ :FullName ].split( "\\" ).size-1 ]
492
- app_name.slice!( ".exe" )
493
- expected_attributes[:name] = app_name
494
-
495
- else
496
-
497
- app_name = expected_attributes[ :FullName ]
498
- app_name.slice!( ".exe" )
499
- expected_attributes[ :name ] = app_name
500
-
501
- end
502
-
503
- expected_attributes.delete( :FullName )
504
-
505
- end
506
-
507
- begin
508
-
509
- self.wait_child(
510
- expected_attributes,
511
- MobyUtil::Parameter[ self.id ][ :application_synchronization_timeout, '5' ].to_f,
512
- MobyUtil::Parameter[ self.id ][ :application_synchronization_retry_interval, '0.5' ].to_f
513
- )
514
-
515
- rescue MobyBase::SyncTimeoutError
516
-
517
- Kernel::raise MobyBase::VerificationError.new("The application (#{ error_details }) was not found on the sut after being launched.")
518
-
519
- end
520
-
521
- # verify run results
522
- foreground_app = self.application( expected_attributes )
523
-
524
- Kernel::raise MobyBase::VerificationError.new("No application type test object was found on the device after starting the application.") unless foreground_app.kind_of?( MobyBehaviour::Application )
525
-
526
- rescue Exception => e
527
-
528
- MobyUtil::Logger.instance.log "behaviour", "FAIL;Failed to launch application.;#{id.to_s};sut;{};run;" << ( target.kind_of?( Hash ) ? target.inspect : target.class.to_s )
529
-
530
- Kernel::raise MobyBase::BehaviourError.new("Run", "Failed to launch application")
531
-
532
- #MobyBase::Error.raise( :BehaviourErrorOccured, "Run", "Failed to launch application", e.message )
533
- #Kernel::raise behaviour_runtime_error("Run", "Failed to launch application", e.message, e.backtrace)
534
- #Kernel::raise e
535
-
536
- end
537
-
538
- MobyUtil::Logger.instance.log "behaviour" , "PASS;The application was launched successfully.;#{id.to_s};sut;{};run;" << target.inspect
539
-
540
- foreground_app
541
-
542
- end
543
-
544
- # Press_key function to pass symbol or sequence to the assosiacted SUT controllers
545
- # execute_cmd function.
546
- # === params
547
- # keypress:: either symbol or object of type MobyController::KeySequence
548
- # === returns
549
- # nil
550
- # === raises
551
- # ArgumentError:: if input not a symbol or not of type MobyCommand::KeySequence
552
- # === examples
553
- # @sut.press_key(:kDown) # presses Down on SUT
554
- # key_sequence = MobyCommand::KeySequence.new(:kDown).times!(3) # creates keysequence to press 3 times down on SUT
555
- # @sut.press_key( key_sequence ) # executes above keysequence on device
556
- def press_key( symbol_or_sequence )
557
-
558
- begin
559
-
560
- if symbol_or_sequence.instance_of?( Symbol )
561
-
562
- sequence = MobyCommand::KeySequence.new( symbol_or_sequence )
563
-
564
- elsif symbol_or_sequence.instance_of? MobyCommand::KeySequence
565
-
566
- sequence = symbol_or_sequence
567
-
568
- else
569
-
570
- raise ArgumentError.new('Data not of type Symbol or MobyController::KeySequence.')
571
-
572
- end
573
-
574
- sequence.set_sut( self )
575
- execute_command( sequence )
576
-
577
- rescue Exception => e
578
-
579
- MobyUtil::Logger.instance.log "behaviour" , "FAIL;Failed to press key(s).;#{id.to_s};sut;{};press_key;#{ symbol_or_sequence }"
580
- Kernel::raise e
581
-
582
- end
583
-
584
- MobyUtil::Logger.instance.log "behaviour" , "PASS;Successfully pressed key(s).;#{id.to_s};sut;{};press_key;#{ symbol_or_sequence }"
585
-
586
- nil
587
-
588
- end
589
-
590
- # Wrapper function to access sut specific parameters
591
- # ==usage
592
- #
593
- # # returns the hash of all sut parameters
594
- # sut.parameter
595
- #
596
- # # returns the value for parameter 'product' for this particular sut
597
- # sut.parameter['product']
598
- #
599
- # # raises exception that 'non_existing_parameter' was not found
600
- # sut.parameter['non_existing_parameter']
601
- #
602
- # # return default value if given parameter is not found
603
- # sut.parameter['non_existing_parameter', 'default']
604
- #
605
- # # set the value of parameter 'product' for this particular sut
606
- # sut.parameter['product'] ='new_value'
607
- #
608
- # parameters for each sut are stored in the file under group tag with name attribute matching the SUT id
609
- # ==params
610
- # ==return
611
- # String:: Value matching the parameter_name
612
- # MobyUtil::ParameterHash:: Hash of values
613
- def parameter( *arguments )
614
-
615
- if ( arguments.count == 0 )
616
-
617
- MobyUtil::ParameterUserAPI.instance[ self.id ]
618
-
619
- else
620
-
621
- #$stderr.puts "%s:%s warning: deprecated method usage convention, please use sut#parameter[] instead of sut#parameter()" % ( caller.first || "%s:%s" % [ __FILE__, __LINE__ ] ).split(":")[ 0..1 ]
622
-
623
- MobyUtil::ParameterUserAPI.instance[ self.id ][ *arguments ]
624
-
625
- end
626
-
627
- end
628
-
629
- # Wrapper function to return translated string for this SUT
630
- # Uses the Localisation singleton to read the values from data base
631
- # ==usage
632
- # sut.translate(:text_softkey_option) #returns the value for logical name 'text_softkey_option' for this particular sut
633
- # ==params
634
- # logical_name:: String or symbol representing the logical name of the item to be translated.
635
- # file_name:: optional FNAME search argument for the translation
636
- # plurality:: optional PLURALITY search argument for the translation
637
- # numerus:: optional numeral replacement of '%Ln' tags on translation strings
638
- # lenthvariant:: optional LENGTHVAR search argument for the translation
639
- # ==return
640
- # String:: Translation matching the logical_name
641
- # ==raises
642
- # LanguageNotFoundError:: In case of language is not found
643
- # LogicalNameNotFoundError:: In case of logical name is not found for current language
644
- # MySqlConnectError:: In case problems with the db connectivity
645
- def translate( logical_name, file_name = nil, plurality = nil, numerus = nil, lengthvariant = nil )
646
- Kernel::raise LogicalNameNotFoundError.new("Logical name is nil") if logical_name.nil?
647
- language=nil
648
- if ( MobyUtil::Parameter[ self.id ][:read_lang_from_app]=='true')
649
- #read localeName app
650
- language=self.application.attribute("localeName")
651
- #determine the language from the locale
652
- language=language.split('_')[0].to_s if (language!=nil && !language.empty?)
653
- else
654
- language=MobyUtil::Parameter[ self.id ][ :language ]
655
- end
656
- Kernel::raise LanguageNotFoundError.new("Language cannot be determind to perform translation") if (language==nil || language.empty?)
657
- translation = MobyUtil::Localisation.translation(
658
- logical_name,
659
- language,
660
- MobyUtil::Parameter[ self.id ][ :localisation_server_database_tablename ],
661
- file_name,
662
- plurality,
663
- lengthvariant
664
- )
665
- if translation.kind_of? String and !numerus.nil?
666
- translation.gsub!(/%Ln/){|s| numerus}
667
- elsif translation.kind_of? Array and !numerus.nil?
668
- translation.each do |trans|
669
- trans.gsub!(/%Ln/){|s| numerus}
670
- end
671
- end
672
- return translation
673
- end
674
-
675
- # Function to update all children of current SUT
676
- # Iterates on all children of the SUT and calls TestObject#update on all children
677
- # === params
678
- # === returns
679
- # ?
680
- # === raises
681
- def update
682
-
683
- #@_child_objects.each{ | test_object | test_object.update( @xml_data ) } if !@childs_updated
684
-
685
- unless @childs_updated
686
-
687
- @_child_object_cache.each_value{ | test_object |
688
-
689
- test_object.update( @xml_data )
690
-
691
- }
692
-
693
-
694
- end
695
-
696
- @childs_updated = true
697
-
698
- end
699
-
700
- def refresh( refresh_args = {} )
701
-
702
- refresh_ui_dump refresh_args
703
-
704
- # update childs only if ui state is new
705
- update if !@childs_updated
706
-
707
- end
708
-
709
-
710
- def verify_always( expected, message = nil, &block )
711
-
712
- @verify_blocks << MobyUtil::VerifyBlock.new( block,expected, message, 0, MobyUtil::KernelHelper.find_source( caller( 3 ).first.to_s ) )
713
-
714
- end
715
-
716
- def clear_verify_blocks
717
-
718
- @verify_blocks = []
719
-
720
- end
721
-
722
- def get_application_id
723
-
724
- orig_frozen = @frozen;
725
-
726
- begin
727
-
728
- freeze unless @frozen
729
-
730
- ret = self.application.id
731
-
732
- unfreeze unless orig_frozen
733
-
734
- return ret
735
-
736
- rescue
737
-
738
- ensure
739
-
740
- unfreeze unless orig_frozen
741
-
742
- end
743
-
744
- '-1'
745
-
746
- end
747
-
748
- private
749
-
750
- def fetch_references( xml )
751
-
752
- pids = []
753
-
754
- x_prev = ''
755
- y_prev = ''
756
-
757
- while true
758
-
759
- nodes = xml.xpath( '//object[@type = "TDriverRef"]' )
760
-
761
- idx = 1
762
-
763
- nodes.each { | element |
764
-
765
- pid = element.xpath('//attribute[@name = "uri"]/value/text()')[ 0 ].to_s
766
-
767
- if pid.nil? or pid.empty? or pid.to_i <= 0 # invalid reference
768
-
769
- element.remove
770
- next
771
-
772
- end
773
-
774
- # Element parent not supported, so query the parent coords
775
- x_abs = xml.xpath( '//object[@type = "TDriverRef"]/../../attributes/attribute[@name ="x_absolute"]/value/text()' )[ idx - 1 ]
776
- y_abs = xml.xpath( '//object[@type = "TDriverRef"]/../../attributes/attribute[@name ="y_absolute"]/value/text()' )[ idx - 1 ]
777
-
778
- # window size
779
- winSize = xml.xpath( "//objects/object[@type = 'MainWindow']/attributes/attribute[@name ='size']/value/text()" )[ 0 ].to_s
780
-
781
- # ref-ref parent does not know x coordinate, use the grandparent xys
782
- x_prev = x_abs.to_s unless x_abs.nil?
783
- y_prev = y_abs.to_s unless y_abs.nil?
784
-
785
- idx += 1
786
-
787
- if !pid.empty?
788
-
789
- begin
790
-
791
- subdata =
792
- MobyUtil::XML.parse_string(
793
- execute_command(
794
- MobyCommand::Application.new(
795
- :State,
796
- nil,
797
- pid,
798
- self,
799
- nil,
800
- nil,
801
- nil,
802
- nil,
803
- {
804
- 'x_parent_absolute' => x_prev,
805
- 'y_parent_absolute' => y_prev,
806
- 'embedded' => 'true',
807
- 'parent_size' => winSize
808
- }
809
- )
810
- )[ 0 ]
811
- )
812
-
813
- child = subdata.root.xpath('//object')[0]
814
-
815
- # Remove the attribute with the pid retrieval was not successful.
816
- # (server returns the previous hit if not found)
817
- if child.attribute('id' ) != pid
818
-
819
- element.remove
820
-
821
- else
822
-
823
- # Remove the application layer
824
- objs = child.xpath( '/tasMessage/tasInfo/object/objects/*' )
825
-
826
- if !objs.nil?
827
-
828
- objs.each { | el | element.add_previous_sibling( el ) }
829
-
830
- element.remove
831
-
832
- end
833
-
834
- end
835
-
836
- rescue RuntimeError => e
837
-
838
- raise e unless e.message.include? "no longer available"
839
-
840
- return xml
841
-
842
- end
843
-
844
- else
845
-
846
- return xml
847
-
848
- end
849
-
850
- }
851
-
852
- return xml if nodes.empty?
853
-
854
- end
855
-
856
- end
857
-
858
- def find_app( app_list, search_params )
859
-
860
- app_info = nil
861
-
862
- begin
863
-
864
- app_info = app_list.application( search_params )
865
-
866
- rescue MobyBase::TestObjectNotFoundError
867
-
868
- app_info = nil
869
-
870
- end
871
-
872
- app_info
873
- end
874
-
875
- # this method will be automatically invoked after module is extended to sut object
876
- def self.extended( target_object )
877
-
878
- target_object.instance_exec{
879
-
880
- initialize_settings
881
-
882
- }
883
-
884
- end
885
-
886
- def initialize_settings
887
-
888
- @xml_data = ""
889
-
890
- @x_path = '.'
891
-
892
- @frozen = false
893
-
894
- @_child_object_cache = {}
895
-
896
- @current_application_id = nil
897
-
898
-
899
- @dump_count = 0
900
-
901
- # default values
902
- @input = :key
903
-
904
- @refresh_tries = 5
905
- @refresh_interval = 0.5
906
-
907
- @childs_updated = false
908
-
909
- # id not found from parameters
910
- if MobyUtil::Parameter[ @id, nil ] != nil
911
-
912
- @input = MobyUtil::Parameter[ @id ][ :input_type, "key" ].to_sym
913
-
914
- @refresh_tries = MobyUtil::Parameter[ @id ][ :ui_state_refresh_tries, @refresh_tries ].to_f
915
-
916
- @refresh_interval = MobyUtil::Parameter[ @id ][ :refresh_interval, @refresh_interval ].to_f
917
-
918
- end
919
-
920
- @last_xml_data = nil
921
-
922
- ruby_file = MobyUtil::Parameter[ @id ][ :verify_blocks ]
923
-
924
- @verify_blocks = []
925
-
926
- if File.exists?( ruby_file )
927
-
928
- load ruby_file
929
-
930
- SutParameters::VERIFY_BLOCKS.each { | block |
931
-
932
- @verify_blocks << block
933
-
934
- }
935
-
936
-
937
- end
938
-
939
- end
940
-
941
- public # deprecated
942
-
943
- #TODO: Update documentation
944
- #TODO: Is this function deprecated? (see SUT#refresh_ui_dump)
945
- #TODO: rethink get_ui_dump and refresh --> functions!
946
- # function to query for UIDump.
947
- # == returns
948
- # xmlDocument:: REXML::Document object containing valid xml fragment
949
- # == raises
950
- # someException:: If Dump does not conform to the tasMessage schema error is raised
951
- def get_ui_dump( refresh_args = {} )
952
-
953
- #$stderr.puts "warning: SUT#get_ui_dump is deprecated, please use SUT#refresh_ui_dump instead."
954
-
955
- refresh_ui_dump refresh_args
956
-
957
- end
958
-
959
- # enable hooking for performance measurement & debug logging
960
- MobyUtil::Hooking.instance.hook_methods( self ) if defined?( MobyUtil::Hooking )
961
-
962
- end # SUT
963
-
964
- end # MobyBehaviour