testability-driver 1.1.1 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. data/config/sut_parameters.rb +21 -8
  2. data/config/tdriver_custom_error_recovery.rb +83 -0
  3. data/ext/extconf.rb +3 -2
  4. data/ext/native_extensions.c +60 -2
  5. data/lib/tdriver-devtools/behaviour/old/xml/example/flick-example.rb +2 -105
  6. data/lib/tdriver/base/behaviour/factory.rb +154 -89
  7. data/lib/tdriver/base/behaviour/factory_new.rb +409 -0
  8. data/lib/tdriver/base/errors.rb +3 -3
  9. data/lib/tdriver/base/state_object.rb +85 -22
  10. data/lib/tdriver/base/sut/adapter.rb +26 -0
  11. data/lib/tdriver/base/sut/controller.rb +1 -1
  12. data/lib/tdriver/base/sut/generic/behaviours/application.rb +89 -118
  13. data/lib/tdriver/base/sut/generic/behaviours/find.rb +67 -62
  14. data/lib/tdriver/base/sut/generic/behaviours/sut.rb +296 -187
  15. data/lib/tdriver/base/sut/generic/behaviours/switchbox_behaviour.rb +7 -7
  16. data/lib/tdriver/base/sut/generic/commands/application.rb +366 -295
  17. data/lib/tdriver/base/sut/sut.rb +19 -3
  18. data/lib/tdriver/base/test_object/abstract.rb +41 -21
  19. data/lib/tdriver/base/test_object/adapter.rb +62 -9
  20. data/lib/tdriver/base/test_object/behaviours/syncronization.rb +10 -6
  21. data/lib/tdriver/base/test_object/behaviours/test_object.rb +84 -47
  22. data/lib/tdriver/base/test_object/factory.rb +124 -68
  23. data/lib/tdriver/base/test_object/loader.rb +3 -4
  24. data/lib/tdriver/base/test_object/verification.rb +3 -3
  25. data/lib/tdriver/base/test_object/xml/adapter.rb +734 -0
  26. data/lib/tdriver/loader.rb +12 -0
  27. data/lib/tdriver/report/error_recovery/tdriver_error_recovery.rb +3 -2
  28. data/lib/tdriver/report/error_recovery/tdriver_error_recovery_settings.rb +14 -14
  29. data/lib/tdriver/report/report.rb +4 -8
  30. data/lib/tdriver/report/report_api.rb +9 -0
  31. data/lib/tdriver/report/report_crash_file_capture.rb +4 -4
  32. data/lib/tdriver/report/report_creator.rb +57 -35
  33. data/lib/tdriver/report/report_cucumber.rb +1 -1
  34. data/lib/tdriver/report/report_cucumber_listener.rb +5 -158
  35. data/lib/tdriver/report/report_cucumber_reporter.rb +7 -161
  36. data/lib/tdriver/report/report_execution_statistics.rb +4 -4
  37. data/lib/tdriver/report/report_file_capture.rb +5 -5
  38. data/lib/tdriver/report/report_grouping.rb +24 -22
  39. data/lib/tdriver/report/report_junit_xml.rb +5 -5
  40. data/lib/tdriver/report/report_test_case_run.rb +31 -22
  41. data/lib/tdriver/report/report_test_run.rb +107 -104
  42. data/lib/tdriver/report/report_writer.rb +150 -83
  43. data/lib/tdriver/tdriver.rb +147 -103
  44. data/lib/tdriver/util/common/boolean.rb +51 -0
  45. data/lib/tdriver/util/common/crc16.rb +110 -68
  46. data/lib/tdriver/util/common/hash.rb +63 -7
  47. data/lib/tdriver/util/common/kernel.rb +46 -1
  48. data/lib/tdriver/util/common/loader.rb +1 -0
  49. data/lib/tdriver/util/common/object.rb +20 -8
  50. data/lib/tdriver/util/common/string.rb +21 -2
  51. data/lib/tdriver/util/logger/logger.rb +4 -4
  52. data/lib/tdriver/util/parameter/loader.rb +2 -19
  53. data/lib/tdriver/util/parameter/parameter.rb +874 -177
  54. data/lib/tdriver/util/plugin/service.rb +1 -1
  55. data/lib/tdriver/util/recorder/recorder.rb +7 -1
  56. data/lib/tdriver/util/xml/abstraction.rb +13 -1
  57. data/lib/tdriver/util/xml/parsers/nokogiri/abstraction.rb +63 -10
  58. data/lib/tdriver/util/xml/parsers/nokogiri/attribute.rb +8 -2
  59. data/lib/tdriver/util/xml/parsers/nokogiri/document.rb +16 -3
  60. data/lib/tdriver/util/xml/parsers/nokogiri/node.rb +36 -32
  61. data/lib/tdriver/util/xml/parsers/nokogiri/nodeset.rb +19 -22
  62. data/lib/tdriver/util/xml/xml.rb +147 -32
  63. data/lib/tdriver/verify/verify.rb +1112 -289
  64. data/lib/tdriver/version.rb +1 -1
  65. data/xml/templates/generic.xml +14 -2
  66. metadata +51 -24
  67. data/lib/tdriver/util/parameter/parameter_hash.rb +0 -104
  68. data/lib/tdriver/util/parameter/parameter_new.rb +0 -869
  69. data/lib/tdriver/util/parameter/parameter_template.rb +0 -120
  70. data/lib/tdriver/util/parameter/parameter_user_api.rb +0 -116
  71. data/lib/tdriver/util/parameter/parameter_xml.rb +0 -261
@@ -138,7 +138,7 @@ module MobyBehaviour
138
138
  def freeze
139
139
 
140
140
  =begin
141
- if $parameters[ @id ][ :use_find_object, 'false' ] == 'true' && self.respond_to?( 'find_object' )
141
+ if sut_parameters[ :use_find_object, 'false' ] == 'true' && self.respond_to?( 'find_object' )
142
142
 
143
143
  warn("warning: SUT##{ __method__ } is not supported when use_find_objects optimization is enabled")
144
144
 
@@ -166,7 +166,7 @@ module MobyBehaviour
166
166
  def unfreeze
167
167
 
168
168
  =begin
169
- if $parameters[ @id ][ :use_find_object, 'false' ] == 'true' && self.respond_to?( 'find_object' )
169
+ if sut_parameters[ :use_find_object, 'false' ] == 'true' && self.respond_to?( 'find_object' )
170
170
 
171
171
  warn("warning: SUT##{ __method__ } is not supported when use_find_objects optimization is enabled")
172
172
 
@@ -280,7 +280,7 @@ module MobyBehaviour
280
280
  ) if identification_directives.has_key?( :__logging )
281
281
 
282
282
  # disable logging if requested, remove pair from creation_hash
283
- $logger.push_enabled( identification_directives[ :__logging ] || TDriver.logger.enabled )
283
+ $logger.push_enabled( identification_directives[ :__logging ] || $logger.enabled )
284
284
 
285
285
  begin
286
286
 
@@ -299,19 +299,19 @@ module MobyBehaviour
299
299
 
300
300
  rescue MobyBase::MultipleTestObjectsIdentifiedError => exception
301
301
 
302
- TDriver.logger.behaviour "FAIL;Multiple child objects matched criteria.;#{ id };sut;{};child;#{ attributes.inspect }"
302
+ $logger.behaviour "FAIL;Multiple child objects matched criteria.;#{ id };sut;{};child;#{ attributes.inspect }"
303
303
 
304
304
  Kernel::raise exception
305
305
 
306
306
  rescue MobyBase::TestObjectNotFoundError => exception
307
307
 
308
- TDriver.logger.behaviour "FAIL;The child object could not be found.;#{ id };sut;{};child;#{ attributes.inspect }"
308
+ $logger.behaviour "FAIL;The child object could not be found.;#{ id };sut;{};child;#{ attributes.inspect }"
309
309
 
310
310
  Kernel::raise exception
311
311
 
312
312
  rescue Exception => exception
313
313
 
314
- TDriver.logger.behaviour "FAIL;Failed when trying to find child object.;#{ id };sut;{};child;#{ attributes.inspect }"
314
+ $logger.behaviour "FAIL;Failed when trying to find child object.;#{ id };sut;{};child;#{ attributes.inspect }"
315
315
 
316
316
  Kernel::raise exception
317
317
 
@@ -330,6 +330,7 @@ module MobyBehaviour
330
330
 
331
331
  # == description
332
332
  # Method for executing sut specific setup method
333
+ # https://projects.forum.nokia.com/Testabilitydriver/wiki/FeatureSutSetupTeardown
333
334
  # == returns
334
335
  # Result
335
336
  # description: -
@@ -344,15 +345,15 @@ module MobyBehaviour
344
345
  if self.parameter[ :sut_setup, nil ]
345
346
  require MobyUtil::FileHelper.expand_path(self.parameter[ :sut_setup ])
346
347
 
347
- TDriver.logger.behaviour "PASS;sut.setup method found"
348
+ $logger.behaviour "PASS;sut.setup method found"
348
349
 
349
350
  self.setup
350
351
 
351
- TDriver.logger.behaviour "PASS;sut.setup executed"
352
+ $logger.behaviour "PASS;sut.setup executed"
352
353
  end
353
354
 
354
355
  if self.parameter[ :setup, nil ]
355
- TDriver.logger.behaviour "PASS;sut.setup parameters found"
356
+ $logger.behaviour "PASS;sut.setup parameters found"
356
357
  methods=self.parameter[ :setup ]
357
358
  methods.each do |method|
358
359
  m=method[0].to_s
@@ -363,11 +364,11 @@ module MobyBehaviour
363
364
  eval("self.#{m}(:#{args.to_sym})")
364
365
  end
365
366
  end
366
- TDriver.logger.behaviour "PASS;sut.setup parameter methods executed"
367
+ $logger.behaviour "PASS;sut.setup parameter methods executed"
367
368
  end
368
369
 
369
370
  else
370
- TDriver.logger.behaviour "FAIL;No methods or parameters found for sut.setup"
371
+ $logger.behaviour "FAIL;No methods or parameters found for sut.setup"
371
372
 
372
373
  Kernel::raise MobyBase::BehaviourError.new("Setup", "Failed to load sut.setup method check the :sut_setup parameter")
373
374
  end
@@ -378,6 +379,7 @@ module MobyBehaviour
378
379
 
379
380
  # == description
380
381
  # Method for executing sut specific teardown method
382
+ # https://projects.forum.nokia.com/Testabilitydriver/wiki/FeatureSutSetupTeardown
381
383
  # == returns
382
384
  # Result
383
385
  # description: -
@@ -392,15 +394,15 @@ module MobyBehaviour
392
394
  if self.parameter[ :sut_teardown, nil ]
393
395
  require MobyUtil::FileHelper.expand_path(self.parameter[ :sut_teardown ])
394
396
 
395
- TDriver.logger.behaviour "PASS;sut.teardown method found"
397
+ $logger.behaviour "PASS;sut.teardown method found"
396
398
 
397
399
  self.teardown
398
400
 
399
- TDriver.logger.behaviour "PASS;sut.teardown executed"
401
+ $logger.behaviour "PASS;sut.teardown executed"
400
402
  end
401
403
 
402
404
  if self.parameter[ :teardown, nil ]
403
- TDriver.logger.behaviour "PASS;sut.teardown parameters found"
405
+ $logger.behaviour "PASS;sut.teardown parameters found"
404
406
  methods=self.parameter[ :teardown ]
405
407
  methods.each do |method|
406
408
  m=method[0].to_s
@@ -411,11 +413,11 @@ module MobyBehaviour
411
413
  eval("self.#{m}(:#{args.to_sym})")
412
414
  end
413
415
  end
414
- TDriver.logger.behaviour "PASS;sut.teardown parameter methods executed"
416
+ $logger.behaviour "PASS;sut.teardown parameter methods executed"
415
417
  end
416
418
 
417
419
  else
418
- TDriver.logger.behaviour "FAIL;No method or parameters found for sut.teardown"
420
+ $logger.behaviour "FAIL;No method or parameters found for sut.teardown"
419
421
 
420
422
  Kernel::raise MobyBase::BehaviourError.new("Teardown", "Failed to load sut.teardown method check the :sut_teardown parameter")
421
423
  end
@@ -423,23 +425,65 @@ module MobyBehaviour
423
425
  end
424
426
 
425
427
  # == description
426
- # Returns a StateObject containing the current state of this test object as XML.
427
- # The state object is static and thus is not refreshed or synchronized etc.
428
+ # Creates a state object of current test object or given XML as argument. The state object is static and thus is not refreshed or synchronized.
429
+ #
430
+ # == arguments
431
+ # source_data
432
+ # String
433
+ # description: Object state as XML string
434
+ # example: -
435
+ # MobyBase::XML::Element
436
+ # description: Object state as XML element
437
+ # example: -
438
+ #
439
+ # parent_object
440
+ # MobyBase::TestObject
441
+ # description: Parent object
442
+ # example: -
443
+ # MobyBase::SUT
444
+ # description: Parent object
445
+ # example: -
446
+ # NilClass
447
+ # description: No parent object defined
448
+ # example: nil
449
+ #
428
450
  # == returns
429
- # StateObject
430
- # description: State of this test object
451
+ # MobyBase::StateObject
452
+ # description: State of this SUT, test object or given XML
431
453
  # example: -
454
+ #
432
455
  # == exceptions
456
+ # ArgumentError
457
+ # description: Wrong argmument type given
433
458
  # RuntimeError
434
459
  # description: If the XML source for the object is not in initialized
435
- def state
460
+ def state_object( source_data = nil, parent_object = nil )
461
+
462
+ if source_data.nil?
436
463
 
437
- # refresh if xml data is empty
438
- self.refresh if @xml_data.empty?
464
+ # refresh if xml data is empty
465
+ self.refresh if @xml_data.empty?
439
466
 
440
- Kernel::raise RuntimeError, "Can not create state object of SUT with id #{ @id.inspect }, no XML content or SUT not initialized properly." if @xml_data.empty?
467
+ Kernel::raise RuntimeError, "Can not create state object of SUT with id #{ @id.inspect }, no XML content or SUT not initialized properly." if @xml_data.empty?
441
468
 
442
- MobyBase::StateObject.new( TDriver::TestObjectAdapter.state_object_xml( @xml_data, @id ), self )
469
+ source_data = @test_object_adapter.state_object_xml( @xml_data, @id )
470
+
471
+ parent_object = self
472
+
473
+ end
474
+
475
+ # verify that type of xml_source argument is correct
476
+ source_data.check_type [ String, MobyUtil::XML::Element ], 'wrong argument type $1 for state object source data (expected $2)'
477
+
478
+ parent_object.check_type [ MobyBase::SUT, MobyBase::TestObject, MobyBase::StateObject, NilClass ], 'wrong argument type $1 for parent object (expected $2)'
479
+
480
+ MobyBase::StateObject.new(
481
+
482
+ :source_data => source_data,
483
+ :parent => parent_object,
484
+ :test_object_adapter => @test_object_adapter
485
+
486
+ )
443
487
 
444
488
  end
445
489
 
@@ -465,7 +509,7 @@ module MobyBehaviour
465
509
 
466
510
  begin
467
511
 
468
- attributes.check_type( Hash, "Wrong argument type $1 for attributes (expected $2)" )
512
+ attributes.check_type( Hash, 'Wrong argument type $1 for attributes (expected $2)' )
469
513
 
470
514
  attributes[ :type ] = 'application'
471
515
 
@@ -483,7 +527,7 @@ module MobyBehaviour
483
527
 
484
528
  rescue
485
529
 
486
- TDriver.logger.behaviour(
530
+ $logger.behaviour(
487
531
  "FAIL;Failed to find application.;#{ id.to_s };sut;{};application;#{ attributes.kind_of?( Hash ) ? attributes.inspect : attributes.class.to_s }"
488
532
  )
489
533
 
@@ -492,7 +536,7 @@ module MobyBehaviour
492
536
 
493
537
  ensure
494
538
 
495
- TDriver.logger.behaviour "PASS;Application found.;#{ id.to_s };sut;{};application;#{ attributes.inspect }" if $!.nil?
539
+ $logger.behaviour "PASS;Application found.;#{ id.to_s };sut;{};application;#{ attributes.inspect }" if $!.nil?
496
540
 
497
541
  end
498
542
 
@@ -565,13 +609,13 @@ module MobyBehaviour
565
609
 
566
610
  rescue
567
611
 
568
- TDriver.logger.behaviour "FAIL;Failed to capture screen.;#{ id.to_s };sut;{};capture_screen;#{ arguments.kind_of?( Hash ) ? arguments.inspect : arguments.class.to_s }"
612
+ $logger.behaviour "FAIL;Failed to capture screen.;#{ id.to_s };sut;{};capture_screen;#{ arguments.kind_of?( Hash ) ? arguments.inspect : arguments.class.to_s }"
569
613
 
570
614
  Kernel::raise $!
571
615
 
572
616
  end
573
617
 
574
- TDriver.logger.behaviour "PASS;Screen was captured successfully.;#{ id.to_s };sut;{};capture_screen;#{ arguments.inspect }"
618
+ $logger.behaviour "PASS;Screen was captured successfully.;#{ id.to_s };sut;{};capture_screen;#{ arguments.inspect }"
575
619
 
576
620
  nil
577
621
 
@@ -584,8 +628,11 @@ module MobyBehaviour
584
628
  # == arguments
585
629
  # target
586
630
  # Hash
587
- # description: used to indetify the application to be executed. All symbols defined in the hash must match with the launched application. See application [link="#run_hash_arguments"]run argument hash keys[/link] table.
588
- # example: { :name => 'calculator' }
631
+ # description: Used to indetify the application to be executed. All symbols defined in the hash must match with the launched application. See application [link="#run_hash_arguments"]run argument hash keys[/link] table.
632
+ # example: { :name => "calculator" }
633
+ # String
634
+ # description: If target application is given in String format it is interpreted as application name. String "calculator"' is equivalent to {:name => "calculator"} hash.
635
+ # example: "calculator"
589
636
  #
590
637
  # == tables
591
638
  # run_hash_arguments
@@ -594,13 +641,15 @@ module MobyBehaviour
594
641
  # |Key|Type|Description|Example|
595
642
  # |:uid|String or Integer|Unique ID of the application|{ :uid => 268458181 }|
596
643
  # |:name|String|Executable name of the application|{ :name => 'calculator' }|
644
+ # |:restart_if_running|Boolean|Restart application if already running||{ :restart_if_running => true }|
597
645
  # |:arguments|String|Comma separated list of arguments passed to the application when it is started|{ :arguments => '--nogui,-v' }|
598
- # |:sleep_time|Integer|Number of seconds to sleep immediately after launching the process|{ :sleep_time => 10 }|
599
- # |:start_command|String|When set, the run method will execute this command and expect the application provided by the :name key to be launched. Note that applications launched this way can't be sent a Kill message and its start up events and signals may not be recorded.|{ :start_command => 'start_app_batch',:name => 'calculator' }|
600
- # |:try_attach|Boolean|If set to true, run will attempt to attach to an existing application with the given name or id. If not found the application will be launched as normal. If more than 1 are found then an exception is thrown|{:try_attach => true, :name => 'calculator'}|
601
- # |:environment|String|Environment variables you want to pass to started process, passed as key value pairs separated by '=' and pairs separated by spaces |{ :environment => 'LC_ALL=en SPECIAL_VAR=value' }|
602
- # |:events_to_listen|String|List of events you want to start listening to when application starts, passed as comma separated string. You can retrieve a list of events fired by a test object by first enabling event listening and then using the get_events method. See methods enable_events, get_events and disable_events |{ :events_to_listen => 'Paint,Show' }|
603
- # |:signals_to_listen|String|List of signals you want to start listening to when application starts, passed as comma separated string. Check your application class what signals it can emit, or you can use the 'signal' fixture's 'list_signal' method to retrieve an xml string listing all the signals the object can emit. E.g. xml = @object.fixture('signal', 'list_signals')|{ :signals_to_listen => 'applicationReady()' }|
646
+ # |:check_pid|Boolean|Overrides default value of SUT parameter :application_check_pid; When set to true, process id is used to test object identification|false|
647
+ # |:sleep_time|Integer|Number of seconds to sleep immediately after launching the process|{ :sleep_time => 10 }|
648
+ # |:start_command|String|When set, the run method will execute this command and expect the application provided by the :name key to be launched. Note that applications launched this way can't be sent a Kill message and its start up events and signals may not be recorded.|{ :start_command => 'start_app_batch',:name => 'calculator' }|
649
+ # |:try_attach|Boolean|If set to true, run will attempt to attach to an existing application with the given name or id. If not found the application will be launched as normal. If more than 1 are found then an exception is thrown|{:try_attach => true, :name => 'calculator'}|
650
+ # |:environment|String|Environment variables you want to pass to started process, passed as key value pairs separated by '=' and pairs separated by spaces |{ :environment => 'LC_ALL=en SPECIAL_VAR=value' }|
651
+ # |:events_to_listen|String|List of events you want to start listening to when application starts, passed as comma separated string. You can retrieve a list of events fired by a test object by first enabling event listening and then using the get_events method. See methods enable_events, get_events and disable_events |{ :events_to_listen => 'Paint,Show' }|
652
+ # |:signals_to_listen|String|List of signals you want to start listening to when application starts, passed as comma separated string. Check your application class what signals it can emit, or you can use the 'signal' fixture's 'list_signal' method to retrieve an xml string listing all the signals the object can emit. E.g. xml = @object.fixture('signal', 'list_signals')|{ :signals_to_listen => 'applicationReady()' }|
604
653
  #
605
654
  # == returns
606
655
  # TestObject
@@ -622,27 +671,51 @@ module MobyBehaviour
622
671
  begin
623
672
 
624
673
  # set the refresh interval to zero while the application is launched
625
- #orig_interval = $parameters[ @id ][ :refresh_interval ]
626
- #$parameters[ @id ][ :refresh_interval ] = '0'
674
+ #orig_interval = sut_parameters[ :refresh_interval ]
675
+ #sut_parameters[ :refresh_interval ] = '0'
627
676
 
628
677
  # raise exception if argument type other than hash
629
- target.check_type( Hash, "Wrong argument type $1 for run method (expected $2)" )
678
+ target.check_type( [ String, Hash ], "Wrong argument type $1 for run method (expected $2)" )
679
+
680
+ # if target application is given as string, interpret it as application name
681
+ target = { :name => target.to_s } if target.kind_of?( String )
630
682
 
631
683
  # default value for missing keys
632
684
  target.default = nil
633
685
 
634
686
  # raise exception if :uid or :name not found from hash
635
- target.require_key( [ :uid, :name ], "Required key :uid or :name not found from argument hash" )
687
+ target.require_one( [ :uid, :name ], "Required key :uid or :name not found from argument hash" )
636
688
 
637
689
  # due to bug #1488
638
690
  sleep_time = ( target[ :sleep_after_launch ] || target[ :sleep_time ] ).to_i
639
691
 
692
+ timeout_time = sut_parameters[ :application_synchronization_timeout, '5' ].to_f
693
+
694
+ retry_interval = sut_parameters[ :application_synchronization_retry_interval, '0.5' ].to_f
695
+
696
+ if target.has_key?( :check_pid )
697
+
698
+ check_pid = target[ :check_pid ].check_type [ TrueClass, FalseClass ], 'wrong argument type $1 for SUT#run :check_pid (expected $2)'
699
+
700
+ else
701
+
702
+ # due to bug #1710; pid checking must be configurable
703
+ check_pid = sut_parameters[ :application_check_pid, false ].to_s.to_boolean( false )
704
+
705
+ end
706
+
640
707
  Kernel::raise ArgumentError, "Sleep time need to be >= 0" unless sleep_time >= 0
641
708
 
642
709
  # try to find an existing app with the current arguments
643
- if target[ :try_attach ]
710
+ if target[ :try_attach ] || target[:restart_if_running]
711
+
712
+ app_list = MobyBase::StateObject.new(
713
+
714
+ :source_data => self.list_apps,
715
+ :parent => nil,
716
+ :test_object_adapter => @test_object_adapter
644
717
 
645
- app_list = MobyBase::StateObject.new( self.list_apps() )
718
+ )
646
719
 
647
720
  # either ID or NAME have been passed to identify the application
648
721
  # raise exception if more than one app has been found for this id/name
@@ -653,15 +726,20 @@ module MobyBehaviour
653
726
 
654
727
  app = self.application(:id => app_info.id) if app_info
655
728
 
656
- if app
729
+ if target[:restart_if_running] && app
730
+
731
+ # Close the application,
732
+ app.close # (:force_kill => true)
657
733
 
734
+ elsif app
735
+
658
736
  begin
659
737
 
660
738
  app.bring_to_foreground
661
739
 
662
740
  rescue Exception => e
663
741
 
664
- TDriver.logger.warning "Could not bring app to foreground"
742
+ $logger.warning "Could not bring app to foreground"
665
743
 
666
744
  end
667
745
 
@@ -679,27 +757,11 @@ module MobyBehaviour
679
757
 
680
758
  else
681
759
 
682
- =begin
683
760
  # execute the application control service request
684
- execute_command(
685
-
686
- MobyCommand::Application.new(
687
- :Run,
688
- target[ :name ],
689
- target[ :uid ],
690
- self,
691
- target[ :arguments ],
692
- target[ :environment ],
693
- target[ :working_directory ],
694
- target[ :events_to_listen ],
695
- target[ :signals_to_listen ]
696
- )
697
-
698
- )
699
- =end
761
+ # the run request will return the pid if all goes well
762
+ app_pid = nil
700
763
 
701
- # execute the application control service request
702
- execute_command(
764
+ app_pid = execute_command(
703
765
  MobyCommand::Application.new(
704
766
  :Run,
705
767
  {
@@ -719,37 +781,39 @@ module MobyBehaviour
719
781
 
720
782
  # do not remove this, unless qttas server & plugin handles the syncronization between plugin registration & first ui state request
721
783
  # first ui dump is requested too early and target/server seems not be ready...
722
- #sleep 0.100
723
-
724
784
  sleep sleep_time if sleep_time > 0
725
-
785
+
786
+ # Now the application id is its PID that we get from the execute_command response
726
787
  expected_attributes = { :type => 'application' }
727
788
 
728
- expected_attributes[ :id ] = target[ :uid ] unless target[ :uid ].nil?
789
+ # fix to bug #1710; pid checking must be configurable
790
+ if check_pid == true
791
+
792
+ expected_attributes[ :id ] = app_pid unless app_pid.nil?
729
793
 
794
+ end
795
+
730
796
  expected_attributes[ :FullName ] = target[ :name ] unless target[ :name ].nil?
731
797
 
798
+ # For error reporting
732
799
  error_details = target[ :name ].nil? ? "" : "name: " << target[ :name ].to_s
733
800
  error_details << ( error_details.empty? ? "" : ", ") << "id: " << target[ :uid ].to_s if !target[ :uid ].nil?
734
801
 
735
- app_name=target[ :name ].nil? ? "" : "name: " << target[ :name ].to_s
802
+ # Calculate the application name from :FullName ( used later )
803
+ app_name = target[ :name ].nil? ? "" : "name: " << target[ :name ].to_s
736
804
 
737
805
  if( !expected_attributes[ :FullName ].nil? )
738
-
739
806
  if( expected_attributes[ :FullName ].include?('/') )
740
-
741
807
  app_name = expected_attributes[ :FullName ].split('/')[ expected_attributes[ :FullName ].split( '/' ).size-1 ]
742
808
  app_name.slice!( ".exe" )
743
809
  expected_attributes[ :name ] = app_name
744
810
 
745
811
  elsif( expected_attributes[ :FullName ].include?("\\") )
746
-
747
812
  app_name = expected_attributes[ :FullName ].split("\\")[ expected_attributes[ :FullName ].split( "\\" ).size-1 ]
748
813
  app_name.slice!( ".exe" )
749
814
  expected_attributes[:name] = app_name
750
815
 
751
816
  else
752
-
753
817
  app_name = expected_attributes[ :FullName ]
754
818
  app_name.slice!( ".exe" )
755
819
  expected_attributes[ :name ] = app_name
@@ -758,17 +822,16 @@ module MobyBehaviour
758
822
 
759
823
  expected_attributes.delete( :FullName )
760
824
  expected_attributes.delete( :name )
761
-
762
825
  end
763
826
 
827
+ # Wait for application to register and then create the application test object
764
828
  begin
765
- timeout_time=$parameters[ @id ][ :application_synchronization_timeout, '5' ].to_f
766
- retryinterval=$parameters[ @id ][ :application_synchronization_retry_interval, '0.5' ].to_f
767
829
 
768
830
  MobyUtil::Retryable.until(
769
831
  :timeout => timeout_time,
770
- :interval => retryinterval,
832
+ :interval => retry_interval,
771
833
  :exception => MobyBase::ApplicationNotAvailableError) {
834
+
772
835
  # verify that application is launched and application test object is found from xml
773
836
  expected_attributes.delete( :name )
774
837
 
@@ -781,17 +844,17 @@ module MobyBehaviour
781
844
  timeout_time,
782
845
 
783
846
  # wait retry interval and try again if application was not found
784
- retryinterval
847
+ retry_interval
785
848
 
786
849
  )
787
850
 
788
851
  expected_attributes[ :name ] = app_name
789
852
  # retrieve application object element from sut.xml_data
790
853
 
791
- @@matches, unused_rule = TDriver::TestObjectAdapter.get_objects( xml_data, expected_attributes, true )
854
+ @matches, unused_rule = @test_object_adapter.get_objects( xml_data, expected_attributes, true )
792
855
 
793
856
  # raise exception if application element was not found; this shouldn't ever happen?
794
- raise MobyBase::ApplicationNotAvailableError if @@matches.count == 0
857
+ raise MobyBase::ApplicationNotAvailableError if @matches.count == 0
795
858
 
796
859
  }
797
860
 
@@ -804,7 +867,7 @@ module MobyBehaviour
804
867
 
805
868
  :object_attributes_hash => expected_attributes,
806
869
 
807
- :xml_object => @@matches.first
870
+ :xml_object => @matches.first
808
871
 
809
872
  )
810
873
 
@@ -824,16 +887,16 @@ module MobyBehaviour
824
887
 
825
888
  end
826
889
 
827
- # raise behaviour error if any exception is raised
828
- rescue # Exception => e
890
+ # raise behaviour error if any exception is raised
891
+ rescue
829
892
 
830
- TDriver.logger.behaviour "FAIL;Failed to launch application.;#{ id.to_s };sut;{};run;#{ target.kind_of?( Hash ) ? target.inspect : target.class.to_s }"
893
+ $logger.behaviour "FAIL;Failed to launch application.;#{ id.to_s };sut;{};run;#{ target.kind_of?( Hash ) ? target.inspect : target.class.to_s }"
831
894
 
832
895
  Kernel::raise MobyBase::BehaviourError.new("Run", "Failed to launch application")
833
896
 
834
897
  end
835
898
 
836
- TDriver.logger.behaviour "PASS;The application was launched successfully.;#{ id.to_s };sut;{};run;#{ target.inspect }"
899
+ $logger.behaviour "PASS;The application was launched successfully.;#{ id.to_s };sut;{};run;#{ target.inspect }"
837
900
 
838
901
  foreground_app
839
902
 
@@ -887,7 +950,15 @@ module MobyBehaviour
887
950
 
888
951
  value.check_type( [ Symbol, MobyCommand::KeySequence ], "Wrong argument type $1 for press_key (expected $2)" )
889
952
 
890
- sequence = value.kind_of?( Symbol ) ? MobyCommand::KeySequence.new( value ) : value
953
+ if value.kind_of?( Symbol )
954
+
955
+ sequence = MobyCommand::KeySequence.new( value )
956
+
957
+ else
958
+
959
+ sequence = value
960
+
961
+ end
891
962
 
892
963
  sequence.set_sut( self )
893
964
 
@@ -895,13 +966,13 @@ module MobyBehaviour
895
966
 
896
967
  rescue
897
968
 
898
- TDriver.logger.behaviour "FAIL;Failed to press key(s).;#{id.to_s};sut;{};press_key;#{ value }"
969
+ $logger.behaviour "FAIL;Failed to press key(s).;#{id.to_s};sut;{};press_key;#{ value }"
899
970
 
900
971
  Kernel::raise $!
901
972
 
902
973
  end
903
974
 
904
- TDriver.logger.behaviour "PASS;Successfully pressed key(s).;#{ id.to_s };sut;{};press_key;#{ value }"
975
+ $logger.behaviour "PASS;Successfully pressed key(s).;#{ id.to_s };sut;{};press_key;#{ value }"
905
976
 
906
977
  nil
907
978
 
@@ -925,7 +996,7 @@ module MobyBehaviour
925
996
  # description: Value matching the parameter name given as argument
926
997
  # example: 'testability-driver-qt-sut-plugin'
927
998
  #
928
- # MobyUtil::ParameterHash
999
+ # TDriver::ParameterHash
929
1000
  # description: Hash of values, if no arguments is specified
930
1001
  # example: { :value => '1', :inner_hash => { :another_value => 100 } }
931
1002
  #
@@ -943,13 +1014,11 @@ module MobyBehaviour
943
1014
 
944
1015
  if ( arguments.count == 0 )
945
1016
 
946
- MobyUtil::ParameterUserAPI[ @id ]
1017
+ $parameters[ @id ]
947
1018
 
948
1019
  else
949
1020
 
950
- #$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 ]
951
-
952
- MobyUtil::ParameterUserAPI[ @id ][ *arguments ]
1021
+ $parameters[ @id ][ *arguments ]
953
1022
 
954
1023
  end
955
1024
 
@@ -985,7 +1054,7 @@ module MobyBehaviour
985
1054
  # example: "1"
986
1055
  # default: nil
987
1056
  # Integer
988
- # description: Optional numeral replacement of an '%Ln | %1' tag on the translated string
1057
+ # description: Optional numeral replacement of an '%Ln | %1 | %D | %U | %N' tag on the translated string
989
1058
  # example: 1
990
1059
  # Array
991
1060
  # description: Optional numeral replacements for multiple '%L1 | %1, %L2 | %2, ...' tags on the translated string
@@ -1055,9 +1124,9 @@ module MobyBehaviour
1055
1124
 
1056
1125
  when "localisation"
1057
1126
 
1058
- language=nil
1127
+ language = nil
1059
1128
 
1060
- if ( $parameters[ self.id ][:read_lang_from_app]=='true')
1129
+ if ( sut_parameters[ :read_lang_from_app ]=='true')
1061
1130
 
1062
1131
  #read localeName app
1063
1132
  language=self.application.attribute("localeName")
@@ -1067,7 +1136,7 @@ module MobyBehaviour
1067
1136
 
1068
1137
  else
1069
1138
 
1070
- language=$parameters[ self.id ][ :language ]
1139
+ language = sut_parameters[ :language ]
1071
1140
 
1072
1141
  end
1073
1142
 
@@ -1076,7 +1145,7 @@ module MobyBehaviour
1076
1145
  translation = MobyUtil::Localisation.translation(
1077
1146
  logical_name,
1078
1147
  language,
1079
- $parameters[ self.id ][ :localisation_server_database_tablename ],
1148
+ sut_parameters[ :localisation_server_database_tablename ],
1080
1149
  file_name,
1081
1150
  plurality,
1082
1151
  lengthvariant
@@ -1090,7 +1159,7 @@ module MobyBehaviour
1090
1159
 
1091
1160
  elsif numerus.kind_of? String or numerus.kind_of? Integer
1092
1161
 
1093
- translation.gsub!(/%(Ln|1)/){|s| numerus.to_s}
1162
+ translation.gsub!(/%(Ln|1|U|D|N)/){|s| numerus.to_s}
1094
1163
 
1095
1164
  end
1096
1165
 
@@ -1104,7 +1173,7 @@ module MobyBehaviour
1104
1173
 
1105
1174
  elsif numerus.kind_of? String or numerus.kind_of? Integer
1106
1175
 
1107
- trans.gsub!(/%(Ln|1)/){|s| numerus.to_s}
1176
+ trans.gsub!(/%(Ln|1|U|D|N)/){|s| numerus.to_s}
1108
1177
 
1109
1178
  end
1110
1179
 
@@ -1191,10 +1260,10 @@ module MobyBehaviour
1191
1260
  user_data_lname,
1192
1261
 
1193
1262
  # language
1194
- $parameters[ self.id ][ :language ],
1263
+ sut_parameters[ :language ],
1195
1264
 
1196
1265
  # table name
1197
- $parameters[ self.id ][ :user_data_server_database_tablename ]
1266
+ sut_parameters[ :user_data_server_database_tablename ]
1198
1267
 
1199
1268
  )
1200
1269
 
@@ -1234,10 +1303,10 @@ module MobyBehaviour
1234
1303
  operator_data_lname,
1235
1304
 
1236
1305
  # operator
1237
- $parameters[ self.id ][ :operator_selected ],
1306
+ sut_parameters[ :operator_selected ],
1238
1307
 
1239
1308
  # table name
1240
- $parameters[ self.id ][ :operator_data_server_database_tablename ]
1309
+ sut_parameters[ :operator_data_server_database_tablename ]
1241
1310
 
1242
1311
  )
1243
1312
 
@@ -1252,9 +1321,7 @@ module MobyBehaviour
1252
1321
  # === raises
1253
1322
  def update
1254
1323
 
1255
- #@_child_objects.each{ | test_object | test_object.update( @xml_data ) } if !@childs_updated
1256
-
1257
- unless @childs_updated
1324
+ if @update_childs
1258
1325
 
1259
1326
  @child_object_cache.each_object{ | test_object |
1260
1327
 
@@ -1264,9 +1331,17 @@ module MobyBehaviour
1264
1331
 
1265
1332
  }
1266
1333
 
1267
- end
1334
+ @update_childs = false
1268
1335
 
1269
- @childs_updated = true
1336
+ # childs were updated
1337
+ true
1338
+
1339
+ else
1340
+
1341
+ # nothing was updated
1342
+ false
1343
+
1344
+ end
1270
1345
 
1271
1346
  end
1272
1347
 
@@ -1275,7 +1350,7 @@ module MobyBehaviour
1275
1350
 
1276
1351
  refresh_ui_dump( refresh_args, creation_attributes )
1277
1352
 
1278
- # update childs only if ui state is new
1353
+ # update childs if required, returns true or false
1279
1354
  update_childs
1280
1355
 
1281
1356
  end
@@ -1340,13 +1415,13 @@ module MobyBehaviour
1340
1415
  def get_application_id
1341
1416
 
1342
1417
  # retrieve application object from sut.xml_data
1343
- matches, unused_rule = TDriver::TestObjectAdapter.get_objects( xml_data, { :type => 'application' }, true )
1418
+ matches, unused_rule = @test_object_adapter.get_objects( xml_data, { :type => 'application' }, true )
1344
1419
 
1345
1420
  # retrieve id attribute if application test object found
1346
1421
  if matches.count > 0
1347
1422
 
1348
1423
  # return id attribute value
1349
- TDriver::TestObjectAdapter.test_object_element_attribute( matches.first, 'id' )
1424
+ @test_object_adapter.test_object_element_attribute( matches.first, 'id' )
1350
1425
 
1351
1426
  else
1352
1427
 
@@ -1357,13 +1432,13 @@ module MobyBehaviour
1357
1432
 
1358
1433
  end
1359
1434
 
1360
- private
1435
+ private
1361
1436
 
1362
1437
  # TODO: document me
1363
1438
  def update_childs
1364
1439
 
1365
1440
  # update childs only if ui state is new
1366
- update if !@childs_updated
1441
+ update if @update_childs
1367
1442
 
1368
1443
  end
1369
1444
 
@@ -1377,72 +1452,77 @@ module MobyBehaviour
1377
1452
 
1378
1453
  if !@frozen #&& ( @_previous_refresh.nil? || ( current_time - @_previous_refresh ).to_f >= @refresh_interval )
1379
1454
 
1380
- use_find_objects = $parameters[ @id ][ :use_find_object, 'false' ] == 'true' and self.respond_to?( 'find_object' )
1455
+ # determine should FindObjects service be used
1456
+ use_find_objects = sut_parameters[ :use_find_object, 'false' ] == 'true' and self.respond_to?( 'find_object' ) == true
1381
1457
 
1458
+ # duplicate refresh arguments hash
1382
1459
  refresh_arguments = refresh_args.clone
1383
1460
 
1384
1461
  MobyUtil::Retryable.while(
1385
1462
  :tries => @refresh_tries,
1386
1463
  :interval => @refresh_interval,
1387
1464
  :unless => [ MobyBase::ControllerNotFoundError, MobyBase::CommandNotFoundError, MobyBase::ApplicationNotAvailableError ]
1388
- ) {
1465
+ ){
1389
1466
 
1390
1467
  #use find_object if set on and the method exists
1391
1468
  if use_find_objects
1392
1469
 
1393
- new_xml_data, crc = find_object( refresh_arguments, creation_attributes )
1470
+ # retrieve new ui dump xml and crc
1471
+ new_xml_data, crc = find_object( refresh_arguments, creation_attributes, @xml_data_crc )
1472
+
1473
+ crc = @xml_data_crc if new_xml_data.empty?
1394
1474
 
1395
1475
  else
1396
1476
 
1397
- =begin
1398
- app_command = MobyCommand::Application.new(
1399
- :State,
1400
- refresh_args[ :FullName ] || refresh_args[ :name ],
1401
- refresh_args[ :id ],
1402
- self
1477
+ # retrieve new ui dump xml and crc
1478
+ new_xml_data, crc = execute_command(
1479
+
1480
+ MobyCommand::Application.new(
1481
+ :State,
1482
+ {
1483
+ :application_name => refresh_args[ :FullName ] || refresh_args[ :name ],
1484
+ :application_uid => refresh_args[ :id ],
1485
+ :sut => self,
1486
+ :refresh_arguments => refresh_args,
1487
+ :checksum => @xml_data_crc
1488
+ }
1489
+ )
1490
+
1403
1491
  )
1404
- =end
1405
1492
 
1406
- app_command = MobyCommand::Application.new(
1407
- :State,
1408
- {
1409
- :application_name => refresh_args[ :FullName ] || refresh_args[ :name ],
1410
- :application_uid => refresh_args[ :id ],
1411
- :sut => self
1412
- }
1413
- )
1493
+ crc = @xml_data_crc if new_xml_data.empty?
1414
1494
 
1415
- # store in case needed
1416
- app_command.refresh_args( refresh_args )
1495
+ end
1417
1496
 
1418
- new_xml_data, crc = execute_command( app_command )
1497
+ # parse the xml if crc does not match with previously retrieved crc
1498
+ if ( @xml_data_crc == 0 || crc != @xml_data_crc || crc.nil? )
1419
1499
 
1420
- end
1500
+ # parse new xml string, return cached object if one is found; crc is used for caching and identifying the duplicate xml strings
1501
+ xml_data, from_cache = MobyUtil::XML.parse_string( new_xml_data, crc )
1421
1502
 
1422
- @dump_count += 1
1503
+ # store new xml data object
1504
+ @xml_data = xml_data.root
1423
1505
 
1424
- @childs_updated = false
1506
+ # store xml crc to be compared while next ui dump request; do not reparse xml if crc values are equal
1507
+ @xml_data_crc = crc
1425
1508
 
1426
- @xml_data = MobyUtil::XML.parse_string( new_xml_data ).root
1509
+ # mark that child objects needs to be updated
1510
+ @update_childs = true #unless from_cache
1427
1511
 
1428
- @_previous_refresh = Time.now
1512
+ end
1429
1513
 
1430
- # remove timestamp from the beginning of tasMessage, parse if not same as previous ui state
1431
- #if ( xml_data_no_timestamp = new_xml_data.split( ">", 2 ).last ) != @last_xml_data
1432
- # @xml_data = MobyUtil::XML.parse_string( new_xml_data ).root
1433
- # @last_xml_data = xml_data_no_timestamp
1434
- #end
1514
+ # increase number of sent ui dump requests by one
1515
+ @dump_count += 1
1435
1516
 
1436
- #if ( @xml_data_crc == 0 || crc != @xml_data_crc || crc.nil? )
1437
- # @xml_data, @xml_data_crc, @childs_updated = MobyUtil::XML.parse_string( new_xml_data ).root, crc, false
1438
- #end
1517
+ # store timestamp of last performed ui dump request
1518
+ @_previous_refresh = Time.now
1439
1519
 
1440
1520
  }
1441
1521
 
1442
1522
  end
1443
1523
 
1444
- # fetch_references( @xml_data )
1445
1524
  @xml_data
1525
+
1446
1526
  end
1447
1527
 
1448
1528
  # TODO: document me
@@ -1604,58 +1684,72 @@ module MobyBehaviour
1604
1684
 
1605
1685
  end
1606
1686
 
1607
- def initialize_settings
1608
-
1609
- @xml_data = ""
1610
-
1611
- @x_path = '.'
1612
-
1613
- @frozen = false
1614
-
1615
- @child_object_cache = TDriver::TestObjectCache.new
1616
-
1617
- @current_application_id = nil
1618
-
1619
- @dump_count = 0
1620
-
1621
- # default values
1622
- @input = :key
1623
-
1624
- @refresh_tries = 5
1625
- @refresh_interval = 0.5
1687
+ def load_verify_blocks( filename )
1626
1688
 
1627
- @childs_updated = false
1689
+ # load verify blocks if filename not empty
1690
+ unless filename.blank?
1628
1691
 
1629
- # id not found from parameters
1630
- if $parameters[ @id, nil ] != nil
1692
+ # verify that file exists
1693
+ if File.exists?( filename )
1631
1694
 
1632
- @input = $parameters[ @id ][ :input_type, "key" ].to_sym
1695
+ # load verify blocks configuration file
1696
+ load filename
1633
1697
 
1634
- @refresh_tries = $parameters[ @id ][ :ui_state_refresh_tries, @refresh_tries ].to_f
1698
+ # return collection of verify blocks; reference directly to VERIFY_BLOCKS must not be used, due to it may get cleared by user
1699
+ SutParameters::VERIFY_BLOCKS.collect{ | block | block }
1635
1700
 
1636
- @refresh_interval = $parameters[ @id ][ :refresh_interval, @refresh_interval ].to_f
1701
+ else
1702
+
1703
+ # return empty array due to file didn't exist
1704
+ []
1705
+
1706
+ end
1637
1707
 
1708
+ else
1709
+
1710
+ # return empty array due to no filename was given
1711
+ []
1712
+
1638
1713
  end
1639
1714
 
1640
- @last_xml_data = nil
1641
-
1642
- ruby_file = $parameters[ @id ][ :verify_blocks ]
1715
+ end
1643
1716
 
1644
- @verify_blocks = []
1717
+ # TODO: document me
1718
+ def initialize_settings
1645
1719
 
1646
- if File.exists?( ruby_file )
1720
+ # default values
1721
+ @x_path = '.'
1722
+ @xml_data = ""
1723
+ @dump_count = 0
1647
1724
 
1648
- load ruby_file
1725
+ # determines that should child test objects be updated
1726
+ @update_childs = true
1727
+
1728
+ @last_xml_data = nil
1729
+ @frozen = false
1649
1730
 
1650
- SutParameters::VERIFY_BLOCKS.each { | block |
1731
+ # initialize cache for sut children
1732
+ @child_object_cache = TDriver::TestObjectCache.new
1651
1733
 
1652
- @verify_blocks << block
1734
+ @current_application_id = nil
1653
1735
 
1654
- }
1736
+ # create empty hash for sut parameters if sut id not found from parameters
1737
+ $parameters[ @id ] = {} unless $parameters.has_key?( @id )
1655
1738
 
1739
+ @input = sut_parameters[ :input_type, 'key' ].to_sym
1740
+ @refresh_tries = sut_parameters[ :ui_state_refresh_tries, '5' ].to_f
1741
+ @refresh_interval = sut_parameters[ :refresh_interval, '0.5' ].to_f
1656
1742
 
1657
- end
1743
+ # load verify blocks from defined sut configuration file
1744
+ @verify_blocks = load_verify_blocks( sut_parameters[ :verify_blocks, nil ] )
1745
+
1746
+ end
1658
1747
 
1748
+ # accessor for sut parameters
1749
+ def sut_parameters
1750
+
1751
+ $parameters[ @id ]
1752
+
1659
1753
  end
1660
1754
 
1661
1755
  public # deprecated
@@ -1669,7 +1763,7 @@ module MobyBehaviour
1669
1763
 
1670
1764
  warn "warning: deprecated method SUT#get_object; please use SUT#child instead"
1671
1765
 
1672
- child object_id
1766
+ child( object_id )
1673
1767
 
1674
1768
  end
1675
1769
 
@@ -1686,7 +1780,22 @@ module MobyBehaviour
1686
1780
 
1687
1781
  #$stderr.puts "warning: SUT#get_ui_dump is deprecated, please use SUT#refresh_ui_dump instead."
1688
1782
 
1689
- refresh_ui_dump refresh_args, {}
1783
+ refresh_ui_dump( refresh_args, {} )
1784
+
1785
+ end
1786
+
1787
+ # This method is deprecated, please use [link="#GenericSut:state_object"]SUT#state_object[/link] instead.
1788
+ # == deprecated
1789
+ # 1.1.1
1790
+ #
1791
+ # == description
1792
+ # This method is deprecated, please use SUT#state_object
1793
+ #
1794
+ def state
1795
+
1796
+ warn "warning: deprecated method SUT#state; please use SUT#state_object instead"
1797
+
1798
+ state_object
1690
1799
 
1691
1800
  end
1692
1801