cutedriver-driver 2.0.0.20210120164037
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.
- checksums.yaml +7 -0
- data/README.md +16 -0
- data/bin/start_app_perf +200 -0
- data/bin/tdriver-devtools +3 -0
- data/config/sut_parameters.rb +52 -0
- data/config/sut_setup.rb +32 -0
- data/config/sut_teardown.rb +32 -0
- data/config/tdriver_custom_error_recovery.rb +83 -0
- data/ext/extconf.rb +70 -0
- data/ext/native_extensions.c +315 -0
- data/lib/matti.rb +25 -0
- data/lib/tdriver-devtools/behaviour/old/xml/example/flick-example.rb +120 -0
- data/lib/tdriver-devtools/behaviour/old/xml/example/impl.rb_invalid +194 -0
- data/lib/tdriver-devtools/behaviour/old/xml/generate_behaviour_xml.rb +95 -0
- data/lib/tdriver-devtools/behaviour/old/xml/lib/tdriver_generator.rb +722 -0
- data/lib/tdriver-devtools/behaviour/old/xml/qdoc_generator.rb +321 -0
- data/lib/tdriver-devtools/behaviour/old/xml/templates/behaviour.method.template +43 -0
- data/lib/tdriver-devtools/behaviour/old/xml/templates/behaviour.module.template +54 -0
- data/lib/tdriver-devtools/behaviour/old/xml/templates/behaviour.xml.argument.template +7 -0
- data/lib/tdriver-devtools/behaviour/old/xml/templates/behaviour.xml.argument_type.template +7 -0
- data/lib/tdriver-devtools/behaviour/old/xml/templates/behaviour.xml.exception.template +5 -0
- data/lib/tdriver-devtools/behaviour/old/xml/templates/behaviour.xml.howto.line.template +2 -0
- data/lib/tdriver-devtools/behaviour/old/xml/templates/behaviour.xml.howto.template +5 -0
- data/lib/tdriver-devtools/behaviour/old/xml/templates/behaviour.xml.method.template +23 -0
- data/lib/tdriver-devtools/behaviour/old/xml/templates/behaviour.xml.template +14 -0
- data/lib/tdriver-devtools/behaviour/old/xml/update +3 -0
- data/lib/tdriver-devtools/behaviour/xml/generate.rb +88 -0
- data/lib/tdriver-devtools/behaviour/xml/rdoc_behaviour_xml_generator.rb +1945 -0
- data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.argument.default.template +1 -0
- data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.argument.template +3 -0
- data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.argument_type.template +4 -0
- data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.exception.template +4 -0
- data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.method.arguments.template +4 -0
- data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.method.deprecated.template +3 -0
- data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.method.exceptions.template +3 -0
- data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.method.info.template +1 -0
- data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.method.returns.template +3 -0
- data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.method.tables.template +3 -0
- data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.method.template +12 -0
- data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.returns.template +5 -0
- data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.table.item.template +1 -0
- data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.table.row.template +2 -0
- data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.table.template +8 -0
- data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.template +14 -0
- data/lib/tdriver-devtools/doc/behaviour_xml/QtExampleGestureBehaviour.xml +138 -0
- data/lib/tdriver-devtools/doc/behaviour_xml/created.rid +1 -0
- data/lib/tdriver-devtools/doc/behaviour_xml/tdriver.hash +1 -0
- data/lib/tdriver-devtools/doc/feature_xml/qt_widget_hold.feature.xml +9 -0
- data/lib/tdriver-devtools/doc/feature_xml/qt_widget_tap.feature.xml +9 -0
- data/lib/tdriver-devtools/doc/generate.rb +917 -0
- data/lib/tdriver-devtools/doc/update +1 -0
- data/lib/tdriver-devtools/doc/xslt/html.rb +7 -0
- data/lib/tdriver-devtools/doc/xslt/template.xsl +2170 -0
- data/lib/tdriver-devtools/doc/xslt/update +3 -0
- data/lib/tdriver-devtools/plugin/placeholder.txt +1 -0
- data/lib/tdriver-devtools/tdriver-devtools.rb +404 -0
- data/lib/tdriver-devtools/tests/feature_tests/example/behaviour_example.rb +100 -0
- data/lib/tdriver-devtools/tests/feature_tests/generate.rb +82 -0
- data/lib/tdriver-devtools/tests/feature_tests/lib/custom_rdoc_generator.rb +468 -0
- data/lib/tdriver-devtools/tests/feature_tests/templates/feature_attribute.template +5 -0
- data/lib/tdriver-devtools/tests/feature_tests/templates/feature_method.template +5 -0
- data/lib/tdriver-devtools/tests/feature_tests/templates/scenario_attribute.template +5 -0
- data/lib/tdriver-devtools/tests/feature_tests/templates/scenario_method.template +5 -0
- data/lib/tdriver-devtools/tests/feature_tests/update +3 -0
- data/lib/tdriver.rb +23 -0
- data/lib/tdriver/base/behaviour/abstract.rb +29 -0
- data/lib/tdriver/base/behaviour/behaviours/object_abstract.rb +107 -0
- data/lib/tdriver/base/behaviour/behaviours/object_behaviour_composition.rb +99 -0
- data/lib/tdriver/base/behaviour/behaviours/object_behaviour_description.rb +278 -0
- data/lib/tdriver/base/behaviour/behaviours/object_composition.rb +119 -0
- data/lib/tdriver/base/behaviour/factory.rb +495 -0
- data/lib/tdriver/base/behaviour/loader.rb +46 -0
- data/lib/tdriver/base/command_data/command_data.rb +51 -0
- data/lib/tdriver/base/command_data/loader.rb +29 -0
- data/lib/tdriver/base/controller/abstraction.rb +56 -0
- data/lib/tdriver/base/controller/loader.rb +21 -0
- data/lib/tdriver/base/errors.rb +134 -0
- data/lib/tdriver/base/loader.rb +47 -0
- data/lib/tdriver/base/state_object.rb +373 -0
- data/lib/tdriver/base/sut/adapter.rb +54 -0
- data/lib/tdriver/base/sut/controller.rb +151 -0
- data/lib/tdriver/base/sut/factory.rb +339 -0
- data/lib/tdriver/base/sut/generic/behaviours/agent.rb +77 -0
- data/lib/tdriver/base/sut/generic/behaviours/application.rb +427 -0
- data/lib/tdriver/base/sut/generic/behaviours/controller.rb +67 -0
- data/lib/tdriver/base/sut/generic/behaviours/find.rb +107 -0
- data/lib/tdriver/base/sut/generic/behaviours/flash_behaviour.rb +337 -0
- data/lib/tdriver/base/sut/generic/behaviours/sut.rb +1888 -0
- data/lib/tdriver/base/sut/generic/behaviours/switchbox_behaviour.rb +210 -0
- data/lib/tdriver/base/sut/generic/behaviours/verification.rb +222 -0
- data/lib/tdriver/base/sut/generic/commands/agent.rb +43 -0
- data/lib/tdriver/base/sut/generic/commands/application.rb +274 -0
- data/lib/tdriver/base/sut/generic/commands/fixture.rb +47 -0
- data/lib/tdriver/base/sut/generic/commands/key_sequence.rb +94 -0
- data/lib/tdriver/base/sut/generic/commands/screen_capture.rb +64 -0
- data/lib/tdriver/base/sut/generic/plugin.rb +97 -0
- data/lib/tdriver/base/sut/loader.rb +35 -0
- data/lib/tdriver/base/sut/sut.rb +98 -0
- data/lib/tdriver/base/test_object/abstract.rb +208 -0
- data/lib/tdriver/base/test_object/adapter.rb +740 -0
- data/lib/tdriver/base/test_object/behaviours/syncronization.rb +144 -0
- data/lib/tdriver/base/test_object/behaviours/test_object.rb +1047 -0
- data/lib/tdriver/base/test_object/cache.rb +134 -0
- data/lib/tdriver/base/test_object/factory.rb +684 -0
- data/lib/tdriver/base/test_object/loader.rb +51 -0
- data/lib/tdriver/base/test_object/verification.rb +178 -0
- data/lib/tdriver/base/test_object/xml/abstraction.rb +63 -0
- data/lib/tdriver/base/test_object/xml/adapter.rb +773 -0
- data/lib/tdriver/env.rb +21 -0
- data/lib/tdriver/loader.rb +57 -0
- data/lib/tdriver/matti.rb +35 -0
- data/lib/tdriver/report/error_recovery/tdriver_custom_error_recovery.rb +83 -0
- data/lib/tdriver/report/error_recovery/tdriver_error_recovery.rb +168 -0
- data/lib/tdriver/report/error_recovery/tdriver_error_recovery_settings.rb +106 -0
- data/lib/tdriver/report/report.rb +61 -0
- data/lib/tdriver/report/report_api.rb +348 -0
- data/lib/tdriver/report/report_combine.rb +86 -0
- data/lib/tdriver/report/report_crash_file_capture.rb +178 -0
- data/lib/tdriver/report/report_creator.rb +665 -0
- data/lib/tdriver/report/report_cucumber.rb +158 -0
- data/lib/tdriver/report/report_cucumber_listener.rb +184 -0
- data/lib/tdriver/report/report_cucumber_reporter.rb +181 -0
- data/lib/tdriver/report/report_data_presentation.rb +156 -0
- data/lib/tdriver/report/report_data_table.rb +64 -0
- data/lib/tdriver/report/report_execution_statistics.rb +400 -0
- data/lib/tdriver/report/report_file_capture.rb +159 -0
- data/lib/tdriver/report/report_graph_generator.rb +59 -0
- data/lib/tdriver/report/report_grouping.rb +541 -0
- data/lib/tdriver/report/report_javascript.rb +199 -0
- data/lib/tdriver/report/report_junit_xml.rb +147 -0
- data/lib/tdriver/report/report_rspec.rb +108 -0
- data/lib/tdriver/report/report_test_case_run.rb +725 -0
- data/lib/tdriver/report/report_test_run.rb +1476 -0
- data/lib/tdriver/report/report_test_unit.rb +223 -0
- data/lib/tdriver/report/report_writer.rb +1621 -0
- data/lib/tdriver/tdriver.rb +209 -0
- data/lib/tdriver/util/agent/loader.rb +22 -0
- data/lib/tdriver/util/agent/service.rb +107 -0
- data/lib/tdriver/util/common/array.rb +39 -0
- data/lib/tdriver/util/common/boolean.rb +48 -0
- data/lib/tdriver/util/common/crc16.rb +149 -0
- data/lib/tdriver/util/common/environment.rb +154 -0
- data/lib/tdriver/util/common/error.rb +40 -0
- data/lib/tdriver/util/common/exception.rb +53 -0
- data/lib/tdriver/util/common/exceptions.rb +12 -0
- data/lib/tdriver/util/common/file.rb +328 -0
- data/lib/tdriver/util/common/gem.rb +109 -0
- data/lib/tdriver/util/common/hash.rb +288 -0
- data/lib/tdriver/util/common/kernel.rb +253 -0
- data/lib/tdriver/util/common/loader.rb +47 -0
- data/lib/tdriver/util/common/numeric.rb +159 -0
- data/lib/tdriver/util/common/object.rb +159 -0
- data/lib/tdriver/util/common/retryable.rb +179 -0
- data/lib/tdriver/util/common/stackable.rb +185 -0
- data/lib/tdriver/util/common/string.rb +174 -0
- data/lib/tdriver/util/database/access.rb +240 -0
- data/lib/tdriver/util/database/connection.rb +44 -0
- data/lib/tdriver/util/database/error.rb +34 -0
- data/lib/tdriver/util/database/loader.rb +28 -0
- data/lib/tdriver/util/filters/attribute_filter.rb +121 -0
- data/lib/tdriver/util/filters/loader.rb +29 -0
- data/lib/tdriver/util/fixture/loader.rb +22 -0
- data/lib/tdriver/util/fixture/service.rb +211 -0
- data/lib/tdriver/util/hooking/hooking.rb +477 -0
- data/lib/tdriver/util/keymap/keymap.rb +81 -0
- data/lib/tdriver/util/loader.rb +80 -0
- data/lib/tdriver/util/localisation/error.rb +31 -0
- data/lib/tdriver/util/localisation/loader.rb +25 -0
- data/lib/tdriver/util/localisation/localisation.rb +762 -0
- data/lib/tdriver/util/logger/loader.rb +22 -0
- data/lib/tdriver/util/logger/logger.rb +591 -0
- data/lib/tdriver/util/operator_data/error.rb +29 -0
- data/lib/tdriver/util/operator_data/loader.rb +27 -0
- data/lib/tdriver/util/operator_data/operator_data.rb +93 -0
- data/lib/tdriver/util/other/config.rb +221 -0
- data/lib/tdriver/util/parameter/error.rb +48 -0
- data/lib/tdriver/util/parameter/loader.rb +25 -0
- data/lib/tdriver/util/parameter/parameter.rb +1161 -0
- data/lib/tdriver/util/plugin/abstract.rb +61 -0
- data/lib/tdriver/util/plugin/error.rb +0 -0
- data/lib/tdriver/util/plugin/loader.rb +28 -0
- data/lib/tdriver/util/plugin/service.rb +319 -0
- data/lib/tdriver/util/recorder/loader.rb +25 -0
- data/lib/tdriver/util/recorder/recorder.rb +72 -0
- data/lib/tdriver/util/recorder/scripter.rb +294 -0
- data/lib/tdriver/util/statistics/statistics.rb +89 -0
- data/lib/tdriver/util/user_data/error.rb +28 -0
- data/lib/tdriver/util/user_data/loader.rb +25 -0
- data/lib/tdriver/util/user_data/user_data.rb +104 -0
- data/lib/tdriver/util/video/camera.rb +67 -0
- data/lib/tdriver/util/video/camera_linux.rb +153 -0
- data/lib/tdriver/util/video/camera_windows.rb +174 -0
- data/lib/tdriver/util/video/loader.rb +31 -0
- data/lib/tdriver/util/video/video_utils.rb +139 -0
- data/lib/tdriver/util/xml/abstraction.rb +117 -0
- data/lib/tdriver/util/xml/attribute.rb +32 -0
- data/lib/tdriver/util/xml/builder.rb +53 -0
- data/lib/tdriver/util/xml/comment.rb +32 -0
- data/lib/tdriver/util/xml/document.rb +32 -0
- data/lib/tdriver/util/xml/element.rb +32 -0
- data/lib/tdriver/util/xml/error.rb +46 -0
- data/lib/tdriver/util/xml/loader.rb +62 -0
- data/lib/tdriver/util/xml/nil_node.rb +95 -0
- data/lib/tdriver/util/xml/nodeset.rb +32 -0
- data/lib/tdriver/util/xml/parsers/libxml/libxml.rb +140 -0
- data/lib/tdriver/util/xml/parsers/loader.rb +21 -0
- data/lib/tdriver/util/xml/parsers/nokogiri/abstraction.rb +167 -0
- data/lib/tdriver/util/xml/parsers/nokogiri/attribute.rb +66 -0
- data/lib/tdriver/util/xml/parsers/nokogiri/builder.rb +64 -0
- data/lib/tdriver/util/xml/parsers/nokogiri/comment.rb +39 -0
- data/lib/tdriver/util/xml/parsers/nokogiri/document.rb +66 -0
- data/lib/tdriver/util/xml/parsers/nokogiri/element.rb +39 -0
- data/lib/tdriver/util/xml/parsers/nokogiri/loader.rb +58 -0
- data/lib/tdriver/util/xml/parsers/nokogiri/node.rb +212 -0
- data/lib/tdriver/util/xml/parsers/nokogiri/nodeset.rb +237 -0
- data/lib/tdriver/util/xml/parsers/nokogiri/text.rb +39 -0
- data/lib/tdriver/util/xml/text.rb +32 -0
- data/lib/tdriver/util/xml/xml.rb +332 -0
- data/lib/tdriver/verify/verify.rb +2398 -0
- data/lib/tdriver/version.rb +21 -0
- data/xml/behaviours/generic.xml +530 -0
- data/xml/defaults/generic.xml +11 -0
- data/xml/defaults/sut_generic.xml +8 -0
- data/xml/parameters/tdriver_parameters.xml +23 -0
- data/xml/templates/generic.xml +292 -0
- metadata +324 -0
@@ -0,0 +1,97 @@
|
|
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
|
+
# verify that plugin engine and modules is loaded
|
21
|
+
raise RuntimeError.new( "This SUT plugin requires Testability Driver and cannot be launched in standalone mode" ) unless defined?( MobyUtil::Plugin )
|
22
|
+
|
23
|
+
module MobyPlugin
|
24
|
+
|
25
|
+
module Generic
|
26
|
+
|
27
|
+
class SUT < MobyUtil::Plugin
|
28
|
+
|
29
|
+
## plugin configuration, constructor and deconstructor methods
|
30
|
+
def self.plugin_name
|
31
|
+
|
32
|
+
# return plugin name as string
|
33
|
+
"testability-driver-generic-sut-plugin"
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.plugin_type
|
38
|
+
|
39
|
+
# return plugin type as symbol
|
40
|
+
:sut
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.register_plugin
|
45
|
+
|
46
|
+
# load plugin specific implementation or other initialization etc.
|
47
|
+
MobyUtil::FileHelper.load_modules(
|
48
|
+
|
49
|
+
# load behaviour(s)
|
50
|
+
'behaviours/*.rb',
|
51
|
+
|
52
|
+
# load commands(s)
|
53
|
+
'commands/*.rb'
|
54
|
+
|
55
|
+
)
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.unregister_plugin
|
60
|
+
|
61
|
+
# unregister plugin
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
## plugin specific methods
|
66
|
+
|
67
|
+
# return sut type that plugin implements
|
68
|
+
def self.sut_type
|
69
|
+
|
70
|
+
# return sut type as string
|
71
|
+
"generic"
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
# returns SUT object - this method will be called from TDriver::SUTFactory
|
76
|
+
def self.make_sut( sut_id )
|
77
|
+
|
78
|
+
MobyBase::SUT.new(
|
79
|
+
MobyBase::SutController.new( "", MobyController::SutAdapter.new() ),
|
80
|
+
TDriver.TestObjectFactory.new( TDriver::TestObjectAdapter ),
|
81
|
+
sut_id
|
82
|
+
)
|
83
|
+
|
84
|
+
|
85
|
+
end
|
86
|
+
|
87
|
+
# enable hooking for performance measurement & debug logging
|
88
|
+
TDriver::Hooking.hook_methods( self ) if defined?( TDriver::Hooking )
|
89
|
+
|
90
|
+
# register plugin
|
91
|
+
TDriver::PluginService.register_plugin( self )
|
92
|
+
|
93
|
+
end # SUT
|
94
|
+
|
95
|
+
end # Generic
|
96
|
+
|
97
|
+
end # MobyPlugin
|
@@ -0,0 +1,35 @@
|
|
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
|
+
|
21
|
+
# load sut abstraction class
|
22
|
+
require File.expand_path( File.join( File.dirname( __FILE__ ), 'sut' ) )
|
23
|
+
|
24
|
+
# load sut adapter abstraction class
|
25
|
+
require File.expand_path( File.join( File.dirname( __FILE__ ), 'adapter' ) )
|
26
|
+
|
27
|
+
# load sut controller
|
28
|
+
require File.expand_path( File.join( File.dirname( __FILE__ ), 'controller' ) )
|
29
|
+
|
30
|
+
# load sut factory
|
31
|
+
require File.expand_path( File.join( File.dirname( __FILE__ ), 'factory' ) )
|
32
|
+
|
33
|
+
# generic sut
|
34
|
+
require File.expand_path( File.join( File.dirname( __FILE__ ), 'generic/plugin.rb' ) )
|
35
|
+
|
@@ -0,0 +1,98 @@
|
|
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
|
+
# abstract class for SUT - no behaviours
|
21
|
+
module MobyBase
|
22
|
+
|
23
|
+
class SUT
|
24
|
+
|
25
|
+
attr_accessor(
|
26
|
+
:id, # id of current SUT
|
27
|
+
:ui_type, # ui type
|
28
|
+
:ui_version, # ui version
|
29
|
+
:input # the input method used for interacting with this sut as a symbol, eg. :key or :touch.
|
30
|
+
)
|
31
|
+
|
32
|
+
attr_reader(
|
33
|
+
:type, # type of object ("SUT"), used when applying behaviour
|
34
|
+
:environment, # sut environment from parameters file
|
35
|
+
:test_object_adapter # test object adapter -- added for now?
|
36
|
+
)
|
37
|
+
|
38
|
+
# Initialize SUT by giving references to the used controller and test object factory
|
39
|
+
# == params
|
40
|
+
# sut_controller:: Controller object that acts as a facade to the device represented by this SUT
|
41
|
+
# test_object_factory:: TestObjectFactory object, a factory for generating creating test objects for this SUT
|
42
|
+
# sut_id:: String representing the identification of this SUT - the identification will need to match with group id in parameters xml
|
43
|
+
def initialize( sut_controller, test_object_factory, sut_id, test_object_adapter = nil )
|
44
|
+
|
45
|
+
@sut_controller = sut_controller
|
46
|
+
|
47
|
+
# remove this line when possible
|
48
|
+
@_sutController = sut_controller
|
49
|
+
|
50
|
+
# remove this line when possible
|
51
|
+
@test_object_factory = test_object_factory
|
52
|
+
|
53
|
+
# remove this line when possible
|
54
|
+
@test_object_adapter = test_object_adapter || TDriver::TestObjectAdapter
|
55
|
+
|
56
|
+
@id = sut_id
|
57
|
+
|
58
|
+
# reference to self; easier to access (parent) SUT in shared behaviours applied to test object/sut/application
|
59
|
+
@sut = self
|
60
|
+
|
61
|
+
# default values
|
62
|
+
@input = :key
|
63
|
+
@type = "sut"
|
64
|
+
|
65
|
+
@object_behaviours = []
|
66
|
+
|
67
|
+
@environment = $parameters[ sut_id ][ :env ]
|
68
|
+
|
69
|
+
@forced_xml = false
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
# Interface to forward command execution to sut specific controller (SutController#execute_command)
|
74
|
+
# == params
|
75
|
+
# command:: MobyBase::CommandData descendant object defining the command
|
76
|
+
# == raises
|
77
|
+
# ?:: what ever SutController#execute_command( command ) raises
|
78
|
+
# == returns
|
79
|
+
# Boolean:: what ever SutController returns
|
80
|
+
def execute_command( command )
|
81
|
+
|
82
|
+
@sut_controller.execute_command( command )
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
# TODO: document me
|
87
|
+
def inspect
|
88
|
+
|
89
|
+
"#<#{ self.class }:0x#{ ( "%x" % ( object_id.to_i << 1 ) )[ 3 .. -1 ] } @id=#{ @id.inspect } @input=\"#{ @input }\" @type=\"#{ @type }\" @ui_type=\"#{ @ui_type }\" @ui_version=\"#{ @ui_version }\">"
|
90
|
+
|
91
|
+
end
|
92
|
+
|
93
|
+
# enable hooking for performance measurement & debug logging
|
94
|
+
TDriver::Hooking.hook_methods( self ) if defined?( TDriver::Hooking )
|
95
|
+
|
96
|
+
end # SUT
|
97
|
+
|
98
|
+
end # MobyBase
|
@@ -0,0 +1,208 @@
|
|
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 TestObject
|
23
|
+
|
24
|
+
attr_reader(
|
25
|
+
:sut, # SUT associated to test object
|
26
|
+
:type, # test object type (from xml)
|
27
|
+
:id, # test object id (from xml)
|
28
|
+
:parent, # parent test object
|
29
|
+
:name, # test object name (from xml)
|
30
|
+
:x_path # xpath for test object, used when updating self with fresh ui dump
|
31
|
+
)
|
32
|
+
|
33
|
+
# Creation of a new TestObject requires options hash to be given to constructor.
|
34
|
+
# === params
|
35
|
+
# options:: Hash containing xml object describing the object and all other required configuration values e.g. test object factory, -adapter etc.
|
36
|
+
# === returns
|
37
|
+
# TestObject:: new TestObject instance
|
38
|
+
# === raises
|
39
|
+
def initialize( options )
|
40
|
+
|
41
|
+
# verify that given argument is type of hash
|
42
|
+
options.check_type Hash, 'wrong argument type $1 for TestObject#new (expected $2)'
|
43
|
+
|
44
|
+
# verify that required keys is found from options hash and initialize the test object with these values
|
45
|
+
@sut = options.require_key :sut
|
46
|
+
|
47
|
+
@test_object_factory = options.require_key :test_object_factory
|
48
|
+
@test_object_adapter = options.require_key :test_object_adapter
|
49
|
+
@creation_attributes = options.require_key :creation_attributes
|
50
|
+
|
51
|
+
# verify that parent object and parent application is given in options hash
|
52
|
+
@parent = options.require_key :parent
|
53
|
+
@parent_application = options.require_key :parent_application
|
54
|
+
|
55
|
+
# store sut id
|
56
|
+
@sut_id = @sut.instance_variable_get :@id
|
57
|
+
|
58
|
+
# initialize cache object
|
59
|
+
@child_object_cache = TDriver::TestObjectCache.new
|
60
|
+
|
61
|
+
# empty test object behaviours list
|
62
|
+
@object_behaviours = []
|
63
|
+
|
64
|
+
# apply xml object if given; test object type, id and name are retrieved from the xml
|
65
|
+
__send__ :xml_data=, options[ :xml_object ] if options.has_key?( :xml_object )
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
# Function to verify is DATA of two TestObjects are the same,
|
70
|
+
# Defined in TestObject#== test_object
|
71
|
+
# === param
|
72
|
+
# test_object:: TestObject other, could be null
|
73
|
+
# === returns
|
74
|
+
# true:: if TestObjects have same DATA
|
75
|
+
# false:: if TestObjects have different DATA
|
76
|
+
# === raises
|
77
|
+
# nothing
|
78
|
+
def eql?( test_object )
|
79
|
+
|
80
|
+
__send__ :==, test_object
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
# Function to verify is DATA of two TestObjects are the same,
|
85
|
+
# return TRUE if test_object:
|
86
|
+
# instance of MobyBase::TestObject
|
87
|
+
# type's are equal
|
88
|
+
# id's are equal
|
89
|
+
# name's are equal
|
90
|
+
# == param
|
91
|
+
# test_object:: TestObject other, could be null
|
92
|
+
# == returns
|
93
|
+
# true:: if TestObjects have same DATA
|
94
|
+
# false:: if TestObjects have different DATA
|
95
|
+
# == raises
|
96
|
+
# nothing
|
97
|
+
def ==( test_object )
|
98
|
+
|
99
|
+
#return false unless test_object.instance_of?( MobyBase::TestObject )
|
100
|
+
#return false unless @type == test_object.type
|
101
|
+
#return false unless @id == test_object.id
|
102
|
+
#return false unless @name == test_object.name
|
103
|
+
#return true
|
104
|
+
|
105
|
+
# optimized version
|
106
|
+
test_object.instance_of?( MobyBase::TestObject ) && ( @type == test_object.type ) && ( @id == test_object.id ) && ( @name == test_object.name )
|
107
|
+
|
108
|
+
end
|
109
|
+
|
110
|
+
# Function to calculate HASH value for a TestObject
|
111
|
+
#
|
112
|
+
# This is required, as eql? method is being overwritten.
|
113
|
+
# === returns
|
114
|
+
# Fixnum:: hash number representing current TestObject
|
115
|
+
def hash
|
116
|
+
|
117
|
+
#result = 17
|
118
|
+
#result = result * 37 + @id.to_i
|
119
|
+
#result = result * 37 + @hash
|
120
|
+
#result = result * 37 + @hash
|
121
|
+
#return result
|
122
|
+
|
123
|
+
# optimized version
|
124
|
+
#( ( ( 17 * 37 + @id.to_i ) * 37 + @type.hash ) * 37 + @name.hash )
|
125
|
+
|
126
|
+
@test_object_adapter.test_object_hash( @id.to_i, @type, @name )
|
127
|
+
|
128
|
+
end
|
129
|
+
|
130
|
+
# Function to support sorting TestObjects within an array.
|
131
|
+
# Mostly for unit testing purposes, as Set is not ordered.
|
132
|
+
# should not be used normally. Thus, not documented.
|
133
|
+
def <=>( test_object )
|
134
|
+
|
135
|
+
#self_type = @type
|
136
|
+
#other_type = test_object.type
|
137
|
+
#return -1 if self_type < other_type
|
138
|
+
#return 1 if self_type > other_type
|
139
|
+
|
140
|
+
#self_name = @name
|
141
|
+
#other_name = test_object.name
|
142
|
+
#return -1 if self_name < other_name
|
143
|
+
#return 1 if self_name > other_name
|
144
|
+
|
145
|
+
#self_id = @id
|
146
|
+
#other_id = test_object.id
|
147
|
+
#return -1 if self_id < other_id
|
148
|
+
#return 1 if self_id > other_id
|
149
|
+
|
150
|
+
#0
|
151
|
+
|
152
|
+
# optimized version
|
153
|
+
( ( result = ( @type <=> test_object.type ) ) == 0 ? ( ( result = ( @name <=> test_object.name ) ) == 0 ? @id <=> test_object.id : result ) : result )
|
154
|
+
|
155
|
+
end
|
156
|
+
|
157
|
+
# Function to be renamed, possibly refactored
|
158
|
+
def xml_data=( xml_object )
|
159
|
+
|
160
|
+
@x_path, @name, @type, @id, @env = @test_object_adapter.get_test_object_identifiers( xml_object, self )
|
161
|
+
|
162
|
+
end
|
163
|
+
|
164
|
+
# Returns a XML node representing this test object.
|
165
|
+
#
|
166
|
+
# === returns
|
167
|
+
# MobyUtil::XML::Element:: XML representation of this test object
|
168
|
+
# === raises
|
169
|
+
# TestObjectNotFoundError:: The test object does not exist on the SUT any longer.
|
170
|
+
def xml_data
|
171
|
+
|
172
|
+
begin
|
173
|
+
|
174
|
+
@test_object_adapter.get_xml_element_for_test_object( self )
|
175
|
+
|
176
|
+
rescue MobyBase::TestObjectNotFoundError
|
177
|
+
|
178
|
+
raise MobyBase::TestObjectNotFoundError.new(
|
179
|
+
|
180
|
+
"The test object (id: #{ @id.inspect }, type: #{ @type.inspect }, name: #{ @name.inspect }) does not exist on #{ @sut.id.inspect } anymore"
|
181
|
+
|
182
|
+
)
|
183
|
+
|
184
|
+
end
|
185
|
+
|
186
|
+
end
|
187
|
+
|
188
|
+
# TODO: document me
|
189
|
+
def inspect
|
190
|
+
|
191
|
+
"#<#{ self.class }:0x#{ ( "%x" % ( object_id.to_i << 1 ) )[ 3 .. -1 ] } @id=\"#{ @id }\" @name=\"#{ @name }\" @parent=#{ @parent.inspect } @sut=#{ @sut.inspect } @type=\"#{ @type }\" @x_path=\"#{ @x_path }\">"
|
192
|
+
|
193
|
+
end
|
194
|
+
|
195
|
+
private
|
196
|
+
|
197
|
+
def sut_parameters
|
198
|
+
|
199
|
+
$parameters[ @sut_id ]
|
200
|
+
|
201
|
+
end
|
202
|
+
|
203
|
+
# enable hooking for performance measurement & debug logging
|
204
|
+
TDriver::Hooking.hook_methods( self ) if defined?( TDriver::Hooking )
|
205
|
+
|
206
|
+
end # TestObject
|
207
|
+
|
208
|
+
end # MobyBase
|
@@ -0,0 +1,740 @@
|
|
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 TDriver
|
21
|
+
|
22
|
+
class TestObjectAdapter
|
23
|
+
|
24
|
+
# private methods and variables
|
25
|
+
class << self
|
26
|
+
|
27
|
+
# include abstraction module
|
28
|
+
include TDriver::Abstraction::TestObjectAdapter
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
# TODO: document me
|
33
|
+
def xpath_attributes( attributes, element_attributes, object_type )
|
34
|
+
|
35
|
+
# collect attributes
|
36
|
+
attributes = attributes.collect{ | key, values |
|
37
|
+
|
38
|
+
# allow multiple values options for attribute, e.g. object which 'text' attribute value is either '1' or '2'
|
39
|
+
( values.kind_of?( Array ) ? values : [ values ] ).collect{ | value |
|
40
|
+
|
41
|
+
# concatenate string if it contains single and double quotes, otherwise return as is
|
42
|
+
value = xpath_literal_string( value )
|
43
|
+
|
44
|
+
prefix_key = "@#{ key }"
|
45
|
+
|
46
|
+
if @partial_match_allowed.include?( [ object_type, key ] )
|
47
|
+
|
48
|
+
# regexp support is needed also here
|
49
|
+
|
50
|
+
prefix_value = "[contains(.,#{ value })]"
|
51
|
+
attribute_value = "contains(value/.,#{ value })"
|
52
|
+
|
53
|
+
else
|
54
|
+
|
55
|
+
if value.kind_of?( Regexp )
|
56
|
+
|
57
|
+
prefix_value = "regexp_compare(#{ prefix_key },'#{ value.source }',#{ value.options })"
|
58
|
+
attribute_value = "regexp_compare(value/.,'#{ value.source }',#{ value.options })"
|
59
|
+
|
60
|
+
prefix_key = ""
|
61
|
+
|
62
|
+
else
|
63
|
+
|
64
|
+
prefix_value = "=#{ value }"
|
65
|
+
attribute_value = "value/.=#{ value }"
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
|
71
|
+
# construct xpath
|
72
|
+
"(#{ element_attributes ? "#{ prefix_key }#{ prefix_value } or " : "" }attributes/attribute[translate(@name,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')='#{ key }' and #{ attribute_value }])"
|
73
|
+
|
74
|
+
}.join( ' or ' ) # join attribute alternative values
|
75
|
+
|
76
|
+
}.join( ' and ' ) # join all required attributes
|
77
|
+
|
78
|
+
# return created xpath or nil if no attributes given
|
79
|
+
if attributes.empty?
|
80
|
+
|
81
|
+
# no attributes given
|
82
|
+
nil
|
83
|
+
|
84
|
+
else
|
85
|
+
|
86
|
+
# return result
|
87
|
+
attributes
|
88
|
+
|
89
|
+
end
|
90
|
+
|
91
|
+
end # xpath_attributes
|
92
|
+
|
93
|
+
#merges elements from the nodeset, used in hybrid app situations
|
94
|
+
def create_merged_element(nodeset, environments, close_element=true)
|
95
|
+
merged_element_set = false
|
96
|
+
|
97
|
+
merged_xml = ""
|
98
|
+
|
99
|
+
nodeset.each{ | object |
|
100
|
+
|
101
|
+
# only one top element
|
102
|
+
unless merged_element_set
|
103
|
+
|
104
|
+
# retrieve object attributes
|
105
|
+
attributes = object.attributes
|
106
|
+
|
107
|
+
# merge env to attributes hash
|
108
|
+
attributes['env'] = environments.join(';')
|
109
|
+
|
110
|
+
# add application object xml element to new xml string
|
111
|
+
merged_xml << "<object #{ hash_to_element_attributes( attributes ) }>"
|
112
|
+
|
113
|
+
# merged element is now set, no need to do it again
|
114
|
+
merged_element_set = true
|
115
|
+
|
116
|
+
end
|
117
|
+
|
118
|
+
# append all found elements
|
119
|
+
object.xpath('./*').each{ | object | merged_xml << object.to_s }
|
120
|
+
}
|
121
|
+
merged_xml << "</object>" if close_element and merged_element_set
|
122
|
+
merged_xml
|
123
|
+
end
|
124
|
+
|
125
|
+
|
126
|
+
|
127
|
+
# TODO: document me
|
128
|
+
def initialize_class
|
129
|
+
|
130
|
+
# special cases: allow partial match when value of type and attribute name matches
|
131
|
+
@partial_match_allowed = [ 'list_item', 'text' ], [ 'application', 'fullname' ]
|
132
|
+
|
133
|
+
end
|
134
|
+
|
135
|
+
end # static
|
136
|
+
|
137
|
+
# TODO: document me
|
138
|
+
def self.regexp_compare( nodeset, source, options )
|
139
|
+
|
140
|
+
# rebuild defined regexp, used while matching element content
|
141
|
+
regexp_object = Regexp.new( source.to_s, options.to_i )
|
142
|
+
|
143
|
+
# collect all nodes matching with regexp
|
144
|
+
nodeset.find_all{ | node | node.content =~ regexp_object }
|
145
|
+
|
146
|
+
end
|
147
|
+
|
148
|
+
# TODO: document me
|
149
|
+
def self.xpath_to_object( rules, find_all_children )
|
150
|
+
|
151
|
+
# convert hash keys to downcased string
|
152
|
+
rules = Hash[
|
153
|
+
|
154
|
+
rules.collect{ | key, value |
|
155
|
+
|
156
|
+
case value
|
157
|
+
|
158
|
+
# pass the value as is if type of regexp or array; array is used in localisation cases e.g. [ 'one', 'yksi', 'uno' ] # etc
|
159
|
+
when Regexp, Array
|
160
|
+
|
161
|
+
[ key.to_s.downcase, value ]
|
162
|
+
|
163
|
+
else
|
164
|
+
|
165
|
+
[ key.to_s.downcase, value.to_s ]
|
166
|
+
|
167
|
+
end
|
168
|
+
|
169
|
+
}
|
170
|
+
|
171
|
+
]
|
172
|
+
|
173
|
+
# xpath container array
|
174
|
+
test_object_xpath_array = []
|
175
|
+
|
176
|
+
# store and remove object element attributes from hash
|
177
|
+
object_element_attributes = rules.delete_keys!( 'name', 'type', 'parent', 'id' )
|
178
|
+
|
179
|
+
# children method may request test objects of any type
|
180
|
+
if object_element_attributes[ 'type' ] == '*'
|
181
|
+
|
182
|
+
# test object with any name, type, parent and id is allowed
|
183
|
+
test_object_xpath_array << '@*'
|
184
|
+
|
185
|
+
else
|
186
|
+
|
187
|
+
# required attributes
|
188
|
+
test_object_xpath_array << xpath_attributes( object_element_attributes, true, object_element_attributes[ 'type' ] )
|
189
|
+
|
190
|
+
end
|
191
|
+
|
192
|
+
# additional attributes, eg. :text, :x, :y etc.
|
193
|
+
test_object_xpath_array << xpath_attributes( rules, false, object_element_attributes[ 'type' ] )
|
194
|
+
|
195
|
+
# join required and additional attribute strings
|
196
|
+
test_object_xpath_string = test_object_xpath_array.compact.join( ' and ' )
|
197
|
+
|
198
|
+
# return any child element under current node or only immediate child element
|
199
|
+
find_all_children ? "*//object[#{ test_object_xpath_string }]" : "objects[1]/object[#{ test_object_xpath_string }]"
|
200
|
+
|
201
|
+
end
|
202
|
+
|
203
|
+
# TODO: document me
|
204
|
+
def self.xpath_literal_string( string )
|
205
|
+
|
206
|
+
return string if string.kind_of?( Regexp )
|
207
|
+
|
208
|
+
# make sure that argument is type of string
|
209
|
+
string = string.to_s
|
210
|
+
|
211
|
+
# does not contain no single quotes
|
212
|
+
if not string.include?("'")
|
213
|
+
|
214
|
+
result = "'#{ string }'"
|
215
|
+
|
216
|
+
# does not contain no double quotes
|
217
|
+
elsif not string.include?('"')
|
218
|
+
|
219
|
+
result = "\"#{ string }\""
|
220
|
+
|
221
|
+
# contains single and double quotes
|
222
|
+
else
|
223
|
+
|
224
|
+
# open new item
|
225
|
+
result = ["'"]
|
226
|
+
|
227
|
+
# iterate through each character
|
228
|
+
string.each_char{ | char |
|
229
|
+
|
230
|
+
case char
|
231
|
+
|
232
|
+
# encapsulate single quotes with double quotes
|
233
|
+
when "'"
|
234
|
+
|
235
|
+
# close current item
|
236
|
+
result.last << char
|
237
|
+
|
238
|
+
# add encapsulated single quote
|
239
|
+
result << "\"'\""
|
240
|
+
|
241
|
+
# open new item
|
242
|
+
result << char
|
243
|
+
|
244
|
+
else
|
245
|
+
|
246
|
+
# any other character will appended as is
|
247
|
+
result.last << char
|
248
|
+
|
249
|
+
end
|
250
|
+
|
251
|
+
}
|
252
|
+
|
253
|
+
# close last sentence
|
254
|
+
result.last << "'"
|
255
|
+
|
256
|
+
# create concat clause for xpath
|
257
|
+
result = "concat(#{ result.join(',') })"
|
258
|
+
|
259
|
+
end
|
260
|
+
|
261
|
+
result
|
262
|
+
|
263
|
+
end
|
264
|
+
|
265
|
+
# TODO: document me
|
266
|
+
def self.get_objects( source_data, rules, find_all_children )
|
267
|
+
|
268
|
+
rule = xpath_to_object( rules, find_all_children )
|
269
|
+
|
270
|
+
[
|
271
|
+
# perform xpath to source xml data
|
272
|
+
source_data.xpath( rule, self ),
|
273
|
+
|
274
|
+
# return also created xpath
|
275
|
+
rule
|
276
|
+
]
|
277
|
+
|
278
|
+
end
|
279
|
+
|
280
|
+
# TODO: document me
|
281
|
+
def self.test_object_hash( object_id, object_type, object_name )
|
282
|
+
|
283
|
+
# calculate test object hash
|
284
|
+
( ( ( 17 * 37 + object_id ) * 37 + object_type.hash ) * 37 + object_name.hash )
|
285
|
+
|
286
|
+
end
|
287
|
+
|
288
|
+
# Sort XML nodeset of test objects with layout direction
|
289
|
+
def self.sort_elements( nodeset, layout_direction = 'LeftToRight' )
|
290
|
+
|
291
|
+
# cache for x_absolute and y_absolute values; reduces dramatically number of xpath calls
|
292
|
+
cache = {}
|
293
|
+
|
294
|
+
# xpath pattern to be used for x_absolute attribute value
|
295
|
+
x_absolute_pattern = './attributes/attribute[@name="x_absolute"]/value/text()'
|
296
|
+
|
297
|
+
# xpath pattern to be used for x_absolute attribute value
|
298
|
+
y_absolute_pattern = './attributes/attribute[@name="y_absolute"]/value/text()'
|
299
|
+
|
300
|
+
# collect only nodes that has x_absolute and y_absolute attributes
|
301
|
+
nodeset.collect!{ | node |
|
302
|
+
|
303
|
+
# retrieve x_absolute attribute
|
304
|
+
x_absolute = node.at_xpath( x_absolute_pattern )
|
305
|
+
|
306
|
+
# retrieve y_absolute attribute
|
307
|
+
y_absolute = node.at_xpath( y_absolute_pattern )
|
308
|
+
|
309
|
+
# return unmodified nodeset if both attributes was not found
|
310
|
+
if x_absolute.nil? || y_absolute.nil?
|
311
|
+
|
312
|
+
#warn("Warning: Unable to sort object set due to object type of #{ node.attribute( 'type' ).inspect } does not have \"x_absolute\" or \"y_absolute\" attribute")
|
313
|
+
|
314
|
+
return nodeset
|
315
|
+
|
316
|
+
else
|
317
|
+
|
318
|
+
# store attributes to cache for further processing
|
319
|
+
cache[ node ] = [ x_absolute.content.to_i, y_absolute.content.to_i ]
|
320
|
+
|
321
|
+
# return node as result
|
322
|
+
node
|
323
|
+
|
324
|
+
end
|
325
|
+
|
326
|
+
}.compact!.sort!{ | element_a, element_b |
|
327
|
+
|
328
|
+
# retrieve element a's attributes x and y
|
329
|
+
element_a_x, element_a_y = cache[ element_a ]
|
330
|
+
|
331
|
+
# retrieve element b's attributes x and y
|
332
|
+
element_b_x, element_b_y = cache[ element_b ]
|
333
|
+
|
334
|
+
case layout_direction
|
335
|
+
|
336
|
+
when 'LeftToRight'
|
337
|
+
|
338
|
+
# compare elements
|
339
|
+
( element_a_y == element_b_y ) ? ( element_a_x <=> element_b_x ) : ( element_a_y <=> element_b_y )
|
340
|
+
|
341
|
+
when 'RightToLeft'
|
342
|
+
|
343
|
+
# compare elements
|
344
|
+
( element_a_y == element_b_y ) ? ( element_b_x <=> element_a_x ) : ( element_a_y <=> element_b_y )
|
345
|
+
|
346
|
+
else
|
347
|
+
|
348
|
+
# raise exception if layout direction it not supported
|
349
|
+
raise ArgumentError, "Unsupported layout direction #{ layout_direction.inspect }"
|
350
|
+
|
351
|
+
end
|
352
|
+
|
353
|
+
}
|
354
|
+
|
355
|
+
end
|
356
|
+
|
357
|
+
def self.parent_test_object_element( test_object )
|
358
|
+
|
359
|
+
# retrieve parent of current xml element; objects/object/objects/object/../..
|
360
|
+
test_object.xml_data.parent.parent
|
361
|
+
|
362
|
+
end
|
363
|
+
|
364
|
+
# TODO: document me
|
365
|
+
def self.test_object_element_attributes( source_data )
|
366
|
+
|
367
|
+
Hash[
|
368
|
+
source_data.attributes.collect{ | key, value |
|
369
|
+
[ key.to_s, value.to_s ]
|
370
|
+
}
|
371
|
+
]
|
372
|
+
|
373
|
+
end
|
374
|
+
|
375
|
+
# TODO: document me
|
376
|
+
def self.test_object_element_attribute( source_data, attribute_name, *default, &block )
|
377
|
+
|
378
|
+
result = source_data.attribute( attribute_name )
|
379
|
+
|
380
|
+
# if no attribute found call optional code block or raise exception
|
381
|
+
unless result
|
382
|
+
|
383
|
+
if block_given?
|
384
|
+
|
385
|
+
# pass return value of block as result
|
386
|
+
yield( attribute_name )
|
387
|
+
|
388
|
+
else
|
389
|
+
|
390
|
+
# raise exception if no default value given
|
391
|
+
if default.empty?
|
392
|
+
|
393
|
+
# raise exception if no such attribute found
|
394
|
+
raise MobyBase::AttributeNotFoundError, "Could not find test object element attribute #{ attribute_name.inspect }"
|
395
|
+
|
396
|
+
else
|
397
|
+
|
398
|
+
# pass default value as result
|
399
|
+
default.first
|
400
|
+
|
401
|
+
end
|
402
|
+
|
403
|
+
end
|
404
|
+
|
405
|
+
else
|
406
|
+
|
407
|
+
result
|
408
|
+
|
409
|
+
end
|
410
|
+
|
411
|
+
end
|
412
|
+
|
413
|
+
# TODO: document me
|
414
|
+
def self.test_object_attribute( source_data, attribute_name, *default, &block )
|
415
|
+
|
416
|
+
# TODO: consider using at_xpath and adding /value/text() to query string; however "downside" is that if multiple matches found only first value will be returned as result
|
417
|
+
|
418
|
+
# retrieve attribute(s) from xml
|
419
|
+
nodeset = source_data.xpath(
|
420
|
+
|
421
|
+
"attributes/attribute[translate(@name,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')='#{ attribute_name.downcase }']/value"
|
422
|
+
|
423
|
+
)
|
424
|
+
|
425
|
+
# if no attributes found call optional code block or raise exception
|
426
|
+
if nodeset.empty?
|
427
|
+
|
428
|
+
if block_given?
|
429
|
+
|
430
|
+
# pass return value of block as result
|
431
|
+
yield( attribute_name )
|
432
|
+
|
433
|
+
else
|
434
|
+
|
435
|
+
# raise exception if no default value given
|
436
|
+
if default.empty?
|
437
|
+
|
438
|
+
# raise exception if no such attribute found
|
439
|
+
raise MobyBase::AttributeNotFoundError, "Could not find attribute #{ attribute_name.inspect }" # for test object of type #{ type.to_s }"
|
440
|
+
|
441
|
+
else
|
442
|
+
|
443
|
+
# pass default value as result
|
444
|
+
default.first
|
445
|
+
|
446
|
+
end
|
447
|
+
|
448
|
+
end # block_given?
|
449
|
+
|
450
|
+
else # not nodeset.empty?
|
451
|
+
|
452
|
+
# attribute(s) found
|
453
|
+
# Need to disable this for now
|
454
|
+
# raise MobyBase::MultipleAttributesFoundError.new( "Multiple attributes found with name '#{ name }'" ) if nodeset.count > 1
|
455
|
+
|
456
|
+
# return found attribute
|
457
|
+
nodeset.first.content
|
458
|
+
|
459
|
+
end
|
460
|
+
|
461
|
+
end
|
462
|
+
|
463
|
+
# TODO: document me
|
464
|
+
def self.test_object_attributes( source_data, inclusive_filter = [] )
|
465
|
+
|
466
|
+
# convert all keys to lowercase
|
467
|
+
inclusive_filter.collect!{ | key | key.to_s.downcase } unless inclusive_filter.empty?
|
468
|
+
|
469
|
+
# return hash of test object attributes
|
470
|
+
object_attributes=Hash.new
|
471
|
+
|
472
|
+
# iterate each attribute and collect name and value
|
473
|
+
source_data.xpath( 'attributes/attribute/value' ).collect{ | value |
|
474
|
+
|
475
|
+
# retrieve attribute name
|
476
|
+
name = value.parent.attribute('name').to_s
|
477
|
+
|
478
|
+
# collect attribute elements name and content
|
479
|
+
unless inclusive_filter.empty?
|
480
|
+
|
481
|
+
object_attributes[name]=value.content if inclusive_filter.include?( name.downcase )
|
482
|
+
|
483
|
+
else
|
484
|
+
|
485
|
+
# pass the attribute pair - no filtering done
|
486
|
+
if object_attributes[name]
|
487
|
+
object_attributes[name]="#{object_attributes[name]},#{value.content}"
|
488
|
+
else
|
489
|
+
object_attributes[name]=value.content
|
490
|
+
end
|
491
|
+
|
492
|
+
end
|
493
|
+
|
494
|
+
}
|
495
|
+
|
496
|
+
object_attributes
|
497
|
+
|
498
|
+
end
|
499
|
+
|
500
|
+
# TODO: document me
|
501
|
+
def self.application_layout_direction( sut )
|
502
|
+
|
503
|
+
# temporary fix until testobject will be associated to parent application object; add 'layoutDirection' to dynamic attributes filtering whitelist...
|
504
|
+
TDriver::AttributeFilter.add_attribute( 'layoutDirection' ){
|
505
|
+
|
506
|
+
# this block will be executed if attribute was not in filter list
|
507
|
+
|
508
|
+
# temporary fix: ... and refresh sut to retrieve updated xml data
|
509
|
+
sut.refresh
|
510
|
+
|
511
|
+
}
|
512
|
+
|
513
|
+
# TODO: parent application test object should be passed to get_test_objects; TestObjectAdapter#test_object_attribute( @app.xml_data, 'layoutDirection')
|
514
|
+
( sut.xml_data.at_xpath('*//object[@type="application"]/attributes/attribute[@name="layoutDirection"]/value/text()').content || 'LeftToRight' ).to_s
|
515
|
+
|
516
|
+
end
|
517
|
+
|
518
|
+
# TODO: document me
|
519
|
+
def self.create_child_accessors!( source_data, test_object )
|
520
|
+
|
521
|
+
# iterate through each child object type attribute and create accessor method
|
522
|
+
source_data.xpath( 'objects/object/@type' ).each{ | object_type |
|
523
|
+
|
524
|
+
# skip if object type value is nil or empty due to child accessor cannot be created
|
525
|
+
next if object_type.nil? || object_type.to_s.empty?
|
526
|
+
|
527
|
+
# convert attribute node value to string
|
528
|
+
object_type = object_type.content
|
529
|
+
|
530
|
+
# skip if child accessor is already created
|
531
|
+
next if test_object.respond_to?( object_type )
|
532
|
+
|
533
|
+
begin
|
534
|
+
|
535
|
+
# create child accessor method to test object unless already exists
|
536
|
+
test_object.instance_eval(
|
537
|
+
|
538
|
+
"def #{ object_type }( rules = {} ); raise TypeError,'parameter <rules> should be hash' unless rules.kind_of?( Hash ); rules[ :type ]=:#{ object_type }; child( rules ); end;"
|
539
|
+
|
540
|
+
) unless object_type.empty?
|
541
|
+
|
542
|
+
# in case if object type has some invalid characters, e.g. type is "ns:object"
|
543
|
+
rescue SyntaxError
|
544
|
+
|
545
|
+
warn "warning: unable to create accessor to child test object whose type is #{ object_type.inspect }"
|
546
|
+
|
547
|
+
end
|
548
|
+
|
549
|
+
}
|
550
|
+
|
551
|
+
end
|
552
|
+
|
553
|
+
# TODO: document me
|
554
|
+
def self.state_object_xml( source_data, id )
|
555
|
+
|
556
|
+
# collect each object from source xml
|
557
|
+
objects = source_data.xpath( 'tasInfo/object' ).collect{ | element | element.to_s }.join
|
558
|
+
|
559
|
+
# return xml root element
|
560
|
+
MobyUtil::XML.parse_string(
|
561
|
+
"<sut name='sut' type='sut' id='#{ id }'><objects>#{ objects }</objects></sut>"
|
562
|
+
).root
|
563
|
+
|
564
|
+
end
|
565
|
+
|
566
|
+
def self.retrieve_parent_application( xml_source )
|
567
|
+
|
568
|
+
xml_source_iterator = xml_source.clone
|
569
|
+
|
570
|
+
while xml_source_iterator.kind_of?( MobyUtil::XML::Element )
|
571
|
+
|
572
|
+
if ( test_object_element_attribute( xml_source_iterator, 'type' ) == 'application' )
|
573
|
+
|
574
|
+
return xml_source_iterator
|
575
|
+
|
576
|
+
end
|
577
|
+
|
578
|
+
if xml_source_iterator.kind_of?( MobyUtil::XML::Element )
|
579
|
+
|
580
|
+
xml_source_iterator = xml_source_iterator.parent.parent
|
581
|
+
|
582
|
+
else
|
583
|
+
|
584
|
+
# not found from xml tree
|
585
|
+
break
|
586
|
+
|
587
|
+
end
|
588
|
+
|
589
|
+
end
|
590
|
+
|
591
|
+
#warn("warning: unable to retrieve parent application")
|
592
|
+
|
593
|
+
raise MobyBase::TestObjectNotFoundError, "Unable to retrieve parent application"
|
594
|
+
|
595
|
+
# return application object or nil if no parent found
|
596
|
+
# Does is make sense to return nil - shouldn't all test objects belong to an application? Maybe throw exception if application not found
|
597
|
+
|
598
|
+
#nil
|
599
|
+
|
600
|
+
#return @sut.child( :type => 'application' ) rescue nil
|
601
|
+
|
602
|
+
end
|
603
|
+
|
604
|
+
# TODO: document me
|
605
|
+
def self.get_xml_element_for_test_object( test_object )
|
606
|
+
|
607
|
+
# retrieve nodeset from sut xml_data
|
608
|
+
nodeset = test_object.instance_variable_get( :@sut ).xml_data.xpath( test_object.instance_variable_get( :@x_path ) )
|
609
|
+
|
610
|
+
# raise exception if no test objects found
|
611
|
+
raise MobyBase::TestObjectNotFoundError if nodeset.empty?
|
612
|
+
|
613
|
+
# return first test object from the nodeset
|
614
|
+
nodeset.first
|
615
|
+
|
616
|
+
end
|
617
|
+
|
618
|
+
# TODO: document me
|
619
|
+
def self.get_test_object_identifiers( xml_source, test_object = nil )
|
620
|
+
|
621
|
+
# retrieve parent xpath if test_object given
|
622
|
+
parent_xpath = test_object ? test_object.instance_variable_get( :@parent ).x_path : ""
|
623
|
+
|
624
|
+
# retrieve type attribute
|
625
|
+
type = xml_source.attribute( 'type' )
|
626
|
+
|
627
|
+
# retrieve id attribute
|
628
|
+
id = xml_source.attribute( 'id' )
|
629
|
+
|
630
|
+
# retrieve env attribute
|
631
|
+
env = xml_source.attribute( 'env' )
|
632
|
+
|
633
|
+
# retrieve test object element attributes and return array containting xpath to test object, name, type and id elements
|
634
|
+
[
|
635
|
+
# x_path to test object
|
636
|
+
test_object ? "#{ parent_xpath }/*//object[@type='#{ type }' and @id='#{ id }']" : nil,
|
637
|
+
|
638
|
+
# test object name
|
639
|
+
xml_source.attribute( 'name' ),
|
640
|
+
|
641
|
+
# test object type
|
642
|
+
type,
|
643
|
+
|
644
|
+
# test object id
|
645
|
+
id,
|
646
|
+
|
647
|
+
env
|
648
|
+
|
649
|
+
]
|
650
|
+
|
651
|
+
end
|
652
|
+
|
653
|
+
# TODO: document me
|
654
|
+
def self.hash_to_element_attributes( hash )
|
655
|
+
|
656
|
+
hash.collect{ | key, value |
|
657
|
+
|
658
|
+
"#{ key.to_s }=\"#{ value.to_s }\""
|
659
|
+
|
660
|
+
}.join(' ')
|
661
|
+
|
662
|
+
end
|
663
|
+
|
664
|
+
# TODO: document me
|
665
|
+
def self.merge_application_elements( xml_string )
|
666
|
+
|
667
|
+
# parse the ui state xml
|
668
|
+
document_root = MobyUtil::XML.parse_string( xml_string ).root
|
669
|
+
|
670
|
+
# retrieve application objects as nodeset
|
671
|
+
nodeset = document_root.xpath('/tasMessage/tasInfo/object')
|
672
|
+
|
673
|
+
# check if multiple application objects found
|
674
|
+
if nodeset.count > 1
|
675
|
+
|
676
|
+
# new header, apply original element attributes
|
677
|
+
new_xml = "<tasMessage #{ hash_to_element_attributes( document_root.attributes ) }><tasInfo #{ hash_to_element_attributes( nodeset.first.parent.attributes ) }>"
|
678
|
+
|
679
|
+
# flag defining that is application element already created
|
680
|
+
application_element_set = false
|
681
|
+
|
682
|
+
# collect environment values
|
683
|
+
environments = document_root.xpath('/tasMessage/tasInfo/object[@type="application"]/@env').collect{ | attribute | attribute.to_s }
|
684
|
+
|
685
|
+
#limit to apps
|
686
|
+
nodeset = document_root.xpath('/tasMessage/tasInfo/object[@type="application"]')
|
687
|
+
close_vkb = false
|
688
|
+
if nodeset.count > 0
|
689
|
+
new_xml << create_merged_element(nodeset, environments, false)
|
690
|
+
close_vkb = true
|
691
|
+
end
|
692
|
+
|
693
|
+
# do the same to the vkbs
|
694
|
+
environments = document_root.xpath('/tasMessage/tasInfo/object[@type="vkb_app"]/@env').collect{ | attribute | attribute.to_s }
|
695
|
+
nodeset = document_root.xpath('/tasMessage/tasInfo/object[@type="vkb_app"]')
|
696
|
+
new_xml << create_merged_element(nodeset, environments, close_vkb)
|
697
|
+
|
698
|
+
# multiple applications found, return merged application xml
|
699
|
+
new_xml << "</object></tasInfo></tasMessage>"
|
700
|
+
|
701
|
+
else
|
702
|
+
|
703
|
+
# only one application found, return data as is
|
704
|
+
xml_string
|
705
|
+
|
706
|
+
end
|
707
|
+
|
708
|
+
end
|
709
|
+
|
710
|
+
# TODO: document me
|
711
|
+
def self.list_test_objects_as_string( matches )
|
712
|
+
|
713
|
+
matches.collect{ | object |
|
714
|
+
|
715
|
+
path = [ object.attribute( 'type' ) ]
|
716
|
+
|
717
|
+
while object.attribute( 'type' ) != 'application' do
|
718
|
+
|
719
|
+
# object/objects/object/../..
|
720
|
+
object = object.parent.parent
|
721
|
+
|
722
|
+
path << object.attribute( 'type' )
|
723
|
+
|
724
|
+
end
|
725
|
+
|
726
|
+
path.reverse.join( '.' )
|
727
|
+
|
728
|
+
}.sort
|
729
|
+
|
730
|
+
end
|
731
|
+
|
732
|
+
# enable hooking for performance measurement & debug logging
|
733
|
+
TDriver::Hooking.hook_methods( self ) if defined?( TDriver::Hooking )
|
734
|
+
|
735
|
+
# initialize TDriver::TestObjectAdapter
|
736
|
+
initialize_class
|
737
|
+
|
738
|
+
end # TestObjectAdapter
|
739
|
+
|
740
|
+
end # TDriver
|