summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSunil Thaha <sunil.thaha@nokia.com>2012-08-21 15:11:48 +1000
committerSunil Thaha <sunil.thaha+qt@gmail.com>2012-08-21 07:29:26 +0200
commit8b3982051badc30d387366bea517cbaaf0a44455 (patch)
tree56de6eb123760620910f5360407ee0929224777f
parenteeb6f6284e40dd0182070b11f2e106437a31b7e1 (diff)
QtSystemTest rocks
Initial version of QtSystemTest based on the former QtUiTest Change-Id: I99b72d26dc623ce5e4a665d3dda380b9fe4eef9d Reviewed-by: Shane Bradley <shane.bradley@nokia.com> Reviewed-by: Sunil Thaha <sunil.thaha+qt@gmail.com> Reviewed-by: David Clark <dac@dclark.org.uk>
-rw-r--r--3rdparty/xunit.xsd184
-rw-r--r--QtSystemTester.pro4
-rw-r--r--examples/tutorial/main.cpp53
-rw-r--r--examples/tutorial/tests/01_parts/PartsTest.qml59
-rw-r--r--examples/tutorial/tests/02_validate/ValidateTest.qml55
-rw-r--r--examples/tutorial/tests/03_applicationUnderTest/ApplicationUnderTest.qml75
-rw-r--r--examples/tutorial/tests/04_findItem/FindItemTest.qml70
-rw-r--r--examples/tutorial/tests/04_findItem/TenPinTest.qml70
-rw-r--r--examples/tutorial/tests/05_input/InputTest.qml79
-rw-r--r--examples/tutorial/tests/05_input/TenPinTest.qml70
-rw-r--r--examples/tutorial/tests/06_data/InputTest.qml93
-rw-r--r--examples/tutorial/tests/06_data/InputTests.qml105
-rw-r--r--examples/tutorial/tests/06_data/TenPinTest.qml70
-rw-r--r--examples/tutorial/tpframe.cpp173
-rw-r--r--examples/tutorial/tpframe.h100
-rw-r--r--examples/tutorial/tpframe.ui357
-rw-r--r--examples/tutorial/tpframeball.cpp184
-rw-r--r--examples/tutorial/tpframeball.h102
-rw-r--r--examples/tutorial/tpgame.cpp75
-rw-r--r--examples/tutorial/tpgame.h63
-rw-r--r--examples/tutorial/tutorial.pro18
-rw-r--r--scripts/update_license.pl56
-rwxr-xr-xscripts/update_licenses.sh6
-rw-r--r--src/interpreter/imports/imports.pro3
-rw-r--r--src/interpreter/imports/qtsystemtest/qml/Application.qml162
-rw-r--r--src/interpreter/imports/qtsystemtest/qml/ApplicationObjectsCache.js75
-rw-r--r--src/interpreter/imports/qtsystemtest/qml/Js.qml49
-rw-r--r--src/interpreter/imports/qtsystemtest/qml/Remote.qml168
-rw-r--r--src/interpreter/imports/qtsystemtest/qml/Test.qml68
-rw-r--r--src/interpreter/imports/qtsystemtest/qml/TestCollection.qml80
-rw-r--r--src/interpreter/imports/qtsystemtest/qml/TestItem.qml83
-rw-r--r--src/interpreter/imports/qtsystemtest/qml/TestMethod.qml80
-rw-r--r--src/interpreter/imports/qtsystemtest/qml/itemhandlers/QstObject.qml117
-rw-r--r--src/interpreter/imports/qtsystemtest/qml/itemhandlers/QstWidget.qml49
-rw-r--r--src/interpreter/imports/qtsystemtest/qmldir11
-rw-r--r--src/interpreter/imports/qtsystemtest/qtsystemtest.json1
-rw-r--r--src/interpreter/imports/qtsystemtest/qtsystemtest.pro74
-rw-r--r--src/interpreter/imports/qtsystemtest/scripts/ApplicationRegistry.js68
-rw-r--r--src/interpreter/imports/qtsystemtest/scripts/Class.js121
-rw-r--r--src/interpreter/imports/qtsystemtest/scripts/ComponentCacher.js147
-rw-r--r--src/interpreter/imports/qtsystemtest/scripts/Console.js128
-rw-r--r--src/interpreter/imports/qtsystemtest/scripts/Datatype.js142
-rw-r--r--src/interpreter/imports/qtsystemtest/scripts/Exception.js105
-rw-r--r--src/interpreter/imports/qtsystemtest/scripts/Expect.js112
-rw-r--r--src/interpreter/imports/qtsystemtest/scripts/Functional.js298
-rw-r--r--src/interpreter/imports/qtsystemtest/scripts/ItemFactory.js117
-rw-r--r--src/interpreter/imports/qtsystemtest/scripts/JsCore.js215
-rw-r--r--src/interpreter/imports/qtsystemtest/scripts/QstCore.js52
-rw-r--r--src/interpreter/imports/qtsystemtest/scripts/SourceBuilder.js172
-rw-r--r--src/interpreter/imports/qtsystemtest/scripts/api.js56
-rw-r--r--src/interpreter/imports/qtsystemtest/src/imports.cpp66
-rw-r--r--src/interpreter/imports/qtsystemtest/src/imports.h58
-rw-r--r--src/interpreter/imports/qtsystemtest/src/qstcoreapi.cpp56
-rw-r--r--src/interpreter/imports/qtsystemtest/src/qstcoreapi.h71
-rw-r--r--src/interpreter/imports/qtsystemtest/src/qstlocalprocess.cpp167
-rw-r--r--src/interpreter/imports/qtsystemtest/src/qstlocalprocess.h131
-rw-r--r--src/interpreter/imports/qtsystemtest/src/qstutils.cpp50
-rw-r--r--src/interpreter/imports/qtsystemtest/src/qstutils.h61
-rw-r--r--src/interpreter/imports/qtsystemtest/src/qtuitestglobal.h84
-rw-r--r--src/interpreter/imports/runner/qml/Config.qml58
-rw-r--r--src/interpreter/imports/runner/qml/Logger.qml101
-rw-r--r--src/interpreter/imports/runner/qml/PlainTextLogger.qml162
-rw-r--r--src/interpreter/imports/runner/qml/XUnitLogger.qml172
-rw-r--r--src/interpreter/imports/runner/qml/XmlLogger.qml178
-rw-r--r--src/interpreter/imports/runner/qmldir7
-rw-r--r--src/interpreter/imports/runner/qtsystemtestrunner.json1
-rw-r--r--src/interpreter/imports/runner/runner.pro70
-rw-r--r--src/interpreter/imports/runner/src/imports.cpp60
-rw-r--r--src/interpreter/imports/runner/src/imports.h58
-rw-r--r--src/interpreter/imports/runner/src/qstlogwriter.cpp166
-rw-r--r--src/interpreter/imports/runner/src/qstlogwriter.h212
-rw-r--r--src/interpreter/imports/runner/src/qstxunitwriter.cpp189
-rw-r--r--src/interpreter/imports/runner/src/qstxunitwriter.h92
-rw-r--r--src/interpreter/interpreter.pro4
-rw-r--r--src/interpreter/runner/main.cpp66
-rw-r--r--src/interpreter/runner/qstjsengine.cpp49
-rw-r--r--src/interpreter/runner/qstjsengine.h59
-rw-r--r--src/interpreter/runner/qstrunnerbootstrap.cpp229
-rw-r--r--src/interpreter/runner/qstrunnerbootstrap.h81
-rw-r--r--src/interpreter/runner/qstrunnercore.cpp102
-rw-r--r--src/interpreter/runner/qstrunnercore.h71
-rw-r--r--src/interpreter/runner/runner.pro30
-rw-r--r--src/interpreter/runner/scripts/QstRunner.js358
-rw-r--r--src/interpreter/runner/scripts/QstRunner.qml138
-rw-r--r--src/objectBrowser/main.cpp104
-rw-r--r--src/objectBrowser/objectBrowser.pro20
-rw-r--r--src/objectBrowser/qtestbrowserdlg.cpp1139
-rw-r--r--src/objectBrowser/qtestbrowserdlg_p.h210
-rw-r--r--src/protocol/QstConnection42
-rw-r--r--src/protocol/QstConnectionManager42
-rw-r--r--src/protocol/QstDebug42
-rw-r--r--src/protocol/QstProtocol42
-rw-r--r--src/protocol/protocol.pro45
-rw-r--r--src/protocol/qstconnection.cpp263
-rw-r--r--src/protocol/qstconnection.h108
-rw-r--r--src/protocol/qstconnectionmanager.cpp59
-rw-r--r--src/protocol/qstconnectionmanager.h66
-rw-r--r--src/protocol/qstdebug.h52
-rw-r--r--src/protocol/qstglobal.h84
-rw-r--r--src/protocol/qstprotocol.cpp1086
-rw-r--r--src/protocol/qstprotocol.h216
-rw-r--r--src/remote/daemon/appmanager.cpp429
-rw-r--r--src/remote/daemon/appmanager.h141
-rw-r--r--src/remote/daemon/daemon.pro29
-rw-r--r--src/remote/daemon/main.cpp55
-rw-r--r--src/remote/daemon/qtuitest_debug.h47
-rw-r--r--src/remote/daemon/qtuitestd.pro51
-rw-r--r--src/remote/daemon/qtuitestdsettings.cpp183
-rw-r--r--src/remote/daemon/qtuitestdsettings.h80
-rw-r--r--src/remote/daemon/qtuitestmaster.cpp98
-rw-r--r--src/remote/daemon/qtuitestmaster_p.h78
-rw-r--r--src/remote/daemon/qtuitestserver.cpp102
-rw-r--r--src/remote/daemon/qtuitestserver.h73
-rw-r--r--src/remote/daemon/qtuitestslave.cpp600
-rw-r--r--src/remote/daemon/qtuitestslave.h71
-rw-r--r--src/remote/remote.pri15
-rw-r--r--src/remote/remote.pro2
-rw-r--r--src/remote/slave/lib/lib.pro93
-rw-r--r--src/remote/slave/lib/qasciikey.cpp526
-rw-r--r--src/remote/slave/lib/qeventwatcher.cpp121
-rw-r--r--src/remote/slave/lib/qeventwatcher_p.h101
-rw-r--r--src/remote/slave/lib/qinputgenerator.cpp93
-rw-r--r--src/remote/slave/lib/qinputgenerator_generic.cpp192
-rw-r--r--src/remote/slave/lib/qinputgenerator_generic_p.h236
-rw-r--r--src/remote/slave/lib/qinputgenerator_p.h95
-rw-r--r--src/remote/slave/lib/qinputgenerator_qwindow.cpp193
-rw-r--r--src/remote/slave/lib/qinputgenerator_qwindow_p.h288
-rw-r--r--src/remote/slave/lib/qsensorgenerator.cpp355
-rw-r--r--src/remote/slave/lib/qsensorgenerator_p.h187
-rw-r--r--src/remote/slave/lib/qtestslave.cpp1678
-rw-r--r--src/remote/slave/lib/qtestslave.h103
-rw-r--r--src/remote/slave/lib/qtestwidgets.cpp623
-rw-r--r--src/remote/slave/lib/qtestwidgets.h158
-rw-r--r--src/remote/slave/lib/qtuitestconnectionmanager.cpp180
-rw-r--r--src/remote/slave/lib/qtuitestconnectionmanager_p.h87
-rw-r--r--src/remote/slave/lib/qtuitestmessagehandler.h65
-rw-r--r--src/remote/slave/lib/qtuitestnamespace.cpp1038
-rw-r--r--src/remote/slave/lib/qtuitestnamespace.h172
-rw-r--r--src/remote/slave/lib/qtuitestwidgetinterface.cpp398
-rw-r--r--src/remote/slave/lib/qtuitestwidgetinterface.h133
-rw-r--r--src/remote/slave/lib/qtuitestwidgets.cpp648
-rw-r--r--src/remote/slave/lib/qtuitestwidgets_p.h126
-rw-r--r--src/remote/slave/lib/testapplication.cpp68
-rw-r--r--src/remote/slave/lib/testapplication.h69
-rw-r--r--src/remote/slave/lib/testobject.cpp110
-rw-r--r--src/remote/slave/lib/testobject.h75
-rw-r--r--src/remote/slave/lib/testquickfactory.cpp97
-rw-r--r--src/remote/slave/lib/testquickfactory.h63
-rw-r--r--src/remote/slave/lib/testquickitem.cpp268
-rw-r--r--src/remote/slave/lib/testquickitem.h92
-rw-r--r--src/remote/slave/lib/testquickobject.cpp259
-rw-r--r--src/remote/slave/lib/testquickobject.h89
-rw-r--r--src/remote/slave/lib/testquickview.cpp130
-rw-r--r--src/remote/slave/lib/testquickview.h78
-rw-r--r--src/remote/slave/lib/testslaveserver.cpp222
-rw-r--r--src/remote/slave/lib/testslaveserver.h73
-rw-r--r--src/remote/slave/lib/testwidget.cpp179
-rw-r--r--src/remote/slave/lib/testwidget.h91
-rw-r--r--src/remote/slave/lib/testwindow.cpp142
-rw-r--r--src/remote/slave/lib/testwindow.h80
-rw-r--r--src/remote/slave/slave.pro3
-rw-r--r--src/remote/slave/styleplugin/qtuiteststyleplugin.cpp117
-rw-r--r--src/remote/slave/styleplugin/styleplugin.pro18
-rw-r--r--src/src.pro13
-rw-r--r--src/testapp/main.cpp52
-rw-r--r--src/testapp/mainwindow.cpp154
-rw-r--r--src/testapp/mainwindow.h75
-rw-r--r--src/testapp/mainwindow.ui291
-rw-r--r--src/testapp/testapp.pro10
-rw-r--r--tests/AllTests.qml53
-rw-r--r--tests/InterpreterTests.qml53
-rw-r--r--tests/MyConfig.qml53
-rw-r--r--tests/RemoteTests.qml56
-rw-r--r--tests/interpreter/CoreTests.qml66
-rw-r--r--tests/interpreter/RunnerTests.qml58
-rw-r--r--tests/interpreter/core/ApplicationRegistryTests.qml52
-rw-r--r--tests/interpreter/core/ClassTest.qml135
-rw-r--r--tests/interpreter/core/ExpectApiTests.qml57
-rw-r--r--tests/interpreter/core/FailApiTest.qml77
-rw-r--r--tests/interpreter/core/ItemHandlerTests.qml52
-rw-r--r--tests/interpreter/core/LocalProcessTest.qml64
-rw-r--r--tests/interpreter/core/SleepTest.qml55
-rw-r--r--tests/interpreter/core/application/CustomApplicationTest.qml79
-rw-r--r--tests/interpreter/core/application/DefaultApplicationTest.qml83
-rw-r--r--tests/interpreter/core/application/MyApplication.js48
-rw-r--r--tests/interpreter/core/application/MyApplication.qml50
-rw-r--r--tests/interpreter/core/application/RegisterUnregisterAppTest.qml96
-rw-r--r--tests/interpreter/core/itemhandlers/CustomItemHandlerTest.qml76
-rw-r--r--tests/interpreter/core/itemhandlers/DefaultItemHandlerTest.qml68
-rw-r--r--tests/interpreter/core/itemhandlers/QstPushButton.qml52
-rw-r--r--tests/interpreter/core/itemhandlers/RegisterUnregisterHandlerTest.qml83
-rw-r--r--tests/interpreter/loggers/data/ExpectTests.qml86
-rw-r--r--tests/interpreter/loggers/data/FailTest.qml52
-rw-r--r--tests/interpreter/loggers/data/PassTest.qml51
-rw-r--r--tests/interpreter/loggers/data/SkipTest.qml53
-rw-r--r--tests/interpreter/loggers/data/SubTests.qml52
-rw-r--r--tests/interpreter/loggers/data/Tests.qml57
-rw-r--r--tests/interpreter/loggers/data/qsystemtest.xsd228
-rw-r--r--tests/interpreter/runner/DefaultConfigTest.qml53
-rw-r--r--tests/interpreter/runner/EmptyTest.qml51
-rw-r--r--tests/interpreter/runner/EmptyTests.qml54
-rw-r--r--tests/interpreter/runner/FailTest.qml71
-rw-r--r--tests/interpreter/runner/MyUtils.js48
-rw-r--r--tests/interpreter/runner/RunnerInternals.js63
-rw-r--r--tests/interpreter/runner/SkipTest.qml72
-rw-r--r--tests/interpreter/runner/UntestedTest.qml90
-rw-r--r--tests/interpreter/runner/UntestedTests.qml99
-rw-r--r--tests/remote/AssistantTest.qml76
-rw-r--r--tests/remote/QstObjectApiTests.qml54
-rw-r--r--tests/remote/RemoteApiTests.qml61
-rw-r--r--tests/remote/RunProcessTests.qml51
-rw-r--r--tests/remote/TestAppWidgetTest.qml68
-rw-r--r--tests/remote/common/ApplicationTest.qml68
-rw-r--r--tests/remote/qstobject/InheritanceBasedItemHandlerTest.qml75
-rw-r--r--tests/remote/qstobject/ItemPropertyTest.qml60
-rw-r--r--tests/remote/qstobject/MyQLineEdit.qml49
-rw-r--r--tests/remote/qstobject/ParentApiTest.qml62
-rw-r--r--tests/remote/qstobject/QstObjectApiTests.qml63
-rw-r--r--tests/remote/runProcess/RunCommandTest.qml61
-rw-r--r--tests/tests.pro31
220 files changed, 28237 insertions, 0 deletions
diff --git a/3rdparty/xunit.xsd b/3rdparty/xunit.xsd
new file mode 100644
index 0000000..e71c456
--- /dev/null
+++ b/3rdparty/xunit.xsd
@@ -0,0 +1,184 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ elementFormDefault="qualified"
+ attributeFormDefault="unqualified">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">Jenkins xUnit test result schema.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:element name="testsuite" type="testsuite"/>
+ <xs:simpleType name="ISO8601_DATETIME_PATTERN">
+ <xs:restriction base="xs:dateTime">
+ <xs:pattern value="[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:element name="testsuites">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">Contains an aggregation of testsuite results</xs:documentation>
+ </xs:annotation>
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="testsuite" minOccurs="0" maxOccurs="unbounded">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:extension base="testsuite">
+ <xs:attribute name="package" type="xs:token" use="required">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">Derived from testsuite/@name in the non-aggregated documents</xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="id" type="xs:int" use="required">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">Starts at '0' for the first testsuite and is incremented by 1 for each following testsuite</xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:complexType name="testsuite">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">Contains the results of exexuting a testsuite</xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="testcase" minOccurs="0" maxOccurs="unbounded">
+ <xs:complexType>
+ <xs:choice minOccurs="0">
+ <xs:element name="error">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">Indicates that the test errored. An errored test is one that had an unanticipated problem. e.g., an unchecked throwable; or a problem with the implementation of the test. Contains as a text node relevant data for the error, e.g., a stack trace</xs:documentation>
+ </xs:annotation>
+ <xs:complexType>
+ <xs:simpleContent>
+ <xs:extension base="pre-string">
+ <xs:attribute name="message" type="xs:string">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">The error message. e.g., if a java exception is thrown, the return value of getMessage()</xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="type" type="xs:string" use="required">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">The type of error that occured. e.g., if a java execption is thrown the full class name of the exception.</xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="failure">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">Indicates that the test failed. A failure is a test which the code has explicitly failed by using the mechanisms for that purpose. e.g., via an assertEquals. Contains as a text node relevant data for the failure, e.g., a stack trace</xs:documentation>
+ </xs:annotation>
+ <xs:complexType>
+ <xs:simpleContent>
+ <xs:extension base="pre-string">
+ <xs:attribute name="message" type="xs:string">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">The message specified in the assert</xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="type" type="xs:string" use="required">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">The type of the assert.</xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="skipped">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">Indicates that the test was skipped. A skipped test is a test which was ignored using framework mechanisms. e.g., @Ignore annotation.</xs:documentation>
+ </xs:annotation>
+ <xs:complexType>
+ <xs:simpleContent>
+ <xs:extension base="pre-string">
+ <xs:attribute name="type" type="xs:string" use="required">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">Skip type.</xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+ </xs:element>
+ </xs:choice>
+ <xs:attribute name="name" type="xs:token" use="required">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">Name of the test method</xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="classname" type="xs:token" use="required">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">Full class name for the class the test method is in.</xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="time" type="xs:decimal" use="required">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">Time taken (in seconds) to execute the test</xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ <xs:attribute name="name" use="required">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">Full class name of the test for non-aggregated testsuite documents. Class name without the package for aggregated testsuites documents</xs:documentation>
+ </xs:annotation>
+ <xs:simpleType>
+ <xs:restriction base="xs:token">
+ <xs:minLength value="1"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+ <xs:attribute name="timestamp" type="ISO8601_DATETIME_PATTERN" use="required">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">when the test was executed. Timezone may not be specified.</xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="hostname" use="required">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">Host on which the tests were executed. 'localhost' should be used if the hostname cannot be determined.</xs:documentation>
+ </xs:annotation>
+ <xs:simpleType>
+ <xs:restriction base="xs:token">
+ <xs:minLength value="1"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+ <xs:attribute name="tests" type="xs:int" use="required">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">The total number of tests in the suite</xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="failures" type="xs:int" use="required">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">The total number of tests in the suite that failed. A failure is a test which the code has explicitly failed by using the mechanisms for that purpose. e.g., via an assertEquals</xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="errors" type="xs:int" use="required">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">The total number of tests in the suite that errored. An errored test is one that had an unanticipated problem. e.g., an unchecked throwable; or a problem with the implementation of the test.</xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="skipped" type="xs:int">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">The total number of tests in the suite that skipped. A skipped test is a test which was ignored using framework mechanisms. e.g., @Ignore annotation.</xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="time" type="xs:decimal" use="required">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">Time taken (in seconds) to execute the tests in the suite</xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:complexType>
+ <xs:simpleType name="pre-string">
+ <xs:restriction base="xs:string">
+ <xs:whiteSpace value="preserve"/>
+ </xs:restriction>
+ </xs:simpleType>
+</xs:schema> \ No newline at end of file
diff --git a/QtSystemTester.pro b/QtSystemTester.pro
new file mode 100644
index 0000000..c427252
--- /dev/null
+++ b/QtSystemTester.pro
@@ -0,0 +1,4 @@
+TEMPLATE = subdirs
+CONFIG += ordered
+
+SUBDIRS = src tests
diff --git a/examples/tutorial/main.cpp b/examples/tutorial/main.cpp
new file mode 100644
index 0000000..b7928ae
--- /dev/null
+++ b/examples/tutorial/main.cpp
@@ -0,0 +1,53 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QApplication>
+#include "tpgame.h"
+
+int main(int argc, char *argv[])
+{
+ QApplication a(argc, argv);
+ a.setApplicationName("tenpinGame");
+ TPGame w;
+ w.show();
+
+ return a.exec();
+}
diff --git a/examples/tutorial/tests/01_parts/PartsTest.qml b/examples/tutorial/tests/01_parts/PartsTest.qml
new file mode 100644
index 0000000..7570353
--- /dev/null
+++ b/examples/tutorial/tests/01_parts/PartsTest.qml
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtSystemTest 1.0
+
+Test {
+ name: 'Parts'
+ description: 'Demonstrates parts of a test object'
+
+ function setup() {
+ print( "Init test function." );
+ }
+
+ function run() {
+ print( "Hello World!" );
+ }
+
+ function cleanup() {
+ print( "Finalize test function." );
+ }
+}
diff --git a/examples/tutorial/tests/02_validate/ValidateTest.qml b/examples/tutorial/tests/02_validate/ValidateTest.qml
new file mode 100644
index 0000000..f701dcc
--- /dev/null
+++ b/examples/tutorial/tests/02_validate/ValidateTest.qml
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtSystemTest 1.0
+
+Test {
+ name: 'Validate'
+ description: 'Demonstrates validating values'
+
+ function run() {
+ var count = 3;
+
+ expect(count).toBe(3);
+ expect(count).not.toBe(2);
+ expect(count).toBeBetween(2, 4);
+ }
+}
diff --git a/examples/tutorial/tests/03_applicationUnderTest/ApplicationUnderTest.qml b/examples/tutorial/tests/03_applicationUnderTest/ApplicationUnderTest.qml
new file mode 100644
index 0000000..e1d6150
--- /dev/null
+++ b/examples/tutorial/tests/03_applicationUnderTest/ApplicationUnderTest.qml
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.1
+import QtSystemTest 1.0
+
+Test {
+ name: 'Start Application'
+ description: 'Start an existing application'
+
+ property string executableName: 'tenpinGame'
+ property Application app
+ property alias remote: host
+
+ remotes: [
+ Remote {
+ id: host
+ host: config.remotes.localhost.address
+ }
+ ]
+
+ function setup() {
+ expect(executableName).not.toBe('');
+ app = host.startApplication(executableName);
+ }
+
+ function run() {
+ var game = app.item({
+ inherits: 'TPGame'
+ });
+ expect(game).not.toBe(undefined);
+ }
+
+ function cleanup() {
+ app.terminate();
+ }
+}
diff --git a/examples/tutorial/tests/04_findItem/FindItemTest.qml b/examples/tutorial/tests/04_findItem/FindItemTest.qml
new file mode 100644
index 0000000..505b753
--- /dev/null
+++ b/examples/tutorial/tests/04_findItem/FindItemTest.qml
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.1
+import QtSystemTest 1.0
+
+TenPinTest {
+ function data() {}
+
+ function setup() {
+ startApplication();
+
+ data.main = app.items({inherits: 'TPFrame'})[0];
+ expect(data.main).not.toBe(null);
+ expect(data.main).not.toBe(undefined);
+
+ data.first = data.main.descendants({inherits: 'TPFrameBall'})[0];
+ expect(data.first).not.toBe(null);
+ data.second = data.main.descendants({inherits: 'TPFrameBall'})[1];
+ expect(data.second).not.toBe(null);
+ }
+
+ function run() {
+ expect(data.main.property('display')).toBe('');
+ expect(data.first.property('display')).toBe('');
+ expect(data.second.property('display')).toBe('');
+ }
+
+ function cleanup() {
+ terminateApplication();
+ }
+}
diff --git a/examples/tutorial/tests/04_findItem/TenPinTest.qml b/examples/tutorial/tests/04_findItem/TenPinTest.qml
new file mode 100644
index 0000000..961321d
--- /dev/null
+++ b/examples/tutorial/tests/04_findItem/TenPinTest.qml
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.1
+import QtSystemTest 1.0
+
+Test {
+ name: 'Start Application'
+ description: 'Start an existing application'
+
+ property string executableName: 'tenpinGame'
+ property alias remote: host
+
+ property Application app
+
+ remotes: [
+ Remote {
+ id: host
+ host: config.remotes.localhost.address
+ }
+ ]
+
+ function startApplication() {
+ expect(executableName).not.toBe('');
+ app = host.startApplication(executableName);
+ expect(app).not.toBe(null);
+ }
+
+ function terminateApplication() {
+ app.terminate();
+ }
+}
diff --git a/examples/tutorial/tests/05_input/InputTest.qml b/examples/tutorial/tests/05_input/InputTest.qml
new file mode 100644
index 0000000..ddfabd1
--- /dev/null
+++ b/examples/tutorial/tests/05_input/InputTest.qml
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.1
+import QtSystemTest 1.0
+
+TenPinTest {
+ function data() {}
+
+ function setup() {
+ startApplication();
+
+ data.main = app.items({inherits: 'TPFrame'})[0];
+ expect(data.main).not.toBe(null);
+ expect(data.main).not.toBe(undefined);
+
+ data.first = data.main.descendants({inherits: 'TPFrameBall'})[0];
+ expect(data.first).not.toBe(null);
+ data.second = data.main.descendants({inherits: 'TPFrameBall'})[1];
+ expect(data.second).not.toBe(null);
+ }
+
+ function run() {
+ expect(data.first.property('display')).toBe('');
+ expect(data.second.property('display')).toBe('');
+ expect(data.main.property('display')).toBe('');
+
+ app.mouseClick(data.first);
+ app.keyPress(Qt.Key_3);
+ app.mouseClick(data.second);
+ app.keyPress(Qt.Key_6);
+
+ expect(data.first.property('display')).toBe('3');
+ expect(data.second.property('display')).toBe('6');
+ expect(data.main.property('display')).toBe('9');
+ }
+
+ function cleanup() {
+ terminateApplication();
+ }
+}
diff --git a/examples/tutorial/tests/05_input/TenPinTest.qml b/examples/tutorial/tests/05_input/TenPinTest.qml
new file mode 100644
index 0000000..961321d
--- /dev/null
+++ b/examples/tutorial/tests/05_input/TenPinTest.qml
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.1
+import QtSystemTest 1.0
+
+Test {
+ name: 'Start Application'
+ description: 'Start an existing application'
+
+ property string executableName: 'tenpinGame'
+ property alias remote: host
+
+ property Application app
+
+ remotes: [
+ Remote {
+ id: host
+ host: config.remotes.localhost.address
+ }
+ ]
+
+ function startApplication() {
+ expect(executableName).not.toBe('');
+ app = host.startApplication(executableName);
+ expect(app).not.toBe(null);
+ }
+
+ function terminateApplication() {
+ app.terminate();
+ }
+}
diff --git a/examples/tutorial/tests/06_data/InputTest.qml b/examples/tutorial/tests/06_data/InputTest.qml
new file mode 100644
index 0000000..1b6610f
--- /dev/null
+++ b/examples/tutorial/tests/06_data/InputTest.qml
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.1
+import QtSystemTest 1.0
+
+TenPinTest {
+ name: 'Input Test'
+ description: 'Add some ball values and validate displays'
+
+ property variant firstEntry: ['3']
+ property variant secondEntry: ['6']
+
+ property string first: '3'
+ property string second: '6'
+ property string display: '9'
+
+ function data() {}
+
+ function setup() {
+ startApplication();
+
+ data.main = app.items({inherits: 'TPFrame'})[0];
+ expect(data.main).not.toBe(null);
+ expect(data.main).not.toBe(undefined);
+
+ data.first = data.main.descendants({inherits: 'TPFrameBall'})[0];
+ expect(data.first).not.toBe(null);
+ data.second = data.main.descendants({inherits: 'TPFrameBall'})[1];
+ expect(data.second).not.toBe(null);
+ }
+
+ function run() {
+ expect(data.first.property('display')).toBe('');
+ expect(data.second.property('display')).toBe('');
+ expect(data.main.property('display')).toBe('');
+
+ app.mouseClick(data.first);
+ firstEntry.forEach(function(item) {
+ app.keyPress(item);
+ });
+ app.mouseClick(data.second);
+ secondEntry.forEach(function(item) {
+ app.keyPress(item);
+ });
+
+ expect(data.first.property('display')).toBe(first);
+ expect(data.second.property('display')).toBe(second);
+ expect(data.main.property('display')).toBe(display);
+ }
+
+ function cleanup() {
+ terminateApplication();
+ }
+}
diff --git a/examples/tutorial/tests/06_data/InputTests.qml b/examples/tutorial/tests/06_data/InputTests.qml
new file mode 100644
index 0000000..d76a8a2
--- /dev/null
+++ b/examples/tutorial/tests/06_data/InputTests.qml
@@ -0,0 +1,105 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtSystemTest 1.0
+
+TestCollection {
+ name: 'Input test collection'
+ description: 'enter various values for first frame and validate display'
+
+ InputTest {
+ name: 'Gutter Ball'
+ firstEntry: ['0']
+ secondEntry: ['0']
+
+ first: '0'
+ second: '0'
+ display: '0'
+ }
+ InputTest {
+ name: 'Strike'
+
+ firstEntry: ['1', '0']
+ secondEntry: []
+
+ first: 'X'
+ second: ''
+ display: ''
+ }
+ InputTest {
+ name: 'Three Seven Spare'
+
+ firstEntry: ['3']
+ secondEntry: ['7']
+
+ first: '3'
+ second: '/'
+ display: ''
+ }
+ InputTest {
+ name: 'Three Zero'
+ firstEntry: ['3']
+ secondEntry: ['0']
+
+ first: '3'
+ second: '0'
+ display: '3'
+ }
+ InputTest {
+ name: 'Zero Ten Spare'
+
+ firstEntry: ['0']
+ secondEntry: ['1', '0']
+
+ first: '0'
+ second: '/'
+ display: ''
+ }
+ InputTest {
+ name: 'Zero Three'
+ firstEntry: ['0']
+ secondEntry: ['3']
+
+ first: '0'
+ second: '3'
+ display: '3'
+ }
+}
diff --git a/examples/tutorial/tests/06_data/TenPinTest.qml b/examples/tutorial/tests/06_data/TenPinTest.qml
new file mode 100644
index 0000000..961321d
--- /dev/null
+++ b/examples/tutorial/tests/06_data/TenPinTest.qml
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.1
+import QtSystemTest 1.0
+
+Test {
+ name: 'Start Application'
+ description: 'Start an existing application'
+
+ property string executableName: 'tenpinGame'
+ property alias remote: host
+
+ property Application app
+
+ remotes: [
+ Remote {
+ id: host
+ host: config.remotes.localhost.address
+ }
+ ]
+
+ function startApplication() {
+ expect(executableName).not.toBe('');
+ app = host.startApplication(executableName);
+ expect(app).not.toBe(null);
+ }
+
+ function terminateApplication() {
+ app.terminate();
+ }
+}
diff --git a/examples/tutorial/tpframe.cpp b/examples/tutorial/tpframe.cpp
new file mode 100644
index 0000000..bd71d0a
--- /dev/null
+++ b/examples/tutorial/tpframe.cpp
@@ -0,0 +1,173 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "tpframe.h"
+#include "ui_tpframe.h"
+
+#include <QDebug>
+
+TPFrame::TPFrame(QWidget *parent) :
+ QFrame(parent),
+ ui(new Ui::TPFrame),
+ m_previous(0),
+ m_next(0),
+ m_score(-1)
+{
+ ui->setupUi(this);
+ connect(ui->firstBall, SIGNAL(ballChanged(int)), ui->secondBall, SLOT(setPreviousBall(int)));
+
+ connect(ui->firstBall, SIGNAL(scoreChanged(int)), this, SIGNAL(ballsChanged()));
+ connect(ui->secondBall, SIGNAL(scoreChanged(int)), this, SIGNAL(ballsChanged()));
+ connect(ui->thirdBall, SIGNAL(scoreChanged(int)), this, SIGNAL(ballsChanged()));
+
+ connect(this, SIGNAL(ballsChanged()), this, SLOT(updateScore()));
+}
+
+TPFrame::~TPFrame()
+{
+ delete ui;
+}
+
+int TPFrame::first() const
+{
+ return ui->firstBall->ball();
+}
+
+int TPFrame::second() const
+{
+ if (m_next)
+ return ui->firstBall->isStrike() ? m_next->first() : ui->secondBall->ball();
+ return ui->secondBall->ball();
+}
+
+int TPFrame::third() const
+{
+ if (m_next)
+ return ui->firstBall->isStrike() ? m_next->second() : m_next->first();
+ return ui->thirdBall->ball();
+}
+
+int TPFrame::runningTotal() const
+{
+ if (m_previous) {
+ int prevTotal = m_previous->runningTotal();
+ if (prevTotal != -1 && m_score != -1)
+ return prevTotal + m_score;
+ return -1;
+ }
+ return m_score;
+}
+
+void TPFrame::setPreviousFrame(TPFrame *frame)
+{
+ if (m_previous)
+ disconnect(m_previous, 0, this, 0);
+
+ m_previous = frame;
+
+ if (m_previous) {
+ connect(m_previous, SIGNAL(runningTotalChanged(int)), this, SLOT(updateTotal()));
+ updateTotal();
+ }
+}
+
+void TPFrame::setNextFrame(TPFrame *frame)
+{
+ if (m_next)
+ disconnect(m_next, 0, this, 0);
+
+ m_next = frame;
+
+ if (m_next) {
+ ui->firstBall->setLastFrame(false);
+ ui->secondBall->setLastFrame(false);
+ ui->thirdBall->setLastFrame(false);
+ ui->thirdBall->hide();
+ connect(m_next, SIGNAL(ballsChanged()), this, SIGNAL(ballsChanged()));
+ } else {
+ ui->firstBall->setLastFrame(true);
+ ui->secondBall->setLastFrame(true);
+ ui->thirdBall->setLastFrame(true);
+ ui->thirdBall->show();
+ }
+}
+
+void TPFrame::reset()
+{
+ ui->firstBall->setBall(-1);
+ ui->secondBall->setBall(-1);
+ ui->thirdBall->setBall(-1);
+}
+
+void TPFrame::updateScore()
+{
+ int score = -1;
+ int f = first();
+ int s = second();
+ int t = third();
+ if (ui->firstBall->isStrike()) {
+ if (s != -1 && t != -1)
+ score = 10 + s + t;
+ } else if (ui->secondBall->isSpare()) {
+ if (t != -1)
+ score = 10 + t;
+ } else {
+ if (f != -1 && s != -1)
+ score = f + s;
+ }
+ if (score == m_score)
+ return;
+ m_score = score;
+ emit scoreChanged(m_score);
+ updateTotal();
+}
+
+void TPFrame::updateTotal()
+{
+ int total = runningTotal();
+ emit runningTotalChanged(total);
+ ui->frameDisplay->setText(total == -1 ? QString() : QString::number(total));
+}
+
+QString TPFrame::display() const
+{
+ return ui->frameDisplay->text();
+}
diff --git a/examples/tutorial/tpframe.h b/examples/tutorial/tpframe.h
new file mode 100644
index 0000000..e0416ba
--- /dev/null
+++ b/examples/tutorial/tpframe.h
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TPFRAME_H
+#define TPFRAME_H
+
+#include <QFrame>
+
+namespace Ui {
+class TPFrame;
+}
+
+class TPFrame : public QFrame
+{
+ Q_OBJECT
+ Q_PROPERTY(int first READ first DESIGNABLE false STORED false)
+ Q_PROPERTY(int second READ second DESIGNABLE false STORED false)
+ Q_PROPERTY(int third READ third DESIGNABLE false STORED false)
+ Q_PROPERTY(int score READ score NOTIFY scoreChanged DESIGNABLE false STORED false)
+ Q_PROPERTY(QString display READ display DESIGNABLE false STORED false)
+ Q_PROPERTY(int runningTotal READ runningTotal NOTIFY runningTotalChanged DESIGNABLE false STORED false)
+
+ Q_PROPERTY(TPFrame *previousFrame READ previousFrame WRITE setPreviousFrame DESIGNABLE false STORED false)
+ Q_PROPERTY(TPFrame *nextFrame READ nextFrame WRITE setNextFrame DESIGNABLE false STORED false)
+
+public:
+ explicit TPFrame(QWidget *parent = 0);
+ ~TPFrame();
+
+ int first() const;
+ int second() const;
+ int third() const;
+ int score() const { return m_score; }
+ int runningTotal() const;
+ QString display() const;
+
+ TPFrame *previousFrame() const { return m_previous; }
+ TPFrame *nextFrame() const { return m_next; }
+
+ void setPreviousFrame(TPFrame *);
+ void setNextFrame(TPFrame *);
+
+public slots:
+ void reset();
+
+signals:
+ void runningTotalChanged(int);
+ void scoreChanged(int);
+ void ballsChanged();
+
+private slots:
+ void updateScore();
+ void updateTotal();
+
+private:
+ Ui::TPFrame *ui;
+ TPFrame *m_previous;
+ TPFrame *m_next;
+ int m_score;
+};
+
+#endif // TPFRAME_H
diff --git a/examples/tutorial/tpframe.ui b/examples/tutorial/tpframe.ui
new file mode 100644
index 0000000..6795608
--- /dev/null
+++ b/examples/tutorial/tpframe.ui
@@ -0,0 +1,357 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>TPFrame</class>
+ <widget class="QFrame" name="TPFrame">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>300</height>
+ </rect>
+ </property>
+ <property name="palette">
+ <palette>
+ <active>
+ <colorrole role="WindowText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>170</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Button">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Mid">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Text">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>170</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Base">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Window">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </active>
+ <inactive>
+ <colorrole role="WindowText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>170</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Button">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Mid">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Text">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>170</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Base">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Window">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </inactive>
+ <disabled>
+ <colorrole role="WindowText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>20</red>
+ <green>19</green>
+ <blue>18</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Button">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Mid">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Text">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>20</red>
+ <green>19</green>
+ <blue>18</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Base">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Window">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </disabled>
+ </palette>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <property name="autoFillBackground">
+ <bool>true</bool>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::Box</enum>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="horizontalSpacing">
+ <number>0</number>
+ </property>
+ <item row="0" column="0">
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>56</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="0" column="2">
+ <widget class="TPFrameBall" name="secondBall" native="true">
+ <property name="minimumSize">
+ <size>
+ <width>50</width>
+ <height>50</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>50</width>
+ <height>50</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="TPFrameBall" name="firstBall" native="true">
+ <property name="minimumSize">
+ <size>
+ <width>50</width>
+ <height>50</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>50</width>
+ <height>50</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="3">
+ <widget class="TPFrameBall" name="thirdBall" native="true">
+ <property name="minimumSize">
+ <size>
+ <width>50</width>
+ <height>50</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>50</width>
+ <height>50</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" colspan="3">
+ <widget class="QLabel" name="frameDisplay">
+ <property name="palette">
+ <palette>
+ <active>
+ <colorrole role="WindowText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Text">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </active>
+ <inactive>
+ <colorrole role="WindowText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Text">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </inactive>
+ <disabled>
+ <colorrole role="WindowText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>20</red>
+ <green>19</green>
+ <blue>18</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Text">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>20</red>
+ <green>19</green>
+ <blue>18</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </disabled>
+ </palette>
+ </property>
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>TPFrameBall</class>
+ <extends>QWidget</extends>
+ <header>tpframeball.h</header>
+ <container>1</container>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/examples/tutorial/tpframeball.cpp b/examples/tutorial/tpframeball.cpp
new file mode 100644
index 0000000..d69884a
--- /dev/null
+++ b/examples/tutorial/tpframeball.cpp
@@ -0,0 +1,184 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "tpframeball.h"
+#include <QKeyEvent>
+#include <QPainter>
+#include <QPaintEvent>
+#include <QTextOption>
+
+#include <QDebug>
+
+TPFrameBall::TPFrameBall(QWidget *parent) :
+ QWidget(parent),
+ m_score(-1),
+ m_ball(-1),
+ m_previousBall(-1),
+ m_lastFrame(true)
+{
+ setFocusPolicy(Qt::StrongFocus);
+}
+
+void TPFrameBall::setBall(int value)
+{
+ if (value < 0 || value > 10)
+ value = -1;
+ if (value == m_ball)
+ return;
+ m_ball = value;
+ emit ballChanged(m_ball);
+ updateScore();
+}
+
+void TPFrameBall::setPreviousBall(int value)
+{
+ if (value < 0 || value > 10)
+ value = -1;
+ if (m_lastFrame && value == 10)
+ value = -1;
+ if (value == m_previousBall)
+ return;
+ m_previousBall = value;
+ updateScore();
+}
+
+void TPFrameBall::mousePressEvent(QMouseEvent *event)
+{
+ Q_UNUSED(event);
+ setFocus();
+}
+
+void TPFrameBall::keyPressEvent(QKeyEvent *event)
+{
+ switch(event->key()) {
+ case Qt::Key_0:
+ if (m_ball == 1)
+ setBall(10);
+ else
+ setBall(0);
+ break;
+ case Qt::Key_1:
+ case Qt::Key_2:
+ case Qt::Key_3:
+ case Qt::Key_4:
+ case Qt::Key_5:
+ case Qt::Key_6:
+ case Qt::Key_7:
+ case Qt::Key_8:
+ case Qt::Key_9:
+ setBall(event->key() - Qt::Key_0);
+ break;
+ case Qt::Key_Backspace:
+ if (m_ball == 10)
+ setBall(1);
+ else
+ setBall(-1);
+ break;
+ case Qt::Key_X:
+ setBall(10);
+ break;
+ case Qt::Key_Slash:
+ if (m_previousBall != -1)
+ setBall(10 - m_previousBall);
+ break;
+ default:
+ break;
+ }
+}
+
+void TPFrameBall::updateScore()
+{
+ int score = -1;
+ if (m_ball != -1 && m_previousBall != -1)
+ score = m_ball + m_previousBall;
+ else if (m_ball != -1)
+ score = m_ball;
+
+ if (m_score != score) {
+ m_score = score;
+ emit scoreChanged(m_score);
+ }
+
+ QString text;
+ if (isStrike())
+ text = QString::fromLatin1("X");
+ else if (isSpare())
+ text = QString::fromLatin1("/");
+ else if (m_ball == -1)
+ text = QString();
+ else if (m_score < 0 || m_score > 10)
+ text = tr("E", "Error letter, not X or /");
+ else
+ text = QString::number(m_ball);
+
+ if (text != m_display) {
+ m_display = text;
+ update();
+ }
+}
+
+void TPFrameBall::paintEvent(QPaintEvent *event)
+{
+ QPainter p(this);
+ p.setClipRect(event->rect());
+
+ QPen pen(Qt::red);
+ QBrush brush(hasFocus() ? Qt::blue : Qt::black);
+ p.setPen(pen);
+ p.setBrush(brush);
+ p.drawRect(0, 0, width(), height()-1);
+
+ pen.setColor(Qt::white);
+ QFont f = font();
+ f.setWeight(QFont::Bold);
+ p.setPen(pen);
+ p.drawText(0, 0, width(), height(), Qt::AlignHCenter | Qt::AlignVCenter, m_display);
+}
+
+void TPFrameBall::focusInEvent(QFocusEvent *)
+{
+ update();
+}
+
+void TPFrameBall::focusOutEvent(QFocusEvent *)
+{
+ update();
+}
diff --git a/examples/tutorial/tpframeball.h b/examples/tutorial/tpframeball.h
new file mode 100644
index 0000000..bf9602e
--- /dev/null
+++ b/examples/tutorial/tpframeball.h
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TPBALL_H
+#define TPBALL_H
+
+#include <QWidget>
+
+#include <QDebug>
+
+class QLabel;
+
+class TPFrameBall : public QWidget
+{
+ Q_OBJECT
+ Q_PROPERTY(int ball READ ball WRITE setBall NOTIFY ballChanged USER true)
+ Q_PROPERTY(int previousBall READ previousBall WRITE setPreviousBall)
+ Q_PROPERTY(int score READ score NOTIFY scoreChanged DESIGNABLE false STORED false)
+ Q_PROPERTY(QString display READ display DESIGNABLE false STORED false)
+ Q_PROPERTY(bool isStrike READ isStrike DESIGNABLE false STORED false)
+ Q_PROPERTY(bool isSpare READ isSpare DESIGNABLE false STORED false)
+ Q_PROPERTY(bool isLastFrame READ isLastFrame WRITE setLastFrame)
+public:
+ explicit TPFrameBall(QWidget *parent = 0);
+
+ QString display() const { return m_display; }
+ int ball() const { return m_ball; }
+ int previousBall() const { return m_previousBall; }
+ int score() const { return m_score; }
+ bool isStrike() const { return m_previousBall == -1 && score() == 10; }
+ bool isSpare() const { return m_previousBall != 10 && score() == 10; }
+ bool isLastFrame() const { return m_lastFrame; }
+ void setLastFrame(bool value) { m_lastFrame = value; updateScore(); }
+
+public slots:
+ void setBall(int);
+ void setPreviousBall(int);
+
+signals:
+ void ballChanged(int);
+ void scoreChanged(int);
+
+protected:
+ void mousePressEvent(QMouseEvent *);
+ void keyPressEvent(QKeyEvent *);
+
+ void paintEvent(QPaintEvent *);
+ void focusInEvent(QFocusEvent *);
+ void focusOutEvent(QFocusEvent *);
+
+private slots:
+ void updateScore();
+
+private:
+ QString m_display;
+ int m_score;
+ int m_ball;
+ int m_previousBall;
+ QLabel *m_label;
+
+ bool m_lastFrame;
+};
+
+#endif // TPBALL_H
diff --git a/examples/tutorial/tpgame.cpp b/examples/tutorial/tpgame.cpp
new file mode 100644
index 0000000..80f2da4
--- /dev/null
+++ b/examples/tutorial/tpgame.cpp
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "tpgame.h"
+#include "tpframe.h"
+#include <QScrollArea>
+#include <QHBoxLayout>
+
+TPGame::TPGame(QWidget *parent) :
+ QWidget(parent)
+{
+ QHBoxLayout *layout = new QHBoxLayout;
+ layout->setMargin(0);
+ layout->setSpacing(0);
+ TPFrame *last = 0;
+ for (int i = 0; i < 10; i++) {
+ TPFrame *frame = new TPFrame;
+ layout->addWidget(frame);
+ m_frames.append(frame);
+ frame->setPreviousFrame(last);
+ if (last)
+ last->setNextFrame(frame);
+ last = frame;
+ }
+ setLayout(layout);
+}
+
+TPGame::~TPGame()
+{
+}
+
+void TPGame::reset()
+{
+ foreach(TPFrame *frame, m_frames) {
+ frame->reset();
+ }
+}
diff --git a/examples/tutorial/tpgame.h b/examples/tutorial/tpgame.h
new file mode 100644
index 0000000..a884211
--- /dev/null
+++ b/examples/tutorial/tpgame.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TENPINGAME_H
+#define TENPINGAME_H
+
+#include <QWidget>
+
+class TPFrame;
+
+class TPGame : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit TPGame(QWidget *parent = 0);
+ ~TPGame();
+
+public slots:
+ void reset();
+private:
+ QList<TPFrame *> m_frames;
+};
+
+#endif // TENPINGAME_H
diff --git a/examples/tutorial/tutorial.pro b/examples/tutorial/tutorial.pro
new file mode 100644
index 0000000..7570b77
--- /dev/null
+++ b/examples/tutorial/tutorial.pro
@@ -0,0 +1,18 @@
+QT += core gui
+
+TARGET = tenpinGame
+TEMPLATE = app
+
+
+SOURCES += main.cpp\
+ tpframe.cpp \
+ tpframeball.cpp \
+ tpgame.cpp
+
+HEADERS += \
+ tpframe.h \
+ tpframeball.h \
+ tpgame.h
+
+FORMS += \
+ tpframe.ui
diff --git a/scripts/update_license.pl b/scripts/update_license.pl
new file mode 100644
index 0000000..9644759
--- /dev/null
+++ b/scripts/update_license.pl
@@ -0,0 +1,56 @@
+@lines = <STDIN>;
+$in_license = true;
+foreach (@lines) {
+ if ($in_license && /^\*\*/ || /\*\*$/) {
+ ;
+ } else {
+ $in_license = false;
+ push @code_lines, $_;
+ }
+}
+
+print <<END;
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** \$QT_BEGIN_LICENSE:LGPL\$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** \$QT_END_LICENSE\$
+**
+****************************************************************************/
+
+END
+
+print(@code_lines);
diff --git a/scripts/update_licenses.sh b/scripts/update_licenses.sh
new file mode 100755
index 0000000..dd01af9
--- /dev/null
+++ b/scripts/update_licenses.sh
@@ -0,0 +1,6 @@
+for f in `grep -d recurse -l QT_BEGIN_LICENSE ./src`
+do
+ mv $f $f.orig
+ perl update_license.pl < $f.orig > $f
+ rm $f.orig
+done
diff --git a/src/interpreter/imports/imports.pro b/src/interpreter/imports/imports.pro
new file mode 100644
index 0000000..dd43ea0
--- /dev/null
+++ b/src/interpreter/imports/imports.pro
@@ -0,0 +1,3 @@
+TEMPLATE = subdirs
+SUBDIRS += qtsystemtest \
+ runner
diff --git a/src/interpreter/imports/qtsystemtest/qml/Application.qml b/src/interpreter/imports/qtsystemtest/qml/Application.qml
new file mode 100644
index 0000000..36c9cdb
--- /dev/null
+++ b/src/interpreter/imports/qtsystemtest/qml/Application.qml
@@ -0,0 +1,162 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.1
+import "../scripts/QstCore.js" as Core
+
+QtObject {
+ id: app
+
+ property Remote remote
+ property variant pid: null
+ property variant __id
+
+ function item(query) {
+ var matches = __queryProperties(query);
+ if ( matches.length !== 1 ) {
+ throw new Core.Qtt.Fail('Error: ' + matches.length +
+ ' items match query, expected a single match', 1);
+ }
+ return __handlerForObject(matches[0]);
+ }
+
+ function items(query) {
+ var matches = __queryProperties(query);
+ var handlers = matches.map(function(obj) {
+ return __handlerForObject(obj);
+ });
+ return handlers;
+ }
+
+ function activeWidgetInfo() { return __sendQuery(arguments.callee.name); }
+
+ function applicationData() {
+ return __sendQuery(arguments.callee.name).applicationdata;
+ }
+
+
+ function keyPress(key) {
+ __sendQuery(arguments.callee.name, { key: key });
+ }
+
+ function keyRelease(key) {
+ __sendQuery(arguments.callee.name, { key: key });
+ }
+
+ function keyClick(key) {
+ __sendQuery(arguments.callee.name, { key: key });
+ }
+
+
+ function mousePress(pos, buttons) {
+ __inputEvent(arguments.callee.name, pos, buttons);
+ }
+
+ function mouseRelease(pos, buttons) {
+ __inputEvent(arguments.callee.name, pos, buttons);
+ }
+
+ function mouseClick(pos, buttons) {
+ __inputEvent(arguments.callee.name, pos, buttons);
+ }
+
+ function mouseDoubleClick(pos, buttons) {
+ __inputEvent(arguments.callee.name, pos, buttons);
+ }
+
+ function terminate() {
+ remote.runProcess( { program: "kill", arguments: [ pid ], timeout: 500 } );
+ }
+
+ function __queryProperties(query) {
+ // traverse the query object replacing any QstObject with its __internals
+ (function prepare(query) {
+ var prop, v;
+ for (prop in query) {
+ v = query[prop];
+ if ( typeof(v) !== 'object' ) { continue; }
+
+ if( v.__isQmlWrapper === true ) {
+ query[prop] = v.__internals;
+ } else {
+ prepare(v);
+ }
+ }
+ })(query);
+
+ var items = __sendQuery("queryProperties", {
+ searchvalues: query
+ }).queryproperties;
+ return items || [];
+ }
+
+ function __handlerForObject(obj) {
+ var ItemFactory = Core.ItemFactory;
+ var component = ItemFactory.handlerForObject(obj, {application: app});
+ return component.createObject(
+ __runner.currentTestItem, {
+ application: app,
+ __internals: obj,
+ }
+ );
+
+ }
+
+
+ function __inheritanceTree(o) {
+ return __sendQuery('inheritance',{}, o).inheritance;
+ }
+
+ function __inputEvent(event, pos, buttons) {
+ buttons = buttons || Qt.LeftButton;
+
+ if (pos.__isQmlWrapper === true) {
+ return __sendQuery(event, {buttons: buttons}, pos.__internals);
+ }
+
+ return remote.__sendPositionQuery(event, {buttons: buttons}, pos);
+ }
+
+
+ function __sendQuery() {
+ return remote.__sendQuery.apply(remote, arguments);
+ }
+}
diff --git a/src/interpreter/imports/qtsystemtest/qml/ApplicationObjectsCache.js b/src/interpreter/imports/qtsystemtest/qml/ApplicationObjectsCache.js
new file mode 100644
index 0000000..15fdc67
--- /dev/null
+++ b/src/interpreter/imports/qtsystemtest/qml/ApplicationObjectsCache.js
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+.pragma library
+
+var __hosts = {};
+
+function host(address) {
+ if ( __hosts[address] === undefined) {
+ __hosts[address] = new Host(address);
+ }
+
+ return __hosts[address];
+}
+
+function Host(address) {
+ this.address = address;
+ this._store = {};
+}
+
+Host.prototype.store = function(appId, props) {
+ if ( !(appId in this._store) ){
+ this._store[appId] = props;
+ return;
+ }
+
+ var s = this._store[appId];
+ for (var x in props) {
+ s[x] = props[x];
+ }
+}
+
+Host.prototype.data = function(appId) {
+ return appId in this._store
+ ? this._store[appId]
+ : null;
+}
diff --git a/src/interpreter/imports/qtsystemtest/qml/Js.qml b/src/interpreter/imports/qtsystemtest/qml/Js.qml
new file mode 100644
index 0000000..703c564
--- /dev/null
+++ b/src/interpreter/imports/qtsystemtest/qml/Js.qml
@@ -0,0 +1,49 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.1
+import '../scripts/QstCore.js' as Core
+
+QtObject {
+ function core() {
+ return Core;
+ }
+}
diff --git a/src/interpreter/imports/qtsystemtest/qml/Remote.qml b/src/interpreter/imports/qtsystemtest/qml/Remote.qml
new file mode 100644
index 0000000..255a291
--- /dev/null
+++ b/src/interpreter/imports/qtsystemtest/qml/Remote.qml
@@ -0,0 +1,168 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.1
+import '../scripts/QstCore.js' as Core
+import 'ApplicationObjectsCache.js' as Cache
+
+QtObject {
+ id: remote
+ property string host
+ property int port: 5656
+ property int applicationStartTimeout: 5000
+ property int appStartRefreshInterval: 250
+
+ property bool __needToReconnect: true
+ property bool __debug_showMessageReceived: false
+
+ onHostChanged: { __needToReconnect = true; }
+ onPortChanged: { __needToReconnect = true; }
+
+
+ function runProcess(params) {
+ return __sendQuery(arguments.callee.name, { cmd: params } );
+ }
+
+ function startApplication(app, args) {
+ args = args || []
+ args.push("-style", "qtuitestd");
+ var currentAppId = __currentAppId();
+ var output = runProcess({
+ program: app,
+ arguments: args,
+ detached: true
+ });
+
+ var timeout = 0;
+ while( __currentAppId() === currentAppId
+ && timeout < applicationStartTimeout) {
+ sleep(appStartRefreshInterval);
+ timeout += appStartRefreshInterval;
+ }
+
+ var newAppId = __currentAppId();
+ if (currentAppId === newAppId) {
+ throw new Core.Qtt.Fail('Application failed to start', 1);
+ }
+ Cache.host(host).store(newAppId, {
+ executable: app,
+ pid: output.pid,
+ });
+ return applicationForId(newAppId)
+ }
+
+
+
+ function currentApplication() {
+ var appId = __currentAppId();
+
+ if (appId === '') {
+ throw new Core.Qtt.Fail('No Current application', 1);
+ }
+
+ return applicationForId(appId);
+ }
+
+ function applicationForId(appId) {
+ // there should be data in the cache already
+ var cache = Cache.host(host);
+ var appData = cache.data(appId);
+ if (appData === null) {
+ throw new Core.Qtt.Fail('Application for Id not found', 1);
+ }
+
+ if (appData.application !== undefined) {
+ return appData.application;
+ }
+
+ var ApplicationRegistry = Core.ApplicationRegistry
+ var component = ApplicationRegistry.applicationForKey(appData.executable);
+ var app = component.createObject(__runner.currentTestItem, {
+ remote: remote,
+ __id: appId,
+ pid: appData.pid,
+ });
+ if (app === null) {
+ throw new Core.Qtt.Error('Failed to create an application object for : ' + appId);
+ }
+ cache.store(appId, {application: app});
+ return app;
+ }
+
+ function applications() {
+ }
+
+ function __connection() {
+ if (__needToReconnect == false) {
+ return __connection.object;
+ }
+ __connection.object = ConnectionManager.connectionForHost(host, port);
+ __connection.object.messageReceived.connect(__messageReceived);
+ var ok = __connection.object.connectToRemote();
+ if ( !ok ) {
+ var e = new Core.Qtt.Fail('Error: Connection to : \
+ host ' + host + 'port :' + port + ' failed', 2);
+ throw e;
+ }
+ __needToReconnect = false;
+ return __connection.object;
+ }
+
+ function __sendQuery(event, params, widgetSpecifier) {
+ return __connection().sendQuery(event, params, widgetSpecifier);
+ }
+
+ function __sendPositionQuery(event, params, position) {
+ return __connection().sendPositionQuery(event, params, position);
+ }
+
+ function __currentAppId() {
+ return __sendQuery('currentApplication').currentapplication;
+ }
+
+ function __messageReceived(event, context, data) {
+ if ( __debug_showMessageReceived ) {
+ console.log("Message received: ",
+ event, " context(" + context + ")",
+ 'data: ', Core.stringify(data));
+ }
+ }
+}
diff --git a/src/interpreter/imports/qtsystemtest/qml/Test.qml b/src/interpreter/imports/qtsystemtest/qml/Test.qml
new file mode 100644
index 0000000..df7f815
--- /dev/null
+++ b/src/interpreter/imports/qtsystemtest/qml/Test.qml
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.1
+import "../scripts/QstCore.js" as Core
+
+TestItem {
+ id: root
+
+ property string __status: Core.Qtt.Status.Untested ///'' // passed, failed, skipped
+ property bool __isTest: true
+ property variant __mustHaves: ['name', 'description', 'run']
+
+ function __validate() {
+ var missingMustHave;
+ var allMustHaves = __mustHaves.every(function(k) {
+ missingMustHave =k;
+ return (k in root) && root[k] !== '';
+ });
+
+ if (!allMustHaves) {
+ return __error('Test Item: ', root.name, ' does not define property or function',
+ '\'', missingMustHave, '\' the must haves are: ', __mustHaves);
+ }
+
+ return __ok();
+ }
+
+}
+
diff --git a/src/interpreter/imports/qtsystemtest/qml/TestCollection.qml b/src/interpreter/imports/qtsystemtest/qml/TestCollection.qml
new file mode 100644
index 0000000..87e5b86
--- /dev/null
+++ b/src/interpreter/imports/qtsystemtest/qml/TestCollection.qml
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.1
+import "../scripts/QstCore.js" as Core
+
+TestItem {
+ id: root
+ property list<TestItem> __subset
+ default property alias children: root.__subset
+
+ function __validate() {
+ var missingMustHave;
+ var allMustHaves = __mustHaves.every(function(k) {
+ missingMustHave =k;
+ return (k in root) && root[k] !== '';
+ });
+
+ if (!allMustHaves) {
+ return __error('Test Item: ', root.name, ' does not define property',
+ '\'', missingMustHave, '\' the must haves are: ', __mustHaves);
+ }
+
+ if( root.__subset.length > 0 && 'run' in root && typeof(root.run) === 'function' ) {
+ return __error('Invalid test: Cannot have sub test-sets and run() defined for ', root.name);
+ }
+
+ if(__subset === null) {
+ return __ok();
+ }
+
+ for( var i = 0; i < __subset.length; i++) {
+ var s = __subset[i];
+ var v = s.__validate();
+ if( v.valid === false) {
+ return v;
+ }
+ }
+
+ return __ok();
+ }
+}
diff --git a/src/interpreter/imports/qtsystemtest/qml/TestItem.qml b/src/interpreter/imports/qtsystemtest/qml/TestItem.qml
new file mode 100644
index 0000000..04fda39
--- /dev/null
+++ b/src/interpreter/imports/qtsystemtest/qml/TestItem.qml
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.1
+import "../scripts/QstCore.js" as Core
+
+TestMethod {
+ id: root
+ property string name:''
+ property string description: ''
+ property bool enabled: true
+
+ property list<Remote> remotes
+
+ property variant __mustHaves: ['name', 'description']
+ property bool __isTest: false
+
+ function __ok() {
+ var path = Core.Js.__validationRoot__;
+ if ( path !== undefined) {
+ path.pop();
+ if (path.length === 0) {
+ delete Core.Js.__validationRoot__;
+ }
+ }
+ return {
+ valid: true,
+ };
+ }
+
+ function __error() {
+ var runner = __runner,
+ msg = Array.prototype.slice.call(arguments).join(' '),
+ e = new Core.Qtt.Error(msg),
+ loc = runner.locationOf(root),
+ err;
+
+ err = e.toString() + '\n'
+ + 'Location: ' + loc.url + '(' + loc.lineNumber + ')';
+ return {
+ valid: false,
+ error : err
+ };
+ }
+}
diff --git a/src/interpreter/imports/qtsystemtest/qml/TestMethod.qml b/src/interpreter/imports/qtsystemtest/qml/TestMethod.qml
new file mode 100644
index 0000000..55cb64d
--- /dev/null
+++ b/src/interpreter/imports/qtsystemtest/qml/TestMethod.qml
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.1
+import QtSystemTest 1.0
+import '../scripts/QstCore.js' as Core
+
+QtObject {
+ // make core c++ stuff internal
+ property variant __core: CoreApi {}
+ function core() { return Core; }
+
+ /*!
+ Causes the current test object to fail immediately
+ */
+ function fail(message) {
+ var msg = Core.stringify.apply(null, arguments);
+ var e = new Core.Qtt.Fail(msg);
+ e.discardCallSites();
+ throw e;
+ }
+
+ function skip(message) {
+ var msg = Core.stringify.apply(null, arguments);
+ var e = new Core.Qtt.Skip(msg);
+ e.discardCallSites();
+ throw e;
+ }
+
+ function log() {
+ __runner.log.apply(__runner, arguments);
+ }
+
+ function expect(o) {
+ return core().expect(o);
+ }
+
+ function sleep(ms) {
+ // calls cpp method
+ __core.sleep(ms);
+ }
+}
diff --git a/src/interpreter/imports/qtsystemtest/qml/itemhandlers/QstObject.qml b/src/interpreter/imports/qtsystemtest/qml/itemhandlers/QstObject.qml
new file mode 100644
index 0000000..6cbee20
--- /dev/null
+++ b/src/interpreter/imports/qtsystemtest/qml/itemhandlers/QstObject.qml
@@ -0,0 +1,117 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.1
+import '..'
+import "../../scripts/QstCore.js" as Core
+
+QtObject {
+ id: me
+
+ property Application application
+ property variant __internals
+ property bool __isQmlWrapper: true
+ property string handles: 'QObject'
+
+ function property(name) {
+ return __sendQuery('getProperty', {property: name}).getproperty;
+ }
+
+ function setProperty(name, value) {
+ return __sendQuery('setProperty', {
+ property: name,
+ value: value,
+ });
+ }
+
+ function descendants(filter) {
+ filter = filter || {};
+ filter.descendant_of = me;
+ return application.items(filter);
+ }
+
+ function ancestors(filter) {
+ filter = filter || {};
+ filter.ancestor_of = me;
+ return application.items(filter);
+ }
+
+ function parent() {
+ return application.item({parent_of: me});
+ }
+
+ function isValid() {
+ try {
+ var x = type();
+ } catch(e) {
+ return false;
+ }
+ return true;
+
+ }
+
+ function type() {
+ return __sendQuery('typeOf')['typeof'];
+ }
+
+// method: function(methodSignature) {
+// return new QtUiTestMethod(this, methodSignature);
+// },
+
+// equals: function(other) {
+// // FIXME other should be checked if it is a QtUiTestObject
+// // but that test fails since for _prefetched_ objects the
+// // type is set as Object and not QtUiTestWidget or QtUiTestObject
+// // try: print(other.constructor.name)
+// return other._signature_ !== undefined
+// && this._signature_ === other._signature_;
+// },
+
+ function toString() {
+ return this._signature_;
+ }
+
+ function __sendQuery(event, params) {
+ params = params || {};
+ return application.__sendQuery(event, params, __internals);
+ }
+
+}
diff --git a/src/interpreter/imports/qtsystemtest/qml/itemhandlers/QstWidget.qml b/src/interpreter/imports/qtsystemtest/qml/itemhandlers/QstWidget.qml
new file mode 100644
index 0000000..4eaa33f
--- /dev/null
+++ b/src/interpreter/imports/qtsystemtest/qml/itemhandlers/QstWidget.qml
@@ -0,0 +1,49 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.1
+import QtSystemTest 1.0
+import "../../scripts/QstCore.js" as Core
+
+QstObject {
+ id: me
+ handles: 'QWidget'
+}
diff --git a/src/interpreter/imports/qtsystemtest/qmldir b/src/interpreter/imports/qtsystemtest/qmldir
new file mode 100644
index 0000000..06f9958
--- /dev/null
+++ b/src/interpreter/imports/qtsystemtest/qmldir
@@ -0,0 +1,11 @@
+plugin qtsystemtest
+Application 1.0 qml/Application.qml
+Remote 1.0 qml/Remote.qml
+TestData 1.0 qml/TestData.qml
+TestItem 1.0 qml/TestItem.qml
+Test 1.0 qml/Test.qml
+TestCollection 1.0 qml/TestCollection.qml
+QstObject 1.0 qml/itemhandlers/QstObject.qml
+QstWidget 1.0 qml/itemhandlers/QstWidget.qml
+Js 1.0 qml/Js.qml
+Core 1.0 scripts/QstCore.js
diff --git a/src/interpreter/imports/qtsystemtest/qtsystemtest.json b/src/interpreter/imports/qtsystemtest/qtsystemtest.json
new file mode 100644
index 0000000..0967ef4
--- /dev/null
+++ b/src/interpreter/imports/qtsystemtest/qtsystemtest.json
@@ -0,0 +1 @@
+{}
diff --git a/src/interpreter/imports/qtsystemtest/qtsystemtest.pro b/src/interpreter/imports/qtsystemtest/qtsystemtest.pro
new file mode 100644
index 0000000..566a570
--- /dev/null
+++ b/src/interpreter/imports/qtsystemtest/qtsystemtest.pro
@@ -0,0 +1,74 @@
+TARGET = qtsystemtest
+TARGETPATH = QtSystemTest
+
+
+TEMPLATE = lib
+CONFIG += no_clean qt plugin
+
+QT += declarative declarative-private testlib
+
+INCLUDEPATH += ../../../../include
+LIBS += -L../../../../lib
+LIBS += -lQstProtocol
+
+SOURCES += src/imports.cpp \
+ src/qstcoreapi.cpp \
+ src/qstutils.cpp \
+ src/qstlocalprocess.cpp
+
+HEADERS += src/imports.h \
+ src/qstcoreapi.h \
+ src/qstutils.h \
+ src/qstlocalprocess.h
+
+OTHER_FILES += \
+ qtsystemtest.json \
+
+target.path += $$[QT_INSTALL_IMPORTS]/QtSystemTest
+
+# public api
+QML_IMPORT_FILES = \
+ qml/TestMethod.qml \
+ qml/TestItem.qml \
+ qml/Test.qml \
+ qml/TestCollection.qml \
+ qml/Remote.qml \
+ qml/Application.qml \
+ qml/itemhandlers/QstObject.qml \
+ qml/Js.qml \
+
+qmlImportFiles.files += $$PWD/qml
+qmlImportFiles.path = $$[QT_INSTALL_IMPORTS]/$$TARGETPATH
+
+# scripts
+SCRIPT_FILES = \
+ scripts/api.js \
+ scripts/Datatype.js \
+ scripts/Functional.js \
+ scripts/JsCore.js \
+ scripts/SourceBuilder.js \
+ scripts/Class.js \
+ scripts/QstCore.js \
+ scripts/Console.js \
+ scripts/Expect.js \
+ scripts/Exception.js \
+ scripts/ComponentCacher.js \
+ scripts/ApplicationRegistry.js \
+ scripts/ItemFactory.js \
+
+scriptFiles.files += $$SCRIPT_FILES
+scriptFiles.path = $$[QT_INSTALL_IMPORTS]/$$TARGETPATH/scripts
+
+# qmldir
+QMLDIR_FILE = qmldir
+qmldirFile.files += $$QMLDIR_FILE
+qmldirFile.path = $$[QT_INSTALL_IMPORTS]/$$TARGETPATH
+
+# show in QtCreator
+OTHER_FILES += $$QML_IMPORT_FILES \
+ $$SCRIPT_FILES \
+ qmldir \
+
+
+INSTALLS += qmlImportFiles scriptFiles qmldirFile target
+
diff --git a/src/interpreter/imports/qtsystemtest/scripts/ApplicationRegistry.js b/src/interpreter/imports/qtsystemtest/scripts/ApplicationRegistry.js
new file mode 100644
index 0000000..9566179
--- /dev/null
+++ b/src/interpreter/imports/qtsystemtest/scripts/ApplicationRegistry.js
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+Js.include_check(ApplicationRegistry === undefined, 'ApplicationRegistry.js already included');
+
+Js.require('ComponentCacher.js');
+Js.require('Exception.js');
+
+// create a factory and make that singleton
+var ApplicationRegistry = function() {
+ var Factory = ComponentCacher.extend(function() {
+ this._super();
+ this.setDefaultItemFile('../qml/Application.qml');
+
+ function applicationForKey(key) {
+ var component = this.componentForKey(key);
+ if (component === null) {
+ throw new Qtt.Fail('Error creating an Application handler for: ' + key +
+ ' using file: ' + this.fileForKey(key) , 2);
+ }
+ return component;
+ }
+
+
+ return {
+ applicationForKey: applicationForKey
+ };
+ });
+ return new Factory();
+}();
diff --git a/src/interpreter/imports/qtsystemtest/scripts/Class.js b/src/interpreter/imports/qtsystemtest/scripts/Class.js
new file mode 100644
index 0000000..e59c7f7
--- /dev/null
+++ b/src/interpreter/imports/qtsystemtest/scripts/Class.js
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+Js.include_check(Class.isFn === undefined, 'Class.js already included');
+
+function Class(){ };
+
+Class.DebugEnabled = false;
+//Class.DebugEnabled = true;
+Class.debug = function debug() {
+ if (Class.DebugEnabled) {
+ var str = '';
+ for (var i=0; i<arguments.length; i++) {
+ str += arguments[i];
+ }
+ console.log(str);
+ }
+}
+
+Class.isFn = function(fn) { return typeof fn === 'function'; };
+Class.isBothFn = function (fn, superFn) {
+ var debug = Class.debug;
+ debug('\t is fn ', (fn ? fn.name: undefined), ', superFn: ', (superFn ? superFn.name : undefined) , ' is a function');
+ return Class.isFn(fn) && Class.isFn(superFn)
+};
+
+Class.create = function(superClass, constructor) {
+ // if 2 args are passed, then SuperClass is specified and else it is of the
+ // from X.extend(definition-of-y)
+ // SuperClass need not be specified in that case, SubClass definition will be
+ // in the SuperClass arg
+ var SuperClass, SubClass,
+ debug = Class.debug;
+ if( arguments.length == 1) {
+ SuperClass = this;
+ SubClass = superClass; // has the definition
+
+ }else {
+ SubClass = constructor;
+ SuperClass = superClass;
+ }
+ debug('Superclass is ', SuperClass.name);
+
+ // NOTE constructor.name for the object created using this is empty
+ var definition = function () {
+ // about to call the constructor of this object, so the super classes are already
+ // constructor and the prototype of this is already set.
+ var myProto = this;
+ debug('My Prototype already has : ', Object.keys(myProto));
+ // define _super before calling the construtor
+ this._super = SuperClass; // _super from constructor should work
+
+ // constructor returns the exported public members
+ var publicMembers = SubClass.apply(this, arguments); // returns the exported members
+ debug('Exported members are: ', Object.keys(publicMembers));
+
+ for (var name in publicMembers) {
+ debug('\t Testing if ', name, ' should be overridden');
+ (function(member, superMember) {
+ // overide the definition in my proto if required
+ if ( Class.isFn(member) ) {
+ var s = Class.isFn(superMember) ? superMember : undefined;
+ myProto[name] = function() {
+ var tmp = this._super;
+ this._super = s;
+ var ret = member.apply(this, arguments);
+ this._super = tmp;
+ return ret;
+ }
+ } else {
+ myProto[name] = member;
+ }
+
+ })(publicMembers[name], myProto[name]);
+ }
+ }; // definition
+ definition.prototype = new SuperClass; // establish prototype chain
+ definition.prototype.constructor = definition; // and the ctor
+ definition.extend = SuperClass.extend || Class.create
+ return definition;
+
+}; // Class.create
+
diff --git a/src/interpreter/imports/qtsystemtest/scripts/ComponentCacher.js b/src/interpreter/imports/qtsystemtest/scripts/ComponentCacher.js
new file mode 100644
index 0000000..781914f
--- /dev/null
+++ b/src/interpreter/imports/qtsystemtest/scripts/ComponentCacher.js
@@ -0,0 +1,147 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+Js.include_check(ComponentCacher === undefined, 'ComponentCacher.js already included');
+Js.require('Exception.js');
+Js.require('Class.js');
+
+var OriginalCallerDepth = 5; // explaination below
+/*
+ the stack for factory.register(foo, bar) or this.setDefaultItemFile would lead to
+ 1. something.register()
+ 2. class.call (register)
+ 3. this.register
+ 3. absolutePathOf
+ 4. inside register
+ to get the file that called register, we would have to traverse back in stack 5 levels
+*/
+
+ function absolutePathOf(path) {
+ if ( !Qt.qst.isRelativePath(path) ) {
+ return path;
+ }
+ // get the filename that called applicaton.register
+ var stack = Js.Engine.callSite(OriginalCallerDepth);
+ var callerFilePath = stack.last().fileName;
+ var lastSlash = callerFilePath.lastIndexOf('/');
+ return callerFilePath.left(lastSlash + 1) + path;
+ }
+
+
+var ComponentCacher = Class.create(function() {
+ var __registry = {
+ //key: qmlFile
+ };
+
+ var __componentsCache = {
+ //key: Component
+ };
+ var __defaultItemFile;
+ var fallbackToDefault = true;
+
+ function setDefaultItemFile(qmlFilePath) {
+ __defaultItemFile = absolutePathOf(qmlFilePath);
+ }
+
+ function unregister(key) {
+ if (key in __registry) {
+ delete __registry[key];
+ }
+ if (key in __componentsCache) {
+ delete __componentsCache[key];
+ }
+ }
+
+ function register(key, qmlFilePath) {
+ __registry[key] = absolutePathOf(qmlFilePath);
+ }
+
+ function fileForKey(key) {
+ if (key in __registry) {
+ return __registry[key];
+ }
+ if ( !fallbackToDefault) {
+ return null;
+ }
+
+ if ( !__defaultItemFile) {
+ throw new Qtt.Error( 'Error: ComponentCacher - unable to find a file for ' + key);
+ }
+ return __defaultItemFile;
+ }
+
+ function componentForKey(key) {
+ var qmlFile = this.fileForKey(key);
+ if (qmlFile === null) {
+ return null;
+ }
+
+ var component = null;
+ if ( ! (qmlFile in __componentsCache)) {
+
+ component = Qt.createComponent(qmlFile)
+ // HACK ... 1 means Component.Ready I want to access Component.Ready here...
+ if (component.status !== 1) {
+ // fix me ... Change error to accept msg and formatted msg,
+ throw new Qtt.Error('Component creation failed : ' + component.errorString(), 2);
+ }
+ __componentsCache[qmlFile] = component;
+ } else {
+ component = __componentsCache[qmlFile];
+ }
+
+ return component;
+ }
+ function setFallbackToDefault(value) {
+ fallbackToDefault = value;
+ }
+
+ return {
+
+ setFallbackToDefault: setFallbackToDefault,
+ setDefaultItemFile: setDefaultItemFile,
+ fileForKey: fileForKey,
+ register: register,
+ unregister: unregister,
+ componentForKey: componentForKey,
+ keys: function() { return Object.keys(__registry); },
+ };
+});
diff --git a/src/interpreter/imports/qtsystemtest/scripts/Console.js b/src/interpreter/imports/qtsystemtest/scripts/Console.js
new file mode 100644
index 0000000..3ddb6f5
--- /dev/null
+++ b/src/interpreter/imports/qtsystemtest/scripts/Console.js
@@ -0,0 +1,128 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+Js.include_check(Topic === undefined, 'Console.js already included');
+Js.require('Class.js');
+
+var Topic = Class.create(function(name, parent) {
+ parent = parent || null;
+ var _subtopic = {
+ // name: Topic
+ };
+ var loglevel = {
+ debug: {enabled: false, activate: false },
+ warn: {enabled: false, activate: false },
+ }
+
+ var DebugEnabled = false;
+ function stringify() {
+ stringify.sb = stringify.sb || new SourceBuilder();
+ var sb = stringify.sb;
+ var str = '';
+ for (var i =0; i<arguments.length; ++i) {
+ str += sb.sourceFor(arguments[i]);
+ }
+ return str;
+ }
+ function _debug() {
+ if (DebugEnabled) {
+ print('Console[Debug]: ', stringify.apply(null, arguments));
+ }
+ }
+
+ function path() {
+ var parents = [name];
+ for (var p = parent; p !== null; p = p.parent) {
+ _debug('....... type: ', typeof(p), ' ctor:', p.constructor.name );
+ parents.unshift(p.name);
+ }
+ return parents;
+ }
+
+ function debug(m) {
+ if ( loglevel.debug.activate) {
+ return;
+ }
+
+ if (arguments.length === 0) {
+ return;
+ }
+ _debug('..................', name);
+
+ function log() {
+ var parents = path();
+ var location = Js.Engine.callSite(4).last();
+ var filePath = location.fileName;
+ var file = filePath.right(filePath.length - filePath.lastIndexOf('/') -1);
+ console.log(' ', Date.timestamp(), ', ' // timestamp
+ + file + '(' + location.lineNumber + ') :', // file (linenumber)
+ parents.join('.'), ': ' + stringify.apply(null, arguments)); // topic.topic.... : msg
+ }
+// log.apply(null, arguments);
+ }
+
+ function topic(t) {
+ _debug('Already existing ones: ', Object.keys(_subtopic) );
+ if ( t in _subtopic ){
+ return _subtopic[t]
+ }
+ _debug('Creating a topic: ', name, '.' , t);
+ var sub = new Topic(t, this);
+ _subtopic[t] = sub;
+ _debug(Object.keys(_subtopic));
+ return sub;
+ }
+
+ function enable() {
+
+ }
+
+ return {
+ debug: debug,
+ topic: topic,
+ name: name,
+ parent: parent,
+ enable: enable,
+ };
+});
+
+
+var Console = new Topic('Console');
diff --git a/src/interpreter/imports/qtsystemtest/scripts/Datatype.js b/src/interpreter/imports/qtsystemtest/scripts/Datatype.js
new file mode 100644
index 0000000..1b2fa7a
--- /dev/null
+++ b/src/interpreter/imports/qtsystemtest/scripts/Datatype.js
@@ -0,0 +1,142 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+.pragma library
+
+/// FIXME: Qt5, Error.stack can be enabled by calling prepareStack once
+Object.defineProperties(Error.prototype, {
+ __addStack: {
+ value: function(level) {
+ if (this.stack) {
+ return;
+ }
+
+ var stack = level === undefined ? Qt.qst.stack() : Qt.qst.stack(level);
+ // this function (top of the stack) with the right values from Error
+ stack[0] = {
+ fileName: this.fileName,
+ lineNumber: this.lineNumber,
+ functionName: '<unknown function>'
+ };
+ this.stack = stack;
+ }
+ }
+});
+
+
+Object.defineProperties(Array.prototype, {
+ isEmpty: {
+ value: function() { return this.length === 0; }
+ },
+
+ clear: {
+ value: function() { this.length = 0; }
+ },
+
+ last: {
+ value: function() { return this[this.length-1]; }
+ },
+
+ first: {
+ value: function() { return this[0]; }
+ },
+
+ contains: {
+ value: function(element) {
+ if (this === undefined || this === null) {
+ throw new TypeError();
+ }
+ return this.indexOf(element) !== -1;
+ }
+ },
+
+ remove: {
+ value: function(from, to) {
+ var rest = this.slice((to || from) + 1 || this.length);
+ this.length = from < 0 ? this.length + from : from;
+ return this.push.apply(this, rest);
+ }
+ }
+});
+
+
+Object.defineProperties(String.prototype, {
+ startsWith: {
+ value: function(prefix) { return this.indexOf(prefix) === 0; }
+ },
+
+ endsWith: {
+ value: function(suffix) {
+ return this.indexOf(suffix, this.length - suffix.length) !== -1; }
+ },
+
+ left: {
+ value: function(len) { return this.substring(0, len); }
+ },
+
+ right: {
+ value: function(len) { return this.substring(this.length- len); }
+ },
+
+ repeat: {
+ value: function( num ) { return new Array( num + 1 ).join(this); }
+ },
+ trim: {
+ value: function() { return this.replace(/^\s+|\s+$/g, ""); }
+ }
+});
+
+
+Date.timestamp = function() {
+ function pad(n, places) {
+ var str = ''+n;
+ if ( str.length >= places) {
+ return str;
+ }
+ return '0'.repeat(places - str.length) + str;
+ }
+ var now = new Date();
+ var timestamp = pad(now.getHours(), 2) + ':'
+ + pad( now.getMinutes(), 2) + ':'
+ + pad( now.getSeconds(), 2) + ' - '
+ + pad( now.getMilliseconds(), 3);
+ return timestamp;
+}
diff --git a/src/interpreter/imports/qtsystemtest/scripts/Exception.js b/src/interpreter/imports/qtsystemtest/scripts/Exception.js
new file mode 100644
index 0000000..25fdafb
--- /dev/null
+++ b/src/interpreter/imports/qtsystemtest/scripts/Exception.js
@@ -0,0 +1,105 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+Js.include_check(Qtt === undefined, 'Exception.js already included');
+Js.require('Class.js');
+Js.require('Console.js');
+
+var Qtt = function(){
+ var QttDebug = Console.topic('Qtt');
+
+ var Status = {
+ Error: 'error',
+ Passed: 'passed',
+ Failed: 'failed',
+ Skipped: 'skipped',
+ Aborted: 'aborted',
+ Untested: 'untested',
+ };
+
+ var QttError = Class.create(function QttError(msg, discardLevel) {
+ discardLevel = (discardLevel || 0 ) + 2;
+ this.name = arguments.callee.name;
+ this.stack = Qt.qst.stack();
+ Js.discardCallSites.call(this, discardLevel);
+ return {
+ status : Status.Error,
+ type: 'QttError',
+ message: msg,
+ __addStack : function(){},
+ discardCallSites: Js.discardCallSites,
+ toString: function() { return this.message; }
+ };
+ });
+
+ var Skip = QttError.extend(function Skip(msg, discardLevel) {
+ discardLevel = (discardLevel || 0 ) + 2;
+ this._super(msg, discardLevel);
+ this.type = 'Skip';
+ this.status = Status.Skipped;
+ return { };
+ });
+
+ var Abort = QttError.extend(function Abort(msg, discardLevel) {
+ discardLevel = (discardLevel || 0 ) + 2;
+ this._super(msg, discardLevel);
+ this.type = 'Abort';
+ this.status = Status.Aborted;
+ return { };
+ });
+
+ var Fail = QttError.extend(function Fail(msg, discardLevel) {
+ discardLevel = (discardLevel || 0 ) + 2;
+ this._super(msg, discardLevel);
+ this.type = 'Fail';
+ this.status =Status.Failed;
+ return { };
+ });
+
+
+ return {
+ Error: QttError,
+ Skip: Skip,
+ Fail: Fail,
+ Abort: Abort,
+ Status: Status
+ };
+}();
diff --git a/src/interpreter/imports/qtsystemtest/scripts/Expect.js b/src/interpreter/imports/qtsystemtest/scripts/Expect.js
new file mode 100644
index 0000000..fc7cee0
--- /dev/null
+++ b/src/interpreter/imports/qtsystemtest/scripts/Expect.js
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+Js.include_check(Expectation === undefined, 'Expect.js already included');
+Js.require('Class.js');
+Js.require('Exception.js');
+
+var Expectation = Class.create(function(actual, value){
+ var ok = value === undefined ? true : value;
+
+ function _not_() {
+ return ok === true? ' ' : ' not ';
+ }
+
+ function toBeBetween(low, high){
+ if ( ( low < actual && actual < high) !== ok) {
+ var msg = 'Expected actual value to be' + _not_() + 'between low and high value.';
+ var formatted = 'Expected (' + actual + ') to be' + _not_()
+ + 'between (' + low + ', ' + high + ')';
+ var e = new Qtt.Fail(msg, formatted, 2);
+ e.meta = {
+ actual: actual,
+ low: low,
+ high: high
+ };
+ throw e;
+ }
+ }
+
+ function toBe(expectation){
+ if ( (actual === expectation) !== ok) {
+ var msg = 'Expected actual value to be' + _not_() + 'expected value.';
+ var e = new Qtt.Fail(msg, 2);
+ e.meta = {
+ actual: actual,
+ expected: expectation
+ };
+ e.formatted = 'Expected (' + actual + ') to be' + _not_()
+ + '(' + expectation + ')';
+ throw e;
+ }
+ }
+
+ function toThrow(expection){
+ }
+
+ function instanceOf(expectation){
+ if( (actual instanceof expectation) !== ok) {
+ var msg = 'Expected actual value to be' + _not_() + 'an instance of expected type.';
+ var e = new Qtt.Fail(msg, 2);
+ e.meta = {
+ actual: actual,
+ expected: expectation.name
+ };
+ e.formated = 'Expected (' + actual + ') to be' + _not_()
+ + 'instance of (' + expectation.name + ')';
+ throw e;
+ }
+ }
+
+
+ return {
+ toBe: toBe,
+ toBeBetween: toBeBetween,
+ instanceOf: instanceOf
+ }
+});
+
+
+function expect(actual) {
+ var x = new Expectation(actual);
+ x.not = new Expectation(actual, false)
+ return x;
+}
diff --git a/src/interpreter/imports/qtsystemtest/scripts/Functional.js b/src/interpreter/imports/qtsystemtest/scripts/Functional.js
new file mode 100644
index 0000000..ddce3f8
--- /dev/null
+++ b/src/interpreter/imports/qtsystemtest/scripts/Functional.js
@@ -0,0 +1,298 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+.pragma library
+
+/*!
+ Returns a function that suppresses throwing the expection when the
+ function \a being wrapped either fails or throws an exception.
+
+ The exception generated is stored in an exception property.
+ The failed property indicates if the function threw an exception.
+
+ Usage:
+ \code
+ var itemExists = findUniqueItem.nothrow();
+ var item = itemExists({QMLTYPE: 'QQuickItem'});
+
+ if (!itemExists.failed) {
+ print(item.property('x'));
+ } else {
+ // item is undefined
+ fail(itemExists.exception.message);
+ }
+ \endcode
+*/
+Function.prototype.nothrow = function nothrow() {
+ var fn = this;
+ function nothrow() {
+ try {
+ var result = fn.apply(this, arguments);
+ arguments.callee.failed = false;
+ return result;
+ } catch(e) {
+ arguments.callee.exception = e;
+ arguments.callee.failed = true;
+ }
+ return undefined;
+ }
+
+ // reduce nothrow().nothrow() to a single nothrow
+ return fn.toString() === nothrow.toString() ? fn : nothrow;
+}
+
+/*!
+ Returns a function that retries the \a fn after every \a interval milliseconds
+ until it doesn't result in a 'fail' or times out after \a timeout milliseconds.
+
+ Usage:
+ \code
+ var item = findUniqueItem.retry({timeout: 1000, interval: 250});
+ var obj = item({QMLTYPE: 'Button', QMLID: 'aButton'})
+ \endcode
+
+ is equal to writing
+
+ \code
+ var obj;
+ var excp;
+ var timeout = 1000;
+ var poll = 250;
+ try {
+ expect( function() {
+ try {
+ obj = findUniqueItem({QMLTYPE: 'Button', QMLID: 'aButton'})
+ return true;
+ }catch(e) {
+ excp = e;
+ }
+ return false;
+ }, timeout, Math.floor(timeout/poll));
+ } catch(e) {
+ fail(excp.message, ' after ', timeout, 'ms' );
+ }
+ \endcode
+
+*/
+//Function.prototype.retry = function(config) {
+// if (!config){
+// throw new Error('Missing args: no timeout and interval specified. \n'
+// + 'Usage retry({timeout: <timeout>, interval: <interval> })');
+// }
+
+// if (typeof(config.timeout) !== 'number') {
+// throw new TypeError('timeout: not a number \n'
+// + 'Usage retry({timeout: <timeout>, interval: <interval> })');
+// }
+// if (typeof(config.interval) !== 'number') {
+// throw new TypeError('interval: not a number \n'
+// + 'Usage retry({timeout: <timeout>, interval: <interval> })');
+// }
+
+// var method = this.nothrow();
+
+// function retry() {
+// // store the original method
+// retry.original = this;
+// var result;
+// var args = Private.Utils.makeArray(arguments) ;
+// var passes = Private.Utils.poll(function autoPoll() {
+// result = method.apply(this, args);
+// return method.failed === false;
+// }, config.timeout, config.interval);
+
+// if (!passes) {
+// fail(method.exception.message, ' after ', config.timeout, ' ms');
+// }
+// return result;
+// }
+
+// // error on retry().retry();
+// if (this.toString() === retry.toString()) {
+// var originalMethod = this.original.name === '' ? '[anonymous]'
+// : this.original.name;
+// return new Error('Cannot create a retry version of already retry version of method: '
+// + originalMethod);
+// }
+// return retry;
+//}
+
+/*!
+ Partially intialize first few arguments of a function
+
+ \code
+ function sum(a, b) { return a+b;};
+ var add5 = sum.curry(5);
+ var x = add5(10); // x = 15 now
+ \endcode
+
+*/
+Function.prototype.bind = function(scope) {
+ var fn = this;
+ var toArray = Array.prototype.slice;
+ var args = toArray.call(arguments);
+ var scope = args.shift();
+ return function() {
+ return fn.apply(scope, args.concat(toArray.call(arguments)));
+ };
+};
+
+Function.prototype.curry = function() {
+ var fn = this;
+ var toArray = Array.prototype.slice;
+ var args = toArray.call(arguments);
+ return function() {
+ return fn.apply(this, args.concat( toArray.call(arguments)));
+ };
+};
+
+
+/*!
+ Partially intialize arguments of a function, using undefined as placeholders for
+ arguments to be filled in later.
+
+ \code
+ function sum(a, b) { return a+b;};
+ var add5 = sum.partial(undefined, 5);
+
+ var x = add5(10); // x = 15 now
+ \endcode
+
+*/
+Function.prototype.partial = function(){
+ var fn = this;
+ var toArray = Array.prototype.slice;
+ var partialArgs = toArray.call(arguments);
+ return function(){
+ var args = partialArgs.slice(); // copy partial
+ var arg = 0;
+ for ( var i = 0; i < args.length && arg < arguments.length; i++ ) {
+ if ( args[i] === undefined ) {
+ args[i] = arguments[arg++];
+ }
+ }
+ return fn.apply(this, args);
+ };
+}
+
+var FunctionHelper = function() {
+ /*!
+ Validate number of the arguments passed to a function \a fn, throws an exception
+ if the number of args passed to the \a fn is less than the minArgsRequired.
+
+ if no minimumArgs is passed, uses the number of named arguments in \a fn
+
+ Usage:
+ \code
+ var findItems = FunctionHelper.validateArgs(function findItems( filter, fetch, mode) {
+ }, 1); // ensures 1 arg is passed when findItems
+ \endcode
+ */
+ function validateArgs(fn, minArgsRequired) {
+ if( typeof(fn) !== 'function' || fn.name === '' ) {
+ throw new Error('The first argument to validateArgs should be a named function');
+ }
+ minArgsRequired = minArgsRequired || fn.length;
+ return function() {
+ if (arguments.length < minArgsRequired) {
+ fail(fn.name, ' expects atleast ', minArgsRequired,
+ ' arguments, whereas only ', arguments.length, ' passed');
+ }
+ return fn.apply(this, arguments)
+ };
+ }
+
+ /*!
+ Deprecates a function with the name \a fnName and replaced by \a replacedBy. Would print of the
+ msg if one is passed or generates one.
+
+ Usage:
+ \code
+ var findWidget = FunctionHelper.deprecate('findWidget', findItems);
+ or
+ var findWidget = FunctionHelper.deprecate('findWidget', findItems,
+ 'Usage of findWidget is deprecated, use findItems instead')
+ var findWidget = FunctionHelper.deprecate('findWidget',
+ {replacedBy: findItems, name: 'findItems'});
+ \endcode
+ */
+ function deprecate(fnName, replacedBy, msg, config) {
+ msg = msg || 'Usage of deprecated function: ' + fnName + ', use ' + replacedBy.name + ' instead.';
+ config = config || {
+ FailOnInvoke : false
+ };
+ return function() {
+ if ( config.FailOnInvoke ) {
+ throw new Error('Error: ' + msg);
+ }
+ warn(msg);
+ // use the function if replacedBy is a Function else if it an object, then use the replacedBy property
+ var fn = replacedBy instanceof Function ? replacedBy : replacedBy.replacedBy;
+ return fn.apply(this, arguments);
+ };
+ }
+
+
+ /*!
+ Helper function that wraps an object of type anything other than function
+ inside an anonymous function, invoking which returns the object;
+
+ Usage:
+ \code
+ var x = 10;
+ x = FunctionHelper.toFunction(x);
+ var y = x(); // y is 10;
+ \endcode
+ */
+ function toFunction(x) {
+ return typeof(x) === 'function' ? x : function(){ return x;};
+ }
+
+ function isFunction(x) {
+ return typeof(x) === 'function';
+ }
+ return {
+ validateArgs: validateArgs,
+ deprecate: deprecate,
+ toFunction: toFunction,
+ isFunction: isFunction
+ };
+}
diff --git a/src/interpreter/imports/qtsystemtest/scripts/ItemFactory.js b/src/interpreter/imports/qtsystemtest/scripts/ItemFactory.js
new file mode 100644
index 0000000..93c2a2f
--- /dev/null
+++ b/src/interpreter/imports/qtsystemtest/scripts/ItemFactory.js
@@ -0,0 +1,117 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// create a factory and make that singleton
+var ItemFactory = function() {
+ /// FIXME: itemshandlers can be resitered or unregistered at run time
+ /// so, the keyForObject.cache would get invalidated
+ var Factory = ComponentCacher.extend(function() {
+ this._super();
+ this.setFallbackToDefault(false);
+ var _handlerForItemCache = {};
+
+ function keyForObject(obj, application) {
+ var key = obj._type_;
+
+ function handlerExists(k) {
+ if ( this.fileForKey(k) !== null ) {
+ handlerExists.key = k;
+ return true;
+ }
+ return false;
+ }
+
+ // perfect match
+ if ( handlerExists.call(this, key) ) {
+ return key;
+ }
+
+ if ( key in _handlerForItemCache) {
+ return _handlerForItemCache[key];
+ }
+
+ var tree = application.__inheritanceTree(obj);
+ tree.shift();
+ var ret = tree.some(handlerExists, this)
+ ? handlerExists.key
+ : null;
+ _handlerForItemCache[key] = ret;
+ return ret;
+ }
+
+ function itemForKey(obj, props) {
+ if ( !('_type_' in obj ) ) {
+ throw new Qtt.Fail('Invalid object passed to handlerForObject: _type_ does not exist ', 2);
+ }
+
+ var key = keyForObject.call(this, obj, props.application);
+ if (key === null) {
+ throw new Qtt.Fail('Error finding a Item handler for: ' + obj._type_ , 2);
+ }
+ var component = this.componentForKey(key);
+ if (component === null) {
+ throw new Qtt.Fail('Error creating an Item handler for: ' + obj._type_ , 2);
+ }
+ return component;
+ }
+
+ function register(k, path) {
+ path = absolutePathOf(path);
+ this._super(k, path);
+ _handlerForItemCache = {};
+ }
+
+ function unregister(key) {
+ this._super(key);
+ _handlerForItemCache = {};
+ }
+
+ return {
+ handlerForObject: itemForKey,
+ register: register,
+ unregister: unregister
+ };
+ });
+ var singleton = new Factory();
+ singleton.register('QObject', '../qml/itemhandlers/QstObject.qml');
+ singleton.register('QWidget', '../qml/itemhandlers/QstWidget.qml');
+ return singleton;
+}();
diff --git a/src/interpreter/imports/qtsystemtest/scripts/JsCore.js b/src/interpreter/imports/qtsystemtest/scripts/JsCore.js
new file mode 100644
index 0000000..30b3736
--- /dev/null
+++ b/src/interpreter/imports/qtsystemtest/scripts/JsCore.js
@@ -0,0 +1,215 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+if( typeof(Js) !== 'undefined') {
+ Js.include_check(Js === undefined, 'JsCore.js already included');
+}
+
+Qt.include('Datatype.js')
+Qt.include('Functional.js');
+
+var Js = function() {
+
+ var Core = {
+ Error: {
+ maxStack: 17
+ }
+ };
+
+// var DebugEnabled = true;
+ var DebugEnabled = false;
+ function _debug() {
+ var str = '',
+ arg,
+ i,
+ now,
+ timestamp;
+
+ if (!DebugEnabled) {
+ return;
+ }
+
+ for (i =0; i<arguments.length; ++i) {
+ arg = arguments[i]
+ if (arg != null) {
+ str += arg.toString();
+ } else {
+ str += 'undefined'
+ }
+ }
+ console.log(Date.timestamp(), 'JsCore[Debug]:', str);
+ }
+
+ function discardCallSites(num) {
+ num = num || 1;
+ if (!this.stack) return;
+ var stack = this.stack;
+ if( stack.length < num ) {
+ _debug(' Error: insufficient stack depth');
+ throw new Error('Insufficient stack depth');
+ }
+ while ( num-- > 0 ) {
+ this.stack.shift();
+ }
+ }
+
+ var JsError = (function() {
+ function JsError(msg) {
+ Error.call(this);
+ this.message = msg;
+ this.name = arguments.callee.name;
+ this.stack = Qt.qst.stack();
+ this._discardCallSites();
+ }
+ JsError.prototype = new Error();
+ JsError.prototype._discardCallSites = discardCallSites;
+ return JsError;
+ })();
+
+ var IncludeError = (function() {
+ function IncludeError(msg) {
+ JsError.call(this, msg);
+ _debug(' Creating include error :', this.message);
+ this.name = arguments.callee.name;
+ this._discardCallSites();
+ }
+
+ IncludeError.prototype = new JsError();
+ IncludeError.prototype.constructor = IncludeError;
+ return IncludeError;
+ })();
+
+ function require(filename) {
+ require.level = require.level || 0;
+
+ function repeat(c, t){
+ var str = '';
+ for(var i=0; i< t; ++i){
+ str += c;
+ }
+ return str;
+ }
+ var spaces = repeat(' ', require.level*4);
+ _debug('including .... '+ spaces + (require.level !==0? '+--': '') + '[', filename, ']');
+
+ require.level++;
+ try {
+ var include = Qt.include(filename);
+ } catch(e) {
+ console.log('Exception caught loading', filename, e.message);
+ console.log('Stack', e.stack.join('\n'));
+ }
+
+ if( include && include.status === include.EXCEPTION) {
+ var ex = include.exception;
+ if (!(ex instanceof IncludeError) ) {
+ console.log('Exception including : ', filename, ': ', ex.message, ex.filename);
+ if ( ex.stack instanceof Array) {
+ ex.stack.forEach( function(cs) {
+ console.log( cs.fileName, ':', s.lineNumber);
+ });
+ }
+ throw ex;
+ } else {
+ _debug('Exception including : ', filename, " exception: ", ex);
+ }
+ }
+ // _debug('including .... [', filename, ']done');
+ require.level--;
+ }
+
+ function include_check(condition, msg) {
+ if(!condition) {
+ throw new IncludeError(msg);
+ }
+ }
+
+
+ var JsEngine = function() {
+ function callSite(depth) {
+ var stack = depth === undefined
+ ? Qt.qst.stack()
+ : Qt.qst.stack(depth++);
+ return stack;
+ }
+
+ function currentFile() {
+ var cs = callSite(3);
+ return cs.last().fileName;
+ }
+
+ function currentPath() {
+ var cs = callSite(3);
+ var filePath = cs.last().fileName;
+ var fileStart = filePath.lastIndexOf('/');
+ return filePath.substring(fileStart + 1);
+ }
+
+ function currentLine() {
+ var cs = callSite(3);
+ return cs.last().lineNumber;
+ }
+
+ return {
+ currentPath: currentPath,
+ currentFile: currentFile,
+ currentLine: currentLine,
+ callSite: callSite
+ }
+ }();
+
+ return {
+ require: require,
+ include_check: include_check,
+ Core: Core,
+ Error: JsError,
+ discardCallSites: discardCallSites,
+ Engine: JsEngine,
+ _debug: _debug,
+ }
+}();
+
+
+function assert(condition, msg) {
+ if (!condition) {
+ throw new JsError(msg);
+ }
+}
diff --git a/src/interpreter/imports/qtsystemtest/scripts/QstCore.js b/src/interpreter/imports/qtsystemtest/scripts/QstCore.js
new file mode 100644
index 0000000..da422be
--- /dev/null
+++ b/src/interpreter/imports/qtsystemtest/scripts/QstCore.js
@@ -0,0 +1,52 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+.pragma library
+
+Qt.include('JsCore.js');
+Js.require('SourceBuilder.js');
+
+Js.require('Class.js');
+Js.require('Console.js');
+Js.require('Exception.js');
+Js.require('Expect.js');
+Js.require('ApplicationRegistry.js');
+Js.require('ItemFactory.js');
diff --git a/src/interpreter/imports/qtsystemtest/scripts/SourceBuilder.js b/src/interpreter/imports/qtsystemtest/scripts/SourceBuilder.js
new file mode 100644
index 0000000..014f118
--- /dev/null
+++ b/src/interpreter/imports/qtsystemtest/scripts/SourceBuilder.js
@@ -0,0 +1,172 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+Js.include_check(SourceBuilder === undefined, 'SourceBuilder.js already included');
+
+var SourceBuilder = function() {
+ var DebugEnabled = false;
+ function debug(enabled){
+ if (enabled && DebugEnabled) {
+ console.log( msg(Array.prototype.slice.call(arguments)) );
+ }
+ }
+
+ function msg() {
+ var str = '';
+ for (var i =0; i<arguments.length; i++) {
+ var arg = arguments[i];
+ str += arg;
+ }
+ return str;
+ }
+
+ // converters
+ function arrayToString(a, level) {
+ if (a.length === 0 ) {
+ return '[]';
+ }
+
+ var str = '[';
+ var quote;
+ for (var i =0; i < a.length; ++i) {
+ quote = typeOf(a[i]) === 'String' ? "'" : '';
+ str += quote + stringify(a[i]) + quote;
+ str += i < (a.length -1) ? ', ' : ']'
+ }
+ return str;
+ }
+
+ function objectToString(obj, level) {
+ debug(DebugEnabled && msg(arguments.callee.name));
+
+ // if toString for the object is overridden then, use that version
+ if ( obj.toString !== Object.prototype.toString) {
+ return obj.toString();
+ }
+
+ var indentation = indentText.repeat(level);
+ var propertyCount = Object.keys(obj).length;
+ var terminator = propertyCount > 1 ? '\n': ''
+ var propertyIndentation = propertyCount > 1 ? (indentation + indentText) : ''
+ var objectType = typeOf(obj)
+
+ function stripObject(o) {
+ return o === 'Object' ? '' : o;
+ }
+ // don't print 'Object', if the type is Object
+ var str = stripObject(objectType) + '{' + terminator;
+ var contents = '';
+ for (var prop in obj) {
+ // add a quote if the value is of type string
+ var quote = typeof(obj[prop]) == 'string' ? "'" : '';
+
+ contents += propertyIndentation + prop + ': '
+ + quote + stringify(obj[prop], level+1) + quote
+ + ',' + terminator;
+ }
+ str += contents.slice(0, -(1 + terminator.length)); // remove the , at the end of contents
+ str += terminator + indentation + '}' + terminator;
+ return str;
+ }
+
+ function typeOf(o) {
+ debug(DebugEnabled && msg(arguments.callee.name));
+ if ( o === undefined ) return 'undefined';
+ if ( o === null ) return 'null';
+
+ // we have a valid object
+ var ctor = o.constructor.name;
+ return ctor.length === 0 ? 'Object' // no Object for a generic object
+ : ctor;
+ }
+
+ function sameObject(x){ return x; }
+ function toString(x){ return x.toString(); }
+ function qtuitestWidget(x){ return 'QtUiTestWidget( ' + x.toString() + ' )'; }
+ function qtuitestObject(x){ return 'QtUiTestObject( ' + x.toString() + ' )'; }
+
+ // converts obj to string
+ function stringify(obj, level) {
+ debug(DebugEnabled && msg(arguments.callee.name));
+ debug(DebugEnabled && msg('Finding type of :', obj) );
+ level = level || 0;
+
+ var typeConverters = {
+ 'null': typeOf,
+ 'undefined': typeOf,
+ 'Number': toString,
+ 'Boolean': toString,
+ 'Function': toString,
+ 'String': sameObject,
+ 'Array': arrayToString,
+ 'QtUiTestWidget': qtuitestWidget,
+ 'QtUiTestObject': qtuitestObject,
+ 'Object': objectToString
+ };
+
+ var type = typeOf(obj);
+ if ( type in typeConverters) {
+ debug(DebugEnabled && msg('Found converter for type: ' + type
+ + ', using converter :' + typeConverters[type].name));
+ return typeConverters[type](obj, level);
+ }
+ debug(DebugEnabled && msg('No converters Found for type: ' + type) );
+ // if no converters are registered, treat the type as an object and print it
+ return objectToString(obj, level);
+ }
+
+ var indentText = ' ';// .repeat(4); // 4 spaces for each level
+ return {
+ sourceFor: function sourceFor(obj) {
+ return stringify(obj);
+ }
+ };
+
+}// SourceBuilder
+
+function stringify() {
+ stringify.sb = stringify.sb || new SourceBuilder();
+ var str = '';
+ for (var i =0; i< arguments.length; ++i) {
+ str += stringify.sb.sourceFor(arguments[i]);
+ }
+ return str;
+}
diff --git a/src/interpreter/imports/qtsystemtest/scripts/api.js b/src/interpreter/imports/qtsystemtest/scripts/api.js
new file mode 100644
index 0000000..f9cf7a1
--- /dev/null
+++ b/src/interpreter/imports/qtsystemtest/scripts/api.js
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+.pragma library
+
+Qt.include('JsCore.js');
+Js.include_check(Private === undefined, 'api.js already included');
+
+
+function api() {
+ var component = Qt.createQmlObject(
+ 'import QtQuick 2.0;'
+ + 'import QtUiTest 1.0;'
+ + 'TestMethod {}', Js.__testRoot);
+ return component;
+}
+
+Js._debug(' api.js ... loaded');
diff --git a/src/interpreter/imports/qtsystemtest/src/imports.cpp b/src/interpreter/imports/qtsystemtest/src/imports.cpp
new file mode 100644
index 0000000..e8f1529
--- /dev/null
+++ b/src/interpreter/imports/qtsystemtest/src/imports.cpp
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "imports.h"
+#include "qstcoreapi.h"
+#include "qstutils.h"
+#include "qstlocalprocess.h"
+#include <QtDeclarative>
+
+#include <QtSystemTest/QstConnection>
+#include <QtSystemTest/QstConnectionManager>
+
+void QtSystemTestQmlModule::registerTypes(const char *uri)
+{
+ Q_ASSERT(QLatin1String(uri) == QLatin1String("QtSystemTest"));
+ qmlRegisterType<QstCoreApi>( uri, 1, 0, "CoreApi");
+ qmlRegisterType<QstConnection>( uri, 1, 0, "Connection");
+ qmlRegisterType<QstLocalProcess>( uri, 1, 0, "LocalProcess");
+}
+
+void QtSystemTestQmlModule::initializeEngine(QDeclarativeEngine *e, const char *uri)
+{
+ qDebug() << Q_FUNC_INFO << "Registering connection manager and Utils" << uri;
+ e->rootContext()->setContextProperty("ConnectionManager", new QstConnectionManager());
+ e->rootContext()->setContextProperty("Utils", new QstUtils());
+}
+
+Q_EXPORT_PLUGIN2(qtsystemtestplugin, QtSystemTestQmlModule);
diff --git a/src/interpreter/imports/qtsystemtest/src/imports.h b/src/interpreter/imports/qtsystemtest/src/imports.h
new file mode 100644
index 0000000..4a41b48
--- /dev/null
+++ b/src/interpreter/imports/qtsystemtest/src/imports.h
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef IMPORTS_H
+#define IMPORTS_H
+
+#include <QDeclarativeExtensionPlugin>
+
+class QDeclarativeEngine;
+
+class QtSystemTestQmlModule : public QDeclarativeExtensionPlugin
+{
+ Q_OBJECT
+
+public:
+ virtual void registerTypes(const char *uri);
+ void initializeEngine(QDeclarativeEngine *, const char *);
+};
+
+#endif // IMPORTS_H
diff --git a/src/interpreter/imports/qtsystemtest/src/qstcoreapi.cpp b/src/interpreter/imports/qtsystemtest/src/qstcoreapi.cpp
new file mode 100644
index 0000000..979070d
--- /dev/null
+++ b/src/interpreter/imports/qtsystemtest/src/qstcoreapi.cpp
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qstcoreapi.h"
+
+#include <QtCore/QDebug>
+#include <QtTest/QTest>
+
+QstCoreApi::QstCoreApi(QObject *parent) :
+ QObject(parent)
+{
+}
+
+void QstCoreApi::sleep(int ms)
+{
+ QTest::qSleep(ms);
+}
+
diff --git a/src/interpreter/imports/qtsystemtest/src/qstcoreapi.h b/src/interpreter/imports/qtsystemtest/src/qstcoreapi.h
new file mode 100644
index 0000000..4efc473
--- /dev/null
+++ b/src/interpreter/imports/qtsystemtest/src/qstcoreapi.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSTCOREAPI_H
+#define QSTCOREAPI_H
+
+#include <QtCore/QObject>
+#include <QtCore/QVariantMap>
+
+class QSystemTestMaster;
+
+class QstCoreApi : public QObject
+{
+ Q_OBJECT
+public:
+ explicit QstCoreApi(QObject *parent = 0);
+
+ static const QLatin1String signatureProperty;
+ static const QLatin1String appIdProperty;
+ static const QLatin1String widgetSpecifierProperty;
+
+signals:
+
+public slots:
+ void sleep(int ms);
+ bool connectApplication(const QString &host, int port);
+
+ private:
+
+ QSystemTestMaster *m_test_app;
+};
+
+#endif // QSTCOREAPI_H
diff --git a/src/interpreter/imports/qtsystemtest/src/qstlocalprocess.cpp b/src/interpreter/imports/qtsystemtest/src/qstlocalprocess.cpp
new file mode 100644
index 0000000..cf60379
--- /dev/null
+++ b/src/interpreter/imports/qtsystemtest/src/qstlocalprocess.cpp
@@ -0,0 +1,167 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qstlocalprocess.h"
+
+#include <QtCore/QTextCodec>
+
+QstLocalProcess::QstLocalProcess(QObject *parent) :
+ QProcess(parent),
+ m_inputCodec(0),
+ m_outputCodec(0),
+ m_outputDecoder(0),
+ m_errorDecoder(0),
+ m_outputMode(DeviceOutput)
+{
+ m_inputCodec = QTextCodec::codecForLocale();
+ m_outputCodec = QTextCodec::codecForLocale();
+
+ connect(this, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(forwardFinished(int, QProcess::ExitStatus)));
+}
+
+void QstLocalProcess::start(const QString &program, const QStringList &arguments)
+{
+ QProcess::start(program, arguments, QIODevice::ReadWrite);
+}
+
+bool QstLocalProcess::waitForStarted(int msecs)
+{
+ return QProcess::waitForStarted(msecs);
+}
+
+bool QstLocalProcess::waitForFinished(int msecs)
+{
+ return QProcess::waitForFinished(msecs);
+}
+
+bool QstLocalProcess::waitForReadyRead(int msecs)
+{
+ return QProcess::waitForReadyRead(msecs);
+}
+
+void QstLocalProcess::closeWriteChannel()
+{
+ QProcess::closeWriteChannel();
+}
+
+QProcess::ProcessState QstLocalProcess::state() const
+{
+ return QProcess::state();
+}
+
+QProcess::ExitStatus QstLocalProcess::exitStatus() const
+{
+ return QProcess::exitStatus();
+}
+
+int QstLocalProcess::exitCode() const
+{
+ return QProcess::exitCode();
+}
+
+QString QstLocalProcess::inputCodec() const
+{
+ return QString::fromLatin1(m_inputCodec->name());
+}
+
+void QstLocalProcess::setInputCodec(const QString &name)
+{
+ m_inputCodec = QTextCodec::codecForName(name.toLatin1().constData());
+}
+
+QString QstLocalProcess::outputCodec() const
+{
+ return QString::fromLatin1(m_outputCodec->name());
+}
+
+void QstLocalProcess::setOutputCodec(const QString &name)
+{
+ if (name == outputCodec())
+ return;
+ m_outputCodec = QTextCodec::codecForName(name.toLatin1().constData());
+ delete m_outputDecoder;
+ delete m_errorDecoder;
+ m_outputDecoder = 0;
+ m_errorDecoder = 0;
+}
+
+void QstLocalProcess::setOutputMode(OutputMode mode)
+{
+ if (mode == m_outputMode)
+ return;
+ m_outputMode = mode;
+ if (m_outputMode == DeviceOutput) {
+ disconnect(this, SIGNAL(readyReadStandardOutput()), this, SLOT(updateOutputBuffer()));
+ disconnect(this, SIGNAL(readyReadStandardError()), this, SLOT(updateErrorBuffer()));
+ } else {
+ setProcessChannelMode(SeparateChannels);
+ connect(this, SIGNAL(readyReadStandardOutput()), this, SLOT(updateOutputBuffer()));
+ connect(this, SIGNAL(readyReadStandardError()), this, SLOT(updateErrorBuffer()));
+ updateOutputBuffer();
+ updateErrorBuffer();
+ }
+}
+void QstLocalProcess::updateOutputBuffer()
+{
+ QByteArray bytes = readAllStandardOutput();
+ if (!bytes.isEmpty()) {
+ if (!m_outputDecoder)
+ m_outputDecoder = m_outputCodec->makeDecoder();
+ m_stdoutBuffer.append(m_outputDecoder->toUnicode((bytes)));
+ emit standardOutputChanged(m_stdoutBuffer);
+ }
+}
+
+void QstLocalProcess::updateErrorBuffer()
+{
+ QByteArray bytes = readAllStandardOutput();
+ if (!bytes.isEmpty()) {
+ if (!m_errorDecoder)
+ m_errorDecoder = m_outputCodec->makeDecoder();
+ m_stderrBuffer.append(m_errorDecoder->toUnicode((bytes)));
+ emit standardErrorChanged(m_stderrBuffer);
+ }
+}
+
+void QstLocalProcess::write(const QString &input)
+{
+ QProcess::write(m_inputCodec->fromUnicode(input));
+}
diff --git a/src/interpreter/imports/qtsystemtest/src/qstlocalprocess.h b/src/interpreter/imports/qtsystemtest/src/qstlocalprocess.h
new file mode 100644
index 0000000..215ee36
--- /dev/null
+++ b/src/interpreter/imports/qtsystemtest/src/qstlocalprocess.h
@@ -0,0 +1,131 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSTLOCALPROCESS_H
+#define QSTLOCALPROCESS_H
+
+#include <QtCore/QProcess>
+
+class QTextCodec;
+class QTextDecoder;
+
+class QstLocalProcess : public QProcess
+{
+ Q_OBJECT
+ Q_ENUMS(ProcessState ExitStatus OutputMode)
+
+ Q_PROPERTY(ProcessState state READ state NOTIFY stateChanged)
+ Q_PROPERTY(ExitStatus exitStatus READ exitStatus NOTIFY exitStatusChanged)
+ Q_PROPERTY(int exitCode READ exitCode NOTIFY exitCodeChanged)
+
+ Q_PROPERTY(QString standardOutput READ standardOutput NOTIFY standardOutputChanged)
+ Q_PROPERTY(QString standardError READ standardError NOTIFY standardErrorChanged)
+
+ Q_PROPERTY(QString inputCodec READ inputCodec WRITE setInputCodec)
+ Q_PROPERTY(QString outputCodec READ outputCodec WRITE setOutputCodec)
+
+ Q_PROPERTY(OutputMode outputMode READ outputMode WRITE setOutputMode)
+
+public:
+ explicit QstLocalProcess(QObject *parent = 0);
+
+ enum OutputMode {
+ DeviceOutput,
+ PropertyOutput
+ };
+
+ Q_INVOKABLE void start(const QString &program, const QStringList &arguments = QStringList());
+ Q_INVOKABLE bool waitForStarted(int msecs);
+ Q_INVOKABLE bool waitForFinished(int msecs);
+ Q_INVOKABLE bool waitForReadyRead(int msecs);
+ Q_INVOKABLE void closeWriteChannel();
+
+ Q_INVOKABLE ProcessState state() const;
+ Q_INVOKABLE ExitStatus exitStatus() const;
+ Q_INVOKABLE int exitCode() const;
+
+ Q_INVOKABLE void write(const QString &input);
+
+ QString standardOutput() const { return m_stdoutBuffer; }
+ Q_INVOKABLE void clearStandardOutput()
+ { m_stdoutBuffer.clear(); emit standardOutputChanged(m_stdoutBuffer); }
+
+ QString standardError() const { return m_stderrBuffer; }
+ Q_INVOKABLE void clearStandardError()
+ { m_stderrBuffer.clear(); emit standardErrorChanged(m_stderrBuffer); }
+
+ QString inputCodec() const;
+ QString outputCodec() const;
+ void setInputCodec(const QString &);
+ void setOutputCodec(const QString &);
+
+ OutputMode outputMode() const { return m_outputMode; }
+ void setOutputMode(OutputMode mode);
+
+signals:
+ void stateChanged(QProcess::ProcessState state);
+ void exitStatusChanged(QProcess::ExitStatus status);
+ void exitCodeChanged(int);
+ void standardOutputChanged(const QString &);
+ void standardErrorChanged(const QString &);
+
+private slots:
+ void forwardFinished(int code, QProcess::ExitStatus status)
+ {
+ emit exitStatusChanged(status);
+ emit exitCodeChanged(code);
+ }
+
+ void updateOutputBuffer();
+ void updateErrorBuffer();
+
+private:
+ QTextCodec *m_inputCodec;
+ QTextCodec *m_outputCodec;
+ QTextDecoder *m_outputDecoder;
+ QTextDecoder *m_errorDecoder;
+ OutputMode m_outputMode;
+
+ QString m_stdoutBuffer;
+ QString m_stderrBuffer;
+};
+
+#endif // QSTLOCALPROCESS_H
diff --git a/src/interpreter/imports/qtsystemtest/src/qstutils.cpp b/src/interpreter/imports/qtsystemtest/src/qstutils.cpp
new file mode 100644
index 0000000..c826094
--- /dev/null
+++ b/src/interpreter/imports/qtsystemtest/src/qstutils.cpp
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qstutils.h"
+#include <QtCore/QUrl>
+#include <QtCore/QDir>
+
+QstUtils::QstUtils(QObject *parent)
+ : QObject(parent)
+{
+}
+
diff --git a/src/interpreter/imports/qtsystemtest/src/qstutils.h b/src/interpreter/imports/qtsystemtest/src/qstutils.h
new file mode 100644
index 0000000..46f68b3
--- /dev/null
+++ b/src/interpreter/imports/qtsystemtest/src/qstutils.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSTUTILS_H
+#define QSTUTILS_H
+
+#include <QObject>
+class QUrl;
+class QScriptValue;
+
+class QstUtils : public QObject
+{
+ Q_OBJECT
+public:
+ explicit QstUtils(QObject *parent = 0);
+
+signals:
+
+public slots:
+
+};
+
+#endif // QSTUTILS_H
diff --git a/src/interpreter/imports/qtsystemtest/src/qtuitestglobal.h b/src/interpreter/imports/qtsystemtest/src/qtuitestglobal.h
new file mode 100644
index 0000000..66a0cef
--- /dev/null
+++ b/src/interpreter/imports/qtsystemtest/src/qtuitestglobal.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QTUITEST_GLOBAL_H
+#define QTUITEST_GLOBAL_H
+
+#include <QtGlobal>
+
+#if defined(Q_OS_WIN32)
+# if defined(QTUITEST_TARGET)
+# define QTUITEST_EXPORT Q_DECL_EXPORT
+# else
+# define QTUITEST_EXPORT Q_DECL_IMPORT
+# endif
+# if defined(QTSLAVE_TARGET)
+# define QTSLAVE_EXPORT Q_DECL_EXPORT
+# else
+# define QTSLAVE_EXPORT Q_DECL_IMPORT
+# endif
+#else
+# define QTUITEST_EXPORT Q_DECL_EXPORT
+# define QTSLAVE_EXPORT Q_DECL_EXPORT
+#endif
+
+#if defined(Q_OS_WIN32) || defined(Q_OS_SYMBIAN)
+# if defined(QSYSTEMTEST_TARGET)
+# define QSYSTEMTEST_EXPORT Q_DECL_EXPORT
+# else
+# define QSYSTEMTEST_EXPORT Q_DECL_IMPORT
+# endif
+# if defined(QTUITESTRUNNER_TARGET)
+# define QTUITESTRUNNER_EXPORT Q_DECL_EXPORT
+# else
+# define QTUITESTRUNNER_EXPORT Q_DECL_IMPORT
+# endif
+#else
+# define QSYSTEMTEST_EXPORT Q_DECL_EXPORT
+# define QTUITESTRUNNER_EXPORT Q_DECL_EXPORT
+#endif
+
+#define xstr(s) str(s)
+#define str(s) #s
+#define QTUITEST_VERSION_STR xstr(QTUITEST_VERSION)
+
+#endif
diff --git a/src/interpreter/imports/runner/qml/Config.qml b/src/interpreter/imports/runner/qml/Config.qml
new file mode 100644
index 0000000..9b5ae0e
--- /dev/null
+++ b/src/interpreter/imports/runner/qml/Config.qml
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.1
+
+QtObject {
+ property variant remotes: ({
+ localhost: {
+ address: 'localhost',
+ port: 5656
+ }
+ })
+
+ property list<Logger> loggers: [
+ PlainTextLogger{ },
+ XmlLogger {
+ path: 'result.xml'
+ }
+ ]
+}
diff --git a/src/interpreter/imports/runner/qml/Logger.qml b/src/interpreter/imports/runner/qml/Logger.qml
new file mode 100644
index 0000000..2ec66d9
--- /dev/null
+++ b/src/interpreter/imports/runner/qml/Logger.qml
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.1
+
+QtObject {
+ id: logger
+ property variant runner: null
+ property list<QtObject> __list
+ property string path
+ default property alias children : logger.__list
+
+ function setup() {
+ runner = __runner;
+ }
+
+ function locationOf(item) {
+ var ret = {
+ fileName : '',
+ lineNumber: 0
+ };
+
+ var loc = runner.locationOf(item);
+ if (loc.url === undefined) {
+ return ret;
+ }
+ var url = loc.url.toString();
+ ret.fileName = url.substr(url.lastIndexOf('/')+1);
+ ret.lineNumber = loc.lineNumber;
+ return ret;
+ }
+
+
+ onRunnerChanged: {
+ if (runner == undefined || runner == null) return;
+ runner.aboutToStartExecution.connect(aboutToStartExecution);
+ runner.finishedExecution.connect(finishedExecution);
+ runner.testCollectionStart.connect(testCollectionStart);
+ runner.testCollectionEnd.connect(testCollectionEnd);
+
+ runner.testStart.connect(testStart);
+ runner.testEnd.connect(testEnd);
+
+ runner.methodStart.connect(methodStart);
+ runner.methodEnd.connect(methodEnd);
+ }
+
+ function aboutToStartExecution() { }
+ function finishedExecution() { }
+
+ function testCollectionStart(testCollection) { }
+ function testCollectionEnd(testCollection) { }
+
+ function testStart(testCollection) { }
+ function testEnd(testCollection) { }
+
+ function methodStart(method) { }
+ function methodEnd(method) { }
+
+ function cleanup() { }
+
+ function log(type, event) { }
+}
diff --git a/src/interpreter/imports/runner/qml/PlainTextLogger.qml b/src/interpreter/imports/runner/qml/PlainTextLogger.qml
new file mode 100644
index 0000000..ab05906
--- /dev/null
+++ b/src/interpreter/imports/runner/qml/PlainTextLogger.qml
@@ -0,0 +1,162 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.1
+import QtSystemTest.Runner 1.0
+
+Logger {
+ id: plaintextLogger
+
+ property PlainTextWriter writer: PlainTextWriter {}
+
+ property int indentLevel : 0
+ property bool writeFinished : true
+ property string indentString: ' '
+ property int maxNameLen: 60
+
+ property variant status : ({
+ });
+
+ function aboutToStartExecution() {
+ writer.filePath = plaintextLogger.path;
+ }
+
+ function testCollectionStart(testCollection) {
+ var loc = locationOf(testCollection);
+ logString( 'Collection', pad("'"+ testCollection.name + "' ", maxNameLen - 2*indentLevel)
+ + ' : ' + loc.fileName + '('+ loc.lineNumber +')');
+ indentLevel++;
+ }
+
+ function testStart(test) { var loc = locationOf(test);
+ logString( 'Test', pad("'"+test.name + "' ", maxNameLen - 2*indentLevel)
+ + ' : ' + loc.fileName + '('+ loc.lineNumber +')');
+ indentLevel++;
+ }
+
+
+ function methodStart(method) {
+ logString('Running', method + '()');
+ writeFinished = false;
+ indentLevel++;
+ }
+
+ function methodEnd(method) {
+ indentLevel--;
+ if ( writeFinished ) {
+ logString('Finished', method + '()');
+ }
+ }
+
+ function testEnd(test) {
+ indentLevel--;
+ var statusMap = {
+ error: { text: 'ERROR', foreground: PlainTextWriter.White, background: PlainTextWriter.Red },
+ passed: { text: 'passed', foreground: PlainTextWriter.Green, background: PlainTextWriter.DefaultColor },
+ skipped: { text: 'skipped', foreground: PlainTextWriter.Yellow, background: PlainTextWriter.DefaultColor },
+ failed: { text: 'FAILED', foreground: PlainTextWriter.Red, background: PlainTextWriter.DefaultColor },
+ untested: { text: 'UNTESTED', foreground: PlainTextWriter.LightRed, background: PlainTextWriter.DefaultColor }
+ };
+
+ var result = test.__status.toLowerCase();
+ var status = statusMap[result];
+ logString( 'Result', pad("'"+test.name + "' ", maxNameLen - 2*indentLevel, '.')
+ + ' : [' + writer.colorize(status.text, status.foreground, status.background) + ']');
+ }
+
+ function testCollectionEnd(testCollection) {
+ indentLevel--;
+ logString( 'Collection', testCollection.name );
+ }
+
+
+ function finishedExecution() {
+ write('-'.repeat(80));
+ var report = runner.report;
+ var totalTests = 0;
+ var keys = ['error', 'passed', 'skipped', 'failed', 'untested'];
+ keys.forEach(function(s) {
+ totalTests += report[s];
+ });
+ write(pad('Total Tests', 15) + ' :' + totalTests);
+
+ keys.forEach(function(s) {
+ if (report[s] > 0 ) {
+ write(pad(s, 15) + ' :' + report[s]);
+ }
+ });
+ write('-'.repeat(80));
+ }
+
+
+ function log(type, event) {
+ var str = event.formatted || event.message;
+ if (event.stack) {
+ event.stack.forEach(function(callSite) {
+ var trace = Qt.qst.relativeToCurrentPath(callSite.fileName)
+ + '(' + callSite.lineNumber +') : '
+ + callSite.functionName;
+ str += '\n';
+ str += trace;
+ });
+ }
+ logString(type, str);
+ }
+
+ function logString(type, str) {
+ writeFinished = true;
+ write(pad(type, 10) + ' : ' + str);
+ }
+
+ function write(str) {
+ var strs = str.split('\n');
+ var prefix = '[' + Date.timestamp() + ']'+ indentString.repeat(indentLevel) + ' ';
+ for (var i = 0; i < strs.length; ++i) {
+ writer.writeLine(prefix + strs[i]);
+ }
+ }
+
+ function pad(text, len, using) {
+ using = using || ' '
+ var padding = text.length < len ? using.repeat(len - text.length) : '';
+ return text + padding;
+ }
+}
diff --git a/src/interpreter/imports/runner/qml/XUnitLogger.qml b/src/interpreter/imports/runner/qml/XUnitLogger.qml
new file mode 100644
index 0000000..fb66d3c
--- /dev/null
+++ b/src/interpreter/imports/runner/qml/XUnitLogger.qml
@@ -0,0 +1,172 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtSystemTest 1.0
+import QtSystemTest.Runner 1.0
+
+Logger {
+ id: xunitLogger
+
+ property var writer: XUnitWriter {
+ filePath: xunitLogger.path
+ }
+
+ property var tests: []
+ property var currentTest
+ property var msecsMarker: 0
+ property var collectionStack: 0
+ property var lastCollection: '';
+
+ function aboutToStartExecution() {
+ writer.writeStartDocument();
+ writer.writeStartTestSuiteSet();
+ }
+
+ function finishedExecution() {
+ writer.writeEndTestSuiteSet();
+ writer.writeEndDocument();
+ }
+
+ function testCollectionStart(testCollection) {
+ if (!collectionStack) {
+ tests = [];
+ msecsMarker = new Date;
+ }
+ lastCollection = testCollection.name;
+ collectionStack++;
+ }
+
+ function testCollectionEnd(testCollection) {
+ collectionStack--;
+ if (collectionStack)
+ return;
+
+ var Status = Core.Qtt.Status;
+
+ var passed = 0;
+ var failed = 0;
+ var skipped = 0;
+ var errors = 0;
+ var i;
+ var test;
+ for (i = 0; i < tests.length; i++) {
+ test = tests[i];
+ switch(test.state) {
+ case Status.Passed:
+ passed++;
+ break;
+ case Status.Failed:
+ failed++;
+ break;
+ default:
+ case Status.Skipped:
+ case Status:Untested:
+ skipped++;
+ break;
+ case Status.Error:
+ errors++;
+ break;
+ }
+ }
+ writer.writeStartTestSuite(
+ testCollection.name,
+ msecsMarker,
+ 'localhost',
+ passed + failed + skipped + errors,
+ failed,
+ errors,
+ skipped,
+ (+(new Date()) - msecsMarker.getTime())/1000);
+ for (i = 0; i < tests.length; i++) {
+ test = tests[i];
+ writer.writeStartTestCase(test.classname, test.name, test.duration);
+ var message;
+ if (test.messages.length > 0) {
+ message = test.messages[test.messages.length-1];
+ var messageWritten;
+ switch(message.type) {
+ case Status.Error:
+ writer.writeError(message.type, message.message);
+ break;
+ case Status.Failed:
+ writer.writeFailure(message.type, message.message);
+ break;
+ case Status.Skipped:
+ case Status.Untested:
+ writer.writeSkipped(message.type, message.message);
+ break;
+ default:
+ break;
+ }
+ }
+
+ writer.writeEndTestCase();
+ }
+ writer.writeEndTestSuite();
+ }
+
+ function testStart(test) {
+ currentTest = {
+ state: Core.Qtt.Status.Passed,
+ time: +(new Date()),
+ classname: lastCollection,
+ name: test.name,
+ messages: []
+ };
+ }
+ function testEnd(test) {
+ currentTest.duration = (+(new Date()) - currentTest.time)/1000;
+ currentTest.state = test.__status
+ if (test.__status === Core.Qtt.Status.Untested) {
+ currentTest.messages.push({type: test.__status, message: 'No verifiable steps performed'});
+
+ }
+
+ tests.push(currentTest);
+
+ }
+
+ function cleanup() { }
+
+ function log(type, msg) {
+ currentTest.messages.push({type: type, message: msg});
+ }
+}
diff --git a/src/interpreter/imports/runner/qml/XmlLogger.qml b/src/interpreter/imports/runner/qml/XmlLogger.qml
new file mode 100644
index 0000000..951eb59
--- /dev/null
+++ b/src/interpreter/imports/runner/qml/XmlLogger.qml
@@ -0,0 +1,178 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtSystemTest 1.0
+import QtSystemTest.Runner 1.0
+
+Logger {
+ id: xmlLogger
+ property XmlWriter writer: XmlWriter {}
+
+ property Js js : Js{}
+ function store(){}
+
+ function aboutToStartExecution() {
+ store.timerStack = [];
+ writer.filePath = xmlLogger.path;
+ writer.writeStartDocument();
+ writer.writeStartElement('systemtestrun');
+ store.timerStack.push(+new Date);
+ }
+
+ function finishedExecution() {
+ var duration = (+new Date) - store.timerStack.pop();
+
+ writer.writeStartElement('report');
+
+ var report = runner.report;
+ var totalTests = 0;
+ var keys = ['passed', 'skipped', 'untested', 'failed', 'error'];
+ keys.forEach(function(s) {
+ totalTests += report[s];
+ writer.writeTextElement(s, report[s].toString());
+ });
+ writer.writeTextElement('total', totalTests.toString());
+ writer.writeTextElement('duration', duration);
+ writer.writeEndElement(); // report
+ writer.writeEndElement(); // systemtestrun
+ writer.writeEndDocument();
+ }
+
+ function testCollectionStart(testCollection) {
+ var loc = locationOf(testCollection);
+ writer.writeStartElement('collection');
+ writer.writeAttribute('name', testCollection.name);
+ writer.writeAttribute('file', loc.fileName);
+ writer.writeAttribute('line', loc.lineNumber);
+ writer.writeAttribute('timestamp', (new Date).toISOString());
+ store.timerStack.push(+new Date);
+ }
+
+ function testCollectionEnd(testCollection) {
+ var duration = (+new Date) - store.timerStack.pop();
+ writer.writeStartElement('report');
+ writer.writeTextElement('duration', duration);
+ writer.writeEndElement();
+ writer.writeEndElement();
+ }
+
+ function testStart(test) {
+ var loc = locationOf(test);
+ writer.writeStartElement('test');
+ writer.writeAttribute('name', test.name);
+ writer.writeAttribute('file', loc.fileName);
+ writer.writeAttribute('line', loc.lineNumber);
+ writer.writeAttribute('timestamp', (new Date).toISOString());
+ store.timerStack.push(+new Date);
+ }
+
+ function testEnd(test) {
+ var duration = (+new Date) - store.timerStack.pop();
+ writer.writeStartElement('report');
+ writer.writeTextElement('status', test.__status.toLowerCase());
+ writer.writeTextElement('duration', duration);
+ writer.writeEndElement();
+ writer.writeEndElement();
+ }
+
+ function methodStart(method) {
+ writer.writeStartElement('method');
+ writer.writeAttribute('name', method);
+ }
+
+ function methodEnd(method) {
+ writer.writeEndElement();
+ }
+
+ function writeFrame(callSite) {
+ var path = Qt.qst.relativeToCurrentPath(callSite.fileName);
+ writer.writeStartElement('frame');
+ writer.writeAttribute('file', path);
+ writer.writeAttribute('line', callSite.lineNumber);
+ writer.writeCharacters(callSite.functionName);
+ writer.writeEndElement();
+ }
+
+ function writeEventContents(event)
+ {
+ var Core = js.core();
+ var stringify = Core.stringify.nothrow();
+ writer.writeTextElement('reason', event.message);
+ if (event.stack) {
+ writer.writeStartElement('stack');
+ event.stack.forEach(writeFrame.bind(this));
+ writer.writeEndElement();
+ }
+ if (event.meta) {
+ writer.writeStartElement('meta')
+ for(var part in event.meta) {
+ var asString = stringify(event.meta[part]);
+ writer.writeStartElement('property');
+ writer.writeAttribute('name', part);
+ writer.writeCharacters(stringify.failed ? 'opaque object' : asString);
+ writer.writeEndElement();
+ }
+ writer.writeEndElement();
+ }
+ }
+
+ function log(type, event) {
+ var ltype = type.toLowerCase();
+ switch(ltype) {
+ case 'passed':
+ case 'skipped':
+ case 'failed':
+ case 'error':
+ case 'untested':
+ writer.writeStartElement(ltype);
+ writeEventContents(event);
+ writer.writeEndElement();
+ break;
+ default:
+ writer.writeStartElement('note');
+ writer.writeAttribute('type', ltype);
+ writeEventContents(event);
+ writer.writeEndElement();
+ break;
+ }
+ }
+
+}
diff --git a/src/interpreter/imports/runner/qmldir b/src/interpreter/imports/runner/qmldir
new file mode 100644
index 0000000..89362d2
--- /dev/null
+++ b/src/interpreter/imports/runner/qmldir
@@ -0,0 +1,7 @@
+plugin qtsystemtestrunner
+Logger 1.0 qml/Logger.qml
+PlainTextLogger 1.0 qml/PlainTextLogger.qml
+XUnitLogger 1.0 qml/XUnitLogger.qml
+XmlLogger 1.0 qml/XmlLogger.qml
+Config 1.0 qml/Config.qml
+
diff --git a/src/interpreter/imports/runner/qtsystemtestrunner.json b/src/interpreter/imports/runner/qtsystemtestrunner.json
new file mode 100644
index 0000000..0967ef4
--- /dev/null
+++ b/src/interpreter/imports/runner/qtsystemtestrunner.json
@@ -0,0 +1 @@
+{}
diff --git a/src/interpreter/imports/runner/runner.pro b/src/interpreter/imports/runner/runner.pro
new file mode 100644
index 0000000..438c683
--- /dev/null
+++ b/src/interpreter/imports/runner/runner.pro
@@ -0,0 +1,70 @@
+TARGET = qtsystemtestrunner
+TARGETPATH = QtSystemTest/Runner
+
+TEMPLATE = lib
+CONFIG += no_clean qt plugin
+QT += declarative declarative-private
+
+
+SOURCES += src/imports.cpp \
+ src/qstxunitwriter.cpp \
+ src/qstlogwriter.cpp \
+
+HEADERS += src/imports.h \
+ src/qstxunitwriter.h \
+ src/qstlogwriter.h \
+
+OTHER_FILES += \
+ qtsystemtest.json \
+
+target.path += $$[QT_INSTALL_IMPORTS]/QtSystemTest/Runner
+
+# public api
+QML_IMPORT_FILES = \
+ qml/Config.qml \
+ qml/Logger.qml \
+ qml/PlainTextLogger.qml \
+ qml/XmlLogger.qml \
+ qml/XUnitLogger.qml
+
+qmlImportFiles.files += $$QML_IMPORT_FILES
+qmlImportFiles.path = $$[QT_INSTALL_IMPORTS]/$$TARGETPATH/qml
+
+# scripts
+#SCRIPT_FILES = \
+# scripts/api.js \
+# scripts/Datatype.js \
+# scripts/Functional.js \
+# scripts/JsCore.js \
+# scripts/SourceBuilder.js \
+# scripts/Class.js \
+# scripts/QstCore.js \
+# scripts/Console.js \
+# scripts/Expect.js \
+# scripts/Exception.js \
+# scripts/ApplicationRegistry.js \
+
+#scriptFiles.files += $$SCRIPT_FILES
+#scriptFiles.path = $$[QT_INSTALL_IMPORTS]/$$TARGETPATH/scripts
+
+# qmldir
+QMLDIR_FILE = qmldir
+qmldirFile.files += $$QMLDIR_FILE
+qmldirFile.path = $$[QT_INSTALL_IMPORTS]/$$TARGETPATH
+
+# show in QtCreator
+OTHER_FILES += $$QML_IMPORT_FILES \
+# $$SCRIPT_FILES \
+ qmldir \
+
+
+INSTALLS += qmlImportFiles qmldirFile target
+
+
+
+
+
+
+
+
+
diff --git a/src/interpreter/imports/runner/src/imports.cpp b/src/interpreter/imports/runner/src/imports.cpp
new file mode 100644
index 0000000..a2852d9
--- /dev/null
+++ b/src/interpreter/imports/runner/src/imports.cpp
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "imports.h"
+#include "qstxunitwriter.h"
+#include <QtDebug>
+#include <QtDeclarative>
+
+void QtSystemTestRunnerModule::registerTypes(const char *uri)
+{
+ qDebug() << Q_FUNC_INFO << uri;
+ Q_ASSERT(QLatin1String(uri) == QLatin1String("QtSystemTest.Runner"));
+ qmlRegisterType<QstPlainTextWriter>(uri, 1, 0, "PlainTextWriter");
+ qmlRegisterType<QstXmlStreamWriter>(uri, 1, 0, "XmlWriter");
+ qmlRegisterType<QstXUnitWriter>(uri, 1, 0, "XUnitWriter");
+}
+
+void QtSystemTestRunnerModule::initializeEngine(QDeclarativeEngine *, const char *)
+{
+}
+
+Q_EXPORT_PLUGIN2(qtsystemtestrunner, QtSystemTestRunnerModule);
diff --git a/src/interpreter/imports/runner/src/imports.h b/src/interpreter/imports/runner/src/imports.h
new file mode 100644
index 0000000..f424a95
--- /dev/null
+++ b/src/interpreter/imports/runner/src/imports.h
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef IMPORTS_H
+#define IMPORTS_H
+
+#include <QDeclarativeExtensionPlugin>
+
+class QDeclarativeEngine;
+
+class QtSystemTestRunnerModule : public QDeclarativeExtensionPlugin
+{
+ Q_OBJECT
+
+public:
+ virtual void registerTypes(const char *uri);
+ void initializeEngine(QDeclarativeEngine *, const char *);
+};
+
+#endif // IMPORTS_H
diff --git a/src/interpreter/imports/runner/src/qstlogwriter.cpp b/src/interpreter/imports/runner/src/qstlogwriter.cpp
new file mode 100644
index 0000000..8ef70de
--- /dev/null
+++ b/src/interpreter/imports/runner/src/qstlogwriter.cpp
@@ -0,0 +1,166 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qstlogwriter.h"
+
+#include <QtCore/QFile>
+#include <QtCore/QFileInfo>
+#include <QtCore/QList>
+
+
+#include <QtCore/QDebug>
+
+static QIODevice *createDevice(const QString &path)
+{
+ QFile *file = new QFile;
+ if (path.isEmpty()) {
+ if (!file->open(stdout, QFile::WriteOnly)) {
+ qWarning("Error opening stdout: %s", qPrintable(file->errorString()));
+ delete file;
+ file = 0;
+ }
+ } else {
+ file->setFileName(path);
+ if (!file->open(QFile::WriteOnly)) {
+ qWarning("Error opening log file %s: %s", qPrintable(path), qPrintable(file->errorString()));
+ delete file;
+ file = 0;
+ }
+ }
+ return file;
+}
+
+
+void QstPlainTextWriter::setFilePath(const QString &path)
+{
+ QIODevice *dev = m_stream->device();
+ m_stream->setDevice(0);
+ dev->deleteLater();
+
+ dev = createDevice(path);
+ if (dev)
+ m_stream->setDevice(dev);
+}
+
+QString QstPlainTextWriter::filePath() const
+{
+ QFile *file = qobject_cast<QFile*>(m_stream->device());
+ if (file) {
+ QFileInfo info(*file);
+ return info.absoluteFilePath();
+ }
+ return QString();
+}
+
+void QstPlainTextWriter::writeLine(const QString &text)
+{
+ *m_stream << text << endl;
+ m_stream->flush();
+}
+
+static QList<int> color_codes(QstPlainTextWriter::Color color, bool foreground = true)
+{
+ QList<int> commands;
+ if (color == QstPlainTextWriter::DefaultColor)
+ return commands;
+ int distance = (int)color - (int)QstPlainTextWriter::Black;
+ commands.append(distance % 2);
+ commands.append((distance / 2) + (foreground ? 30 : 40));
+ return commands;
+}
+
+QString QstPlainTextWriter::colorize(const QString &text, Color foreground, Color background)
+{
+ if (m_colorSetting == NeverColor || (m_colorSetting == AutoColor && !isConsole()))
+ return text;
+
+ QList<int> commands;
+ commands << color_codes(foreground, true) << color_codes(background, false);
+ if (commands .isEmpty())
+ return text;
+ QString result = QString::fromLatin1("\033[");
+ QListIterator<int> it(commands);
+ while(it.hasNext()) {
+ result += QString::number(it.next());
+ if (it.hasNext())
+ result += QString::fromLatin1(";");
+ }
+ result += "m";
+ return result + text + "\033[0m";
+}
+
+bool QstPlainTextWriter::isConsole() const
+{
+ QFile *file = qobject_cast<QFile*>(m_stream->device());
+ if (file) {
+ // not sure, but may need to use _isatty on win
+ return isatty(file->handle());
+ }
+ return false;
+}
+
+void QstXmlStreamWriter::setFilePath(const QString &path)
+{
+ QIODevice *dev = m_writer->device();
+ m_writer->setDevice(0);
+ dev->deleteLater();
+
+ dev = createDevice(path);
+ if (dev)
+ m_writer->setDevice(dev);
+}
+
+QString QstXmlStreamWriter::filePath() const
+{
+ QFile *file = qobject_cast<QFile*>(m_writer->device());
+ if (file) {
+ QFileInfo info(*file);
+ return info.absoluteFilePath();
+ }
+ return QString();
+}
+
+void QstXmlStreamWriter::flush()
+{
+ QFile *file = qobject_cast<QFile *>(m_writer->device());
+ if (file)
+ file->flush();
+}
diff --git a/src/interpreter/imports/runner/src/qstlogwriter.h b/src/interpreter/imports/runner/src/qstlogwriter.h
new file mode 100644
index 0000000..8e87eac
--- /dev/null
+++ b/src/interpreter/imports/runner/src/qstlogwriter.h
@@ -0,0 +1,212 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSTLOGWRITER_H
+#define QSTLOGWRITER_H
+
+#include <QtCore/QTextStream>
+#include <QtCore/QXmlStreamWriter>
+
+
+class QstPlainTextWriter : public QObject
+{
+ Q_OBJECT
+ Q_ENUMS(ColorSetting Color)
+ Q_PROPERTY(QString filePath READ filePath WRITE setFilePath)
+ Q_PROPERTY(ColorSetting colorSetting READ colorSetting WRITE setColorSetting)
+public:
+ enum ColorSetting {
+ AutoColor,
+ AlwaysColor,
+ NeverColor
+ };
+
+ enum Color {
+ DefaultColor,
+ Black, // the order of these colors matters, see colorize
+ DarkGray,
+ Red,
+ LightRed,
+ Green,
+ LightGreen,
+ Brown,
+ Yellow,
+ Blue,
+ LightBlue,
+ Purple,
+ LightPurple,
+ Cyan,
+ LightCyan,
+ LightGray,
+ White
+ };
+
+ QstPlainTextWriter(QObject *parent = 0)
+ : QObject(parent),
+ m_colorSetting(AutoColor)
+ {
+ m_stream = new QTextStream;
+ m_stream->setCodec("UTF8");
+ }
+
+ ~QstPlainTextWriter() {
+ if (m_stream->device()) {
+ m_stream->device()->close();
+ m_stream->device()->deleteLater();
+ }
+ delete m_stream;
+ }
+
+ void setColorSetting(ColorSetting setting) { m_colorSetting = setting; }
+ ColorSetting colorSetting() const { return m_colorSetting; }
+
+ void setFilePath(const QString &);
+ QString filePath() const;
+
+ Q_INVOKABLE void writeLine(const QString &);
+
+ Q_INVOKABLE QString colorize(const QString &text, Color foreground = DefaultColor, Color background = DefaultColor);
+
+private:
+ Q_INVOKABLE bool isConsole() const;
+ QTextStream *m_stream;
+ ColorSetting m_colorSetting;
+};
+
+class QstXmlStreamWriter : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QString filePath READ filePath WRITE setFilePath)
+ Q_PROPERTY(bool autoFormatting READ autoFormatting WRITE setAutoFormatting)
+ Q_PROPERTY(int autoFormattingIndent READ autoFormattingIndent WRITE setAutoFormattingIndent)
+
+public:
+ QstXmlStreamWriter(QObject *parent = 0)
+ : QObject(parent)
+ {
+ m_writer = new QXmlStreamWriter;
+ m_writer->setAutoFormatting(true);
+ }
+
+ ~QstXmlStreamWriter()
+ {
+ flush();
+ if (m_writer->device()) {
+ m_writer->device()->close();
+ m_writer->device()->deleteLater();
+ }
+ delete m_writer;
+ }
+
+ void setFilePath(const QString &);
+ QString filePath() const;
+
+ void setAutoFormatting(bool value)
+ { m_writer->setAutoFormatting(value); }
+ bool autoFormatting() const
+ { return m_writer->autoFormatting(); }
+
+ void setAutoFormattingIndent(int spacesOrTabs)
+ { m_writer->setAutoFormattingIndent(spacesOrTabs); }
+ int autoFormattingIndent() const
+ { return m_writer->autoFormattingIndent(); }
+
+ Q_INVOKABLE void writeAttribute(const QString &qualifiedName, const QString &value)
+ { m_writer->writeAttribute(qualifiedName, value); }
+ Q_INVOKABLE void writeAttribute(const QString &namespaceUri, const QString &name, const QString &value)
+ { m_writer->writeAttribute(namespaceUri, name, value); }
+
+ Q_INVOKABLE void writeCDATA(const QString &text)
+ { m_writer->writeCDATA(text); }
+ Q_INVOKABLE void writeCharacters(const QString &text)
+ { m_writer->writeCharacters(text); }
+ Q_INVOKABLE void writeComment(const QString &text)
+ { m_writer->writeComment(text); }
+
+ Q_INVOKABLE void writeDTD(const QString &dtd)
+ { m_writer->writeDTD(dtd); }
+
+ Q_INVOKABLE void writeEmptyElement(const QString &qualifiedName)
+ { m_writer->writeEmptyElement(qualifiedName); }
+ Q_INVOKABLE void writeEmptyElement(const QString &namespaceUri, const QString &name)
+ { m_writer->writeEmptyElement(namespaceUri, name); }
+
+ Q_INVOKABLE void writeTextElement(const QString &qualifiedName, const QString &text)
+ { m_writer->writeTextElement(qualifiedName, text); }
+ Q_INVOKABLE void writeTextElement(const QString &namespaceUri, const QString &name, const QString &text)
+ { m_writer->writeTextElement(namespaceUri, name, text); }
+
+ Q_INVOKABLE void writeEndDocument()
+ { m_writer->writeEndDocument(); flush(); }
+ Q_INVOKABLE void writeEndElement()
+ { m_writer->writeEndElement(); }
+
+ Q_INVOKABLE void writeEntityReference(const QString &name)
+ { m_writer->writeEntityReference(name); }
+ Q_INVOKABLE void writeNamespace(const QString &namespaceUri, const QString &prefix = QString())
+ { m_writer->writeNamespace(namespaceUri, prefix); }
+ Q_INVOKABLE void writeDefaultNamespace(const QString &namespaceUri)
+ { m_writer->writeDefaultNamespace(namespaceUri); }
+ Q_INVOKABLE void writeProcessingInstruction(const QString &target, const QString &data = QString())
+ { m_writer->writeProcessingInstruction(target, data); }
+
+ Q_INVOKABLE void writeStartDocument()
+ { m_writer->writeStartDocument(); }
+ Q_INVOKABLE void writeStartDocument(const QString &version)
+ { m_writer->writeStartDocument(version); }
+ Q_INVOKABLE void writeStartDocument(const QString &version, bool standalone)
+ { m_writer->writeStartDocument(version, standalone); }
+ Q_INVOKABLE void writeStartElement(const QString &qualifiedName)
+ { m_writer->writeStartElement(qualifiedName); }
+ Q_INVOKABLE void writeStartElement(const QString &namespaceUri, const QString &name)
+ { m_writer->writeStartElement(namespaceUri, name); }
+
+ Q_INVOKABLE bool hasError() const
+ { return m_writer->hasError(); }
+
+ void flush();
+private:
+
+ QXmlStreamWriter *m_writer;
+};
+
+
+#endif // QSTLOGWRITER_H
diff --git a/src/interpreter/imports/runner/src/qstxunitwriter.cpp b/src/interpreter/imports/runner/src/qstxunitwriter.cpp
new file mode 100644
index 0000000..976d98e
--- /dev/null
+++ b/src/interpreter/imports/runner/src/qstxunitwriter.cpp
@@ -0,0 +1,189 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qstxunitwriter.h"
+#include <QtCore/QDateTime>
+
+
+QstXUnitWriter::QstXUnitWriter()
+ : QstXmlStreamWriter(),
+ m_state(Document),
+ m_suiteId(1)
+{
+}
+
+QstXUnitWriter::~QstXUnitWriter()
+{
+}
+
+bool QstXUnitWriter::checkState(State state, const QString &element, bool start)
+{
+ if (m_state != state) {
+ if (m_state != Error) {
+ if (start)
+ qWarning("unexpected state when starting '%s'", element.toLocal8Bit().constData());
+ else
+ qWarning("unexpected state when ending '%s'", element.toLocal8Bit().constData());
+ m_state = Error;
+ }
+ return false;
+ }
+ if (hasError()) {
+ if (m_state != Error) {
+ qWarning("unexpected error with device");
+ m_state = Error;
+ }
+ return false;
+ }
+ return true;
+}
+
+static const QString s_suiteSet(QString::fromLatin1("testsuites"));
+static const QString s_suite(QString::fromLatin1("testsuite"));
+static const QString s_case(QString::fromLatin1("testcase"));
+static const QString s_error(QString::fromLatin1("error"));
+static const QString s_failure(QString::fromLatin1("failure"));
+static const QString s_skipped(QString::fromLatin1("skipped"));
+
+void QstXUnitWriter::writeStartTestSuiteSet()
+{
+ if (!checkState(Document, s_suiteSet, true))
+ return;
+ m_state = SuiteSet;
+
+ writeStartElement(s_suiteSet);
+}
+
+void QstXUnitWriter::writeEndTestSuiteSet()
+{
+ if (!checkState(SuiteSet, s_suiteSet, false))
+ return;
+ m_state = Document;
+
+ writeEndElement();
+ flush();
+}
+
+void QstXUnitWriter::writeStartTestSuite(
+ const QString &name,
+ const QDateTime &timestamp,
+ const QString &hostname,
+ int testTotal, int testFails, int testErrors, int testSkips,
+ int duration)
+{
+ if (!checkState(SuiteSet, s_suite, true))
+ return;
+ m_state = Suite;
+
+ writeStartElement(s_suite);
+ writeAttribute("name", name);
+ writeAttribute("package", QString::fromLatin1("none"));
+ writeAttribute("timestamp", timestamp.toLocalTime().toString("yyyy-MM-ddThh:mm:ss"));
+ writeAttribute("hostname", hostname.isEmpty() ? "localhost" : hostname);
+ writeAttribute("tests", QString::number(testTotal));
+ writeAttribute("failures", QString::number(testFails));
+ writeAttribute("errors", QString::number(testErrors));
+ writeAttribute("skipped", QString::number(testSkips));
+ writeAttribute("time", QString::number(duration));
+ writeAttribute("id", QString::number(m_suiteId++));
+}
+
+void QstXUnitWriter::writeEndTestSuite()
+{
+ if (!checkState(Suite, s_suite, false))
+ return;
+ m_state = SuiteSet;
+
+ writeEndElement();
+}
+
+
+void QstXUnitWriter::writeStartTestCase(const QString &classname, const QString &name, int duration)
+{
+ if (!checkState(Suite, s_case, true))
+ return;
+ m_state = Case;
+
+ writeStartElement(s_case);
+ writeAttribute("classname", classname);
+ writeAttribute("name", name);
+ writeAttribute("time", QString::number(duration));
+}
+
+void QstXUnitWriter::writeEndTestCase()
+{
+ if (!checkState(Case, s_case, false))
+ return;
+ m_state = Suite;
+
+ writeEndElement();
+}
+
+void QstXUnitWriter::writeError(const QString &type, const QString &message)
+{
+ if (!checkState(Case, s_error, true))
+ return;
+
+ writeStartElement(s_error);
+ writeAttribute("type", type);
+ writeCharacters(message);
+ writeEndElement();
+}
+void QstXUnitWriter::writeFailure(const QString &type, const QString &message)
+{
+ if (!checkState(Case, s_failure, true))
+ return;
+
+ writeStartElement(s_failure);
+ writeAttribute("type", type);
+ writeCharacters(message);
+ writeEndElement();
+}
+void QstXUnitWriter::writeSkipped(const QString &type, const QString &message)
+{
+ if (!checkState(Case, s_skipped, true))
+ return;
+
+ writeStartElement(s_skipped);
+ writeAttribute("type", type);
+ writeCharacters(message);
+ writeEndElement();
+}
diff --git a/src/interpreter/imports/runner/src/qstxunitwriter.h b/src/interpreter/imports/runner/src/qstxunitwriter.h
new file mode 100644
index 0000000..93904fc
--- /dev/null
+++ b/src/interpreter/imports/runner/src/qstxunitwriter.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSTXUNITWRITER_H
+#define QSTXUNITWRITER_H
+
+#include "qstlogwriter.h"
+
+class QstXUnitWriter : public QstXmlStreamWriter
+{
+ Q_OBJECT
+public:
+ QstXUnitWriter();
+ ~QstXUnitWriter();
+
+ Q_INVOKABLE void writeStartTestSuiteSet();
+ Q_INVOKABLE void writeEndTestSuiteSet();
+
+ Q_INVOKABLE void writeStartTestSuite(
+ const QString &name,
+ const QDateTime &timestamp,
+ const QString &hostname,
+ int testTotal,
+ int testFails,
+ int testErrors,
+ int testSkips,
+ int duration);
+
+ Q_INVOKABLE void writeEndTestSuite();
+
+ Q_INVOKABLE void writeStartTestCase(const QString &classname, const QString &name, int duration);
+ Q_INVOKABLE void writeEndTestCase();
+
+ Q_INVOKABLE void writeError(const QString &type, const QString &message);
+ Q_INVOKABLE void writeFailure(const QString &type, const QString &message);
+ Q_INVOKABLE void writeSkipped(const QString &type, const QString &message);
+
+private:
+ enum State {
+ Document,
+ SuiteSet,
+ Suite,
+ Case,
+ Error
+ };
+
+ bool checkState(State, const QString &element, bool start = true);
+
+ State m_state;
+
+ int m_suiteId;
+};
+
+#endif // QSTXUNITWRITER_H
diff --git a/src/interpreter/interpreter.pro b/src/interpreter/interpreter.pro
new file mode 100644
index 0000000..a89fbfb
--- /dev/null
+++ b/src/interpreter/interpreter.pro
@@ -0,0 +1,4 @@
+TEMPLATE = subdirs
+CONFIG += ordered
+
+SUBDIRS = imports runner
diff --git a/src/interpreter/runner/main.cpp b/src/interpreter/runner/main.cpp
new file mode 100644
index 0000000..f7f7ae1
--- /dev/null
+++ b/src/interpreter/runner/main.cpp
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/QApplication>
+#include <qstrunnerbootstrap.h>
+
+int main(int argc, char *argv[])
+{
+ QCoreApplication *app = 0;
+
+ bool guiEnabled = false;
+ for (int i = 1; i < argc; ++i) {
+ if ( qstrcmp(argv[i], "--disable-manual-tests") == 0) {
+ guiEnabled = false;
+ break;
+ }
+ }
+
+ if (guiEnabled) {
+ app = new QApplication(argc, argv);
+ } else {
+ app = new QCoreApplication(argc, argv);
+ }
+
+ QstRunnerBootstrap runner(app);
+ int ret = runner.run();
+ return ret;
+}
diff --git a/src/interpreter/runner/qstjsengine.cpp b/src/interpreter/runner/qstjsengine.cpp
new file mode 100644
index 0000000..1e3b225
--- /dev/null
+++ b/src/interpreter/runner/qstjsengine.cpp
@@ -0,0 +1,49 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qstjsengine.h"
+
+
+QstJsEngine::QstJsEngine(QObject *parent) :
+ QObject(parent)
+{
+
+}
diff --git a/src/interpreter/runner/qstjsengine.h b/src/interpreter/runner/qstjsengine.h
new file mode 100644
index 0000000..14828a7
--- /dev/null
+++ b/src/interpreter/runner/qstjsengine.h
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSTJSENGINE_H
+#define QSTJSENGINE_H
+
+#include <QObject>
+
+class QstJsEngine : public QObject
+{
+ Q_OBJECT
+public:
+ explicit QstJsEngine(QObject *parent = 0);
+
+signals:
+
+public slots:
+
+};
+
+#endif // QSTJSENGINE_H
diff --git a/src/interpreter/runner/qstrunnerbootstrap.cpp b/src/interpreter/runner/qstrunnerbootstrap.cpp
new file mode 100644
index 0000000..0c44c56
--- /dev/null
+++ b/src/interpreter/runner/qstrunnerbootstrap.cpp
@@ -0,0 +1,229 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qstrunnerbootstrap.h"
+#include "qstrunnercore.h"
+#include <QtCore/QFileInfo>
+#include <QtCore/QStringList>
+#include <QtCore/QCoreApplication>
+#include <QtCore/QDebug>
+#include <QtCore/QDir>
+#include <QtScript/QScriptEngine>
+#include <QtScript/QScriptContext>
+#include <QtScript/QScriptValue>
+#include <QtScript/QScriptContextInfo>
+#include <QDeclarativeEngine>
+#include <QDeclarativeComponent>
+
+static const int InternalError = 1 << 6;
+
+
+static QScriptValue isRelativePath(QScriptContext *ctx, QScriptEngine *)
+{
+ QUrl url = ctx->argument(0).toString();
+ return url.isRelative();
+}
+
+static QScriptValue relativeToCurrentPath(QScriptContext *ctx, QScriptEngine *)
+{
+ QUrl url = ctx->argument(0).toString();
+ if (url.isLocalFile())
+ return QDir::current().relativeFilePath(url.toLocalFile());
+ return url.toString();
+}
+
+
+static QScriptValue qscriptengine_stack(QScriptContext *ctx, QScriptEngine *e)
+{
+ QVariantList stack;
+
+ qint32 frame = 0;
+ bool framesSpecified = ctx->argumentCount() > 0;
+ if (framesSpecified) {
+ frame = ctx->argument(0).toInt32();
+ }
+
+ while (ctx) {
+ // count down if user has requested for certain number of frames
+ if ( framesSpecified && frame-- <= 0 )
+ break;
+ ctx = ctx->parentContext();
+ QScriptContextInfo info(ctx);
+ QVariantMap callsite;
+ callsite["fileName"] = info.fileName();
+ callsite["lineNumber"] = info.lineNumber();
+ callsite["functionName"] = info.functionName();
+ stack << callsite;
+ }
+ return qScriptValueFromSequence(e, stack);
+}
+
+// Copied from qdeclarativedebughelper_p.h in Qt
+class Q_DECLARATIVE_EXPORT QDeclarativeDebugHelper
+{
+public:
+ static QScriptEngine *getScriptEngine(QDeclarativeEngine *engine);
+};
+
+bool QstRunnerBootstrap::setupScriptEngine(QDeclarativeEngine *declarativeEngine)
+{
+ QScriptEngine *e = QDeclarativeDebugHelper::getScriptEngine(declarativeEngine);
+ QScriptValue qst = e->newObject();
+ qst.setProperty(QLatin1String("stack"), e->newFunction(qscriptengine_stack));
+ qst.setProperty(QLatin1String("isRelativePath"), e->newFunction(isRelativePath));
+ qst.setProperty(QLatin1String("relativeToCurrentPath"), e->newFunction(relativeToCurrentPath));
+
+ QScriptValue qtObject = e->globalObject().property(QLatin1String("Qt"));
+ qtObject.setProperty(QLatin1String("qst"), qst);
+ return true;
+}
+
+QstRunnerBootstrap::QstRunnerBootstrap(QCoreApplication *app)
+ : QObject(app)
+ , m_app(app)
+ , m_qmlRunner(0)
+{
+ QStringList args = app->arguments();
+ // Skips executable
+ args.removeAt(0);
+
+ if (args.count() == 0) {
+ qDebug() << "No arguments passed, failing back to qmlunit Test Suite (" << app->applicationDirPath() << ")\n";
+ args = QStringList(app->applicationDirPath() + "/test");
+ }
+
+ foreach (const QString &arg, args) {
+ findTests(arg);
+ }
+}
+
+
+bool QstRunnerBootstrap::setup()
+{
+ qmlRegisterType<QstRunnerCore>("QstRunner", 1, 0, "Runner");
+ QDeclarativeEngine *engine = new QDeclarativeEngine(this);
+ engine->setOfflineStoragePath(QDir::currentPath() + "/storage");
+ setupScriptEngine(engine);
+
+ qDebug()<< "Loading Runner";
+ QUrl runnerPath = QUrl::fromLocalFile(
+ m_app->applicationDirPath() + "/scripts/QstRunner.qml");
+
+ QDeclarativeComponent runnerCom(engine, runnerPath);
+ if (!runnerCom.errors().isEmpty()) {
+ qDebug() << "Internal error in Qml runner"
+ << runnerCom.errors();
+ return false; // may be exit 2
+ }
+ m_qmlRunner = qobject_cast<QstRunnerCore *>(runnerCom.create());
+ if (!m_qmlRunner) {
+ qDebug() << "Internal Error: qmlRunner creation failed"
+ << runnerCom.errors();
+ return false; // may be exit 2
+ }
+
+ if ( !m_qmlRunner->setup(engine, qApp->arguments()) ) {
+ return false;
+ }
+
+ qDebug()<< "Loading test file";
+ QDeclarativeComponent com(engine, QUrl::fromLocalFile(m_testFile.first()));
+ if (!com.errors().isEmpty()) {
+ qDebug() << "Errors in testcase \n"
+ << com.errors();
+ return false; // may be exit 1
+ }
+ QObject *test = com.create();
+ if (!test ) {
+ qDebug() << "Internal Error testcase object creation \n"
+ << com.errors();
+ return false; // may be exit 1
+ }
+ m_qmlRunner->setTest(test);
+ return true;
+}
+
+int QstRunnerBootstrap::run()
+{
+ if (!setup()) {
+ return InternalError;
+ }
+ qDebug() << Q_FUNC_INFO << "---------------[setup is ok]-------------------";
+ return m_qmlRunner->exec();
+}
+
+void QstRunnerBootstrap::findTests(const QString &path)
+{
+ if (isTest(path)) {
+ m_testFile << QDir(path).absolutePath();
+ return;
+ }
+
+ QStringList filters; filters << "*";
+ QDir dir = QDir(QDir(path).absolutePath());
+
+ QListIterator<QFileInfo> files(dir.entryInfoList(filters, QDir::AllEntries | QDir::NoDotAndDotDot));
+ while(files.hasNext()) {
+ QFileInfo file = files.next();
+ if (file.fileName() == "." || file.fileName() == "..") continue;
+
+ if (isTest(file))
+ m_testFile << file.absoluteFilePath();
+ else if (isDir(file))
+ findTests(file.absoluteFilePath());
+ }
+}
+
+bool QstRunnerBootstrap::isTest(const QFileInfo &file)
+{
+ return isTest(file.fileName());
+}
+
+bool QstRunnerBootstrap::isTest(const QString &filePath)
+{
+ return filePath.endsWith("Test.qml")
+ || filePath.endsWith("Tests.qml");
+}
+
+bool QstRunnerBootstrap::isDir(const QFileInfo &file)
+{
+ return QDir(file.absoluteFilePath()).exists();
+}
diff --git a/src/interpreter/runner/qstrunnerbootstrap.h b/src/interpreter/runner/qstrunnerbootstrap.h
new file mode 100644
index 0000000..a294306
--- /dev/null
+++ b/src/interpreter/runner/qstrunnerbootstrap.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTUITESTRUNNER_H
+#define QTUITESTRUNNER_H
+
+#include <QtCore/QObject>
+#include <QtCore/QStringList>
+
+class QDeclarativeEngine;
+class QCoreApplication;
+class QFileInfo;
+class QStringList;
+class QstRunnerCore;
+
+class QstRunnerBootstrap : public QObject
+{
+ Q_OBJECT
+
+public:
+ explicit QstRunnerBootstrap(QCoreApplication *app);
+ int run();
+
+public slots:
+
+signals:
+
+private:
+ bool setup();
+ void findTests(const QString &path);
+ bool isDir(const QFileInfo &file);
+ bool isTest(const QFileInfo &file);
+ bool isTest(const QString &filePath);
+ bool setupScriptEngine(QDeclarativeEngine *declarativeEngine);
+
+
+private:
+ QCoreApplication *m_app;
+ QStringList m_testFile;
+ QstRunnerCore *m_qmlRunner;
+};
+
+#endif // QTUITESTRUNNER_H
diff --git a/src/interpreter/runner/qstrunnercore.cpp b/src/interpreter/runner/qstrunnercore.cpp
new file mode 100644
index 0000000..9116936
--- /dev/null
+++ b/src/interpreter/runner/qstrunnercore.cpp
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qstrunnercore.h"
+#include <private/qdeclarativecontext_p.h>
+#include <QDeclarativeEngine>
+#include <QDeclarativeContext>
+#include <QtDebug>
+
+QstRunnerCore::QstRunnerCore(QObject *parent) :
+ QObject(parent)
+{
+}
+
+
+
+QVariant QstRunnerCore::locationOf(QObject *o)
+{
+ QVariantMap ret;
+ if (!o) {
+ return ret;
+ }
+ QDeclarativeData *d = QDeclarativeData::get(o, false);
+ if (d && d->outerContext && !d->outerContext->url.isEmpty()) {
+ ret["url"] = d->outerContext->url;
+ ret["lineNumber"] = d->lineNumber;
+ }
+ return ret;
+}
+
+
+void QstRunnerCore::setRootProperty(const QString &name, QObject *obj)
+{
+ m_engine->rootContext()->setContextProperty(name, obj);
+}
+
+bool QstRunnerCore::setup(QDeclarativeEngine *engine, const QStringList &args)
+{
+ m_engine = engine;
+ qDebug()<< "setting __runner : " << this;
+ m_engine->rootContext()->setContextProperty("__runner", this);
+
+ QVariant ret;
+ qDebug()<< "Invoking qml __setup";
+ QMetaObject::invokeMethod(this, "__setup",
+ Q_RETURN_ARG(QVariant, ret),
+ Q_ARG(QVariant, args) );
+ return ret.toBool();
+}
+
+void QstRunnerCore::setTest(QObject *test)
+{
+ setRootProperty("__testRoot", test);
+}
+
+
+int QstRunnerCore::exec()
+{
+ qDebug()<< "Validate test and exec";
+ QVariant ret;
+ QMetaObject::invokeMethod(this, "__exec",
+ Q_RETURN_ARG(QVariant, ret) );
+ return ret.toInt();
+}
diff --git a/src/interpreter/runner/qstrunnercore.h b/src/interpreter/runner/qstrunnercore.h
new file mode 100644
index 0000000..524260a
--- /dev/null
+++ b/src/interpreter/runner/qstrunnercore.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSYSTEMTESTRUNNERCORE_H
+#define QSYSTEMTESTRUNNERCORE_H
+
+#include <QtCore/QObject>
+#include <QtCore/QVariant>
+
+class QDeclarativeEngine;
+
+class QstRunnerCore : public QObject
+{
+ Q_OBJECT
+public:
+ explicit QstRunnerCore(QObject *parent = 0);
+
+ bool setup(QDeclarativeEngine *engine, const QStringList &args);
+ void setTest(QObject *test);
+ int exec();
+
+signals:
+
+public slots:
+ QVariant locationOf(QObject *o);
+ void setRootProperty(const QString &name, QObject* obj);
+
+private:
+ QDeclarativeEngine *m_engine;
+
+};
+
+#endif // QSYSTEMTESTRUNNERCORE_H
diff --git a/src/interpreter/runner/runner.pro b/src/interpreter/runner/runner.pro
new file mode 100644
index 0000000..f5205b2
--- /dev/null
+++ b/src/interpreter/runner/runner.pro
@@ -0,0 +1,30 @@
+CONFIG += qt
+QT += declarative declarative-private script
+
+TARGET = qtsystemtestrunner
+TEMPLATE = app
+
+macx:CONFIG-=app_bundle
+
+SOURCES += main.cpp\
+ qstrunnercore.cpp \
+ qstrunnerbootstrap.cpp \
+ qstjsengine.cpp
+
+HEADERS += \
+ qstrunnercore.h \
+ qstrunnerbootstrap.h \
+ qstjsengine.h
+
+SCRIPTS += \
+ scripts/QstRunner.js \
+ scripts/QstRunner.qml
+
+DESTDIR = ../../../bin
+SCRIPTSDIR = $$OUT_PWD/../../../bin/scripts
+scripts.target = dummytarget
+scripts.commands = (mkdir -p $$SCRIPTSDIR && cd $$PWD && cp $$SCRIPTS $$SCRIPTSDIR/)
+
+QMAKE_EXTRA_TARGETS += scripts
+
+POST_TARGETDEPS += dummytarget
diff --git a/src/interpreter/runner/scripts/QstRunner.js b/src/interpreter/runner/scripts/QstRunner.js
new file mode 100644
index 0000000..da34bc6
--- /dev/null
+++ b/src/interpreter/runner/scripts/QstRunner.js
@@ -0,0 +1,358 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+.pragma library
+
+var create = function(Core){
+// import to this namespace
+var
+ InternalError = 1<<6,
+ Console = Core.Console,
+ Class = Core.Class,
+ Js = Core.Js,
+ Qtt = Core.Qtt,
+ runner,
+ Topic = Console.topic('Runner')
+;
+
+function relevantStack(e){
+ relevantStack.currentFile = relevantStack.currentFile
+ || Js.Engine.currentFile();
+
+ Topic.debug('Runner: file: ', relevantStack.currentFile);
+ var filtered = [];
+ e.stack.some(function(callSite) {
+ var hasReachedRunner = callSite.fileName === relevantStack.currentFile;
+ if (!hasReachedRunner) {
+ filtered.push(callSite);
+ }
+ return hasReachedRunner;
+ });
+ return (e instanceof Qtt.Error)
+ ? filtered
+ : filtered.length > 0 ? filtered
+ : e.stack;
+}
+
+var AbstractTestRunner = Class.create(function(item) {
+ var Topic = Console.topic('Runner').topic('AbstractTestRunner');
+
+ function validate(fnName, config){
+ config = config || { }
+ config.mustExist = config.mustExist === undefined ? true : config.mustExist;
+
+ if ( !(fnName in item) ) {
+ if (config.mustExist === true) {
+ throw new ReferenceError( 'Missing mandatory property or function "'
+ + fnName + '" in test item (Name:' + item.name + ')')
+ }
+ Topic.debug('Name: ', fnName, ' is missing, but ok to ignore' );
+ return {ok: true, exists : false};
+ }
+
+ var m = item[fnName];
+ if (typeof (m) !== 'function') {
+ throw new TypeError(fnName + ' not a function');
+ }
+ return {ok: true, exists : true};
+ }
+
+ function exec() {
+ var Topic = Console.topic('Runner').topic('exec');
+ Topic.debug( 'Running .............', item);
+
+ // skip disabled items
+ var result = true;
+ if (item.enabled === false) {
+ Topic.debug(item, 'is disabled ');
+ return result;
+ }
+
+ this.start();
+ runner.currentTestItem = item;
+ try {
+ var ok = invokeSetup.call(this);
+ if (ok) {
+ this.run();
+ }
+ } catch (e) {
+ /// FIXME: Qt5, remove this as e.stack *can be* enabled by default
+ e.__addStack(1);
+ this.setStatus(Qtt.Status.Failed);
+ console.log("Internal error: ", e.status || 'JsError', e.message);
+ ok = false;
+ e.stack.forEach( function(s) {
+ console.log(s.fileName, ': ', s.lineNumber, ' : ', s.functionName); });
+
+ var error = {
+ message: e.message,
+ stack: relevantStack(e),
+ formatted: e.formatted,
+ meta: e.meta
+ };
+ runner.logEvent(e.status || 'JsError', error);
+ throw e;
+ } finally {
+ invokeCleanup.call(this);
+ this.end();
+ }
+ }
+
+
+ function invokeSetup() {
+ var Topic = Console.topic('AbstractTestRunner').topic('invokeSetup');
+
+ Topic.debug( 'validating setup');
+ var setup = 'setup';
+ var result = validate(setup, {mustExist: false});
+ if ( result.ok && result.exists === false ) {
+ return true;
+ }
+
+ setup = item.setup;
+ var ok = true;
+ try {
+ runner.methodStart(setup.name);
+ runner.currentMethod = setup.name;
+ setup();
+ runner.methodEnd(setup.name);
+ } catch (e) {
+ /// FIXME: Qt5, remove this as e.stack *can be* enabled by default
+ e.__addStack(1);
+ Topic.debug('Exception caught: ', e);
+ ok = false;
+ var status = (e instanceof Qtt.Error)
+ ? Qtt.Status.Untested
+ : Qtt.Status.Failed;
+ var error = {
+ message: e.message,
+ stack: relevantStack(e),
+ formatted: e.formatted,
+ meta: e.meta
+ };
+ runner.logEvent(e.status || 'JsError', error);
+ runner.methodEnd(setup.name);
+ this.setStatus(status);
+ }
+ return ok;
+ }
+
+ // don't throw any errors, just report them and end the cleanup
+ function invokeCleanup() {
+ var Topic = Console.topic('TestRunner').topic('runCleanup');
+
+ var cleanup = 'cleanup';
+ var result = validate(cleanup, {mustExist: false});
+ if ( result.ok && result.exists === false ) {
+ return;
+ }
+
+ cleanup = item.cleanup;
+ runner.methodStart(cleanup.name);
+ runner.currentMethod = cleanup.name;
+
+ try {
+ cleanup();
+ } catch (e) {
+ /// FIXME: Qt5, remove this as e.stack *can be* enabled by default
+ e.__addStack(1);
+ Topic.debug('Exception in cleanup: ', e);
+
+ var error = {
+ message: e.message,
+ stack: e.stack,
+ formatted: e.formatted,
+ meta: e.meta
+ };
+
+ runner.logEvent('WARNING', error);
+ } finally {
+ Topic.debug('run finally - finishing method : cleanup ');
+ runner.methodEnd(cleanup.name);
+ }
+ }
+
+ return {
+ validate: validate,
+ item: function() { return item },
+ exec: exec,
+ start: function() { throw new Error('Must override start')},
+ run: function() { throw new Error('Must override run')},
+ end: function() { throw new Error('Must override end')},
+ setStatus: function() { throw new Error('Must override setStatus')},
+ };
+});
+
+var TestRunner = AbstractTestRunner.extend(function(item) {
+ this._super(item);
+ var Topic = Console.topic('TestRunner').topic('AbstractTestRunner');
+ Topic.debug(' Creating a Test runner for ', item.name);
+
+ function start() { runner.testStart(item); }
+
+ function end() { runner.testEnd(item); }
+
+ function setStatus(status) {
+ Topic.debug('Setting ... ', item.name , ' :', status)
+ item.__status = status;
+ /// FIXME Qt5: change report to var and runner.report[status]++
+ var report = runner.report;
+ report[status]++;
+ runner.report = report;
+ }
+
+ function run() {
+ var Topic = Console.topic('TestRunner').topic('runRun');
+
+ Topic.debug( 'validating run');
+ var run = 'run';
+ var status = Qtt.Status.Failed;
+ try {
+ this.validate(run);
+
+ run = item.run;
+ runner.methodStart(run.name);
+ runner.currentMethod = run.name;
+
+ Topic.debug('Going to run ... run');
+ run();
+ status = Qtt.Status.Passed;
+ } catch (e) {
+ /// FIXME: Qt5, remove this as e.stack *can be* enabled by default
+ e.__addStack(1);
+ status = (e instanceof Qtt.Error)
+ ? e.status
+ : Qtt.Status.Failed;
+ var error = {
+ message: e.message,
+ stack: relevantStack(e),
+ formatted: e.formatted,
+ meta: e.meta
+ };
+ Topic.debug(status, Core.stringify(error));
+ runner.logEvent(status, error);
+ } finally {
+ runner.methodEnd(run.name);
+ this.setStatus(status);
+ }
+ }
+
+ return {
+ start: start,
+ end: end,
+ run: run,
+ setStatus: setStatus
+ };
+});
+
+var TestCollectionRunner = AbstractTestRunner.extend(function(item) {
+ this._super(item);
+
+
+ function start() { runner.testCollectionStart(item); }
+
+ function end() { runner.testCollectionEnd(item); }
+
+
+ function setStatus(status) {
+ // recurse and run the subsets ...
+ var subset = item.children;
+ for (var i = 0; i< subset.length; ++i) {
+ var testItem = subset[i];
+ if ( !testItem.enabled ) {
+ continue;
+ }
+ var tr = runnerForItem(testItem);
+ tr.start();
+ tr.setStatus(status);
+ tr.end();
+ }
+ }
+
+ function run() {
+ // recurse and run the subsets ...
+ var subset = item.__subset;
+ for (var i = 0; i< subset.length; ++i) {
+ var tr = runnerForItem(subset[i]);
+ tr.exec();
+ }
+ }
+
+ return {
+ start: start,
+ end: end,
+ run: run,
+ setStatus: setStatus
+ };
+});
+
+
+function runnerForItem(item) {
+ var Runner = item.__isTest ? TestRunner : TestCollectionRunner;
+ return new Runner(item);
+}
+
+function exec(qmlRunner, item){
+ runner = qmlRunner
+ try {
+ runner.aboutToStartExecution();
+ var tr = runnerForItem(item);
+ tr.exec();
+ runner.finishedExecution();
+
+ var report = runner.report;
+ var result = (report.failed > 0)
+ | (report.skipped > 0) << 1
+ | (report.untested > 0) << 2
+ | (report.error > 0) << 3;
+ } catch (e) {
+ /// FIXME: Qt5, remove this as e.stack *can be* enabled by default
+ e.__addStack(1);
+ result = InternalError;
+ }
+ return result;
+}
+
+ return {
+ exec: exec
+ }
+
+};
diff --git a/src/interpreter/runner/scripts/QstRunner.qml b/src/interpreter/runner/scripts/QstRunner.qml
new file mode 100644
index 0000000..32aee06
--- /dev/null
+++ b/src/interpreter/runner/scripts/QstRunner.qml
@@ -0,0 +1,138 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.1
+
+import QstRunner 1.0
+import QtSystemTest 1.0
+import QtSystemTest.Runner 1.0
+import "QstRunner.js" as JsRunner
+
+Runner {
+ id: runner
+
+ property variant currentTestItem
+ property string currentMethod
+
+ property variant report : ({
+ 'passed': 0,
+ 'failed': 0,
+ 'skipped': 0,
+ 'untested': 0,
+ 'error': 0,
+ });
+
+ property variant __loggers
+
+ signal aboutToStartExecution()
+ signal finishedExecution()
+ signal testCollectionStart(variant testCollection)
+ signal testCollectionEnd(variant testCollection)
+
+ signal testStart(variant test)
+ signal testEnd(variant test)
+
+ signal methodStart(string methodName)
+ signal methodEnd(string methodName)
+
+ property variant component: Component {
+ id: configComponent
+ Config { }
+ }
+
+
+
+ function __broadcast(fnName, args) {
+ for (var i =0; i < __loggers.length; ++i) {
+ var logger = __loggers[i];
+ if ( ! (fnName in logger) ) {
+ throw new Error('function ' + fnName + ' not in ' + logger);
+ }
+ var f = logger[fnName];
+ f.apply(logger, args);
+ };
+ }
+
+ function logEvent(type, error) {
+ __broadcast('log', [type, error]);
+ }
+
+
+ function log(messages) {
+ var str = js.core().stringify.apply(null, arguments);
+ __broadcast(arguments.callee.name, ['debug', { message: str }]);
+ }
+
+
+ function __setup(args) {
+ var x = configComponent.createObject(runner);
+ setRootProperty('config', x);
+ __loggers = x.loggers;
+ Array.prototype.forEach.call(__loggers, function(l) {
+ l.setup();
+ });
+ return true;
+ }
+
+ property Js js: Js { }
+
+ function __exec() {
+ var result = __testRoot.__validate();
+ if (!result.valid) {
+ __broadcast('log', ['Error', result.error]);
+ return JsRunner.InternalError;
+ }
+ console.log('Test validation - okay?: ', result.valid);
+
+ result = 1 << 6;
+ try {
+ var x = JsRunner.create(js.core());
+ result = x.exec(runner, __testRoot);
+ } catch (e) {
+ console.log('Error: internal: ', e.toString());
+ console.log('Details:')
+ for (var k in e) {
+ console.log(' ', k, ': ' , e[k]);
+ }
+ }
+ return result;
+ }
+}
diff --git a/src/objectBrowser/main.cpp b/src/objectBrowser/main.cpp
new file mode 100644
index 0000000..b799927
--- /dev/null
+++ b/src/objectBrowser/main.cpp
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtSystemTest/QstConnection>
+#include "qtestbrowserdlg_p.h"
+#include <QApplication>
+
+#define DEFAULT_HOST "localhost"
+#define DEFAULT_PORT 5657
+
+int main(int argc, char *argv[])
+{
+ QApplication *app = new QApplication(argc, argv);
+
+ const QStringList arguments = QCoreApplication::arguments();
+ int args = arguments.size();
+ QStringList deviceConfig;
+
+ QString hostName(DEFAULT_HOST);
+ int port = DEFAULT_PORT;
+ for (int i=1; i<args; ++i) {
+ QString arg = arguments.at(i);
+ if (QString("-help").indexOf(arg) == 0) {
+ qWarning() << QString(
+ "%1 - Object Browser\n\n"
+ " -help : Display this help text and exit\n"
+ " -authost : Host name of system under test (default: %2)\n"
+ " -port port : Port qtuitestd is listening on (default: %3)\n"
+ ).arg(arguments[0]).arg(DEFAULT_HOST).arg(DEFAULT_PORT).toLatin1().data();
+ exit(0);
+ } else if (QString("-authost").indexOf(arg) == 0) {
+ if (i == args-1) {
+ qWarning() << "Must provide host name";
+ exit(1);
+ } else {
+ hostName = arguments.at(++i);
+ }
+ } else if (QString("-port").indexOf(arg) == 0) {
+ if (i == args-1) {
+ qWarning() << "Must provide port";
+ exit(1);
+ } else {
+ port = arguments.at(++i).toInt();
+ if (port == 0) {
+ qWarning() << "Invalid port";
+ exit(1);
+ }
+ }
+ }
+ }
+
+ //TODO: Parse command line args for host and port
+ QstConnection *connection = new QstConnection(hostName, port);
+ if (!connection->connectToRemote()) {
+ qWarning() << "Failed to connect to host" << hostName << "on port" << port;
+ exit(1);
+ }
+ QTestBrowserDlg *browser = new QTestBrowserDlg(connection);
+ browser->exec();
+
+ delete browser;
+ delete connection;
+ delete app;
+ return 0;
+}
diff --git a/src/objectBrowser/objectBrowser.pro b/src/objectBrowser/objectBrowser.pro
new file mode 100644
index 0000000..4489579
--- /dev/null
+++ b/src/objectBrowser/objectBrowser.pro
@@ -0,0 +1,20 @@
+TEMPLATE = app
+TARGET=qstobjectbrowser
+DESTDIR=../../bin
+
+QT+=network
+
+contains(QT_MAJOR_VERSION, 5) {
+ QT+=widgets
+}
+
+INCLUDEPATH += ../../include
+LIBS += -L../../lib
+LIBS += -lQstProtocol
+
+HEADERS +=\
+ qtestbrowserdlg_p.h
+
+SOURCES +=\
+ qtestbrowserdlg.cpp \
+ main.cpp
diff --git a/src/objectBrowser/qtestbrowserdlg.cpp b/src/objectBrowser/qtestbrowserdlg.cpp
new file mode 100644
index 0000000..b0531ec
--- /dev/null
+++ b/src/objectBrowser/qtestbrowserdlg.cpp
@@ -0,0 +1,1139 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "qtestbrowserdlg_p.h"
+#include <QtSystemTest/QstConnection>
+
+#include <QAction>
+#include <QMenu>
+#include <QPushButton>
+#include <QDesktopWidget>
+#include <QLineEdit>
+#include <QComboBox>
+#include <QSpinBox>
+#include <QTreeWidget>
+#include <QTableWidget>
+#include <QHeaderView>
+#include <QSplitter>
+#include <QLayout>
+#include <QPixmap>
+#include <QMouseEvent>
+#include <QPaintEvent>
+#include <QPainter>
+#include <QVariantMap>
+#include <QMetaMethod>
+#include <QApplication>
+#include <QClipboard>
+#include <QMessageBox>
+#include <QCheckBox>
+#include <QScrollArea>
+
+QString signature(const QVariantMap &map)
+{
+ return map[QstConnection::signatureProperty].toString();
+}
+
+TestImageViewer::TestImageViewer(QWidget *parent, Qt::WindowFlags f)
+ : QLabel(parent, f)
+{
+}
+
+TestImageViewer::~TestImageViewer()
+{
+}
+
+void TestImageViewer::setSelectedArea(const QRect& rect)
+{
+ m_selectedArea = rect;
+ update();
+}
+
+void TestImageViewer::mouseReleaseEvent(QMouseEvent *event)
+{
+ if (event->button() == Qt::LeftButton) {
+ emit clicked(event->pos());
+ }
+}
+
+void TestImageViewer::paintEvent(QPaintEvent *event)
+{
+ QLabel::paintEvent(event);
+ if (m_selectedArea.isNull()) {
+ return;
+ }
+
+ QPainter painter(this);
+ painter.setPen(Qt::red);
+ painter.drawRect(m_selectedArea);
+}
+
+QTestBrowserDlg::QTestBrowserDlg( QstConnection* test, const QVariantMap &item, const QVariantMap &imgItem )
+ : QDialog(0, Qt::Window)
+ , m_test(0)
+ , m_image(0)
+ , m_appContext(0)
+ , m_tree(0)
+ , m_queryTab(0)
+ , m_propertyTab(0)
+ , m_itemPropertyTable(0)
+ , m_queryTable(0)
+ , m_resultsTable(0)
+ , m_contextTableItem(0)
+ , m_flagInvisible(0)
+ , m_flagDisabled(0)
+ , m_flagIgnoreScan(0)
+ , m_refreshAction(0)
+ , m_expandAction(0)
+ , m_collapseAction(0)
+ , m_methodsAction(0)
+ , m_propertyRefreshAction(0)
+ , m_propertyMethodsAction(0)
+ , m_propertyPropertiesAction(0)
+ , m_propertyQueryAction(0)
+ , m_propertyCopyAction(0)
+ , m_propertyCopyTableAction(0)
+ , m_queryClearAction(0)
+ , m_queryCopyAction(0)
+{
+ setSystemTest(test);
+ createActions();
+ createWidgets();
+ updateAppContext();
+ setBaseItems(item, imgItem);
+}
+
+QTestBrowserDlg::~QTestBrowserDlg()
+{
+}
+
+void QTestBrowserDlg::createActions()
+{
+ m_refreshAction = new QAction(tr("Refresh"), this);
+ m_refreshAction->setShortcut(QKeySequence::Refresh);
+ connect(m_refreshAction, SIGNAL(triggered()), this, SLOT(refresh()));
+ addAction(m_refreshAction);
+
+ m_expandAction = new QAction(tr("Expand Tree"), this);
+ m_expandAction->setShortcut(QKeySequence(tr("Alt+E")));
+ connect(m_expandAction, SIGNAL(triggered()), this, SLOT(expandAll()));
+ addAction(m_expandAction);
+
+ m_collapseAction = new QAction(tr("Collapse Tree"), this);
+ m_collapseAction->setShortcut(QKeySequence(tr("Alt+C")));
+ connect(m_collapseAction, SIGNAL(triggered()), this, SLOT(collapseAll()));
+ addAction(m_collapseAction);
+
+ m_methodsAction = new QAction(tr("View Methods"), this);
+ m_methodsAction->setShortcut(QKeySequence(tr("Alt+M")));
+ connect(m_methodsAction, SIGNAL(triggered()), this, SLOT(viewMethods()));
+ addAction(m_methodsAction);
+
+ m_propertyRefreshAction = new QAction(tr("Refresh Properties"), this);
+ connect(m_propertyRefreshAction, SIGNAL(triggered()), this, SLOT(refreshProperties()));
+
+ m_propertyMethodsAction = new QAction(this);
+ connect(m_propertyMethodsAction, SIGNAL(triggered()), this, SLOT(viewPropertyMethods()));
+
+ m_propertyPropertiesAction = new QAction(this);
+ connect(m_propertyPropertiesAction, SIGNAL(triggered()), this, SLOT(viewPropertyProperties()));
+
+ m_propertyQueryAction = new QAction(tr("Add as Query Condition"), this);
+ connect(m_propertyQueryAction, SIGNAL(triggered()), this, SLOT(addPropertyAsQueryCondition()));
+
+ m_propertyCopyAction = new QAction(tr("Copy"), this);
+ connect(m_propertyCopyAction, SIGNAL(triggered()), this, SLOT(copyTableItemValue()));
+
+ m_propertyCopyTableAction = new QAction(tr("Copy Table"), this);
+ connect(m_propertyCopyTableAction, SIGNAL(triggered()), this, SLOT(copyTable()));
+
+ m_queryClearAction = new QAction(tr("Clear Query"), this);
+ connect(m_queryClearAction, SIGNAL(triggered()), this, SLOT(clearQuery()));
+
+ m_queryCopyAction = new QAction(tr("Copy Query"), this);
+ connect(m_queryCopyAction, SIGNAL(triggered()), this, SLOT(copyQuery()));
+
+}
+
+void QTestBrowserDlg::createWidgets()
+{
+ QHBoxLayout *mainLayout = new QHBoxLayout( this );
+ QSplitter *mainSplitter = new QSplitter(Qt::Horizontal, this);
+ QSplitter *leftSplitter = new QSplitter(Qt::Vertical, this);
+ QSplitter *rightSplitter = new QSplitter(Qt::Vertical, this);
+
+ mainLayout->addWidget(mainSplitter);
+ mainSplitter->addWidget(leftSplitter);
+ mainSplitter->addWidget(rightSplitter);
+ mainSplitter->setStretchFactor(0, 0);
+ mainSplitter->setStretchFactor(1, 1);
+
+ m_image = new TestImageViewer();
+ m_image->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred);
+ connect(m_image, SIGNAL(clicked(QPoint)), this, SLOT(onImageClicked(QPoint)));
+
+ m_image->setAlignment( Qt::AlignCenter );
+ m_image->setFrameShape( QLabel::NoFrame );
+ m_image->setScaledContents( false );
+
+ QScrollArea *scrollArea = new QScrollArea;
+ scrollArea->setWidget(m_image);
+ leftSplitter->addWidget(scrollArea);
+ leftSplitter->setStretchFactor(0, 2);
+
+ m_appContext = new QComboBox(this);
+ m_appContext->installEventFilter(this);
+ leftSplitter->addWidget(m_appContext);
+
+ m_queryTab = createQueryTab();
+ leftSplitter->addWidget(m_queryTab);
+
+ m_tree = new QTreeWidget( this );
+ connect(m_tree, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), this, SLOT(onItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)));
+ m_tree->setColumnCount(6);
+ m_tree->setHeaderLabels(QStringList() << QLatin1String("Type") << QLatin1String("Signature") << QLatin1String("QML id") << QLatin1String("objectName") << QLatin1String("Geometry") << QLatin1String("text"));
+
+ rightSplitter->addWidget(m_tree);
+ rightSplitter->setStretchFactor(0, 2);
+ m_propertyTab = new QTabWidget(this);
+ m_itemPropertyTable = new QTableWidget(this);
+ initPropertyTable(m_itemPropertyTable);
+
+ m_propertyTab->addTab(m_itemPropertyTable, QLatin1String("Item Properties"));
+ m_propertyTab->setTabEnabled(0, false);
+ m_propertyTab->setTabPosition(QTabWidget::South);
+ m_propertyTab->setTabsClosable(true);
+ connect(m_propertyTab, SIGNAL(tabCloseRequested(int)), this, SLOT(onTabCloseRequested(int)));
+
+ rightSplitter->addWidget(m_propertyTab);
+
+ setWindowTitle( "Object Browser" );
+ m_tabItemSignatures.append("");
+}
+
+QTabWidget * QTestBrowserDlg::createQueryTab()
+{
+ QTabWidget *tabWidget = new QTabWidget(this);
+ QFrame *queryFrame = new QFrame(this);
+ QFrame *flagsFrame = new QFrame(this);
+ QVBoxLayout *queryLayout = new QVBoxLayout(queryFrame);
+ QVBoxLayout *flagsLayout = new QVBoxLayout(flagsFrame);
+
+ m_queryTable = new QTableWidget(this);
+ static QStringList labels(QStringList() << QString() << QLatin1String("Property") << QLatin1String("Value"));
+ m_queryTable->setColumnCount(labels.count());
+ m_queryTable->verticalHeader()->hide();
+ m_queryTable->horizontalHeader()->setStretchLastSection(true);
+ m_queryTable->setHorizontalHeaderLabels(labels);
+ m_queryTable->setContextMenuPolicy(Qt::CustomContextMenu);
+ m_queryTable->setEditTriggers(QAbstractItemView::AllEditTriggers);
+ m_queryTable->setRowCount(1);
+ addQueryRow();
+ m_queryTable->resizeColumnsToContents();
+ m_queryTable->setSpan(1, 0, 1, labels.count());
+ QPushButton *addButton = new QPushButton(tr("Add New Condition"));
+ m_queryTable->setCellWidget(1, 0, addButton);
+ connect(addButton, SIGNAL(clicked()), this, SLOT(addQueryRow()) );
+ connect(m_queryTable, SIGNAL(itemChanged(QTableWidgetItem*)), this, SLOT(onQueryItemChanged(QTableWidgetItem*)));
+ connect(m_queryTable, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(onQueryContextMenu(QPoint)));
+ QPushButton *queryButton = new QPushButton("Query");
+ connect( queryButton, SIGNAL(clicked()), this, SLOT(doQuery()) );
+ queryLayout->addWidget(m_queryTable);
+ queryLayout->addWidget(queryButton);
+
+ m_flagInvisible = new QCheckBox(QLatin1String("Scan Invisible Items"), this);
+ m_flagDisabled = new QCheckBox(QLatin1String("Scan Disabled Items"), this);
+ m_flagIgnoreScan = new QCheckBox(QLatin1String("Ignore Scanned"), this);
+ QLabel *flagsInfo = new QLabel(QLatin1String("Query Flags are used to control how the search is performed. Please refer to the QtUiTest documentation for details."));
+ flagsInfo->setWordWrap(true);
+ flagsLayout->addWidget(m_flagInvisible);
+ flagsLayout->addWidget(m_flagDisabled);
+ flagsLayout->addWidget(m_flagIgnoreScan);
+ flagsLayout->addWidget(flagsInfo);
+
+ m_resultsTable = new QTableWidget(this);
+ static QStringList resultLabels(QStringList() << QLatin1String("Signature") << QLatin1String("QML id"));
+ m_resultsTable->setEditTriggers(QAbstractItemView::NoEditTriggers);
+ m_resultsTable->setColumnCount(resultLabels.count());
+ m_resultsTable->setSelectionBehavior(QAbstractItemView::SelectRows);
+ m_resultsTable->setSelectionMode(QAbstractItemView::SingleSelection);
+ m_resultsTable->verticalHeader()->hide();
+ m_resultsTable->horizontalHeader()->setStretchLastSection(true);
+ m_resultsTable->setHorizontalHeaderLabels(resultLabels);
+ connect(m_resultsTable, SIGNAL(itemSelectionChanged()), this, SLOT(onResultsItemSelected()));
+
+ tabWidget->addTab(queryFrame, tr("Query"));
+ tabWidget->addTab(flagsFrame, tr("Query Flags"));
+ tabWidget->addTab(m_resultsTable, tr("Results"));
+
+ return tabWidget;
+}
+
+void QTestBrowserDlg::updateAppContext()
+{
+ disconnect(m_appContext, SIGNAL(currentIndexChanged(QString)), this, SLOT(onAppContextChanged(QString)));
+ m_appContext->clear();
+ m_appContext->setCurrentIndex(-1);
+ QStringList appIds = m_test->getAppIds();
+ int appIndex = appIds.indexOf(m_test->currentAppId());
+ foreach (const QString &id, appIds) {
+ QString appName;
+ QVariantMap appData = m_test->applicationData(id);
+ appName = appData["appName"].toString();
+ appName.append(QString("(%1)").arg(id));
+ m_appContext->addItem(appName, id);
+ }
+ m_appContext->setCurrentIndex(appIndex);
+ connect(m_appContext, SIGNAL(currentIndexChanged(QString)), this, SLOT(onAppContextChanged(QString)));
+}
+
+QSize QTestBrowserDlg::sizeHint() const
+{
+ return QSize(960, 960);
+}
+
+void QTestBrowserDlg::contextMenuEvent(QContextMenuEvent *e)
+{
+ m_methodsAction->setText(QString("View Methods for %1").arg(currentTabSignature()));
+
+ QMenu menu(this);
+ menu.addAction(m_refreshAction);
+ menu.addSeparator();
+ menu.addAction(m_expandAction);
+ menu.addAction(m_collapseAction);
+ menu.addSeparator();
+ menu.addAction(m_methodsAction);
+ menu.addSeparator();
+
+ QMenu *subMenu = menu.addMenu(tr("Add Query Condition"));
+ subMenu->addAction(QLatin1String("CHILD_OF"));
+ subMenu->addAction(QLatin1String("DESCENDANT_OF"));
+ subMenu->addAction(QLatin1String("PARENT_OF"));
+ subMenu->addAction(QLatin1String("ANCESTOR_OF"));
+ connect(subMenu, SIGNAL(triggered(QAction*)), this, SLOT(onMenuQueryCondition(QAction*)));
+ menu.exec(e->globalPos());
+}
+
+void QTestBrowserDlg::setSystemTest ( QstConnection *test )
+{
+ m_test = test;
+ connect(m_test, SIGNAL(appFinished(QString)), this, SLOT(onAppFinished(QString)));
+ connect(m_test, SIGNAL(appStarted(QString)), this, SLOT(onAppStarted(QString)));
+}
+
+void QTestBrowserDlg::setImage( const QPixmap &img )
+{
+ if (!img.isNull()) {
+ m_image->setPixmap(img);
+ } else {
+ m_image->setText("No image available");
+ }
+
+ m_image->adjustSize();
+ updateGeometry();
+}
+
+void QTestBrowserDlg::setBaseItems( const QVariantMap &item, const QVariantMap &imgItem )
+{
+ if (item.isEmpty()) {
+ m_appId = m_test->currentAppId();
+ qDebug() << "current app id" << m_appId;
+ m_appId = m_appContext->itemData(m_appContext->currentIndex()).toString();
+ m_test->setAppId(m_appId);
+ QVariantMap appData = m_test->applicationData(m_appId);
+ m_baseItem = appData["appObject"].toMap();
+ m_imgItem = m_baseItem;
+ } else {
+ m_baseItem = item;
+ m_imgItem = imgItem;
+ m_appId = item[QstConnection::appIdProperty].toString();
+ }
+ refresh();
+}
+
+void QTestBrowserDlg::setObjectMap ( const QVariantMap &map )
+{
+ m_tree->setCursor(Qt::WaitCursor);
+ m_map = map;
+ m_geometry = m_map["geometry"].toMap();
+ m_children = m_map["children"].toMap();
+ m_window = m_map["window"].toMap();
+ QString sig = signature(m_baseItem);
+
+ m_tree->clear();
+ m_treeMap.clear();
+
+ addItemToTree(sig);
+ m_tree->expandAll();
+ m_tree->resizeColumnToContents(0);
+ m_tree->setCursor(Qt::ArrowCursor);
+}
+
+void QTestBrowserDlg::closeWindow()
+{
+ QDialog::accept();
+ deleteLater();
+}
+
+void QTestBrowserDlg::onImageClicked( const QPoint& point )
+{
+ QPoint p = point + m_origin;
+ QString selectedItem;
+ int selectedArea=-1;
+
+ foreach (const QString &item, m_window.keys()) {
+ if (m_window[item] == m_currentWindowSignature) {
+ QRect rect = m_geometry[item].toRect();
+ if (rect.contains(p) && m_map["visible"].toMap()[item].toBool()) {
+ if (selectedArea == -1 || selectedArea > abs(rect.width() * rect.height())) {
+ selectedItem = item;
+ selectedArea = abs(rect.width() * rect.height());
+ }
+ }
+ }
+ }
+ selectItem(selectedItem);
+}
+
+void QTestBrowserDlg::selectItem( const QString &item )
+{
+ QTreeWidgetItem *treeItem = m_treeMap[item];
+ if (treeItem && treeItem != m_tree->currentItem() && !treeItem->isDisabled()) {
+ m_tree->collapseAll();
+ m_tree->setCurrentItem(treeItem);
+ }
+}
+
+void QTestBrowserDlg::onItemChanged(QTreeWidgetItem *item, QTreeWidgetItem *prev)
+{
+ Q_UNUSED(prev);
+ if (!item || !m_test) {
+ return;
+ }
+
+ QString itemSignature = item->text(1);
+ QString windowSignature = m_window[itemSignature].toString();
+ if (windowSignature != m_currentWindowSignature) {
+ m_currentWindowSignature = windowSignature;
+ m_imgItem = widgetSpec(windowSignature);
+ refreshImage();
+ }
+
+ QRect rect;
+ rect = m_geometry[item->text(1)].toRect();
+ rect.moveTopLeft(rect.topLeft() - m_origin);
+ m_image->setSelectedArea(rect);
+
+ QVariantMap propertyMap =
+ m_test->getProperties(widgetSpec(itemSignature));
+
+ updatePropertyTable(m_itemPropertyTable, propertyMap);
+ m_tabItemSignatures.replace(0, itemSignature);
+ m_propertyTab->setCurrentIndex(0);
+ m_propertyTab->setTabEnabled(0, true);
+ m_propertyTab->setTabToolTip(0, QString("Properties: %1").arg(itemSignature));
+}
+
+void QTestBrowserDlg::onAppContextChanged(const QString &context)
+{
+ Q_UNUSED(context);
+ setBaseItems();
+}
+
+void QTestBrowserDlg::initTable(QTableWidget *table, const QStringList &labels)
+{
+ table->setColumnCount(labels.count());
+ table->verticalHeader()->hide();
+ table->horizontalHeader()->setStretchLastSection(true);
+ table->setHorizontalHeaderLabels(labels);
+ table->setContextMenuPolicy(Qt::CustomContextMenu);
+}
+
+void QTestBrowserDlg::initPropertyTable(QTableWidget *table)
+{
+ static QStringList propertyHeaders(QStringList()
+ << QLatin1String("Property")
+ << QLatin1String("Value")
+ );
+
+ initTable(table, propertyHeaders);
+ connect(table, SIGNAL(itemDoubleClicked(QTableWidgetItem*)), this, SLOT(onPropertyDoubleClicked(QTableWidgetItem*)));
+ connect(table, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(onPropertyContextMenu(QPoint)));
+}
+
+void QTestBrowserDlg::initMethodsTable(QTableWidget *table)
+{
+ static QStringList methodsHeaders(QStringList()
+ << QLatin1String("Method Type")
+ << QLatin1String("Return Type")
+ << QLatin1String("Method Signature")
+ );
+
+ initTable(table, methodsHeaders);
+ connect(table, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(onMethodsContextMenu(QPoint)));
+}
+
+void QTestBrowserDlg::updatePropertyTable(QTableWidget *table, const QVariantMap &propertyMap)
+{
+ QVariantMap previousValues = table->property("_qttPrevMap").toMap();
+
+ table->clearContents();
+ table->setRowCount(propertyMap.size());
+ table->clearSpans();
+
+ int row = 0;
+ foreach (const QString &propertyName, propertyMap.keys()) {
+ QTableWidgetItem *nameItem = new QTableWidgetItem(propertyName);
+ nameItem->setFlags(Qt::ItemIsEnabled);
+ table->setItem(row, 0, nameItem);
+ QVariant value = propertyMap[propertyName];
+
+ if (value.type() == QVariant::List) {
+ QVariantList list = value.toList();
+ if (list.size() > 0) {
+ if (list.size() > 1) {
+ table->setRowCount(table->rowCount() + list.size() -1);
+ table->setSpan(row, 0, list.size(), 1);
+ }
+ foreach (const QVariant &item, list) {
+ QTableWidgetItem *valueItem = valueToTableItem(item);
+ valueItem->setFlags(Qt::ItemIsEnabled);
+ table->setItem(row++, 1, valueItem);
+ }
+ continue;
+ }
+ }
+
+ QTableWidgetItem *valueItem = valueToTableItem(value, previousValues.value(propertyName));
+ valueItem->setFlags(Qt::ItemIsEnabled);
+ table->setItem(row, 1, valueItem);
+ row++;
+ }
+
+ table->resizeRowsToContents();
+ int size = table->horizontalHeader()->sectionSize(0);
+ table->resizeColumnToContents(0);
+ if (size > table->horizontalHeader()->sectionSize(0)) {
+ table->horizontalHeader()->resizeSection(0, size);
+ }
+ table->setProperty("_qttPrevMap", propertyMap);
+}
+
+void QTestBrowserDlg::updateMethodsTable(QTableWidget *table, const QVariantList &methods)
+{
+ table->clearContents();
+ table->setRowCount(methods.size());
+ table->clearSpans();
+
+ int row = 0;
+ foreach (const QVariant &method, methods) {
+ QVariantMap map = method.toMap();
+ int methodType = map["methodType"].toInt();
+ QString methodTypeName;
+ switch (methodType) {
+ case QMetaMethod::Method:
+ methodTypeName = QLatin1String("Method");
+ break;
+ case QMetaMethod::Signal:
+ methodTypeName = QLatin1String("Signal");
+ break;
+ case QMetaMethod::Slot:
+ methodTypeName = QLatin1String("Slot");
+ break;
+ case QMetaMethod::Constructor:
+ methodTypeName = QLatin1String("Constructor");
+ break;
+ }
+ QString returnType = map["returnType"].toString();
+ QString signature = map["signature"].toString();
+
+ QTableWidgetItem *typeItem = new QTableWidgetItem(methodTypeName);
+ typeItem->setFlags(Qt::ItemIsEnabled);
+ table->setItem(row, 0, typeItem);
+
+ QTableWidgetItem *retItem = new QTableWidgetItem(returnType);
+ retItem->setFlags(Qt::ItemIsEnabled);
+ table->setItem(row, 1, retItem);
+
+ QTableWidgetItem *sigItem = new QTableWidgetItem(signature);
+ sigItem->setFlags(Qt::ItemIsEnabled);
+ table->setItem(row, 2, sigItem);
+
+ row++;
+ }
+
+ table->resizeRowsToContents();
+ table->resizeColumnsToContents();
+ table->sortItems(1);
+}
+
+QTableWidgetItem *QTestBrowserDlg::valueToTableItem(const QVariant &value, const QVariant &previous)
+{
+ QString valueString = valueToString(value);
+ QTableWidgetItem *valueItem = new QTableWidgetItem(valueString);
+ if (previous.isValid() && valueToString(previous) != valueString) {
+ valueItem->setBackground(QBrush("#ffff80"));
+ }
+ if (value.type() == QVariant::Map) {
+ QString sig = signature(value.toMap());
+ if (m_treeMap.contains(sig)) {
+ valueItem->setForeground(QBrush(Qt::blue));
+ } else if (!sig.isEmpty()) {
+ valueItem->setForeground(QBrush(Qt::darkGreen));
+ }
+ } else if (valueString.startsWith(QChar('<'))
+ && valueString.endsWith(QChar('>'))) {
+ valueItem->setForeground(QBrush(Qt::gray));
+ return valueItem;
+ }
+ valueItem->setData(Qt::UserRole, value);
+ return valueItem;
+}
+
+QString QTestBrowserDlg::valueToString(const QVariant &value)
+{
+ QString valueString;
+ if (value.canConvert(QVariant::String)) {
+ valueString = value.toString();
+ } else if (value.type() == QVariant::List) {
+ QVariantList list = value.toList();
+ if (list.length() == 0) {
+ valueString = QLatin1String("<Empty List>");
+ } else {
+ QStringList itemStrings;
+ foreach (const QVariant& item, list) {
+ itemStrings << valueToString(item);
+ }
+ valueString = itemStrings.join(QLatin1String(", "));
+ }
+ } else if (value.type() == QVariant::Map) {
+ QVariantMap map = value.toMap();
+ valueString = signature(map);
+ if (valueString.isEmpty()) {
+ if (map.contains(QstConnection::enumProperty)) {
+ valueString = QString("%1 (%2)").arg(map[QstConnection::valueProperty].toInt()).arg(map[QstConnection::enumProperty].toString());
+ } else {
+ valueString = QLatin1String("<QVariantMap>");
+ }
+ }
+ } else if (value.type() == QVariant::PointF) {
+ QRectF rectf = value.toRectF();
+ valueString = QString("QPointF (%1,%2)").arg(rectf.x()).arg(rectf.y());
+ } else if (value.type() == QVariant::RectF) {
+ QRectF rectf = value.toRectF();
+ valueString = QString("QRectF (%1,%2 %3x%4)").arg(rectf.x()).arg(rectf.y()).arg(rectf.width()).arg(rectf.height());
+ } else if (value.type() == QVariant::Size) {
+ QSize size = value.toSize();
+ valueString = QString("QSize (%1x%2)").arg(size.width()).arg(size.height());
+ } else if (value.type() == QVariant::SizeF) {
+ QSizeF size = value.toSizeF();
+ valueString = QString("QSizeF (%1x%2)").arg(size.width()).arg(size.height());
+ } else {
+ valueString = QString("<%1>").arg(value.typeName());
+ }
+ return valueString;
+}
+
+void QTestBrowserDlg::addItemToTree(const QString &item, QTreeWidgetItem *parent)
+{
+ QString geoString;
+ if (m_geometry.contains(item)) {
+ QRect rect = m_geometry[item].toRect();
+ geoString = QString("%1,%2 %3x%4").arg(rect.x()).arg(rect.y()).arg(rect.width()).arg(rect.height());
+ }
+ QTreeWidgetItem *treeItem = new QTreeWidgetItem(parent, QStringList() <<
+ m_map["type"].toMap()[item].toString() <<
+ item <<
+ m_map["qmlid"].toMap()[item].toString() <<
+ m_map["objectName"].toMap()[item].toString() <<
+ geoString <<
+ m_map["text"].toMap()[item].toString()
+ );
+ if (!m_map["visible"].toMap()[item].toBool()) {
+ treeItem->setForeground(0, QBrush(Qt::gray));
+ }
+ m_tree->addTopLevelItem(treeItem);
+ m_treeMap[item] = treeItem;
+
+ foreach (const QString &child, m_children[item].toStringList()) {
+ addItemToTree(child, treeItem);
+ }
+}
+
+void QTestBrowserDlg::addQueryRow(const QString &property, const QVariant &value)
+{
+ static QStringList relationshipProperties(QStringList()
+ << QLatin1String("ANCESTOR_OF") << QLatin1String("CHILD_OF") << QLatin1String("DESCENDANT_OF") << QLatin1String("PARENT_OF"));
+
+ static QStringList qmlProperties(QStringList()
+ << QLatin1String("QMLID") << QLatin1String("QMLINHERITS") << QLatin1String("QMLTYPE"));
+
+ static QStringList defaultProperties(QStringList()
+ << QLatin1String("CLASSNAME") << QLatin1String("INHERITS") << QLatin1String("LABEL") << QLatin1String("PROPERTY"));
+
+ int row = m_queryTable->rowCount()-1;
+ m_queryTable->insertRow(row);
+
+ QTableWidgetItem *checkItem = new QTableWidgetItem(QString());
+ checkItem->setCheckState(Qt::Checked);
+ m_queryTable->setItem(row, 0, checkItem);
+
+ QComboBox *propertyCombo = new QComboBox();
+ propertyCombo->addItems(defaultProperties);
+ propertyCombo->insertSeparator(99);
+ propertyCombo->addItems(relationshipProperties);
+ propertyCombo->insertSeparator(99);
+ propertyCombo->addItems(qmlProperties);
+ propertyCombo->setEditable(true);
+ propertyCombo->lineEdit()->setText(property);
+ propertyCombo->setMaxVisibleItems(propertyCombo->count()+1);
+ m_queryTable->setCellWidget(row, 1, propertyCombo);
+
+ QTableWidgetItem *valueItem = new QTableWidgetItem();
+ if (value.canConvert(QVariant::String)) {
+ valueItem->setText(value.toString());
+ valueItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsEditable);
+ } else {
+ valueItem->setText(valueToString(value));
+ valueItem->setData(Qt::UserRole, value);
+ valueItem->setFlags(Qt::NoItemFlags);
+ }
+
+ m_queryTable->setItem(row, 2, valueItem);
+ m_queryTable->resizeRowsToContents();
+ m_queryTable->scrollToItem(checkItem, QAbstractItemView::PositionAtTop);
+}
+
+QVariantMap QTestBrowserDlg::queryMap() const
+{
+ QVariantMap map;
+ for (int i=0; i<m_queryTable->rowCount()-1;) {
+ QComboBox *propertyCombo = qobject_cast<QComboBox*>(m_queryTable->cellWidget(i, 1));
+ QString property;
+ if (propertyCombo) {
+ property = propertyCombo->currentText();
+ }
+ QTableWidgetItem *valueItem = m_queryTable->item(i, 2);
+ QVariant value = valueItem->data(Qt::UserRole);
+ if (!value.isValid()) {
+ value = valueItem->text();
+ }
+ if (property.isEmpty() && value.isNull()) {
+ m_queryTable->removeRow(i);
+ continue;
+ }
+
+ if (property.isEmpty()) {
+ QMessageBox::warning(const_cast<QTestBrowserDlg*>(this), tr("Invalid Query"), QLatin1String("An empty property is not permitted"));
+ return QVariantMap();
+ }
+
+ if (map.contains(property)) {
+ QMessageBox::warning(const_cast<QTestBrowserDlg*>(this), tr("Invalid Query"), QString("There are duplicate instances of property '%1'").arg(property));
+ return QVariantMap();
+ }
+
+ map[property] = value;
+ i++;
+ }
+
+ if (map.isEmpty()) {
+ QMessageBox::warning(const_cast<QTestBrowserDlg*>(this), tr("Invalid Query"), QLatin1String("No properties were specified !"));
+ }
+
+ return map;
+}
+
+void QTestBrowserDlg::doQuery()
+{
+ m_resultsTable->clearContents();
+ m_resultsTable->setRowCount(0);
+
+ QVariantMap map = queryMap();
+ if (map.isEmpty()) {
+ return;
+ }
+
+ int flags=0;
+ if (m_flagInvisible->isChecked()) flags |= QstConnection::ScanInvisible;
+ if (m_flagDisabled->isChecked()) flags |= QstConnection::ScanDisabledItems;
+ if (m_flagIgnoreScan->isChecked()) flags |= QstConnection::IgnoreScanned;
+
+ QString currentAppId = m_test->currentAppId();
+ if (currentAppId != m_appId) {
+ m_test->setAppId(m_appId);
+ }
+ m_matches = m_test->findByProperties(map, flags);
+ if (currentAppId != m_appId) {
+ m_test->setAppId(currentAppId);
+ }
+
+ m_resultsTable->setRowCount(m_matches.count());
+ int row=0;
+ QVariantMap idMap = m_map["qmlid"].toMap();
+ foreach (const QString &match, m_matches) {
+ QTableWidgetItem *item = new QTableWidgetItem(match);
+ m_resultsTable->setItem(row, 0, item);
+ QTableWidgetItem *idItem = new QTableWidgetItem(idMap[match].toString());
+ m_resultsTable->setItem(row, 1, idItem);
+ row++;
+ }
+ m_resultsTable->resizeRowsToContents();
+ m_resultsTable->resizeColumnsToContents();
+ m_queryTab->setTabText(2, QString("Results (%1)").arg(m_matches.count()));
+ m_queryTab->setCurrentIndex(2);
+}
+
+void QTestBrowserDlg::clearQuery()
+{
+ for (int i=0; i<m_queryTable->rowCount()-1;) {
+ m_queryTable->removeRow(i);
+ }
+}
+
+void QTestBrowserDlg::copyQuery()
+{
+ QVariantMap map = queryMap();
+ if (map.isEmpty()) {
+ return;
+ }
+// QApplication::clipboard()->setText(m_test->objectToString(map));
+}
+
+void QTestBrowserDlg::expandAll()
+{
+ m_tree->expandAll();
+ m_tree->scrollToItem(m_tree->currentItem());
+}
+
+void QTestBrowserDlg::collapseAll()
+{
+
+ m_tree->collapseAll();
+ m_tree->scrollToItem(m_tree->currentItem());
+}
+
+void QTestBrowserDlg::refresh()
+{
+ setObjectMap(m_test->getObjects(m_baseItem));
+ refreshImage();
+}
+
+void QTestBrowserDlg::refreshImage()
+{
+ m_tree->setEnabled(false);
+ QImage img(m_test->grabImage(m_imgItem));
+ m_origin = m_geometry[m_imgItem["_signature_"].toString()].toRect().topLeft();
+ setImage(QPixmap::fromImage(img));
+ m_tree->setEnabled(true);
+}
+
+void QTestBrowserDlg::showMatch(int index)
+{
+ selectItem(m_matches[index]);
+}
+
+void QTestBrowserDlg::viewMethods()
+{
+ QString currentItem = currentTabSignature();
+ QVariantList methods =
+ m_test->getMethods(widgetSpec(currentItem));
+
+ QTableWidget *methodsTable = new QTableWidget();
+ initMethodsTable(methodsTable);
+ updateMethodsTable(methodsTable, methods);
+ int newTabIndex = m_propertyTab->addTab(methodsTable, QString("Methods: %1").arg(currentItem));
+ m_tabItemSignatures.append(currentItem);
+ m_propertyTab->setCurrentIndex(newTabIndex);
+}
+
+void QTestBrowserDlg::onPropertyDoubleClicked(QTableWidgetItem *item)
+{
+ QString itemText = item->text();
+ if (m_treeMap.contains(itemText)) {
+ selectItem(itemText);
+ } else {
+ QVariant value = item->data(Qt::UserRole);
+ if (value.type() == QVariant::Map) {
+ QVariantMap map = value.toMap();
+ if (map.contains(QstConnection::signatureProperty)) {
+ openPropertyTab(map[QstConnection::signatureProperty].toString());
+ }
+ }
+ }
+}
+
+void QTestBrowserDlg::openPropertyTab(const QString &signature)
+{
+ QVariantMap propertyMap =
+ m_test->getProperties(widgetSpec(signature));
+
+ QTableWidget *propertyTable = new QTableWidget();
+ initPropertyTable(propertyTable);
+ updatePropertyTable(propertyTable, propertyMap);
+ int newTabIndex = m_propertyTab->addTab(propertyTable, QString("Properties: %1").arg(signature));
+ m_tabItemSignatures.append(signature);
+ m_propertyTab->setCurrentIndex(newTabIndex);
+
+}
+
+void QTestBrowserDlg::onTabCloseRequested(int tabIndex)
+{
+ if (tabIndex > 0) {
+ QWidget *w = m_propertyTab->widget(tabIndex);
+ m_propertyTab->removeTab(tabIndex);
+ delete w;
+ m_tabItemSignatures.removeAt(tabIndex);
+ }
+}
+
+QString QTestBrowserDlg::currentTabSignature() const
+{
+ return m_tabItemSignatures.at(m_propertyTab->currentIndex());
+}
+
+void QTestBrowserDlg::onPropertyContextMenu(const QPoint &pos)
+{
+ QTableWidget *propertyTable = qobject_cast<QTableWidget*>(m_propertyTab->currentWidget());
+ if (propertyTable) {
+ m_contextTableItem = propertyTable->itemAt(pos);
+ QMenu menu(this);
+
+ m_methodsAction->setText(QString("View Methods for %1").arg(currentTabSignature()));
+ menu.addAction(m_propertyRefreshAction);
+ menu.addSeparator();
+ menu.addAction(m_methodsAction);
+
+ if (tableItemIsWidgetIdentifier(m_contextTableItem)) {
+ m_propertyMethodsAction->setText(QString("View Methods for %1").arg(m_contextTableItem->text()));
+ m_propertyPropertiesAction->setText(QString("View Properties for %1").arg(m_contextTableItem->text()));
+ menu.addSeparator();
+ menu.addAction(m_propertyMethodsAction);
+ menu.addAction(m_propertyPropertiesAction);
+ }
+
+ // Add as Query Condition, only if item is not part of a list
+ // and the value is valid
+ if (m_contextTableItem
+ && propertyTable->rowSpan(m_contextTableItem->row(), 0) == 1
+ && propertyTable->item(m_contextTableItem->row(), 1)->data(Qt::UserRole).isValid()) {
+ menu.addSeparator();
+ menu.addAction(m_propertyQueryAction);
+ }
+ menu.addSeparator();
+ menu.addAction(m_propertyCopyAction);
+ menu.addAction(m_propertyCopyTableAction);
+ menu.exec(propertyTable->mapToGlobal(pos));
+ m_contextTableItem = 0;
+ }
+}
+
+void QTestBrowserDlg::onMethodsContextMenu(const QPoint &pos)
+{
+ QTableWidget *propertyTable = qobject_cast<QTableWidget*>(m_propertyTab->currentWidget());
+ if (propertyTable) {
+ m_contextTableItem = propertyTable->itemAt(pos);
+ QMenu menu(this);
+ menu.addAction(m_propertyCopyAction);
+ menu.addAction(m_propertyCopyTableAction);
+ menu.exec(propertyTable->mapToGlobal(pos));
+ m_contextTableItem = 0;
+ }
+}
+
+void QTestBrowserDlg::refreshProperties()
+{
+ QTableWidget *propertyTable = qobject_cast<QTableWidget*>(m_propertyTab->currentWidget());
+ if (propertyTable) {
+ propertyTable->setCursor(Qt::WaitCursor);
+ QVariantMap propertyMap =
+ m_test->getProperties(widgetSpec(currentTabSignature()));
+ updatePropertyTable(propertyTable, propertyMap);
+ propertyTable->setCursor(Qt::ArrowCursor);
+ }
+}
+
+void QTestBrowserDlg::viewPropertyMethods()
+{
+ if (m_contextTableItem) {
+ QString signature = m_contextTableItem->text();
+ QVariantList methods =
+ m_test->getMethods(widgetSpec(signature));
+
+ QTableWidget *methodsTable = new QTableWidget();
+ initMethodsTable(methodsTable);
+ updateMethodsTable(methodsTable, methods);
+ int newTabIndex = m_propertyTab->addTab(methodsTable, QString("Methods: %1").arg(signature));
+ m_tabItemSignatures.append(signature);
+ m_propertyTab->setCurrentIndex(newTabIndex);
+ }
+}
+
+void QTestBrowserDlg::viewPropertyProperties()
+{
+ if (m_contextTableItem) {
+ QString signature = m_contextTableItem->text();
+ openPropertyTab(signature);
+ }
+}
+
+void QTestBrowserDlg::addPropertyAsQueryCondition()
+{
+ if (m_contextTableItem) {
+ int row = m_contextTableItem->row();
+ QTableWidget *table = m_contextTableItem->tableWidget();
+ QTableWidgetItem *propertyItem = table->item(row, 0);
+ QTableWidgetItem *valueItem = table->item(row, 1);
+ QVariant value = valueItem->data(Qt::UserRole);
+ if (value.type() == QVariant::Map) {
+ QVariantMap map = value.toMap();
+ if (map.contains("_enum_"))
+ value = map.value("_enum_");
+ else if (map.contains("_signature_"))
+ value = map.value("_signature_");
+ else
+ return;
+ }
+ addQueryRow(propertyItem->text(), value);
+ }
+ m_queryTab->setCurrentIndex(0);
+}
+
+void QTestBrowserDlg::copyTableItemValue()
+{
+ if (m_contextTableItem) {
+ QApplication::clipboard()->setText(m_contextTableItem->text());
+ }
+}
+
+void QTestBrowserDlg::copyTable()
+{
+ QTableWidget *propertyTable = qobject_cast<QTableWidget*>(m_propertyTab->currentWidget());
+ QString text;
+ for (int row = 0; row < propertyTable->rowCount(); ++row) {
+ for (int col = 0; col < propertyTable->columnCount(); ++col) {
+ QString cellText;
+ QTableWidgetItem *item = propertyTable->item(row, col);
+ if (item) {
+ cellText = propertyTable->item(row, col)->text();
+ }
+ text += QString("%1%2").arg(col ? "\t" : "").arg(cellText);
+ }
+ text += QLatin1String("\n");
+ }
+ QApplication::clipboard()->setText(text);
+}
+
+bool QTestBrowserDlg::tableItemIsWidgetIdentifier(const QTableWidgetItem *item)
+{
+ if (!item) return false;
+ QVariant value = item->data(Qt::UserRole);
+ return value.type() == QVariant::Map
+ && value.toMap().contains(QstConnection::signatureProperty);
+}
+
+QVariantMap QTestBrowserDlg::widgetSpec(const QString &signature)
+{
+ return m_test->widgetFromSignature(signature, m_appId);
+}
+
+void QTestBrowserDlg::onConnectionClosed()
+{
+ QMessageBox::warning(this, tr("Connection Lost"), tr("Connection to the test system has been lost."));
+}
+
+void QTestBrowserDlg::onQueryItemChanged(QTableWidgetItem *item)
+{
+ if (item->column() == 0 && item->checkState() == Qt::Unchecked) {
+ m_queryTable->removeRow(item->row());
+ }
+}
+
+void QTestBrowserDlg::onQueryContextMenu(const QPoint &pos)
+{
+ QMenu menu(this);
+
+ menu.addAction(m_queryClearAction);
+ menu.addAction(m_queryCopyAction);
+
+ menu.exec(m_queryTable->mapToGlobal(pos));
+}
+
+void QTestBrowserDlg::onResultsItemSelected()
+{
+ selectItem(m_resultsTable->item(m_resultsTable->currentRow(), 0)->text());
+}
+
+void QTestBrowserDlg::onMenuQueryCondition(QAction *action)
+{
+ addQueryRow(action->text(), currentTabSignature());
+ m_queryTab->setCurrentIndex(0);
+}
+
+void QTestBrowserDlg::onAppFinished(const QString& appId)
+{
+ updateAppContext();
+ if (appId == m_appId) {
+ QMessageBox::warning(this, tr("Application Closed"), tr("The application was closed."));
+ setBaseItems();
+ }
+}
+
+void QTestBrowserDlg::onAppStarted(const QString& appId)
+{
+ Q_UNUSED(appId);
+ updateAppContext();
+}
+
+bool QTestBrowserDlg::eventFilter(QObject *obj, QEvent *event)
+{
+ if (obj == m_appContext && event->type() == QEvent::MouseButtonPress) {
+ for (int i=0; i<m_appContext->count(); i++) {
+ if (m_appContext->itemText(i).isEmpty()) {
+ QVariantMap appData = m_test->applicationData(m_appContext->itemData(i).toString());
+ m_appContext->setItemText(i, appData["appId"].toString());
+ }
+ }
+ return false;
+ } else {
+ return QDialog::eventFilter(obj, event);
+ }
+}
diff --git a/src/objectBrowser/qtestbrowserdlg_p.h b/src/objectBrowser/qtestbrowserdlg_p.h
new file mode 100644
index 0000000..ecdfa8e
--- /dev/null
+++ b/src/objectBrowser/qtestbrowserdlg_p.h
@@ -0,0 +1,210 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QTESTBROWSERDLG_P_H
+#define QTESTBROWSERDLG_P_H
+
+#include <QDialog>
+#include <QLabel>
+#include <QVariant>
+#include <QVariantMap>
+#include <QtSystemTest/qstglobal.h>
+
+class QstConnection;
+
+QT_BEGIN_NAMESPACE
+class QAction;
+class QMenu;
+class QPushButton;
+class QMouseEvent;
+class QPaintEvent;
+class QTreeWidget;
+class QTreeWidgetItem;
+class QTableWidget;
+class QTableWidgetItem;
+class QComboBox;
+class QLineEdit;
+class QSpinBox;
+class QTabWidget;
+class QCheckBox;
+QT_END_NAMESPACE
+
+class TestImageViewer : public QLabel
+{
+ Q_OBJECT
+
+public:
+ TestImageViewer( QWidget * parent = 0, Qt::WindowFlags f = 0 );
+ ~TestImageViewer();
+ void setSelectedArea(const QRect& rect);
+
+protected:
+ void mouseReleaseEvent(QMouseEvent *event);
+ void paintEvent(QPaintEvent *event);
+
+signals:
+ void clicked(const QPoint&);
+
+private:
+ QRect m_selectedArea;
+};
+
+class QSYSTEMTEST_EXPORT QTestBrowserDlg : public QDialog
+{
+ Q_OBJECT
+
+public:
+ QTestBrowserDlg(QstConnection*, const QVariantMap& = QVariantMap(), const QVariantMap& = QVariantMap());
+ ~QTestBrowserDlg();
+
+ virtual QSize sizeHint() const;
+ virtual void contextMenuEvent(QContextMenuEvent *e);
+ void setSystemTest ( QstConnection *test );
+ void setImage( const QPixmap& );
+ void setBaseItems( const QVariantMap& = QVariantMap(), const QVariantMap& = QVariantMap() );
+ void setObjectMap ( const QVariantMap& );
+
+public slots:
+ void closeWindow();
+ void onImageClicked(const QPoint&);
+ void onItemChanged(QTreeWidgetItem *item, QTreeWidgetItem *prev);
+ void onAppContextChanged(const QString& context);
+ void addQueryRow(const QString &property = QString(), const QVariant &value = QString());
+ void doQuery();
+ void clearQuery();
+ void copyQuery();
+ void expandAll();
+ void collapseAll();
+ void refresh();
+ void refreshImage();
+ void showMatch(int);
+ void viewMethods();
+ void selectItem(const QString& item);
+ void onPropertyDoubleClicked(QTableWidgetItem *item);
+ void onTabCloseRequested(int);
+ void onPropertyContextMenu(const QPoint&);
+ void onMethodsContextMenu(const QPoint&);
+ void refreshProperties();
+ void viewPropertyMethods();
+ void viewPropertyProperties();
+ void addPropertyAsQueryCondition();
+ void copyTableItemValue();
+ void copyTable();
+ void onConnectionClosed();
+ void onQueryItemChanged(QTableWidgetItem *item);
+ void onQueryContextMenu(const QPoint&);
+ void onResultsItemSelected();
+ void onMenuQueryCondition(QAction *action);
+ void onAppFinished(const QString&);
+ void onAppStarted(const QString&);
+
+protected:
+ bool eventFilter( QObject *obj, QEvent *event);
+
+private:
+ void createActions();
+ void createWidgets();
+ QTabWidget *createQueryTab();
+ void updateAppContext();
+
+ void addItemToTree(const QString &item, QTreeWidgetItem *parent = 0);
+ void initTable(QTableWidget *table, const QStringList&);
+ void initPropertyTable(QTableWidget *table);
+ void initMethodsTable(QTableWidget *table);
+ void updatePropertyTable(QTableWidget *table, const QVariantMap &propertyMap);
+ void updateMethodsTable(QTableWidget *table, const QVariantList &methods);
+ QTableWidgetItem *valueToTableItem(const QVariant &value, const QVariant &previous = QVariant());
+ QString valueToString(const QVariant &value);
+ QString currentTabSignature() const;
+ bool tableItemIsWidgetIdentifier(const QTableWidgetItem *item);
+ QVariantMap widgetSpec(const QString &signature);
+ void openPropertyTab(const QString &signature);
+ QVariantMap queryMap() const;
+
+ QVariantMap m_baseItem;
+ QVariantMap m_imgItem;
+ QString m_appId;
+ QString m_visibleTabItem;
+ QPoint m_origin;
+ QVariantMap m_map;
+ QVariantMap m_geometry;
+ QVariantMap m_children;
+ QVariantMap m_window;
+ QMap<QString,QTreeWidgetItem*> m_treeMap;
+ QStringList m_matches;
+ QStringList m_tabItemSignatures;
+ QString m_currentWindowSignature;
+
+ QstConnection *m_test;
+ TestImageViewer *m_image;
+ QComboBox *m_appContext;
+ QTreeWidget *m_tree;
+ QTabWidget *m_queryTab;
+ QTabWidget *m_propertyTab;
+ QTableWidget *m_itemPropertyTable;
+ QTableWidget *m_queryTable;
+ QTableWidget *m_resultsTable;
+ QTableWidgetItem *m_contextTableItem;
+
+ QCheckBox *m_flagInvisible;
+ QCheckBox *m_flagDisabled;
+ QCheckBox *m_flagIgnoreScan;
+
+ QAction *m_refreshAction;
+ QAction *m_expandAction;
+ QAction *m_collapseAction;
+ QAction *m_methodsAction;
+
+ // Table context menu actions
+ QAction *m_propertyRefreshAction;
+ QAction *m_propertyMethodsAction;
+ QAction *m_propertyPropertiesAction;
+ QAction *m_propertyQueryAction;
+ QAction *m_propertyCopyAction;
+ QAction *m_propertyCopyTableAction;
+
+ // Query actions
+ QAction *m_queryClearAction;
+ QAction *m_queryCopyAction;
+};
+
+#endif
diff --git a/src/protocol/QstConnection b/src/protocol/QstConnection
new file mode 100644
index 0000000..6d2fbf2
--- /dev/null
+++ b/src/protocol/QstConnection
@@ -0,0 +1,42 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qstconnection.h"
diff --git a/src/protocol/QstConnectionManager b/src/protocol/QstConnectionManager
new file mode 100644
index 0000000..dc9726b
--- /dev/null
+++ b/src/protocol/QstConnectionManager
@@ -0,0 +1,42 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qstconnectionmanager.h"
diff --git a/src/protocol/QstDebug b/src/protocol/QstDebug
new file mode 100644
index 0000000..aa3c4d3
--- /dev/null
+++ b/src/protocol/QstDebug
@@ -0,0 +1,42 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qstdebug.h"
diff --git a/src/protocol/QstProtocol b/src/protocol/QstProtocol
new file mode 100644
index 0000000..8afe44f
--- /dev/null
+++ b/src/protocol/QstProtocol
@@ -0,0 +1,42 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qstprotocol.h"
diff --git a/src/protocol/protocol.pro b/src/protocol/protocol.pro
new file mode 100644
index 0000000..c9ad254
--- /dev/null
+++ b/src/protocol/protocol.pro
@@ -0,0 +1,45 @@
+TEMPLATE = lib
+
+TARGET = QstProtocol
+TARGETPATH = QtSystemTest
+
+TEMPLATE = lib
+
+CONFIG += no_clean qt
+QT += core
+
+SOURCES += \
+ qstprotocol.cpp \
+ qstconnection.cpp \
+ qstconnectionmanager.cpp
+
+PUBLIC_HEADERS += \
+ qstprotocol.h \
+ qstconnection.h \
+ qstconnectionmanager.h \
+ qstglobal.h \
+ qstdebug.h \
+ QstProtocol \
+ QstConnection \
+ QstConnectionManager \
+ QstDebug
+
+HEADERS = $$PUBLIC_HEADERS
+
+# Installing libs and headers into Qt lib
+includes.files = $$PUBLIC_HEADERS
+includes.path = $$[QT_INSTALL_HEADERS]/$$TARGETPATH
+
+target.path = $$[QT_INSTALL_LIBS]
+
+INSTALLS += includes target
+
+# Building so that other libs in project can access this lib
+DESTDIR = ../../lib
+INCLUDEDESTDIR = $$OUT_PWD/../../include/$$TARGETPATH
+includedir.target = dummytarget
+includedir.commands = (mkdir -p $$INCLUDEDESTDIR && cd $$PWD && cp $$PUBLIC_HEADERS $$INCLUDEDESTDIR/)
+
+QMAKE_EXTRA_TARGETS += includedir
+
+PRE_TARGETDEPS += dummytarget
diff --git a/src/protocol/qstconnection.cpp b/src/protocol/qstconnection.cpp
new file mode 100644
index 0000000..c57cae8
--- /dev/null
+++ b/src/protocol/qstconnection.cpp
@@ -0,0 +1,263 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qstconnection.h"
+#include "qstprotocol.h"
+
+#include <QtCore/QDebug>
+
+const QLatin1String QstConnection::appIdProperty("_appid_");
+const QLatin1String QstConnection::enumProperty("_enum_");
+const QLatin1String QstConnection::signatureProperty("_signature_");
+const QLatin1String QstConnection::valueProperty("_value_");
+const QLatin1String QstConnection::widgetSpecifierProperty("widgetSpecifier");
+
+QstConnection::QstConnection(QObject *parent)
+ : QstProtocol(parent)
+{
+}
+
+QstConnection::QstConnection(const QString &host, int port, QObject *parent)
+ : QstProtocol(parent)
+ , m_host(host)
+ , m_port(port)
+ , m_queryFailed(false)
+{
+}
+
+void QstConnection::processMessage( QstMessage *msg )
+{
+ if (!msg) return;
+
+ if (msg->event() == QLatin1String("APP_STARTED")) {
+ emit appStarted(msg->context());
+ } else if (msg->event() == QLatin1String("APP_FINISHED")) {
+ emit appFinished(msg->context());
+ } else {
+ emit messageReceived(msg->event(), msg->context(), msg->toMap());
+ }
+}
+
+bool QstConnection::connectToRemote()
+{
+ if (isConnected()) {
+ qDebug() << Q_FUNC_INFO << "Already connected to "<< m_host;
+ return true;
+ }
+
+ QTime t;
+ t.start();
+ while (t.elapsed() < 10000 && !isConnected()) {
+ QstProtocol::connect(m_host, m_port);
+ waitForConnected(2000);
+ }
+
+ if (!isConnected()) {
+ qDebug() << Q_FUNC_INFO << "Could not connect to " << m_host << ':' << m_port;
+/// FIXME: is this needed?
+// errorMsg = errorStr() ;
+ return false;
+ }
+
+ return true;
+}
+
+QVariantMap QstConnection::sendQuery(const QString &event, const QVariantMap &params, const QVariantMap &widgetSpecifier)
+{
+ QstMessage message(event, params);
+// qDebug() << "message " << event << message.toMap();
+ message[widgetSpecifierProperty] = widgetSpecifier[signatureProperty].toString();
+ if (widgetSpecifier.contains(appIdProperty)) {
+ qDebug() << " context set ";
+ message.setContext(widgetSpecifier[appIdProperty].toString());
+ }
+ else if (params.contains(appIdProperty)) {
+ message.setContext(params[appIdProperty].toString());
+ }
+
+ m_queryFailed = false;
+ QstMessage reply;
+ if (!sendMessage( message, reply, 10000 )) {
+ // Unable to send - should fail test
+ qDebug() << "Failed to send message";
+ m_queryFailed = true;
+ return reply.toMap();
+ }
+
+ return reply.toMap();
+}
+
+QVariantMap QstConnection::sendPositionQuery(const QString &event, const QVariantMap &params, const QPointF &position)
+{
+// qDebug() << event << position;
+ QVariantMap _params(params);
+ _params["pos"] = position;
+ return sendQuery(event, _params);
+}
+
+
+QVariantMap QstConnection::applicationData(const QString &appId)
+{
+ QstMessage message("applicationData");
+ if (!appId.isEmpty()) {
+ message.setContext(appId);
+ }
+
+ QVariantMap ret;
+ QstMessage reply;
+ if (!sendMessage(message, reply, 10000)) {
+ return ret;
+ }
+ ret = reply["applicationdata"].toMap();
+ return ret;
+}
+
+QImage QstConnection::grabImage(const QVariantMap &widgetSpecifier)
+{
+ QImage im;
+ QVariantMap reply = sendQuery("grabImage", QVariantMap(), widgetSpecifier);
+ if (!m_queryFailed) {
+ im = reply["grabimage"].value<QImage>();
+ }
+ return im;
+}
+
+QVariantMap QstConnection::getObjects( const QVariantMap &widgetSpecifier )
+{
+ QVariantMap map;
+ QVariantMap reply = sendQuery("getObjects", QVariantMap(), widgetSpecifier);
+ if (!m_queryFailed) {
+ map = reply["getobjects"].toMap();
+ }
+ return map;
+}
+
+QVariantMap QstConnection::getProperties( const QVariantMap &widgetSpecifier )
+{
+ QVariantMap ret;
+ QVariantMap reply = sendQuery("getProperties", QVariantMap(), widgetSpecifier);
+ if (!m_queryFailed) {
+ ret = reply["getproperties"].toMap();
+ }
+ return ret;
+}
+
+QVariantList QstConnection::getMethods( const QVariantMap &widgetSpecifier )
+{
+ QVariantList ret;
+ QVariantMap reply = sendQuery("getMethods", QVariantMap(), widgetSpecifier);
+ if (!m_queryFailed) {
+ ret = reply["getmethods"].toList();
+ }
+ return ret;
+}
+
+QVariantMap QstConnection::widgetFromSignature( const QString &signature, const QString &appId )
+{
+ QVariantMap ret;
+ ret[signatureProperty] = signature;
+ if (!appId.isEmpty())
+ ret[appIdProperty] = appId;
+
+ return ret;
+}
+
+QStringList QstConnection::getAppIds(const QString &name)
+{
+ QVariantMap params;
+ if (!name.isEmpty()) {
+ params["name"] = name;
+ }
+ QStringList ret;
+ QVariantMap reply = sendQuery("getApplications", params);
+ if (!m_queryFailed) {
+ ret = reply["getapplications"].toStringList();
+ }
+ return ret;
+}
+
+QString QstConnection::currentAppId()
+{
+ QString ret;
+ QVariantMap reply = sendQuery("currentApplication", QVariantMap());
+ if (!m_queryFailed) {
+ ret = reply["currentapplication"].toString();
+ }
+ return ret;
+}
+
+QString QstConnection::homeAppId()
+{
+ QString ret;
+ QVariantMap reply = sendQuery("homeApplication", QVariantMap());
+ if (!m_queryFailed) {
+ ret = reply["homeapplication"].toString();
+ }
+ return ret;
+}
+
+void QstConnection::setAppId(const QString& appId)
+{
+ QstMessage message("setApplication");
+ message.setContext(appId);
+
+ QstMessage reply;
+ sendMessage(message, reply, 10000);
+}
+
+QStringList QstConnection::findByProperties( const QVariantMap &searchValues, int flags )
+{
+ QVariantMap params;
+ params["searchvalues"] = searchValues;
+ params["flags"] = flags;
+
+ QStringList ret;
+ QVariantMap reply = sendQuery("queryProperties", params);
+
+ if (!m_queryFailed) {
+ QVariantList matches = reply["queryproperties"].toList();
+ foreach (const QVariant &item, matches)
+ {
+ ret << item.toMap()[signatureProperty].toString();
+ }
+ }
+ return ret;
+}
diff --git a/src/protocol/qstconnection.h b/src/protocol/qstconnection.h
new file mode 100644
index 0000000..f4107db
--- /dev/null
+++ b/src/protocol/qstconnection.h
@@ -0,0 +1,108 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSTCONNECTION_H
+#define QSTCONNECTION_H
+
+#include "qstprotocol.h"
+#include <QtCore/QVariantMap>
+#include <QtCore/QPointF>
+#include <QImage>
+#include <QStringList>
+
+class QstConnection : public QstProtocol
+{
+ Q_OBJECT
+
+public:
+
+ enum QueryFlag
+ {
+ NoSort = 0x01,
+ NoScan = 0x02,
+ ScanInvisible = 0x04,
+ ScanDisabledItems = 0x08,
+ IgnoreScanned = 0x10
+ };
+ Q_DECLARE_FLAGS(QueryFlags, QueryFlag)
+
+ QstConnection(QObject *parent = 0);
+ explicit QstConnection(const QString & host, int port, QObject *parent = 0);
+
+ static const QLatin1String appIdProperty;
+ static const QLatin1String enumProperty;
+ static const QLatin1String signatureProperty;
+ static const QLatin1String valueProperty;
+ static const QLatin1String widgetSpecifierProperty;
+
+
+ QVariantMap applicationData(const QString &appId);
+ QImage grabImage(const QVariantMap &widgetSpecifier);
+ QVariantMap getObjects( const QVariantMap &widgetSpecifier );
+ QVariantMap getProperties( const QVariantMap &widgetSpecifier );
+ QVariantList getMethods( const QVariantMap &widgetSpecifier );
+ QVariantMap widgetFromSignature( const QString &signature, const QString &appId );
+ QStringList getAppIds(const QString & = QString());
+ QString currentAppId();
+ QString homeAppId();
+ void setAppId(const QString& appId);
+ QStringList findByProperties( const QVariantMap &searchValues, int flags );
+
+signals:
+ void appStarted(const QString &context);
+ void appFinished(const QString &context);
+ void messageReceived(const QString &event, const QString &context, const QVariantMap &data);
+
+protected:
+ virtual void processMessage( QstMessage *msg );
+
+public slots:
+ bool connectToRemote();
+ QVariantMap sendQuery(const QString &event, const QVariantMap &params, const QVariantMap &widgetSpecifier = QVariantMap());
+ QVariantMap sendPositionQuery(const QString &event, const QVariantMap &params, const QPointF &position);
+
+private:
+ QString m_host;
+ int m_port;
+ bool m_queryFailed;
+};
+
+#endif
diff --git a/src/protocol/qstconnectionmanager.cpp b/src/protocol/qstconnectionmanager.cpp
new file mode 100644
index 0000000..d3fc295
--- /dev/null
+++ b/src/protocol/qstconnectionmanager.cpp
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qstconnectionmanager.h"
+#include "qstconnection.h"
+
+#include <QtDebug>
+
+QstConnectionManager::QstConnectionManager(QObject *parent) :
+ QObject(parent)
+{
+}
+
+QstConnection* QstConnectionManager::connectionForHost(const QString &host, int port)
+{
+ if ( !m_connections.contains(host) ) {
+// qDebug() << Q_FUNC_INFO << " Creating a new connection with (" << host << ":" << port << ")";
+ m_connections[host] = new QstConnection(host, port);
+ }
+ return m_connections[host];
+}
diff --git a/src/protocol/qstconnectionmanager.h b/src/protocol/qstconnectionmanager.h
new file mode 100644
index 0000000..04b6daf
--- /dev/null
+++ b/src/protocol/qstconnectionmanager.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSTCONNECTIONMANAGER_H
+#define QSTCONNECTIONMANAGER_H
+
+#include <QtCore/QObject>
+#include <QtCore/QMap>
+
+class QstConnection;
+
+class QstConnectionManager : public QObject
+{
+ Q_OBJECT
+public:
+ explicit QstConnectionManager(QObject *parent = 0);
+
+signals:
+
+public slots:
+ QstConnection *connectionForHost(const QString &host, int port = 5656);
+
+private:
+ typedef QMap<QString, QstConnection*> Connections;
+ Connections m_connections;
+};
+
+#endif // QSTCONNECTIONMANAGER_H
diff --git a/src/protocol/qstdebug.h b/src/protocol/qstdebug.h
new file mode 100644
index 0000000..4afa3c0
--- /dev/null
+++ b/src/protocol/qstdebug.h
@@ -0,0 +1,52 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTT_DEBUG_H
+#define QTT_DEBUG_H
+
+#include <QDebug>
+#ifndef qttDebug
+#define qttDebug qDebug
+#endif
+
+#define QTT_TRACE_FUNCTION()
+
+#endif // QTT_DEBUG_H
diff --git a/src/protocol/qstglobal.h b/src/protocol/qstglobal.h
new file mode 100644
index 0000000..f25915a
--- /dev/null
+++ b/src/protocol/qstglobal.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QST_GLOBAL_H
+#define QST_GLOBAL_H
+
+#include <QtGlobal>
+
+#if defined(Q_OS_WIN32)
+# if defined(QTUITEST_TARGET)
+# define QTUITEST_EXPORT Q_DECL_EXPORT
+# else
+# define QTUITEST_EXPORT Q_DECL_IMPORT
+# endif
+# if defined(QTSLAVE_TARGET)
+# define QTSLAVE_EXPORT Q_DECL_EXPORT
+# else
+# define QTSLAVE_EXPORT Q_DECL_IMPORT
+# endif
+#else
+# define QTUITEST_EXPORT Q_DECL_EXPORT
+# define QTSLAVE_EXPORT Q_DECL_EXPORT
+#endif
+
+#if defined(Q_OS_WIN32) || defined(Q_OS_SYMBIAN)
+# if defined(QSYSTEMTEST_TARGET)
+# define QSYSTEMTEST_EXPORT Q_DECL_EXPORT
+# else
+# define QSYSTEMTEST_EXPORT Q_DECL_IMPORT
+# endif
+# if defined(QTUITESTRUNNER_TARGET)
+# define QTUITESTRUNNER_EXPORT Q_DECL_EXPORT
+# else
+# define QTUITESTRUNNER_EXPORT Q_DECL_IMPORT
+# endif
+#else
+# define QSYSTEMTEST_EXPORT Q_DECL_EXPORT
+# define QTUITESTRUNNER_EXPORT Q_DECL_EXPORT
+#endif
+
+#define xstr(s) str(s)
+#define str(s) #s
+#define QTUITEST_VERSION_STR xstr(QTUITEST_VERSION)
+
+#endif
diff --git a/src/protocol/qstprotocol.cpp b/src/protocol/qstprotocol.cpp
new file mode 100644
index 0000000..c5a69b8
--- /dev/null
+++ b/src/protocol/qstprotocol.cpp
@@ -0,0 +1,1086 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+/*
+ This cpp file contains a number of socket related classes that are used heavily in QtUiTest.
+ The classes are documented later in the file.
+*/
+#include "qstprotocol.h"
+
+#ifdef QTUITEST_TARGET
+#include <qtuitestnamespace.h>
+#endif
+
+#include <QCoreApplication>
+#include <QString>
+#include <QTimer>
+#include <QUuid>
+#include <QFileInfo>
+#include <QDir>
+#include <QtNetwork/QTcpSocket>
+#include <QtNetwork/QTcpServer>
+#include <QtNetwork/QHostAddress>
+#include <QtNetwork/QHostInfo>
+#include <QPointer>
+
+#include <QDebug>
+#define qLog(A) if (1); else qDebug()
+
+#if defined(Q_OS_WIN32) && !defined(Q_OS_TEMP)
+# include <io.h>
+#endif
+
+static const int CONNECT_TIMEOUT = 20000;
+
+static const quint32 TEST_MSG_SIGNATURE = 0xEDBAEDBA;
+static const quint32 TEST_MSG_END = 0xEDBAABDE;
+static uint g_unique_id = 0;
+
+bool waitForSignal(QObject* object, const char* signal, int timeout)
+{
+#ifdef QTUITEST_TARGET
+ return QtUiTest::waitForSignal(object, signal, timeout);
+#else
+ QEventLoop loop;
+ QTimer dummy;
+ dummy.setInterval(1000);
+ if (!QObject::connect(object, signal, &dummy, SLOT(start())))
+ return false;
+ if (!QObject::connect(object, signal, &loop, SLOT(quit())))
+ return false;
+ QTimer::singleShot(timeout, &loop, SLOT(quit()));
+ loop.exec();
+ return dummy.isActive();
+#endif
+}
+
+void wait(int timeout)
+{
+#ifdef QTUITEST_TARGET
+ QtUiTest::wait(timeout);
+#else
+ QEventLoop loop;
+ QTimer::singleShot(timeout, &loop, SLOT(quit()));
+ loop.exec();
+#endif
+}
+
+
+/*
+ \class QstMessage qstprotocol.h
+ \inpublicgroup QtUiTestModule
+
+ \brief The QstMessage class can be used for exchanging messages between separate
+ processes. The class is never used directly but instead is used by QstProtocol.
+
+ The class basically wraps a number of strings (i.e. 'event' and 'message') and binary data
+ (i.e. a bytearray or a file) into a datastream that is sent to a peer using a socket
+ connection. On the receiving side a QstMessage instance is decoding the datastream
+ and performs a number of sanity checks to make it a bit more robost.
+
+ A TCP connection 'should' be reliable but in exceptional cases bytes may be lost. This
+ would result in the connection becoming useless because all future data reception would
+ be out of sync. To solve this a 'resync' function is implemented that can re-sync the datastream
+ by throwing away bytes until the data seems in sync again. The obvious downside is that
+ at least one message will be lost.
+
+ Message format is as follows:
+
+ Field: Length: Remarks:
+
+ Start signature 4 Fixed value - 0xEDBAEDBA
+ Message state 1 See MessageState enum
+ Message number 2
+ Length 4 Length of event/context block
+ Event:Context Length QString value (event and context)
+ Data length 4 Length of following binary data
+ File data Data length Binary data
+ End signature 4 Fixed value - 0xEDBAABDE
+*/
+
+/*
+ \internal
+
+ Constructs a default (empty) message.
+*/
+
+QstMessage::QstMessage(const QString &event, QVariantMap const &map)
+ : m_phase(0)
+ , m_msg_id(0)
+ , m_event(event)
+ , m_state(MessageEmpty)
+ , m_map(map)
+{
+}
+
+/*
+ \internal
+
+ Copy constructor.
+*/
+
+QstMessage::QstMessage(const QstMessage &other)
+ : m_phase(0)
+ , m_msg_id(other.m_msg_id)
+ , m_event(other.m_event)
+ , m_context(other.m_context)
+ , m_state(other.m_state)
+ , m_map(other.m_map)
+ , m_buffer(other.m_buffer)
+{
+}
+
+/*
+ \internal
+
+ Destroys the message.
+*/
+
+QstMessage::~QstMessage()
+{
+}
+
+/*
+ \internal
+
+ Assignment operator.
+*/
+
+QstMessage& QstMessage::operator=(const QstMessage &other)
+{
+ m_msg_id = other.m_msg_id;
+ m_event = other.m_event;
+ m_context = other.m_context;
+ m_state = other.m_state;
+ m_map = other.m_map;
+ m_buffer = other.m_buffer;
+
+ return *this;
+}
+
+QVariant &QstMessage::operator[](const QString &key)
+{
+ unpack();
+ return m_map[key.toLower()];
+}
+
+const QVariant QstMessage::operator[](const QString &key) const
+{
+ unpack();
+ return m_map[key.toLower()];
+}
+
+bool QstMessage::contains(const QString &key) const
+{
+ unpack();
+ return m_map.contains(key.toLower());
+}
+
+QList<QString> QstMessage::keys() const
+{
+ unpack();
+ return m_map.keys();
+}
+
+QString QstMessage::toString() const
+{
+ QString ret;
+ if (!isUnpacked()) {
+ ret = QLatin1String("(packed)\n");
+ return ret;
+ }
+
+ QVariantMap::const_iterator i = m_map.constBegin();
+ while (i != m_map.constEnd()) {
+ if (!i.value().isValid()) {
+ i++;
+ continue;
+ }
+ ret += i.key() + QLatin1String(": ");
+ if (i.value().canConvert<QStringList>())
+ ret += QLatin1String("'") + i.value().toStringList().join(QLatin1String("','")) + QLatin1String("'");
+ else if (i.value().canConvert<QString>())
+ ret += QLatin1String("'") + i.value().toString() + QLatin1String("'");
+ else
+ ret += QLatin1String("(data)");
+ ret += QLatin1Char('\n');
+ ++i;
+ }
+
+ if (ret.endsWith(QLatin1Char('\n'))) ret.chop(1);
+ return ret;
+}
+
+QVariantMap QstMessage::toMap() const
+{
+ return m_map;
+}
+
+/*
+ \internal
+ Returns the event that was received.
+*/
+
+QString QstMessage::event() const
+{
+ return m_event;
+}
+
+void QstMessage::setEvent(const QString &event)
+{
+ m_event = event;
+}
+
+/*
+ \internal
+ Returns the message number.
+*/
+
+quint16 QstMessage::msgId() const
+{
+ return m_msg_id;
+}
+
+bool QstMessage::isNull() const
+{
+ return m_map.isEmpty();
+}
+
+bool QstMessage::isUnpacked() const
+{
+ return m_buffer.isEmpty();
+}
+
+void QstMessage::unpack() const
+{
+ if (isUnpacked()) return;
+
+ QDataStream s(&m_buffer, QIODevice::ReadOnly);
+ s.setVersion(QDataStream::Qt_4_6);
+ s >> m_map;
+ m_buffer.clear();
+}
+
+
+/*
+ \class QstProtocol qstprotocol.h
+ \inpublicgroup QtUiTestModule
+
+ \brief The QstProtocol class can be used for exchanging messages between separate
+ processes.
+
+ It is intended to be fast but at the same time ultra reliable and robust communication protocol.
+
+ The main function that is used on the sending side is:
+ \code
+ myConnection.postMessage( "My-Event", "My-Message", ptr_to_my_data );
+ \endcode
+
+ On the receiving side the main function is a re-implemented 'processMessage':
+ \code
+ void MyTestConnection::processMessage( QstMessage *msg )
+ {
+ if (msg->event() == "My-Event") {
+ print( msg->message() );
+ }
+ }
+ \endcode
+*/
+
+#include <stdio.h>
+
+QstProtocol::QstProtocol(QObject *parent)
+ : QTcpSocket(parent)
+ , tx_msg_id(1)
+ , port(0)
+ , onData_busy(false)
+ , enable_reconnect(false)
+ , reconnect_interval(10000)
+ , last_data_received(false)
+ , connection_valid(false)
+ , debug_on(false)
+ , m_auto_unpack(true)
+{
+ static int id1 = qRegisterMetaType<QstMessage>(); Q_UNUSED(id1);
+ static int id2 = qRegisterMetaType<QstMessage*>(); Q_UNUSED(id2);
+ static int id3 = qRegisterMetaType<const QstMessage*>(); Q_UNUSED(id3);
+
+ unique_id = QString::number(++g_unique_id);
+ if (debug_on) {
+ qDebug() << QString("%1 QstProtocol::QstProtocol()").arg(uniqueId()).toLatin1();
+ }
+ cur_message = 0;
+ rx_busy = false;
+
+ QObject::connect( &connect_timer, SIGNAL(timeout()), this, SLOT(connectTimeout()), Qt::DirectConnection );
+
+ QObject::connect( this,SIGNAL(connected()),this,SLOT(onSocketConnected()), Qt::DirectConnection );
+ QObject::connect( this,SIGNAL(disconnected()),this,SLOT(onSocketClosed()), Qt::DirectConnection );
+ QObject::connect( this,SIGNAL(readyRead()),this,SLOT(onData()), Qt::DirectConnection );
+
+ // initialize. Any time is better than no time.
+ rx_timer.start();
+}
+
+/*!
+ Destructs the instance of QstProtocol.
+*/
+
+QstProtocol::~QstProtocol()
+{
+ if (debug_on) {
+ qDebug() << QString("%1 QstProtocol::~QstProtocol()").arg(uniqueId()).toLatin1();
+ }
+ enableReconnect( false, 0 );
+
+ // anything that is still in the tx buffer gets lost
+ abort();
+ close();
+
+ while (send_msg_replies.count() > 0)
+ delete send_msg_replies.takeFirst();
+ while (unhandled_msg.count() > 0)
+ delete unhandled_msg.takeFirst();
+}
+
+void QstProtocol::setSocket( int socket )
+{
+ if (debug_on) {
+ qDebug() << ( QString("%1 QstProtocol::setSocket(socket=%2)").
+ arg(uniqueId()).
+ arg(socket).toLatin1());
+ }
+ setSocketDescriptor( socket );
+
+ rx_timer.start();
+ testConnection();
+}
+
+void QstProtocol::enableReconnect( bool enable, uint reconnectInterval )
+{
+ if (debug_on) {
+ qDebug() << ( QString("%1 QstProtocol::enableReconnect( enable=%2, interval=%3)").
+ arg(uniqueId()).
+ arg(enable).
+ arg(reconnectInterval).toLatin1());
+ }
+ enable_reconnect = enable;
+ reconnect_interval = reconnectInterval;
+}
+
+/*!
+ Opens a socket connection to the specified \a hostname and \a port.
+
+ After a connection is successfully opened the instance will listen for and process
+ incoming commands received from the remote host.
+*/
+void QstProtocol::connect( const QString& hostname, int port )
+{
+ if (state() == ConnectedState) {
+ if (hostname == this->host && port == this->port)
+ return;
+ disconnect();
+ }
+
+ if (debug_on) {
+ qDebug() << ( QString("%1 QstProtocol::connect(%2:%3)").
+ arg(uniqueId()).
+ arg(hostname).
+ arg(port).toLatin1());
+ }
+
+ rx_timer.start();
+
+ this->host = hostname;
+ this->port = port;
+
+ reconnect();
+}
+
+void QstProtocol::disconnect( bool disableReconnect )
+{
+ if (state() == ConnectedState) {
+ if (debug_on) {
+ qDebug() << ( QString("%1 QstProtocol::disconnect(disableReconnect=%2)").
+ arg(uniqueId()).
+ arg(disableReconnect).toLatin1());
+ }
+ // be polite and tell the other side we are closing
+ postMessage( QstMessage("QTEST_CLOSING_CONNECTION") );
+
+ // we are closing ourselves, so we don't want to reconnect
+ if (disableReconnect) enable_reconnect = false;
+
+ onSocketClosed();
+ }
+}
+
+bool QstProtocol::isConnected()
+{
+ return ((state() == ConnectedState) && connection_valid);
+}
+
+bool QstProtocol::waitForConnected( int timeout )
+{
+ QTime t;
+ t.start();
+ bool ok = false;
+ QTime t2;
+ t2.start();
+ while (t.elapsed() < timeout && !ok) {
+ ok = QTcpSocket::waitForConnected(timeout);
+ if (!ok) {
+ wait(100);
+ if (t2.elapsed() > 1000) {
+ t2.start();
+ reconnect();
+ }
+ }
+ }
+
+ if (ok) {
+ if (debug_on) {
+ qDebug() << QString("%1 QstProtocol::waitForConnected(%2, %3) ...")
+ .arg(uniqueId()).arg(timeout).arg(stateStr()).toLatin1();
+ }
+ t2.start();
+ while (t.elapsed() < timeout && !isConnected()) {
+ wait(10);
+ if (!isConnected() && t2.elapsed() > 500) {
+ postMessage( QstMessage(QLatin1String("QTEST_NEW_CONNECTION")) );
+ t2.start();
+ }
+ }
+ ok = isConnected();
+ }
+
+ if (debug_on) {
+ qDebug() << QString("%1 QstProtocol::waitForConnected() ... %2 (%3 ms)").arg(uniqueId()).arg(ok ? "OK" : "FAILED" ).arg(t.elapsed()).toLatin1();
+ if (!ok) qDebug() << errorStr();
+ }
+ return ok;
+}
+
+/*!
+ \internal
+ Posts (e.g. non blocking) an \a event, \a message and contents of \a fileName to the remote host.
+*/
+
+uint QstProtocol::postMessage(const QstMessage &message )
+{
+ if (debug_on && message.event() != QLatin1String("PING") && message.event() != QLatin1String("PONG")) {
+ qDebug() << ( QString("%1 QstProtocol::postMessage(%2)").
+ arg(uniqueId()).
+ arg(message.event()).toLatin1());
+ }
+ if (state() != ConnectedState)
+ return 0;
+ QstMessage msg(message);
+ msg.m_msg_id = tx_msg_id++;
+ send( msg );
+ return msg.m_msg_id;
+}
+
+void QstProtocol::onReplyReceived( QstMessage* /*reply*/ )
+{
+}
+
+/*!
+ \internal
+ Sends an \a event, \a message and \a data to the remote host and waits for up to
+ \a timeout milliseconds for a reply. If a reply is received, the reply's message
+ string is placed in \a reply.
+*/
+bool QstProtocol::sendMessage( const QstMessage &message, QstMessage &reply, int timeout )
+{
+ QstMessage msg(message);
+ QPointer<QstProtocol> safeThis(this);
+ bool safeDebugOn(debug_on);
+ QString safeUniqueId(uniqueId());
+
+ last_send_cmd = message.event();
+
+ if (state() == ConnectingState) {
+ wait(4000);
+ }
+
+ if (state() == ConnectedState) {
+ msg.m_msg_id = tx_msg_id++;
+
+ if (debug_on) {
+ qDebug() << ( QString("%1 QstProtocol::sendMessage(%2) msgid=%3)").
+ arg(uniqueId()).
+ arg(msg.event()).
+ arg(msg.msgId()).
+ toLatin1());
+ }
+
+ send( msg );
+
+ QTime t1;
+ t1.start();
+ QTime t2;
+ t2.start();
+ bool first_time = true;
+ while ( (state() == ConnectedState) &&
+ (timeout < 0 || t1.elapsed() < timeout) ) {
+
+ if (debug_on) {
+ if (first_time || t2.elapsed() > 1000) {
+ qDebug() << ( QString("%1 QstProtocol::sendMessage(%2) ... waiting for reply").
+ arg(uniqueId()).
+ arg(message.event()).toLatin1());
+ t2.start();
+ first_time = false;
+ }
+ }
+
+ waitForSignal(this, SIGNAL(replyReceived()), 500);
+
+ if (!safeThis) {
+ if (safeDebugOn) {
+ qDebug() << ( QString("%1 QstProtocol::sendMessage(%2) ... object deleted unexpectedly").
+ arg(safeUniqueId).
+ arg(message.event()).toLatin1());
+ }
+ reply[QLatin1String("status")] = "ERROR: Connection was terminated unexpectedly. This may be caused by an application crash.";
+ reply[QLatin1String("_q_inResponseTo")] = QString("%1\n%2").arg(message.event()).arg(message.toString());
+ return false;
+ } else {
+ if (send_msg_replies.count() > 0) {
+ if (debug_on) {
+ qDebug() << ( QString("%1 QstProtocol::sendMessage(%2) ... check replies").
+ arg(uniqueId()).
+ arg(message.event()).toLatin1());
+ }
+ for (int i=0; i<send_msg_replies.size(); i++) {
+ QstMessage * possible_reply = send_msg_replies.at(i);
+ if (possible_reply && possible_reply->m_msg_id == msg.m_msg_id) {
+ reply = *possible_reply;
+ delete send_msg_replies.takeAt( i );
+ if (debug_on) {
+ qDebug() << ( QString("%1 QstProtocol::sendMessage(%2) ... reply received").
+ arg(uniqueId()).
+ arg(message.event()).toLatin1());
+ }
+
+ onReplyReceived(&reply);
+ return true;
+ }
+ }
+ }
+ }
+ }
+ if (state() != ConnectedState) {
+ reply[QLatin1String("status")] = "ERROR: Connection lost. This is likely caused by a crash in the Application Under Test.";
+ reply[QLatin1String("_q_inResponseTo")] = QString("%1\n%2").arg(message.event()).arg(message.toString());
+ } else {
+ qDebug() << "ERROR-REPLY-TIMEOUT: " << t1.elapsed() << t2.elapsed();
+ reply[QLatin1String("status")] = QLatin1String("ERROR_REPLY_TIMEOUT");
+ reply[QLatin1String("_q_inResponseTo")] = QString("%1\n%2").arg(message.event()).arg(message.toString());
+ }
+ reply[QLatin1String("location")] = QString("%1:%2").arg(__FILE__).arg(__LINE__);
+ } else {
+ reply[QLatin1String("status")] = QLatin1String("ERROR_NO_CONNECTION");
+ reply[QLatin1String("_q_inResponseTo")] = QString("%1\n%2").arg(message.event()).arg(message.toString());
+ reply[QLatin1String("location")] = QString("%1:%2").arg(__FILE__).arg(__LINE__);
+ }
+
+ if (debug_on) {
+ qDebug() << ( QString("%1 QstProtocol::sendMessage(%2) ... done. Status: %3").
+ arg(uniqueId()).
+ arg(message.event()).arg(reply[QLatin1String("status")].toString()).toLatin1());
+ }
+
+ return false;
+}
+
+/*!
+ Send the string \a result as a reply to \a originalMsg.
+*/
+
+void QstProtocol::replyMessage( const QstMessage *originalMsg, const QstMessage &message )
+{
+ if (debug_on) {
+ qDebug() << ( QString("%1 QstProtocol::replyMessage(%2)").
+ arg(uniqueId()).
+ arg(originalMsg->event()).toLatin1());
+ }
+
+ QstMessage msg(message);
+ msg.m_msg_id = originalMsg->msgId();
+ msg.m_event = QLatin1String("@REPLY@");
+ if (originalMsg->state() == QstMessage::MessageOldVersion) {
+ msg["status"] = QLatin1String(
+ "\n**********************************************"
+ "\nThe version of qtuitestrunner you are using is"
+ "\nincompatible with this version of QtUiTest!"
+ "\n**********************************************\n");
+ }
+ send( msg );
+}
+
+bool QstProtocol::lastDataReceived()
+{
+ return last_data_received;
+}
+
+QString QstProtocol::errorStr()
+{
+ QString S = QLatin1String("Connection error: ");
+ switch (error()) {
+ case ConnectionRefusedError: S += QString("Connection attempt to %1:%2 failed").arg(host).arg(port).toLatin1(); break;
+ case HostNotFoundError: S += QString("Host %1:%2 not found").arg(host).arg(port).toLatin1(); break;
+ case RemoteHostClosedError: S += QLatin1String("RemoteHostClosedError"); break;
+ case SocketAccessError: S += QLatin1String("SocketAccessError"); break;
+ case SocketResourceError: S += QLatin1String("SocketResourceError"); break;
+ case SocketTimeoutError: S += QLatin1String("SocketTimeoutError"); break;
+ case DatagramTooLargeError: S += QLatin1String("DatagramTooLargeError"); break;
+ case NetworkError: S += QLatin1String("NetworkError"); break;
+ case AddressInUseError: S += QLatin1String("AddressInUseError"); break;
+ case SocketAddressNotAvailableError: S += QLatin1String("SocketAddressNotAvailableError"); break;
+ case UnsupportedSocketOperationError: S += QLatin1String("UnsupportedSocketOperationError"); break;
+ case UnknownSocketError: S += QLatin1String("UnknownSocketError"); break;
+ default: S += QLatin1String("Unknown error");
+ }
+
+ return S;
+}
+
+QString QstProtocol::stateStr()
+{
+ switch (state()) {
+ case QAbstractSocket::UnconnectedState: return QLatin1String("UnconnectedState");
+ case QAbstractSocket::HostLookupState: return QLatin1String("HostLookupState");
+ case QAbstractSocket::ConnectingState: return QLatin1String("ConnectingState");
+ case QAbstractSocket::ConnectedState: return QLatin1String("ConnectedState");
+ case QAbstractSocket::BoundState: return QLatin1String("BoundState");
+ case QAbstractSocket::ClosingState: return QLatin1String("ClosingState");
+ case QAbstractSocket::ListeningState: return QLatin1String("ListeningState");
+ }
+ return QLatin1String("Unknown state");
+}
+
+void QstProtocol::onConnectionFailed( const QString &reason )
+{
+ emit connectionFailed( this, reason );
+}
+
+void QstProtocol::testConnection()
+{
+ if (debug_on) {
+ qDebug() << QString("%1 QstProtocol::testConnection()").arg(uniqueId()).toLatin1();
+ }
+
+ while (send_msg_replies.count() > 0)
+ delete send_msg_replies.takeFirst();
+
+ postMessage( QstMessage(QLatin1String("QTEST_NEW_CONNECTION")) );
+}
+
+void QstProtocol::send( const QstMessage &message )
+{
+ QByteArray data;
+
+ if (!message.isUnpacked()) {
+ data = message.m_buffer;
+ } else if (!message.m_map.isEmpty()) {
+ QDataStream s(&data, QIODevice::WriteOnly);
+ s.setVersion(QDataStream::Qt_4_6);
+ s << message.m_map;
+ }
+
+ QDataStream tmp(this);
+ tmp.setVersion(QDataStream::Qt_4_6);
+ sendPreamble(&tmp, message);
+
+ // phase 2
+ quint32 len = data.count();
+ tmp << len;
+ if (len > 0) {
+ // phase 3
+ tmp.writeRawData( data.data(), (int)len );
+ }
+
+ // phase 4
+ tmp << TEST_MSG_END;
+
+ flush(); // Force socket to send data now
+}
+
+void QstProtocol::sendPreamble( QDataStream *ds, const QstMessage &message)
+{
+ // phase 0
+ *ds << TEST_MSG_SIGNATURE;
+ *ds << static_cast<quint8>(message.state());
+ *ds << message.msgId();
+
+ // phase 1
+ QString event;
+ if (message.context().isEmpty()) {
+ event = message.event();
+ } else {
+ event = message.event() + QChar(':') + message.context();
+ }
+
+ quint32 len = (event.length() *2) + 4;
+ *ds << len;
+ *ds << event;
+}
+
+bool QstProtocol::receive( QstMessage *msg, bool &syncError )
+{
+ syncError = false;
+
+ QDataStream stream(this);
+ stream.setVersion(QDataStream::Qt_4_6);
+
+ quint8 msgState;
+ if (msg->m_phase == uint(0)) {
+ msg->m_len = 0;
+ quint32 sig;
+ if (bytesAvailable() >= sizeof( sig ) + sizeof( msgState ) + sizeof( msg->m_msg_id ) + sizeof( msg->m_len )) {
+ stream >> sig;
+ if (sig != TEST_MSG_SIGNATURE) {
+ qWarning() << QString("QstMessage::receive(), Invalid start signature (0x%1)").arg(sig,8,16).toLatin1();
+ syncError = true;
+ return false;
+ } else {
+ stream >> msgState;
+ msg->m_state = static_cast<QstMessage::MessageState>(msgState);
+ stream >> msg->m_msg_id;
+ stream >> msg->m_len;
+ msg->m_phase++;
+ }
+ }
+ }
+
+ if (msg->m_phase == uint(1)) {
+ if (bytesAvailable() >= msg->m_len) {
+ QString event;
+ stream >> event;
+ int i = event.indexOf(QLatin1Char(':'));
+ if (i == -1) {
+ msg->m_event = event;
+ } else {
+ msg->m_event = event.left(i);
+ msg->m_context = event.mid(i+1);
+ }
+ msg->m_phase++;
+ }
+ }
+
+ if (msg->m_phase == uint(2)) {
+ if (bytesAvailable() >= sizeof( msg->m_len )) {
+ stream >> msg->m_len;
+ msg->m_phase++;
+ }
+ }
+
+ if (msg->m_phase == uint(3)) {
+ if (msg->m_len > 0) {
+ QByteArray buf;
+ quint32 len = msg->m_len;
+ uint bytes_available = bytesAvailable();
+ if (bytes_available < len)
+ len = bytes_available;
+ buf.resize( len );
+ stream.readRawData( buf.data(), len );
+ msg->m_buffer.append(buf);
+ msg->m_len -= len;
+
+ if (msg->m_len == 0) {
+ // received OK
+ msg->m_phase++;
+ } else {
+ // waiting for more data
+ return false;
+ }
+
+ } else {
+ msg->m_phase++;
+ }
+ }
+
+ if (msg->m_phase == uint(4)) {
+ quint32 id2;
+ if (bytesAvailable() >= sizeof( id2 )) {
+ stream >> id2;
+ msg->m_phase = 0;
+ if (id2 != TEST_MSG_END) {
+ qWarning() << QString("QstMessage::receive(), Invalid end signature (0x%2)").arg(id2,8,16).toLatin1();
+ syncError = true;
+ return false;
+ } else {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+bool QstProtocol::rxBusy()
+{
+ return rx_busy;
+}
+
+/*!
+ Reads the remote control connection and responds to received commands.
+*/
+
+void QstProtocol::onData()
+{
+ if (onData_busy) return;
+ onData_busy = true;
+
+ int sync_error_count = 0;
+ bool msg_received = true;
+ while (msg_received && bytesAvailable() > 0) {
+ msg_received = false;
+ // set the time to now :-)
+ rx_timer.start();
+
+ bool sync_error;
+ if (cur_message == 0)
+ cur_message = new QstMessage();
+
+ if (receive( cur_message, sync_error )) {
+
+ msg_received = true;
+ QString last_event = cur_message->event();
+
+ if (m_auto_unpack) {
+ cur_message->unpack();
+ }
+
+ if (debug_on) {
+ qDebug() << ( QString("%1 QstProtocol::onData(%2) msgid = %3").
+ arg(uniqueId()).
+ arg(last_event).
+ arg(cur_message->m_msg_id).
+ toLatin1());
+ }
+
+ // We received a full message
+ if (last_event == QLatin1String("@REPLY@")) {
+ // add the reply to a list
+ send_msg_replies.append( cur_message );
+ int id = cur_message->m_msg_id;
+ QstMessage *received_message(cur_message);
+ // and make sure we create a new one
+ cur_message = 0;
+ emit replyReceived( id, received_message );
+ } else if (last_event == QLatin1String("QTEST_NEW_CONNECTION")) {
+ // Acknowledge the other side we can receive data
+ postMessage( QstMessage(QLatin1String("QTEST_ACK_CONNECTION")) );
+ } else if (last_event == QLatin1String("QTEST_ACK_CONNECTION")) {
+ // we don't assume we have a connection until both sides
+ // have actually received data from the other side
+ connection_valid = true;
+ onConnected();
+ connect_timer.stop();
+ } else if (last_event == QLatin1String("QTEST_CLOSING_CONNECTION")) {
+ last_data_received = true;
+ QTimer::singleShot( 0, this, SLOT(onSocketClosed()));
+ } else if (last_event == QLatin1String("PONG")) {
+ // Do nothing
+ } else if (last_event == QLatin1String("TEST")) {
+ if (!debug_on) {
+ // don't show the same information twice
+ qDebug() << QString("%1 Test message received").arg(uniqueId()).toLatin1();
+ }
+ } else if (last_event == QLatin1String("PING")) {
+ postMessage( QstMessage(QLatin1String("PONG")) );
+ } else {
+ // add the msg to a list
+ unhandled_msg.append( cur_message );
+ cur_message = 0;
+ QTimer::singleShot(0, this, SLOT(processMessages()));
+ }
+
+ delete cur_message;
+ cur_message = 0;
+ } else {
+ // We didn't receive a full message
+ if (sync_error) {
+ sync_error_count++;
+ if (sync_error_count > 10)
+ return;
+ // receiving garbage messages - nothing can be done but closing the connection and try again.
+ delete cur_message;
+ cur_message = 0;
+ disconnect(!enable_reconnect);
+ reconnect();
+ }
+ // else we are waiting on more fragments to arrive
+ }
+ }
+ onData_busy = false;
+}
+
+void QstProtocol::processMessages()
+{
+ while (!rx_busy && unhandled_msg.count() > 0) {
+ QstMessage *tmp = unhandled_msg.takeFirst();
+ if (tmp) {
+ rx_busy = true;
+ processMessage( tmp );
+ delete tmp;
+ rx_busy = false;
+ }
+ }
+}
+
+/*!
+ Signals the instance that the other side has closed the connection.
+*/
+void QstProtocol::onSocketClosed()
+{
+ if (debug_on) {
+ qDebug() << QString("%1 QstProtocol::onSocketClosed()").arg(uniqueId()).toLatin1();
+ }
+
+ // anything that is still in the tx buffer gets lost
+ abort();
+
+ close();
+
+ connection_valid = false;
+
+ // if the close was spontaneous and we want to keep the connection alive, we try to reconnect
+ if (enable_reconnect) {
+ if (debug_on) {
+ qDebug() <<
+ QString("%1 QstProtocol::onSocketClosed() singleshot reconnect in .5 seconds").arg(uniqueId()).toLatin1();
+ }
+ QTimer::singleShot(500,this,SLOT(reconnect()));
+ }
+
+ // tell the world we are closed
+ QTimer::singleShot(0, this, SLOT(emitConnectionClosed()));
+}
+
+/*!
+ Signals the instance that a connection is established with a remote control host.
+*/
+void QstProtocol::onSocketConnected()
+{
+ connect_timer.stop();
+ if (debug_on) {
+ qDebug() << QString("%1 QstProtocol::onSocketConnected()").arg(uniqueId()).toLatin1();
+ }
+ testConnection();
+}
+
+void QstProtocol::reconnect()
+{
+ if (!host.isEmpty() && state() != ConnectedState) {
+ if (debug_on) {
+ qDebug() << QString("%1 QstProtocol::reconnect(%2)").arg(uniqueId()).arg(stateStr()).toLatin1();
+ }
+
+ connect_timer.stop();
+ connect_timer.start( CONNECT_TIMEOUT );
+
+ // if we are trying to connect to the local machine, always use 127.0.0.1
+ // (and avoid the need for dns)
+ QString hostname = QHostInfo::localHostName().toUpper();
+ if (hostname == host.toUpper() || hostname.startsWith( host.toUpper() + "." ))
+ host = QLatin1String("127.0.0.1");
+
+ close();
+ wait(100);
+ if (state() == ConnectingState) {
+ // Will just get a warning, retry later
+ return;
+ }
+ connectToHost( host, port );
+ } else {
+ if (host.isEmpty()) {
+ qWarning( "QstProtocol::reconnect() FAILED, no host specified" );
+ enable_reconnect = false;
+ }
+ }
+}
+
+void QstProtocol::connectTimeout()
+{
+ if (debug_on) {
+ qDebug() << QString("%1 QstProtocol::connectTimeout()").arg(uniqueId()).toLatin1();
+ }
+
+ connect_timer.stop();
+ if (enable_reconnect) {
+ reconnect();
+ } else {
+ onConnectionFailed( errorStr() );
+ }
+}
+
+void QstProtocol::emitConnectionClosed()
+{
+ if (debug_on) {
+ qDebug() << QString("%1 QstProtocol::emitConnectionClosed()").arg(uniqueId()).toLatin1();
+ }
+
+ // force sendMessage to quit
+ emit replyReceived();
+ emit connectionClosed( this );
+}
+
+
+QString QstProtocol::uniqueId() const
+{
+ return QString("%1 %2").arg(unique_id).arg(qApp->applicationName());
+}
+
+void QstProtocol::enableDebug( bool debugOn )
+{
+ debug_on = debugOn;
+ qDebug() << QString("Debugging is switched %1 for Test Protocol %2").arg(debugOn ? "ON" : "OFF").arg(uniqueId()).toLatin1() ;
+}
+
+void QstProtocol::disableDebug()
+{
+ debug_on = false;
+ qDebug() << QString("Debugging is switched %1 for Test Protocol %2").arg(debug_on ? "ON" : "OFF").arg(uniqueId()).toLatin1() ;
+}
diff --git a/src/protocol/qstprotocol.h b/src/protocol/qstprotocol.h
new file mode 100644
index 0000000..502c114
--- /dev/null
+++ b/src/protocol/qstprotocol.h
@@ -0,0 +1,216 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QTESTPROTOCOL_P_H
+#define QTESTPROTOCOL_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtUiTest API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QTimer>
+#include <QTime>
+#include <QObject>
+#include <QString>
+#include <QFile>
+#include <QVariant>
+#include <QMap>
+#include <QtNetwork/QTcpSocket>
+#include <QtNetwork/QTcpServer>
+
+#include "qstglobal.h"
+
+#define REMOTE_CONNECT_ERROR 99
+
+#define MESSAGE_ERROR(message, str) (\
+ message.setState(QstMessage::MessageError),\
+ message["status"] = str,\
+ message)
+
+class QstMessage
+{
+public:
+ enum MessageState {
+ MessageEmpty = 0,
+ MessageSuccess = 1,
+ MessageError = 2,
+ MessageOldVersion = 3
+ };
+
+ QstMessage(const QString &event = QString(), QVariantMap const &map = QVariantMap() );
+ QstMessage(const QstMessage &other);
+ virtual ~QstMessage();
+
+ QstMessage& operator=(const QstMessage &other);
+
+ QString event() const;
+ void setEvent(const QString &event);
+ quint16 msgId() const;
+
+ const QVariant operator[](const QString &key) const;
+ QVariant &operator[](const QString &key);
+ bool contains(const QString &key) const;
+ QList<QString> keys() const;
+
+ QString toString() const;
+ QVariantMap toMap() const;
+
+ bool isNull() const;
+ bool isUnpacked() const;
+ void unpack() const;
+ MessageState state() const { return m_state; }
+ void setState(MessageState state) { m_state = state; }
+
+ QString context() const { return m_context; }
+ void setContext(const QString &context) { m_context = context; }
+
+protected:
+ uint m_phase;
+ quint32 m_len;
+
+ quint16 m_msg_id;
+ QString m_event;
+ QString m_context;
+ MessageState m_state;
+
+ mutable QVariantMap m_map;
+ mutable QByteArray m_buffer;
+
+ friend class QstProtocol;
+};
+Q_DECLARE_METATYPE( QstMessage )
+Q_DECLARE_METATYPE( QstMessage* )
+Q_DECLARE_METATYPE( const QstMessage* )
+
+class QstProtocol : public QTcpSocket
+{
+ Q_OBJECT
+
+public:
+ QstProtocol(QObject *parent = 0);
+ virtual ~QstProtocol();
+
+ virtual void setSocket( int socket );
+
+ void enableReconnect( bool enable, uint reconnectInterval = 5000 );
+
+ void connect( const QString& hostname, int port );
+ void disconnect( bool disableReconnect = true );
+ bool isConnected();
+ virtual bool waitForConnected( int timeout = 10000 );
+
+ virtual uint postMessage( const QstMessage &message );
+
+ virtual bool sendMessage( const QstMessage &message, QstMessage &reply, int timeout );
+ virtual void replyMessage( const QstMessage *originalMsg, const QstMessage &message );
+
+ bool lastDataReceived();
+ bool rxBusy();
+ virtual void onReplyReceived( QstMessage *reply );
+
+ QString errorStr();
+ QString stateStr();
+
+ virtual void onConnectionFailed( const QString &reason );
+ virtual void onConnected() {}; // re-implement in derived class
+
+ QString uniqueId() const;
+ void enableDebug( bool debugOn );
+ void setAutoUnpack( bool autoUnpack ) { m_auto_unpack = autoUnpack; }
+
+public slots:
+ void reconnect();
+ void disableDebug();
+
+protected:
+ virtual void processMessage( QstMessage *msg ) = 0;
+
+ void send( const QstMessage &message );
+ void sendPreamble( QDataStream *ds, const QstMessage &message );
+ bool receive( QstMessage *msg, bool &syncError );
+
+signals:
+ void connectionClosed( QstProtocol *socket );
+ void connectionFailed( QstProtocol *socket, const QString &reason );
+ void replyReceived(int id = -1, const QstMessage *message = 0);
+ void replyConfirmed();
+
+protected slots:
+ void onData();
+ void onSocketConnected();
+ void onSocketClosed();
+ void connectTimeout();
+ void emitConnectionClosed();
+ void processMessages();
+ void testConnection();
+
+private:
+ quint16 tx_msg_id;
+ QString host;
+ int port;
+ bool onData_busy;
+ bool enable_reconnect;
+ uint reconnect_interval;
+ QTimer connect_timer;
+ QTime rx_timer;
+ bool last_data_received;
+ bool rx_busy;
+ bool connection_valid;
+
+ QList<QstMessage*> send_msg_replies;
+ QList<QstMessage*> unhandled_msg;
+ QstMessage *cur_message;
+
+ QString last_send_cmd;
+ QString unique_id;
+ bool debug_on;
+ bool m_auto_unpack;
+};
+
+#endif
diff --git a/src/remote/daemon/appmanager.cpp b/src/remote/daemon/appmanager.cpp
new file mode 100644
index 0000000..46b23fd
--- /dev/null
+++ b/src/remote/daemon/appmanager.cpp
@@ -0,0 +1,429 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "appmanager.h"
+#include "qtuitestmaster_p.h"
+#include "qtuitestdsettings.h"
+#include "qtuitest_debug.h"
+
+#include <qtuitestslave.h>
+#include <QLocalServer>
+#include <QLocalSocket>
+
+TestApplication::TestApplication(const QString &appId, AppManager *appManager)
+ : m_appId(appId)
+ , m_port(0)
+ , m_env()
+ , m_connection(0)
+ , m_appManager(appManager)
+ , m_state(NotStarted)
+{
+}
+
+TestApplication::~TestApplication()
+{
+ m_connection->deleteLater();
+}
+
+void TestApplication::onConnectionClosed()
+{
+ if (m_state == Disconnected)
+ return;
+
+ qLog() << "Connection to application closed" << this << m_state;
+ if (m_state == ProcessingMessage) {
+ qLog() << "Still processing message";
+ m_state = Disconnected;
+ return;
+ }
+ m_state = Disconnected;
+ emit finished();
+}
+
+void TestApplication::onSignalReceived(const QVariantMap &sender, const QString &signal, const QVariantList &args)
+{
+ QstMessage msg("SIGNAL_RECEIVED");
+ msg.setContext(m_appId);
+ msg["sender"] = sender;
+ msg["signal"] = signal;
+ msg["args"] = args;
+ m_appManager->postMessage( msg );
+}
+
+bool TestApplication::forwardMessage( QstMessage *msg, QtUiTestSlave *slave )
+{
+ qLog() << "TestApplication::forwardMessage" << msg->event() << "to" << m_appId << "on port" << m_port;
+
+ if (m_connection) {
+ QstMessage reply;
+ m_state = ProcessingMessage;
+ m_connection->sendMessage(*msg, reply, 20000);
+ reply.setContext(m_appId);
+ slave->replyMessage(msg, reply);
+ if (m_state == Disconnected) {
+ qLog() << "Connection closed while processing message";
+ emit finished();
+ return false;
+ }
+ m_state = Connected;
+ return true;
+ }
+ return false;
+}
+
+bool TestApplication::connectToAut(int timeout)
+{
+ if (!m_connection) {
+ m_connection = new QtUiTestMaster();
+ connect(m_connection, SIGNAL(signalReceived(QVariantMap,QString,QVariantList)), this, SLOT(onSignalReceived(QVariantMap,QString,QVariantList)));
+ }
+
+ QTime t;
+ t.start();
+ while (t.elapsed() < timeout && !m_connection->isConnected()) {
+ m_connection->connect( QString("127.0.0.1"), m_port );
+ m_connection->waitForConnected(2000);
+ }
+
+ if (!m_connection->isConnected()) {
+ qLog() << "Failed to connect to" << m_appId << "on port" << m_port;
+ qLog() << "Connection state" << m_connection->state();
+ if (m_connection->state() == QAbstractSocket::ConnectedState) {
+ // Connected, but no response!
+ qLog() << "Connected but did not receive reply";
+ m_connection->disconnect();
+ emit finished(false);
+ } else {
+ emit finished();
+ }
+ return false;
+ }
+ qLog() << "Connected to" << m_appId << "on port" << m_port;
+ m_state = Connected;
+
+ // Don't try to reconnect if connection is lost ... it's pointless
+ m_connection->enableReconnect(false, 0);
+ connect(static_cast<QstProtocol*>(m_connection), SIGNAL(connectionClosed(QstProtocol*)), this, SLOT(onConnectionClosed()));
+
+ QstMessage msg("appName");
+ QstMessage response;
+ m_connection->sendMessage( msg, response, 2000 );
+ response.unpack();
+ m_appName = response["appName"].toString();
+ qLog() << "Application name is" << m_appName;
+ if (!m_appName.isEmpty() && m_appName == QtUiTestDSettings::instance()->homeApp()) {
+ qLog() << "This is the home application";
+ m_appManager->setDefaultApplication(this);
+ }
+
+ return true;
+}
+
+bool TestApplication::isConnected() const
+{
+ if (m_connection) {
+ return m_connection->isConnected();
+ }
+ return false;
+}
+
+void TestApplication::cleanup()
+{
+ QstMessage msg("cleanup");
+ m_connection->postMessage(msg);
+}
+
+AppManager::AppManager()
+ : m_currentApplication(0)
+ , m_defaultApplication(0)
+ , m_server(0)
+{
+ QLocalServer::removeServer(QString::fromLocal8Bit(QTUITEST_PORT_PATH));
+ m_server = new QLocalServer(this);
+ m_server->listen(QString::fromLocal8Bit(QTUITEST_PORT_PATH));
+ connect(m_server, SIGNAL(newConnection()), this, SLOT(onNewConnection()));
+
+ if (int port = QtUiTestDSettings::instance()->prestartPort()) {
+ qLog() << "Trying to connect to existing application on port" << port;
+ m_defaultApplication = new TestApplication(QtUiTestDSettings::instance()->prestartApp(), this);
+ if (!m_defaultApplication || !connectApplication(port, m_defaultApplication)) {
+ qWarning() << "Failed to connect to existing application on port" << port;
+ exit(1);
+ }
+ }
+}
+
+AppManager::~AppManager()
+{
+}
+
+AppManager* AppManager::instance() {
+ static AppManager appManager;
+ return &appManager;
+}
+
+bool AppManager::connectApplication(int port, TestApplication *app, int timeout)
+{
+ connect(app, SIGNAL(finished(bool)), this, SLOT(onFinished(bool)));
+
+ app->setPort(port);
+ if (!app->connectToAut(timeout))
+ return false;
+
+ m_portMap.insert(port, app);
+ m_appMap.insert(app->appId(), app);
+ m_pendingPorts.removeAll(port);
+
+ if (app == m_defaultApplication || QtUiTestDSettings::instance()->homeApp().isEmpty()) {
+ setApplication(app);
+ }
+
+ return true;
+}
+
+void AppManager::purgeApplications()
+{
+ foreach (const QString &appId, m_appMap.keys()) {
+ m_appMap[appId]->deleteLater();
+ }
+
+ m_appMap.clear();
+}
+
+bool AppManager::forwardMessage( QstMessage *msg, QtUiTestSlave *slave )
+{
+ QString appId = msg->context();
+ TestApplication *app;
+
+ if (appId.isEmpty()) {
+ app = m_currentApplication;
+ } else {
+ app = m_appMap[appId];
+ if (app) {
+ qLog() << "Forwarding message to application id" << appId;
+ } else {
+ qLog() << "Cannot forward to application id" << appId;
+ }
+ }
+
+ if (app) {
+ return app->forwardMessage(msg, slave);
+ }
+ return false;
+}
+
+void AppManager::onNewConnection()
+{
+ qLog() << "New application requesting connection";
+ int port = getFreePort();
+ m_pendingPorts.append(port);
+ QString portString = QString::number(port).toLatin1() + QLatin1Char('\n');
+ qLog() << "Assigning port:" << port;
+ QLocalSocket *socket = m_server->nextPendingConnection();
+ socket->write(portString.toLatin1());
+ socket->disconnect();
+ socket->deleteLater();
+
+ //FIXME what identifier to use?
+ static int counter=0;
+ QString application = QString("app_%1:%2").arg(counter++, 5, 10, QLatin1Char('0')).arg(port);
+ TestApplication *app = new TestApplication(application, this);
+ if (!connectApplication(port, app)) {
+ qWarning() << "Failed to connect to application on port" << port;
+ return;
+ }
+
+ // Send message to notify test runner of new application
+ QstMessage msg("APP_STARTED");
+ msg.setContext(application);
+ postMessage( msg );
+}
+
+void AppManager::onFinished(bool reusePort)
+{
+ TestApplication *app = qobject_cast<TestApplication*>(sender());
+
+ if (app) {
+ qLog() << "Finished" << app->appId();
+
+ // Send message to notify test runner that app has closed
+ QstMessage msg("APP_FINISHED");
+ msg.setContext(app->appId());
+ if (app == m_defaultApplication) {
+ msg["homeapp"] = QtUiTestDSettings::instance()->homeApp();
+ }
+ postMessage( msg );
+
+ if (m_defaultApplication && app == m_currentApplication)
+ setApplication(m_defaultApplication);
+
+ if (reusePort) {
+ m_portMap.remove(app->port());
+ }
+
+ m_appMap.remove(app->appId());
+ qLog() << "Apps now: " << m_appMap.keys();
+
+ app->deleteLater();
+
+ if (app == m_defaultApplication) {
+ // The home application has died!
+ qLog() << "The home application has terminated!";
+ m_defaultApplication = 0;
+ purgeApplications();
+ return;
+ }
+
+ }
+}
+
+int AppManager::getFreePort() const
+{
+ int port = QtUiTestDSettings::instance()->appPortMin();
+
+ //Find first unused port in range
+ foreach (int usedPort, m_portMap.keys()) {
+ if ((port != usedPort)
+ && !(m_pendingPorts.contains(port))) {
+ break;
+ }
+ port++;
+ }
+ if (m_pendingPorts.contains(port)) {
+ port++;
+ }
+
+ if (port > QtUiTestDSettings::instance()->appPortMax()) {
+ qWarning("Exceeded maximum port number");
+ }
+
+ return port;
+}
+
+bool AppManager::isConnected() const
+{
+ if (m_currentApplication) {
+ return m_currentApplication->isConnected();
+ }
+ return false;
+}
+
+void AppManager::setDefaultApplication(TestApplication *app)
+{
+ m_defaultApplication = app;
+}
+
+QString AppManager::currentApplication() const
+{
+ QString ret;
+ if (m_currentApplication) {
+ ret = m_currentApplication->appId();
+ }
+ return ret;
+}
+
+QString AppManager::homeApplication() const
+{
+ QString ret;
+ if (m_defaultApplication) {
+ ret = m_defaultApplication->appId();
+ }
+ return ret;
+}
+
+QStringList AppManager::getApplications(const QString &name)
+{
+ QStringList result;
+ foreach (const QString &appId, m_appMap.keys()) {
+ if (!m_appMap[appId])
+ m_appMap.remove(appId);
+ if (name.isEmpty() || m_appMap[appId]->appName() == name)
+ result.append(appId);
+ }
+ return result;
+}
+
+bool AppManager::setApplication(const QString &appId)
+{
+ TestApplication *app = m_appMap[appId];
+ if (!app) {
+ return false;
+ }
+
+ setApplication(app);
+ return true;
+}
+
+void AppManager::setApplication(TestApplication *app)
+{
+ qLog() << "Setting current application to" << app << app->appId();
+ m_currentApplication = app;
+}
+
+void AppManager::postMessage(const QstMessage &msg)
+{
+ //FIXME - should inform all runners
+ foreach (QtUiTestSlave *slave, m_slaves) {
+ slave->postMessage( msg );
+ }
+}
+
+void AppManager::testrunnerConnected(QtUiTestSlave *slave)
+{
+ if (!m_slaves.contains(slave)) {
+ m_slaves << slave;
+ }
+}
+
+void AppManager::testrunnerDisconnected(QtUiTestSlave *slave)
+{
+ if (m_slaves.contains(slave)) {
+ m_slaves.removeAll(slave);
+ }
+
+ if (m_slaves.isEmpty()) {
+ foreach (QPointer<TestApplication> app, m_appMap.values()) {
+ if (app)
+ app->cleanup();
+ }
+ }
+}
diff --git a/src/remote/daemon/appmanager.h b/src/remote/daemon/appmanager.h
new file mode 100644
index 0000000..acbc79f
--- /dev/null
+++ b/src/remote/daemon/appmanager.h
@@ -0,0 +1,141 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef APPMANAGER_H
+#define APPMANAGER_H
+
+#include <QStringList>
+#include <QPointer>
+#include <QVariantMap>
+#include <QMap>
+
+class AppManager;
+class QtUiTestMaster;
+class QLocalServer;
+class QstMessage;
+class QtUiTestSlave;
+
+class TestApplication : public QObject
+{
+ Q_OBJECT
+
+public:
+
+ enum State { NotStarted=0, Connected=1, ProcessingMessage=2, Disconnected=3 };
+ explicit TestApplication( const QString &appId, AppManager *appManager = 0 );
+ virtual ~TestApplication();
+ bool connectToAut( int timeout );
+
+ bool forwardMessage( QstMessage *msg, QtUiTestSlave *slave );
+ void setPort(int port) { m_port = port; }
+ int port() const { return m_port; }
+ QString appId() const { return m_appId; }
+ QString appName() const { return m_appName; }
+ bool isConnected() const;
+ State state() { return m_state; }
+ void cleanup();
+
+private slots:
+ void onConnectionClosed();
+ void onSignalReceived(const QVariantMap &sender, const QString &signal, const QVariantList &args);
+
+signals:
+ void finished(bool reusePort=true);
+
+private:
+ QString m_appId;
+ QString m_appName;
+ int m_port;
+ QStringList m_env;
+ QtUiTestMaster *m_connection;
+ AppManager *m_appManager;
+ State m_state;
+};
+
+class AppManager : public QObject
+{
+ Q_OBJECT
+
+public:
+ AppManager();
+ virtual ~AppManager();
+
+ void init(QtUiTestSlave *slave);
+ bool forwardMessage( QstMessage *msg, QtUiTestSlave *slave );
+ bool isConnected() const;
+ int getFreePort() const;
+ void setDefaultApplication(TestApplication*);
+ QString currentApplication() const;
+ QString homeApplication() const;
+ QStringList getApplications(const QString & = QString());
+ bool setApplication(const QString&);
+ void purgeApplications();
+
+ void appStandardOutput( TestApplication *app, QByteArray text );
+ void appStandardError( TestApplication *app, QByteArray text );
+ void postMessage( const QstMessage &msg );
+ void testrunnerConnected( QtUiTestSlave *slave );
+ void testrunnerDisconnected( QtUiTestSlave *slave );
+
+ static AppManager* instance();
+
+protected:
+ bool connectApplication( int port, TestApplication *app, int timeout=30000 );
+ void setApplication(TestApplication *app);
+
+private slots:
+ void onNewConnection();
+ void onFinished(bool reusePort);
+
+private:
+ QList<QtUiTestSlave*> m_slaves;
+ QPointer<TestApplication> m_currentApplication;
+
+ // Default application is the system application, pre-started outside qtuitestd
+ QPointer<TestApplication> m_defaultApplication;
+ QMap<int, QPointer<TestApplication> > m_portMap;
+ QList<int> m_pendingPorts;
+ QMap<QString, QPointer<TestApplication> > m_appMap;
+ QLocalServer *m_server;
+};
+
+#endif
diff --git a/src/remote/daemon/daemon.pro b/src/remote/daemon/daemon.pro
new file mode 100644
index 0000000..71d8cac
--- /dev/null
+++ b/src/remote/daemon/daemon.pro
@@ -0,0 +1,29 @@
+!include (../remote.pri)
+
+TEMPLATE = app
+TARGET = qstdaemon
+DESTDIR = ../../../bin
+
+QT += network
+QT -= gui
+
+INCLUDEPATH += ../../../include
+LIBS += -L../../../lib
+LIBS += -lQstProtocol
+
+HEADERS += \
+ appmanager.h \
+ qtuitest_debug.h \
+ qtuitestdsettings.h \
+ qtuitestmaster_p.h \
+ qtuitestserver.h \
+ qtuitestslave.h
+
+SOURCES += \
+ main.cpp \
+ appmanager.cpp \
+ qtuitestdsettings.cpp \
+ qtuitestmaster.cpp \
+ qtuitestserver.cpp \
+ qtuitestslave.cpp
+
diff --git a/src/remote/daemon/main.cpp b/src/remote/daemon/main.cpp
new file mode 100644
index 0000000..d783d10
--- /dev/null
+++ b/src/remote/daemon/main.cpp
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <qtuitestserver.h>
+#include <qtuitestdsettings.h>
+#include <QCoreApplication>
+
+bool qtuitest_debug = false;
+
+int main(int argc, char *argv[])
+{
+ QCoreApplication app(argc, argv);
+ qtuitest_debug = QtUiTestDSettings::instance()->debug();
+ qtuitestServer()->startService();
+ return app.exec();
+}
diff --git a/src/remote/daemon/qtuitest_debug.h b/src/remote/daemon/qtuitest_debug.h
new file mode 100644
index 0000000..b7efa21
--- /dev/null
+++ b/src/remote/daemon/qtuitest_debug.h
@@ -0,0 +1,47 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QDebug>
+
+extern bool qtuitest_debug;
+
+#define qLog() if (!qtuitest_debug); else qDebug() << QString("[%1]").arg(QTime::currentTime().toString(QLatin1String("hh:mm:ss:zzz"))).toLatin1().data()
diff --git a/src/remote/daemon/qtuitestd.pro b/src/remote/daemon/qtuitestd.pro
new file mode 100644
index 0000000..bee9005
--- /dev/null
+++ b/src/remote/daemon/qtuitestd.pro
@@ -0,0 +1,51 @@
+!include(../../../global.pri): error(global.pri not found)
+!include($$SRCROOT/src/common/common.pri): error(common.pri not found)
+
+SOURCES += main.cpp \
+ qtuitestslave.cpp \
+ qtuitestserver.cpp \
+ qtuitestmaster.cpp \
+ appmanager.cpp \
+ qtuitestdsettings.cpp
+
+HEADERS += qtuitestslave.h \
+ appmanager.h \
+ qtuitestmaster_p.h \
+ qtuitest_debug.h \
+ qtuitestdsettings.h
+
+TEMPLATE=app
+VPATH+=$$PWD
+INCLUDEPATH+=$$PWD
+
+DEFINES += QTT_NO_DEBUG_AND_TRACEBACKS
+!include(../../common/libs/QttDebug/qttdebug.pri): error(qttdebug.pri not found)
+
+QT+=network
+QT-=gui
+TARGET=qtuitestd
+
+unix {
+ # install the script to start qtuitestd in the required
+ # two places avoiding the need for symbolic links
+ initscripts.path = /etc/init/test
+ initscripts.files = initscripts/qtuitestd.conf
+ # TODO: Disabled for now
+ INSTALLS += initscripts
+}
+
+!symbian {
+ MOC_DIR=$$OUT_PWD/.moc
+ OBJECTS_DIR=$$OUT_PWD/.obj
+ DESTDIR=$$BUILDROOT/bin
+ target.path=$$QTT_INSTALL_BIN_DIR
+ INSTALLS+=target
+}
+
+win32 {
+ CONFIG+=console
+}
+
+mac {
+ CONFIG-=app_bundle
+}
diff --git a/src/remote/daemon/qtuitestdsettings.cpp b/src/remote/daemon/qtuitestdsettings.cpp
new file mode 100644
index 0000000..27126a2
--- /dev/null
+++ b/src/remote/daemon/qtuitestdsettings.cpp
@@ -0,0 +1,183 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <qtuitestdsettings.h>
+#include <QCoreApplication>
+#include <QStringList>
+#include <QDebug>
+
+#define DEFAULT_PORT 5656
+#define DEFAULT_APPPORTMIN 5658
+#define DEFAULT_APPPORTMAX 5699
+
+QtUiTestDSettings::QtUiTestDSettings() :
+ m_debug(false),
+ m_port(DEFAULT_PORT),
+ m_portMax(DEFAULT_PORT),
+ m_appPortMin(DEFAULT_APPPORTMIN),
+ m_appPortMax(DEFAULT_APPPORTMAX),
+ m_prestartPort(0)
+{
+ const QStringList arguments = QCoreApplication::arguments();
+ int args = arguments.size();
+ QStringList deviceConfig;
+
+ for (int i=1; i<args; ++i) {
+ QString arg = arguments.at(i);
+ if (QString("-help").indexOf(arg) == 0) {
+ qWarning() << QString(
+ "%1 - QtUITest daemon\n\n"
+ " -help : Display this help text and exit\n"
+ " -debug : Display debugging information\n\n"
+ " -port port : Specify port to listen on (default: %2)\n"
+ " -port start,end : Specify port range to listen on\n\n"
+ " -appport start,end : Specify port range for launched applications (default: %3,%4)\n"
+ " -homeapp : Specify home application name\n\n"
+ "The following are optional, but both must be specified to connect to an existing\n"
+ "application instance (which must have QtUITest plugin loaded) :\n\n"
+ " -prestartapp : Specify application name of existing application\n"
+ " -prestartport : Specify port of existing application\n\n"
+ ).arg(arguments[0]).arg(DEFAULT_PORT).arg(DEFAULT_APPPORTMIN).arg(DEFAULT_APPPORTMAX)
+ .toLatin1().data();
+ exit(0);
+ } else if (QString("-debug").indexOf(arg) == 0) {
+ m_debug = true;
+ } else if (QString("-port").indexOf(arg) == 0) {
+ if (i == args-1) {
+ qWarning() << "Must provide port";
+ exit(1);
+ } else {
+ QString portRange = arguments.at(++i);
+ int commaPos = portRange.indexOf(QChar(','));
+ if (commaPos == -1) {
+ m_port = portRange.toInt();
+ m_portMax = m_port;
+ } else {
+ m_port = portRange.left(commaPos).toInt();
+ m_portMax = portRange.mid(commaPos+1).toInt();
+ }
+ if (!m_port || !m_portMax) {
+ qWarning() << "Invalid port specified";
+ exit(1);
+ }
+ }
+ } else if (QString("-appport").indexOf(arg) == 0) {
+ if (i == args-1) {
+ qWarning() << "Must provide port range";
+ exit(1);
+ } else {
+ QString appPortRange = arguments.at(++i);
+ int commaPos = appPortRange.indexOf(QChar(','));
+ if (commaPos == -1) {
+ qWarning() << "Must specify port range start,end";
+ exit(1);
+ }
+ m_appPortMin = appPortRange.left(commaPos).toInt();
+ m_appPortMax = appPortRange.mid(commaPos+1).toInt();
+ if (!m_appPortMin || !m_appPortMax) {
+ qWarning() << "Invalid port specified";
+ exit(1);
+ }
+ }
+ } else if (QString("-prestartport").indexOf(arg) == 0) {
+ if (i == args-1) {
+ qWarning() << "Must provide port";
+ exit(1);
+ } else {
+ m_prestartPort = arguments.at(++i).toInt();
+ if (!m_prestartPort) {
+ qWarning() << "Invalid port specified";
+ exit(1);
+ }
+ }
+ } else if (QString("-prestartapp").indexOf(arg) == 0) {
+ if (i == args-1) {
+ qWarning() << "Must provide prestarted application name";
+ exit(1);
+ } else {
+ m_prestartApp = arguments.at(++i);
+ }
+ } else if (QString("-homeapp").indexOf(arg) == 0) {
+ if (i == args-1) {
+ qWarning() << "Must provide home application name";
+ exit(1);
+ } else {
+ m_homeApp = arguments.at(++i);
+ }
+ } else if (QString("-config").indexOf(arg) == 0) {
+ if (i == args-1) {
+ qWarning() << "Must provide config value";
+ exit(1);
+ } else {
+ QString conf = arguments.at(++i);
+ if (!conf.contains(QLatin1Char('='))) {
+ qWarning() << "Config argument must be of format key=value";
+ exit(1);
+ }
+ deviceConfig << conf;
+ }
+ }
+ }
+
+ if ( (m_prestartPort && m_prestartApp.isNull()) ||
+ (!m_prestartPort && !m_prestartApp.isNull()) ) {
+ qWarning() << "Must specify both prestart port and application name";
+ exit(1);
+ }
+
+ foreach (const QString& conf, deviceConfig) {
+ int equals = conf.indexOf(QLatin1Char('='));
+ QString key = conf.left(equals);
+ QString value = conf.mid(equals+1);
+ m_deviceConfig[key] = value;
+ }
+}
+
+QtUiTestDSettings::~QtUiTestDSettings()
+{
+}
+
+QtUiTestDSettings *QtUiTestDSettings::instance()
+{
+ static QtUiTestDSettings instance;
+ return &instance;
+} \ No newline at end of file
diff --git a/src/remote/daemon/qtuitestdsettings.h b/src/remote/daemon/qtuitestdsettings.h
new file mode 100644
index 0000000..c046c1f
--- /dev/null
+++ b/src/remote/daemon/qtuitestdsettings.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QTUITESTDSETTINGS_H
+#define QTUITESTDSETTINGS_H
+
+#include <QString>
+#include <QVariantMap>
+
+class QtUiTestDSettings
+{
+
+public:
+ QtUiTestDSettings();
+ ~QtUiTestDSettings();
+
+ inline bool debug() const { return m_debug; }
+ inline int port() const { return m_port; }
+ inline int portMax() const { return m_portMax; }
+ inline int appPortMin() const { return m_appPortMin; }
+ inline int appPortMax() const { return m_appPortMax; }
+ inline int prestartPort() const { return m_prestartPort; }
+ inline QString prestartApp() const { return m_prestartApp; }
+ inline QString homeApp() const { return m_homeApp; }
+ inline QVariantMap deviceConfig() const { return m_deviceConfig; }
+
+ static QtUiTestDSettings* instance();
+
+private:
+ bool m_debug;
+ int m_port;
+ int m_portMax;
+ int m_appPortMin;
+ int m_appPortMax;
+ int m_prestartPort;
+ QString m_prestartApp;
+ QString m_homeApp;
+ QVariantMap m_deviceConfig;
+};
+
+#endif
diff --git a/src/remote/daemon/qtuitestmaster.cpp b/src/remote/daemon/qtuitestmaster.cpp
new file mode 100644
index 0000000..fcded65
--- /dev/null
+++ b/src/remote/daemon/qtuitestmaster.cpp
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "qtuitestmaster_p.h"
+
+#include <QFile>
+#include <QDir>
+#include <QTextStream>
+#include <QIODevice>
+
+QtUiTestMaster::QtUiTestMaster()
+ : QstProtocol()
+{
+ setAutoUnpack(false);
+}
+
+QtUiTestMaster::~QtUiTestMaster()
+{
+}
+
+void QtUiTestMaster::processMessage( QstMessage *msg )
+{
+ msg->unpack();
+ if (msg->event() == QLatin1String("APP_NAME")) {
+ m_appName = (*msg)["appName"].toString();
+ m_appVersion = (*msg)["appVersion"].toString();
+ m_qtVersion = (*msg)["qtVersion"].toString();
+ } else if (msg->event() == QLatin1String("SIGNAL_RECEIVED")) {
+ emit signalReceived( (*msg)["sender"].toMap(), (*msg)["signal"].toString(), (*msg)["args"].toList() );
+ }
+}
+
+bool QtUiTestMaster::forwardMessage( const QstMessage &msg )
+{
+ QstMessage reply;
+ // FIXME: This timeout should really be configurable
+ return sendMessage(msg, reply, 20000);
+}
+
+QString QtUiTestMaster::appName() const
+{
+ return m_appName;
+}
+
+QString QtUiTestMaster::appVersion() const
+{
+ return m_appVersion;
+}
+
+QString QtUiTestMaster::qtVersion() const
+{
+ return m_qtVersion;
+}
+
+void QtUiTestMaster::onReplyReceived( QstMessage *reply )
+{
+ // TODO - should emit signal
+// emit newMessage(reply);
+}
diff --git a/src/remote/daemon/qtuitestmaster_p.h b/src/remote/daemon/qtuitestmaster_p.h
new file mode 100644
index 0000000..29fb958
--- /dev/null
+++ b/src/remote/daemon/qtuitestmaster_p.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QTUITESTMASTER_P_H
+#define QTUITESTMASTER_P_H
+
+#include <QtSystemTest/QstProtocol>
+#include <QObject>
+#include <QtSystemTest/qstglobal.h>
+
+class QtUiTestMaster : public QstProtocol
+{
+ Q_OBJECT
+
+public:
+ QtUiTestMaster();
+ virtual ~QtUiTestMaster();
+
+ QString appName() const;
+ QString appVersion() const;
+ QString qtVersion() const;
+ bool forwardMessage( const QstMessage &msg );
+
+ virtual void onReplyReceived( QstMessage *reply );
+
+signals:
+ void signalReceived( const QVariantMap &sender, const QString &signal, const QVariantList &args);
+
+protected:
+ virtual void processMessage( QstMessage *msg );
+
+private:
+ QString m_appName;
+ QString m_appVersion;
+ QString m_qtVersion;
+};
+
+#endif
+
diff --git a/src/remote/daemon/qtuitestserver.cpp b/src/remote/daemon/qtuitestserver.cpp
new file mode 100644
index 0000000..d6f67c9
--- /dev/null
+++ b/src/remote/daemon/qtuitestserver.cpp
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "qtuitestserver.h"
+#include "qtuitest_debug.h"
+#include "qtuitestdsettings.h"
+
+#include <qtuitestslave.h>
+#include <QCoreApplication>
+#include <QStringList>
+#include <QtSystemTest/QstDebug>
+
+QtUiTestServer::QtUiTestServer(int port)
+ : QTcpServer(), showDebug(false)
+{
+ QTT_TRACE_FUNCTION();
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
+ if (!listen(QHostAddress::AnyIPv4, port)) {
+#else
+ if (!listen(QHostAddress::Any, port)) {
+#endif
+ qWarning() << "QtUiTestServer: couldn't listen for connections on " << port;
+ exit(-1);
+ }
+ qLog() << "QtUiTestServer: listening for connections on" << port;
+}
+
+QtUiTestServer::~QtUiTestServer()
+{
+ QTT_TRACE_FUNCTION();
+ close();
+}
+
+void QtUiTestServer::incomingConnection(int sd)
+{
+ QTT_TRACE_FUNCTION();
+ qLog() << "New connection to qtuitestrunner on port" << sd;
+ slave.setSocket(sd);
+}
+
+void QtUiTestServerManager::startService()
+{
+ QTT_TRACE_FUNCTION();
+ qLog() << "QtUiTestServer: Starting service";
+
+ int port = QtUiTestDSettings::instance()->port();
+ int portMax = QtUiTestDSettings::instance()->portMax();
+
+ for (int i=port; i<=portMax; ++i) {
+ QtUiTestServer *server = new QtUiTestServer(i);
+ m_servers << server;
+ }
+}
+
+void QtUiTestServerManager::stopService()
+{
+ QTT_TRACE_FUNCTION();
+ qLog() << "QtUiTestServer : Stoping service";
+
+ foreach (QtUiTestServer *server, m_servers) {
+ delete server;
+ }
+}
diff --git a/src/remote/daemon/qtuitestserver.h b/src/remote/daemon/qtuitestserver.h
new file mode 100644
index 0000000..a8c7d86
--- /dev/null
+++ b/src/remote/daemon/qtuitestserver.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QTUITESTSERVER_H
+#define QTUITESTSERVER_H
+
+#include <QTcpServer>
+#include <qtuitestslave.h>
+
+struct QtUiTestServer : public QTcpServer
+{
+ QtUiTestServer(int port);
+ ~QtUiTestServer();
+ void incomingConnection(int);
+ void startService();
+ void stopService();
+
+ QtUiTestSlave slave;
+ bool showDebug;
+};
+
+class QtUiTestServerManager
+{
+public:
+ void startService();
+ void stopService();
+
+private:
+ QList<QtUiTestServer*> m_servers;
+};
+
+Q_GLOBAL_STATIC(QtUiTestServerManager, qtuitestServer);
+
+#endif \ No newline at end of file
diff --git a/src/remote/daemon/qtuitestslave.cpp b/src/remote/daemon/qtuitestslave.cpp
new file mode 100644
index 0000000..653b003
--- /dev/null
+++ b/src/remote/daemon/qtuitestslave.cpp
@@ -0,0 +1,600 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "appmanager.h"
+#include "qtuitestslave.h"
+#include "qtuitestmaster_p.h"
+#include "qtuitest_debug.h"
+#include "qtuitestdsettings.h"
+
+#include <QDir>
+#include <QVariant>
+#include <QMetaProperty>
+#include <QMetaObject>
+#include <QMetaType>
+#include <QProcess>
+#include <QCoreApplication>
+#include <QSettings>
+#include <QPointer>
+
+class QtUiTestSlavePrivate : public QObject
+{
+Q_OBJECT
+public:
+ QtUiTestSlavePrivate(QtUiTestSlave *parent)
+ : p(parent)
+ {
+ AppManager::instance();
+ }
+
+ QString recursiveDelete(const QString&) const;
+
+ QtUiTestSlave *p;
+ AppManager *appManager()
+ {
+ return AppManager::instance();
+ }
+
+public slots:
+
+ QstMessage currentApplication (const QstMessage&);
+ QstMessage homeApplication (const QstMessage&);
+ QstMessage setApplication (const QstMessage&);
+ QstMessage isValidApplication (const QstMessage&);
+ QstMessage getApplications (const QstMessage&);
+
+ QstMessage runProcess (const QstMessage&);
+ QstMessage getSetting (const QstMessage&);
+ QstMessage setSetting (const QstMessage&);
+ QstMessage putFile (const QstMessage&);
+ QstMessage getFile (const QstMessage&);
+ QstMessage deletePath (const QstMessage&);
+ QstMessage getDirectoryEntries(const QstMessage&);
+ QstMessage checkOS (const QstMessage&);
+ QstMessage deviceConfig (const QstMessage&);
+ QstMessage systemTime (const QstMessage&);
+};
+
+#include "qtuitestslave.moc"
+
+QtUiTestSlave::QtUiTestSlave()
+ : QstProtocol()
+ , d(new QtUiTestSlavePrivate(this))
+{
+ setAutoUnpack(false);
+ QObject::connect(static_cast<QstProtocol*>(this), SIGNAL(connectionClosed(QstProtocol*)), this, SLOT(onConnectionClosed()));
+}
+
+QtUiTestSlave::~QtUiTestSlave()
+{
+ delete d;
+ disconnect();
+}
+
+void QtUiTestSlave::onConnected()
+{
+ QstProtocol::onConnected();
+ QstMessage msg("AUT_CONNECT");
+ msg["qtVersion"] = QT_VERSION_STR;
+ msg["autVersion"] = QTUITEST_VERSION_STR;
+ msg["autTime"] = QTime::currentTime();
+ d->appManager()->testrunnerConnected(this);
+ postMessage( msg );
+}
+
+void QtUiTestSlave::onConnectionClosed()
+{
+ qLog() << "Connection to qtuitestrunner has closed";
+ d->appManager()->testrunnerDisconnected(this);
+}
+
+QstMessage QtUiTestSlavePrivate::currentApplication(const QstMessage &message)
+{
+ Q_UNUSED(message);
+ QstMessage reply;
+
+ reply[QLatin1String("currentApplication")] = appManager()->currentApplication();
+ return reply;
+}
+
+QstMessage QtUiTestSlavePrivate::homeApplication(const QstMessage &message)
+{
+ Q_UNUSED(message);
+ QstMessage reply;
+
+ reply[QLatin1String("homeApplication")] = appManager()->homeApplication();
+ return reply;
+}
+
+QstMessage QtUiTestSlavePrivate::setApplication(const QstMessage &message)
+{
+ QstMessage reply;
+ QString appId = message.context();
+
+ if (appId.isEmpty()) {
+ return MESSAGE_ERROR(reply, QLatin1String("ERROR_MISSING_PARAMETERS"));
+ }
+
+ bool ok = appManager()->setApplication(appId);
+ if (!ok) {
+ return MESSAGE_ERROR(reply, QLatin1String("Unable to set application"));
+ }
+ return reply;
+}
+
+QstMessage QtUiTestSlavePrivate::isValidApplication(const QstMessage &message)
+{
+ QstMessage reply;
+ QString appId = message.context();
+
+ if (appId.isEmpty()) {
+ return MESSAGE_ERROR(reply, QLatin1String("ERROR_MISSING_PARAMETERS"));
+ }
+
+ bool ok = appManager()->getApplications().contains(appId);
+ reply[QLatin1String("isValidApplication")] = ok;
+ return reply;
+}
+
+QstMessage QtUiTestSlavePrivate::getApplications(const QstMessage &message)
+{
+ Q_UNUSED(message);
+ QstMessage reply;
+ QString appName = message["name"].toString();
+
+ reply[QLatin1String("getApplications")] = appManager()->getApplications(appName);
+ return reply;
+}
+
+QstMessage QtUiTestSlavePrivate::runProcess(const QstMessage &message)
+{
+ QstMessage reply;
+
+ QVariantMap cmd = message["cmd"].toMap();
+ if (cmd.isEmpty()) {
+ return MESSAGE_ERROR(reply, QLatin1String("ERROR_MISSING_PARAMETERS"));
+ }
+
+ QString program = cmd["program"].toString();
+ QStringList arguments = cmd["arguments"].toStringList();
+ int timeout = cmd["timeout"].toInt();
+ QString directory = cmd["directory"].toString();
+ QVariantMap environment = cmd["environment"].toMap();
+ QVariantMap appendEnvironment = cmd["appendEnvironment"].toMap();
+ bool detached = cmd["detached"].toBool();
+
+ QProcessEnvironment env;
+ if (!environment.isEmpty()) {
+ foreach (const QString &key, environment.keys()) {
+ env.insert(key, environment[key].toString());
+ }
+ }
+ if (!appendEnvironment.isEmpty()) {
+ if (env.isEmpty()) {
+ env = QProcessEnvironment::systemEnvironment();
+ }
+ foreach (const QString &key, appendEnvironment.keys()) {
+ env.insert(key, appendEnvironment[key].toString());
+ }
+ }
+
+ bool ok = true;
+ QString status;
+
+ if (detached) {
+ // Run command in background
+ qint64 pid = 0;
+ if (QProcess::startDetached(program, arguments, directory, &pid)) {
+ status = QLatin1String("Started");
+ reply["pid"] = pid;
+ } else {
+ status = QLatin1String("FailedToStart");
+ ok = false;
+ }
+ } else {
+ // Run command and wait for completion
+ QString stdout;
+ QString stderr;
+ int exitCode = 0;
+ QProcess *process = new QProcess(this);
+
+ if (!env.isEmpty()) {
+ process->setProcessEnvironment(env);
+ }
+ if (!directory.isEmpty()) {
+ process->setWorkingDirectory(directory);
+ }
+
+ process->start(program, arguments);
+ while (process->state() == QProcess::Starting) {
+ QCoreApplication::processEvents();
+ }
+
+ if (process->error() == QProcess::FailedToStart) {
+ status = QLatin1String("FailedToStart");
+ ok = false;
+ } else {
+ QTime t;
+ t.start();
+ while (process->state() == QProcess::Running && t.elapsed() < timeout) {
+ QCoreApplication::processEvents();
+ }
+
+ stdout += process->readAllStandardOutput();
+ stderr += process->readAllStandardError();
+ if (process->state() == QProcess::Running) {
+ status = QLatin1String("TimedOut");
+ } else if (process->exitStatus() != QProcess::NormalExit) {
+ status = QLatin1String("Crashed");
+ ok = false;
+ } else {
+ status = QLatin1String("Finished");
+ }
+ }
+
+ exitCode = process->exitCode();
+ delete process;
+
+ reply["stdout"] = stdout;
+ reply["stderr"] = stderr;
+ reply["exitCode"] = exitCode;
+ }
+ qLog() << "Command status:" << status;
+ reply["cmdStatus"] = status;
+
+ if (!ok) {
+ return MESSAGE_ERROR(reply, QString("Error: Command failed to run (%1)").arg(status));
+ }
+ return reply;
+}
+
+QstMessage QtUiTestSlavePrivate::getSetting(const QstMessage &message)
+{
+ QstMessage reply;
+ QString org = message[QLatin1String("org")].toString();
+ QString app = message[QLatin1String("app")].toString();
+ QString path = message[QLatin1String("path")].toString();
+ QString group = message[QLatin1String("group")].toString();
+ QString key = message[QLatin1String("key")].toString();
+ path = p->processEnvironment(path);
+ if (group.isEmpty() || key.isEmpty()) {
+ return MESSAGE_ERROR(reply, QLatin1String("ERROR_MISSING_PARAMETERS"));
+ }
+ if (!path.isEmpty() && (!org.isEmpty() || !app.isEmpty())) {
+ return MESSAGE_ERROR(reply, QLatin1String("ERROR_BAD_PARAMETERS"));
+ } else if (path.isEmpty() && org.isEmpty()) {
+ return MESSAGE_ERROR(reply, QLatin1String("ERROR_MISSING_PARAMETERS"));
+ }
+
+ QSettings *settings = 0;
+ if (!path.isEmpty()) settings = new QSettings(path, QSettings::NativeFormat);
+ else settings = new QSettings(org, app);
+
+ settings->beginGroup(group);
+ reply[QLatin1String("getSetting")] = settings->value(key);
+ delete settings;
+
+ return reply;
+}
+
+QstMessage QtUiTestSlavePrivate::setSetting(const QstMessage &message)
+{
+ QstMessage reply;
+ QString org = message[QLatin1String("org")].toString();
+ QString app = message[QLatin1String("app")].toString();
+ QString path = message[QLatin1String("path")].toString();
+ QString group = message[QLatin1String("group")].toString();
+ QString key = message[QLatin1String("key")].toString();
+ path = p->processEnvironment(path);
+ if (key.isEmpty()) {
+ return MESSAGE_ERROR(reply, QLatin1String("ERROR_MISSING_PARAMETERS"));
+ }
+ if (!path.isEmpty() && (!org.isEmpty() || !app.isEmpty())) {
+ return MESSAGE_ERROR(reply, QLatin1String("ERROR_BAD_PARAMETERS"));
+ } else if (path.isEmpty() && org.isEmpty()) {
+ return MESSAGE_ERROR(reply, QLatin1String("ERROR_MISSING_PARAMETERS"));
+ }
+
+ QSettings *settings = 0;
+ if (!path.isEmpty()) settings = new QSettings(path, QSettings::NativeFormat);
+ else settings = new QSettings(org, app);
+
+ if (!group.isEmpty())
+ settings->beginGroup(group);
+ settings->setValue(key, message[QLatin1String("value")]);
+ delete settings;
+
+ return reply;
+}
+
+QstMessage QtUiTestSlavePrivate::putFile(const QstMessage &message)
+{
+ QstMessage reply;
+ QString path = message[QLatin1String("path")].toString();
+ path = p->processEnvironment(path);
+ QByteArray data = message[QLatin1String("data")].toByteArray();
+
+ if (path.isEmpty())
+ return MESSAGE_ERROR(reply, QLatin1String("ERROR_MISSING_PARAMETERS"));
+
+ {
+ QFileInfo info = QFileInfo(path);
+ QDir dir = info.dir();
+ if (info.exists()) {
+ dir.remove(info.fileName());
+ } else if (!dir.exists() && !QDir(QLatin1String("/")).mkpath(dir.absolutePath())) {
+ return MESSAGE_ERROR(reply, QLatin1String("Could not create path '") + dir.absolutePath() + QLatin1String("'"));
+ }
+ }
+
+ QFile f(path);
+ if (f.open(QIODevice::WriteOnly)) {
+ if (message[QLatin1String("permissions")].isValid() && !f.setPermissions(static_cast<QFile::Permissions>(message[QLatin1String("permissions")].toInt()))) {
+ return MESSAGE_ERROR(reply, QLatin1String("ERROR_FILE_PERMISSIONS"));
+ }
+ QDataStream ds(&f);
+ if (data.constData()) {
+ quint64 bytesWritten = ds.writeRawData(data.constData(), data.size());
+ if ((qint64)bytesWritten == data.size())
+ return reply;
+ else {
+ reply[QLatin1String("warning")] = QString("Wrote %1 byte(s), expected %2").arg(bytesWritten).arg(data.size());
+ return MESSAGE_ERROR(reply, QLatin1String("ERROR_TRUNCATED"));
+ }
+ }
+ // It's OK for data to be empty, then we create an empty file.
+ return reply;
+ }
+
+ return MESSAGE_ERROR(reply, QLatin1String("ERROR_FILE_OPEN"));
+}
+
+QstMessage QtUiTestSlavePrivate::getFile(const QstMessage &message)
+{
+ QstMessage reply;
+ QString path = message[QLatin1String("path")].toString();
+ path = p->processEnvironment(path);
+
+ if (path.isEmpty())
+ return MESSAGE_ERROR(reply, QLatin1String("ERROR_MISSING_PARAMETERS"));
+
+ QFile f(path);
+ if (!f.exists()) return MESSAGE_ERROR(reply, QLatin1String("ERROR_FILE_NOT_EXIST"));
+ if (f.open(QIODevice::ReadOnly)) {
+ QByteArray data;
+ QDataStream ds(&f);
+ data.resize(f.size());
+ quint64 bytesRead = ds.readRawData(data.data(), f.size());
+ reply[QLatin1String("getFile")] = data;
+ if ((qint64)bytesRead == f.size())
+ return reply;
+ else {
+ reply[QLatin1String("warning")] = QString("Read %1 byte(s), expected %2").arg(bytesRead).arg(data.size());
+ return MESSAGE_ERROR(reply, QLatin1String("ERROR_TRUNCATED"));
+ }
+ }
+ return MESSAGE_ERROR(reply, QLatin1String("ERROR_FILE_OPEN"));
+}
+
+QstMessage QtUiTestSlavePrivate::getDirectoryEntries(const QstMessage &message)
+{
+ QstMessage reply;
+ QString path = message[QLatin1String("path")].toString();
+ path = p->processEnvironment(path);
+
+ if (path.isEmpty()) {
+ return MESSAGE_ERROR(reply, QLatin1String("ERROR_MISSING_PARAMETERS"));
+ }
+
+ QDir d(path);
+ if (!d.exists()) {
+ reply[QLatin1String("getDirectoryEntries")] = QStringList();
+ return reply;
+ }
+
+ QDir::Filters filters;
+ {
+ int filters_int = message[QLatin1String("filters")].toInt();
+ filters = QFlag(filters_int);
+ }
+
+ QStringList list = d.entryList(filters);
+ reply[QLatin1String("getDirectoryEntries")] = list;
+ return reply;
+}
+
+QstMessage QtUiTestSlavePrivate::deletePath(const QstMessage &message)
+{
+ QstMessage reply;
+ QString path = message[QLatin1String("path")].toString();
+ path = p->processEnvironment(path);
+ QString deleteResult = recursiveDelete(path);
+ if (deleteResult != QLatin1String("OK")) {
+ return MESSAGE_ERROR(reply, deleteResult);
+ }
+ return reply;
+}
+
+void QtUiTestSlave::processMessage( QstMessage *msg )
+{
+ qLog() << "QtUiTestSlave::processMessage" << msg->event();
+
+ QstMessage reply;
+ QString methodSignature = msg->event() + QLatin1String("(QstMessage)");
+
+ if (d->metaObject()->indexOfMethod(methodSignature.toLatin1().constData()) == -1) {
+ if (!d->appManager()->isConnected()) {
+ (void)MESSAGE_ERROR(reply, QLatin1String("ERROR: Not connected to test application"));
+ } else if (!d->appManager()->forwardMessage(msg, this)) {
+ (void)MESSAGE_ERROR(reply, QLatin1String("ERROR: Could not forward message '") + msg->event() + QLatin1String("'"));
+ }
+
+ } else {
+ msg->unpack();
+ if (!QMetaObject::invokeMethod(d, msg->event().toLatin1().constData(), Qt::DirectConnection,
+ Q_RETURN_ARG(QstMessage, reply),
+ Q_ARG(QstMessage, *msg))) {
+ (void)MESSAGE_ERROR(reply, QLatin1String("ERROR: Failed to invoke method '") + msg->event() + QLatin1String("'"));
+ }
+ if (reply.state() != QstMessage::MessageError) {
+ reply.setState(QstMessage::MessageSuccess);
+ }
+ }
+
+ replyMessage(msg, reply);
+}
+
+QString QtUiTestSlave::processEnvironment( const QString& in ) const
+{
+ struct SystemEnvironment {
+ static QMap<QString,QString> get() {
+ QMap<QString,QString> ret;
+ QStringList env = QProcess::systemEnvironment();
+ foreach (const QString &str, env) {
+ if (str.contains(QLatin1Char('='))) {
+ ret[str.left(str.indexOf(QLatin1Char('='))).toUpper()] = str.mid(str.indexOf(QLatin1Char('=')) + 1);
+ }
+ }
+ return ret;
+ }
+ };
+ static const QMap<QString,QString> environment( SystemEnvironment::get() );
+
+ QString out;
+ static QRegExp re("\\$[{(]?([A-Za-z0-9_]+)[})]?");
+ int offset = 0;
+ while (true) {
+ int index = re.indexIn(in, offset);
+ if (-1 == index) {
+ out += in.mid(offset);
+ break;
+ }
+ out += in.mid(offset, index - offset);
+ out += environment.value(re.cap(1).toUpper());
+ offset += re.matchedLength();
+ }
+
+ return out;
+}
+
+QString QtUiTestSlavePrivate::recursiveDelete( const QString &path ) const
+{
+ if (path.isEmpty()) return QLatin1String("ERROR_CANT_DELETE_EMPTY_PATH");
+
+ QFileInfo i(path);
+ if (!i.exists()) return QLatin1String("OK");
+ if (!i.isDir() || i.isSymLink()) {
+ if (!i.dir().remove(i.fileName())) {
+ return QLatin1String("ERROR_CANT_DELETE_FILE_") + path;
+ } else {
+ return QLatin1String("OK");
+ }
+ }
+
+ QDir dir(path);
+
+ QStringList children = dir.entryList( QDir::AllEntries | QDir::System | QDir::Hidden | QDir::NoDotAndDotDot );
+
+ QString res;
+ foreach (QString child, children) {
+ res = recursiveDelete( dir.absolutePath() + QLatin1String("/") + child );
+ if (res != QLatin1String("OK") ) return res;
+ }
+
+ QString dirName = dir.dirName();
+ dir.cdUp();
+
+ if (!dir.rmdir(dirName)) {
+ return QLatin1String("ERROR_CANT_DELETE_DIRECTORY_") + path;
+ }
+ return QLatin1String("OK");
+}
+
+QstMessage QtUiTestSlavePrivate::checkOS( const QstMessage &message )
+{
+ QstMessage reply;
+ QString os = message[QLatin1String("os")].toString().toUpper();
+
+ bool result = false;
+
+#ifdef Q_OS_UNIX
+ if (os == QLatin1String("UNIX")) result = true;
+#endif
+#ifdef Q_OS_LINUX
+ if (os == QLatin1String("LINUX")) result = true;
+#endif
+#ifdef Q_OS_MAEMO
+ if (os == QLatin1String("MAEMO")) result = true;
+#endif
+#ifdef Q_OS_MAC
+ if (os == QLatin1String("MAC")) result = true;
+#endif
+#ifdef Q_OS_WIN32
+ if (os == QLatin1String("WIN32")) result = true;
+#endif
+#ifdef Q_OS_WINCE
+ if (os == QLatin1String("WINCE")) result = true;
+#endif
+#ifdef Q_OS_SYMBIAN
+ if (os == QLatin1String("SYMBIAN")) result = true;
+#endif
+
+ reply[QLatin1String("checkOS")] = result;
+ return reply;
+}
+
+QstMessage QtUiTestSlavePrivate::deviceConfig( const QstMessage &message )
+{
+ Q_UNUSED(message);
+ QstMessage reply;
+ reply[QLatin1String("deviceConfig")] = QtUiTestDSettings::instance()->deviceConfig();
+ return reply;
+}
+
+QstMessage QtUiTestSlavePrivate::systemTime(const QstMessage &message)
+{
+ Q_UNUSED(message);
+ QstMessage reply;
+
+ reply["systemTime"] = QDateTime::currentDateTime().toString(Qt::ISODate);
+ return reply;
+}
diff --git a/src/remote/daemon/qtuitestslave.h b/src/remote/daemon/qtuitestslave.h
new file mode 100644
index 0000000..dbd81aa
--- /dev/null
+++ b/src/remote/daemon/qtuitestslave.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QTUITESTSLAVE_H
+#define QTUITESTSLAVE_H
+
+#include <QtSystemTest/QstProtocol>
+
+class QtUiTestSlavePrivate;
+
+class QtUiTestSlave : public QstProtocol
+{
+ Q_OBJECT
+
+public:
+ QtUiTestSlave();
+ virtual ~QtUiTestSlave();
+ virtual void processMessage(QstMessage*);
+
+public slots:
+ virtual void onConnected();
+ virtual void onConnectionClosed();
+
+protected:
+ QString processEnvironment(const QString&) const;
+
+private:
+ friend class QtUiTestSlavePrivate;
+ QtUiTestSlavePrivate *d;
+};
+
+#endif
diff --git a/src/remote/remote.pri b/src/remote/remote.pri
new file mode 100644
index 0000000..bbdfb74
--- /dev/null
+++ b/src/remote/remote.pri
@@ -0,0 +1,15 @@
+!contains(DEFINES, DEFAULT_AUT_PORT) {
+ DEFINES += DEFAULT_AUT_PORT=6565
+}
+
+!contains(DEFINES, DEFAULT_AUTSSH_PORT) {
+ DEFINES += DEFAULT_AUT_AUTPORT=22
+}
+
+!contains(DEFINES, DEFAULT_AUT_HOST) {
+ DEFINES += DEFAULT_AUT_HOST="127.0.0.1"
+}
+
+!contains(DEFINES, QTUITEST_PORT_PATH) {
+ DEFINES += 'QTUITEST_PORT_PATH=\\"/tmp/qtuitest_port\\"'
+}
diff --git a/src/remote/remote.pro b/src/remote/remote.pro
new file mode 100644
index 0000000..317a146
--- /dev/null
+++ b/src/remote/remote.pro
@@ -0,0 +1,2 @@
+TEMPLATE = subdirs
+SUBDIRS = daemon slave
diff --git a/src/remote/slave/lib/lib.pro b/src/remote/slave/lib/lib.pro
new file mode 100644
index 0000000..ca73a91
--- /dev/null
+++ b/src/remote/slave/lib/lib.pro
@@ -0,0 +1,93 @@
+!include (../../remote.pri)
+
+TEMPLATE = lib
+
+TARGET = QstSlave
+TARGETPATH = QtSystemTest
+
+TEMPLATE = lib
+
+CONFIG += no_clean qt
+QT += core network widgets declarative quick
+
+INCLUDEPATH += ../../../../include
+LIBS += -L../../../../lib
+LIBS += -lQstProtocol
+
+contains(QT_MAJOR_VERSION, 5) {
+ SOURCES += \
+ qinputgenerator_qwindow.cpp \
+ testquickobject.cpp \
+ testquickitem.cpp \
+ testquickview.cpp \
+ testwindow.cpp
+
+ PUBLIC_HEADERS += \
+ testquickobject.h \
+ testquickitem.h \
+ testquickview.h \
+ testwindow.h \
+
+ HEADERS += \
+ qinputgenerator_qwindow_p.h
+
+ QT += qml qml-private quick gui-private core-private widgets
+} else {
+ INCLUDEPATH += $$QT_DECLARATIVE_PRIVATE_HEADERS_DIR
+}
+
+SOURCES += \
+ qinputgenerator_generic.cpp \
+ testquickfactory.cpp \
+ testobject.cpp \
+ testwidget.cpp \
+ qasciikey.cpp \
+ qtuitestconnectionmanager.cpp \
+ qtuitestwidgetinterface.cpp \
+ qeventwatcher.cpp \
+ qtestslave.cpp \
+ testapplication.cpp \
+ testslaveserver.cpp \
+ qtuitestwidgets.cpp \
+ qinputgenerator.cpp \
+ qtestwidgets.cpp \
+ qtuitestnamespace.cpp
+
+PUBLIC_HEADERS += \
+ qtestwidgets.h \
+ qtuitestnamespace.h \
+ testquickfactory.h \
+ testobject.h \
+ testwidget.h \
+ testapplication.h \
+ qtuitestwidgetinterface.h \
+ qtestslave.h \
+ qtuitestmessagehandler.h \
+ testslaveserver.h
+
+HEADERS = \
+ qinputgenerator_p.h \
+ qtuitestconnectionmanager_p.h \
+ qeventwatcher_p.h \
+ qtuitestwidgets_p.h \
+ qinputgenerator_generic_p.h \
+ $$PUBLIC_HEADERS
+
+# Installing libs and headers into Qt lib
+includes.files = $$PUBLIC_HEADERS
+includes.path = $$[QT_INSTALL_HEADERS]/$$TARGETPATH
+
+target.path = $$[QT_INSTALL_LIBS]
+
+INSTALLS += includes target
+
+# Building so that other libs in project can access this lib
+DESTDIR = ../../../../lib
+INCLUDEDESTDIR = $$OUT_PWD/../../../../include/$$TARGETPATH
+includedir.target = dummytarget
+includedir.commands = (mkdir -p $$INCLUDEDESTDIR && cd $$PWD && cp $$PUBLIC_HEADERS $$INCLUDEDESTDIR/)
+
+QMAKE_EXTRA_TARGETS += includedir
+
+PRE_TARGETDEPS += dummytarget
+
diff --git a/src/remote/slave/lib/qasciikey.cpp b/src/remote/slave/lib/qasciikey.cpp
new file mode 100644
index 0000000..0e682c1
--- /dev/null
+++ b/src/remote/slave/lib/qasciikey.cpp
@@ -0,0 +1,526 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "qtuitestnamespace.h"
+
+/*! \internal
+ Convert an ascii char key value to a Qt Key value.
+ If the key is unknown a 0 is returned.
+
+ Note: this may happen more than you like since not all known
+ ascii keys _are_ converted already. So feel free to add all the keys you need.
+ */
+Qt::Key QtUiTest::asciiToKey(char ascii)
+{
+ switch ((unsigned char)ascii) {
+ case 0x08: return Qt::Key_Backspace;
+ case 0x09: return Qt::Key_Tab;
+ case 0x0b: return Qt::Key_Backtab;
+ case 0x0d: return Qt::Key_Return;
+ case 0x1b: return Qt::Key_Escape;
+ case 0x13: return Qt::Key_Up;
+ case 0x15: return Qt::Key_Down;
+ case 0x20: return Qt::Key_Space;
+ case 0x21: return Qt::Key_Exclam;
+ case 0x22: return Qt::Key_QuoteDbl;
+ case 0x23: return Qt::Key_NumberSign;
+ case 0x24: return Qt::Key_Dollar;
+ case 0x25: return Qt::Key_Percent;
+ case 0x26: return Qt::Key_Ampersand;
+ case 0x27: return Qt::Key_Apostrophe;
+ case 0x28: return Qt::Key_ParenLeft;
+ case 0x29: return Qt::Key_ParenRight;
+ case 0x2a: return Qt::Key_Asterisk;
+ case 0x2b: return Qt::Key_Plus;
+ case 0x2c: return Qt::Key_Comma;
+ case 0x2d: return Qt::Key_Minus;
+ case 0x2e: return Qt::Key_Period;
+ case 0x2f: return Qt::Key_Slash;
+ case 0x30: return Qt::Key_0;
+ case 0x31: return Qt::Key_1;
+ case 0x32: return Qt::Key_2;
+ case 0x33: return Qt::Key_3;
+ case 0x34: return Qt::Key_4;
+ case 0x35: return Qt::Key_5;
+ case 0x36: return Qt::Key_6;
+ case 0x37: return Qt::Key_7;
+ case 0x38: return Qt::Key_8;
+ case 0x39: return Qt::Key_9;
+ case 0x3a: return Qt::Key_Colon;
+ case 0x3b: return Qt::Key_Semicolon;
+ case 0x3c: return Qt::Key_Less;
+ case 0x3d: return Qt::Key_Equal;
+ case 0x3e: return Qt::Key_Greater;
+ case 0x3f: return Qt::Key_Question;
+ case 0x40: return Qt::Key_At;
+ case 0x41: return Qt::Key_A;
+ case 0x42: return Qt::Key_B;
+ case 0x43: return Qt::Key_C;
+ case 0x44: return Qt::Key_D;
+ case 0x45: return Qt::Key_E;
+ case 0x46: return Qt::Key_F;
+ case 0x47: return Qt::Key_G;
+ case 0x48: return Qt::Key_H;
+ case 0x49: return Qt::Key_I;
+ case 0x4a: return Qt::Key_J;
+ case 0x4b: return Qt::Key_K;
+ case 0x4c: return Qt::Key_L;
+ case 0x4d: return Qt::Key_M;
+ case 0x4e: return Qt::Key_N;
+ case 0x4f: return Qt::Key_O;
+ case 0x50: return Qt::Key_P;
+ case 0x51: return Qt::Key_Q;
+ case 0x52: return Qt::Key_R;
+ case 0x53: return Qt::Key_S;
+ case 0x54: return Qt::Key_T;
+ case 0x55: return Qt::Key_U;
+ case 0x56: return Qt::Key_V;
+ case 0x57: return Qt::Key_W;
+ case 0x58: return Qt::Key_X;
+ case 0x59: return Qt::Key_Y;
+ case 0x5a: return Qt::Key_Z;
+ case 0x5b: return Qt::Key_BracketLeft;
+ case 0x5c: return Qt::Key_Backslash;
+ case 0x5d: return Qt::Key_BracketRight;
+ case 0x5e: return Qt::Key_AsciiCircum;
+ case 0x5f: return Qt::Key_Underscore;
+ case 0x60: return Qt::Key_QuoteLeft;
+ case 0x61: return Qt::Key_A;
+ case 0x62: return Qt::Key_B;
+ case 0x63: return Qt::Key_C;
+ case 0x64: return Qt::Key_D;
+ case 0x65: return Qt::Key_E;
+ case 0x66: return Qt::Key_F;
+ case 0x67: return Qt::Key_G;
+ case 0x68: return Qt::Key_H;
+ case 0x69: return Qt::Key_I;
+ case 0x6a: return Qt::Key_J;
+ case 0x6b: return Qt::Key_K;
+ case 0x6c: return Qt::Key_L;
+ case 0x6d: return Qt::Key_M;
+ case 0x6e: return Qt::Key_N;
+ case 0x6f: return Qt::Key_O;
+ case 0x70: return Qt::Key_P;
+ case 0x71: return Qt::Key_Q;
+ case 0x72: return Qt::Key_R;
+ case 0x73: return Qt::Key_S;
+ case 0x74: return Qt::Key_T;
+ case 0x75: return Qt::Key_U;
+ case 0x76: return Qt::Key_V;
+ case 0x77: return Qt::Key_W;
+ case 0x78: return Qt::Key_X;
+ case 0x79: return Qt::Key_Y;
+ case 0x7a: return Qt::Key_Z;
+ case 0x7b: return Qt::Key_BraceLeft;
+ case 0x7c: return Qt::Key_Bar;
+ case 0x7d: return Qt::Key_BraceRight;
+ case 0x7e: return Qt::Key_AsciiTilde;
+
+ // Latin 1 codes adapted from X: keysymdef.h,v 1.21 94/08/28 16:17:06
+ case 0xa0: return Qt::Key_nobreakspace;
+ case 0xa1: return Qt::Key_exclamdown;
+ case 0xa2: return Qt::Key_cent;
+ case 0xa3: return Qt::Key_sterling;
+ case 0xa4: return Qt::Key_currency;
+ case 0xa5: return Qt::Key_yen;
+ case 0xa6: return Qt::Key_brokenbar;
+ case 0xa7: return Qt::Key_section;
+ case 0xa8: return Qt::Key_diaeresis;
+ case 0xa9: return Qt::Key_copyright;
+ case 0xaa: return Qt::Key_ordfeminine;
+ case 0xab: return Qt::Key_guillemotleft;
+ case 0xac: return Qt::Key_notsign;
+ case 0xad: return Qt::Key_hyphen;
+ case 0xae: return Qt::Key_registered;
+ case 0xaf: return Qt::Key_macron;
+ case 0xb0: return Qt::Key_degree;
+ case 0xb1: return Qt::Key_plusminus;
+ case 0xb2: return Qt::Key_twosuperior;
+ case 0xb3: return Qt::Key_threesuperior;
+ case 0xb4: return Qt::Key_acute;
+ case 0xb5: return Qt::Key_mu;
+ case 0xb6: return Qt::Key_paragraph;
+ case 0xb7: return Qt::Key_periodcentered;
+ case 0xb8: return Qt::Key_cedilla;
+ case 0xb9: return Qt::Key_onesuperior;
+ case 0xba: return Qt::Key_masculine;
+ case 0xbb: return Qt::Key_guillemotright;
+ case 0xbc: return Qt::Key_onequarter;
+ case 0xbd: return Qt::Key_onehalf;
+ case 0xbe: return Qt::Key_threequarters;
+ case 0xbf: return Qt::Key_questiondown;
+ case 0xc0: return Qt::Key_Agrave;
+ case 0xc1: return Qt::Key_Aacute;
+ case 0xc2: return Qt::Key_Acircumflex;
+ case 0xc3: return Qt::Key_Atilde;
+ case 0xc4: return Qt::Key_Adiaeresis;
+ case 0xc5: return Qt::Key_Aring;
+ case 0xc6: return Qt::Key_AE;
+ case 0xc7: return Qt::Key_Ccedilla;
+ case 0xc8: return Qt::Key_Egrave;
+ case 0xc9: return Qt::Key_Eacute;
+ case 0xca: return Qt::Key_Ecircumflex;
+ case 0xcb: return Qt::Key_Ediaeresis;
+ case 0xcc: return Qt::Key_Igrave;
+ case 0xcd: return Qt::Key_Iacute;
+ case 0xce: return Qt::Key_Icircumflex;
+ case 0xcf: return Qt::Key_Idiaeresis;
+ case 0xd0: return Qt::Key_ETH;
+ case 0xd1: return Qt::Key_Ntilde;
+ case 0xd2: return Qt::Key_Ograve;
+ case 0xd3: return Qt::Key_Oacute;
+ case 0xd4: return Qt::Key_Ocircumflex;
+ case 0xd5: return Qt::Key_Otilde;
+ case 0xd6: return Qt::Key_Odiaeresis;
+ case 0xd7: return Qt::Key_multiply;
+ case 0xd8: return Qt::Key_Ooblique;
+ case 0xd9: return Qt::Key_Ugrave;
+ case 0xda: return Qt::Key_Uacute;
+ case 0xdb: return Qt::Key_Ucircumflex;
+ case 0xdc: return Qt::Key_Udiaeresis;
+ case 0xdd: return Qt::Key_Yacute;
+ case 0xde: return Qt::Key_THORN;
+ case 0xdf: return Qt::Key_ssharp;
+ case 0xe5: return Qt::Key_Aring;
+ case 0xe6: return Qt::Key_AE;
+ case 0xf7: return Qt::Key_division;
+ case 0xf8: return Qt::Key_Ooblique;
+ case 0xff: return Qt::Key_ydiaeresis;
+ default: return Qt::Key(0);
+ }
+}
+
+/*! \internal
+ Convert a Qt Key to an ascii char value.
+ If the Qt key is unknown a 0 is returned.
+
+ Note: this may happen more than you like since not all known
+ Qt keys _are_ converted already. So feel free to add all the keys you need.
+*/
+char QtUiTest::keyToAscii(Qt::Key key)
+{
+ switch (key) {
+ case Qt::Key_Backspace: return 0x8; //BS
+ case Qt::Key_Tab: return 0x09; // HT
+ case Qt::Key_Backtab: return 0x0b; // VT
+ case Qt::Key_Enter:
+ case Qt::Key_Return: return 0x0d; // CR
+ case Qt::Key_Escape: return 0x1b; // ESC
+ case Qt::Key_Space: return 0x20; // 7 bit printable ASCII
+ case Qt::Key_Exclam: return 0x21;
+ case Qt::Key_QuoteDbl: return 0x22;
+ case Qt::Key_NumberSign: return 0x23;
+ case Qt::Key_Dollar: return 0x24;
+ case Qt::Key_Percent: return 0x25;
+ case Qt::Key_Ampersand: return 0x26;
+ case Qt::Key_Apostrophe: return 0x27;
+ case Qt::Key_ParenLeft: return 0x28;
+ case Qt::Key_ParenRight: return 0x29;
+ case Qt::Key_Asterisk: return 0x2a;
+ case Qt::Key_Plus: return 0x2b;
+ case Qt::Key_Comma: return 0x2c;
+ case Qt::Key_Minus: return 0x2d;
+ case Qt::Key_Period: return 0x2e;
+ case Qt::Key_Slash: return 0x2f;
+ case Qt::Key_0: return 0x30;
+ case Qt::Key_1: return 0x31;
+ case Qt::Key_2: return 0x32;
+ case Qt::Key_3: return 0x33;
+ case Qt::Key_4: return 0x34;
+ case Qt::Key_5: return 0x35;
+ case Qt::Key_6: return 0x36;
+ case Qt::Key_7: return 0x37;
+ case Qt::Key_8: return 0x38;
+ case Qt::Key_9: return 0x39;
+ case Qt::Key_Colon: return 0x3a;
+ case Qt::Key_Semicolon: return 0x3b;
+ case Qt::Key_Less: return 0x3c;
+ case Qt::Key_Equal: return 0x3d;
+ case Qt::Key_Greater: return 0x3e;
+ case Qt::Key_Question: return 0x3f;
+ case Qt::Key_At: return 0x40;
+ case Qt::Key_A: return 0x61; // 0x41 == 'A', 0x61 == 'a'
+ case Qt::Key_B: return 0x62;
+ case Qt::Key_C: return 0x63;
+ case Qt::Key_D: return 0x64;
+ case Qt::Key_E: return 0x65;
+ case Qt::Key_F: return 0x66;
+ case Qt::Key_G: return 0x67;
+ case Qt::Key_H: return 0x68;
+ case Qt::Key_I: return 0x69;
+ case Qt::Key_J: return 0x6a;
+ case Qt::Key_K: return 0x6b;
+ case Qt::Key_L: return 0x6c;
+ case Qt::Key_M: return 0x6d;
+ case Qt::Key_N: return 0x6e;
+ case Qt::Key_O: return 0x6f;
+ case Qt::Key_P: return 0x70;
+ case Qt::Key_Q: return 0x71;
+ case Qt::Key_R: return 0x72;
+ case Qt::Key_S: return 0x73;
+ case Qt::Key_T: return 0x74;
+ case Qt::Key_U: return 0x75;
+ case Qt::Key_V: return 0x76;
+ case Qt::Key_W: return 0x77;
+ case Qt::Key_X: return 0x78;
+ case Qt::Key_Y: return 0x79;
+ case Qt::Key_Z: return 0x7a;
+ case Qt::Key_BracketLeft: return 0x5b;
+ case Qt::Key_Backslash: return 0x5c;
+ case Qt::Key_BracketRight: return 0x5d;
+ case Qt::Key_AsciiCircum: return 0x5e;
+ case Qt::Key_Underscore: return 0x5f;
+ case Qt::Key_QuoteLeft: return 0x60;
+
+ case Qt::Key_BraceLeft: return 0x7b;
+ case Qt::Key_Bar: return 0x7c;
+ case Qt::Key_BraceRight: return 0x7d;
+ case Qt::Key_AsciiTilde: return 0x7e;
+
+ case Qt::Key_Delete: return 0;
+ case Qt::Key_Insert: return 0; // = 0x1006,
+ case Qt::Key_Pause: return 0; // = 0x1008,
+ case Qt::Key_Print: return 0; // = 0x1009,
+ case Qt::Key_SysReq: return 0; // = 0x100a,
+
+ case Qt::Key_Clear: return 0; // = 0x100b,
+
+ case Qt::Key_Home: return 0; // = 0x1010, // cursor movement
+ case Qt::Key_End: return 0; // = 0x1011,
+ case Qt::Key_Left: return 0; // = 0x1012,
+ case Qt::Key_Up: return 0; // = 0x1013,
+ case Qt::Key_Right: return 0; // = 0x1014,
+ case Qt::Key_Down: return 0; // = 0x1015,
+ case Qt::Key_PageUp: return 0; // = 0x1016,
+ case Qt::Key_PageDown: return 0; // = 0x1017,
+ case Qt::Key_Shift: return 0; // = 0x1020, // modifiers
+ case Qt::Key_Control: return 0; // = 0x1021,
+ case Qt::Key_Meta: return 0; // = 0x1022,
+ case Qt::Key_Alt: return 0; // = 0x1023,
+ case Qt::Key_CapsLock: return 0; // = 0x1024,
+ case Qt::Key_NumLock: return 0; // = 0x1025,
+ case Qt::Key_ScrollLock: return 0; // = 0x1026,
+ case Qt::Key_F1: return 0; // = 0x1030, // function keys
+ case Qt::Key_F2: return 0; // = 0x1031,
+ case Qt::Key_F3: return 0; // = 0x1032,
+ case Qt::Key_F4: return 0; // = 0x1033,
+ case Qt::Key_F5: return 0; // = 0x1034,
+ case Qt::Key_F6: return 0; // = 0x1035,
+ case Qt::Key_F7: return 0; // = 0x1036,
+ case Qt::Key_F8: return 0; // = 0x1037,
+ case Qt::Key_F9: return 0; // = 0x1038,
+ case Qt::Key_F10: return 0; // = 0x1039,
+ case Qt::Key_F11: return 0; // = 0x103a,
+ case Qt::Key_F12: return 0; // = 0x103b,
+ case Qt::Key_F13: return 0; // = 0x103c,
+ case Qt::Key_F14: return 0; // = 0x103d,
+ case Qt::Key_F15: return 0; // = 0x103e,
+ case Qt::Key_F16: return 0; // = 0x103f,
+ case Qt::Key_F17: return 0; // = 0x1040,
+ case Qt::Key_F18: return 0; // = 0x1041,
+ case Qt::Key_F19: return 0; // = 0x1042,
+ case Qt::Key_F20: return 0; // = 0x1043,
+ case Qt::Key_F21: return 0; // = 0x1044,
+ case Qt::Key_F22: return 0; // = 0x1045,
+ case Qt::Key_F23: return 0; // = 0x1046,
+ case Qt::Key_F24: return 0; // = 0x1047,
+ case Qt::Key_F25: return 0; // = 0x1048, // F25 .. F35 only on X11
+ case Qt::Key_F26: return 0; // = 0x1049,
+ case Qt::Key_F27: return 0; // = 0x104a,
+ case Qt::Key_F28: return 0; // = 0x104b,
+ case Qt::Key_F29: return 0; // = 0x104c,
+ case Qt::Key_F30: return 0; // = 0x104d,
+ case Qt::Key_F31: return 0; // = 0x104e,
+ case Qt::Key_F32: return 0; // = 0x104f,
+ case Qt::Key_F33: return 0; // = 0x1050,
+ case Qt::Key_F34: return 0; // = 0x1051,
+ case Qt::Key_F35: return 0; // = 0x1052,
+ case Qt::Key_Super_L: return 0; // = 0x1053, // extra keys
+ case Qt::Key_Super_R: return 0; // = 0x1054,
+ case Qt::Key_Menu: return 0; // = 0x1055,
+ case Qt::Key_Hyper_L: return 0; // = 0x1056,
+ case Qt::Key_Hyper_R: return 0; // = 0x1057,
+ case Qt::Key_Help: return 0; // = 0x1058,
+ case Qt::Key_Direction_L: return 0; // = 0x1059,
+ case Qt::Key_Direction_R: return 0; // = 0x1060,
+
+ // Latin 1 codes adapted from X: keysymdef.h,v 1.21 94/08/28 16:17:06
+ case Qt::Key_nobreakspace: return char(0xa0);
+ case Qt::Key_exclamdown: return char(0xa1);
+ case Qt::Key_cent: return char(0xa2);
+ case Qt::Key_sterling: return char(0xa3);
+ case Qt::Key_currency: return char(0xa4);
+ case Qt::Key_yen: return char(0xa5);
+ case Qt::Key_brokenbar: return char(0xa6);
+ case Qt::Key_section: return char(0xa7);
+ case Qt::Key_diaeresis: return char(0xa8);
+ case Qt::Key_copyright: return char(0xa9);
+ case Qt::Key_ordfeminine: return char(0xaa);
+ case Qt::Key_guillemotleft: return char(0xab); // left angle quotation mar
+ case Qt::Key_notsign: return char(0xac);
+ case Qt::Key_hyphen: return char(0xad);
+ case Qt::Key_registered: return char(0xae);
+ case Qt::Key_macron: return char(0xaf);
+ case Qt::Key_degree: return char(0xb0);
+ case Qt::Key_plusminus: return char(0xb1);
+ case Qt::Key_twosuperior: return char(0xb2);
+ case Qt::Key_threesuperior: return char(0xb3);
+ case Qt::Key_acute: return char(0xb4);
+ case Qt::Key_mu: return char(0xb5);
+ case Qt::Key_paragraph: return char(0xb6);
+ case Qt::Key_periodcentered: return char(0xb7);
+ case Qt::Key_cedilla: return char(0xb8);
+ case Qt::Key_onesuperior: return char(0xb9);
+ case Qt::Key_masculine: return char(0xba);
+ case Qt::Key_guillemotright: return char(0xbb); // right angle quotation mar
+ case Qt::Key_onequarter: return char(0xbc);
+ case Qt::Key_onehalf: return char(0xbd);
+ case Qt::Key_threequarters: return char(0xbe);
+ case Qt::Key_questiondown: return char(0xbf);
+ case Qt::Key_Agrave: return char(0xc0);
+ case Qt::Key_Aacute: return char(0xc1);
+ case Qt::Key_Acircumflex: return char(0xc2);
+ case Qt::Key_Atilde: return char(0xc3);
+ case Qt::Key_Adiaeresis: return char(0xc4);
+ case Qt::Key_Aring: return char(0xe5);
+ case Qt::Key_AE: return char(0xe6);
+ case Qt::Key_Ccedilla: return char(0xc7);
+ case Qt::Key_Egrave: return char(0xc8);
+ case Qt::Key_Eacute: return char(0xc9);
+ case Qt::Key_Ecircumflex: return char(0xca);
+ case Qt::Key_Ediaeresis: return char(0xcb);
+ case Qt::Key_Igrave: return char(0xcc);
+ case Qt::Key_Iacute: return char(0xcd);
+ case Qt::Key_Icircumflex: return char(0xce);
+ case Qt::Key_Idiaeresis: return char(0xcf);
+ case Qt::Key_ETH: return char(0xd0);
+ case Qt::Key_Ntilde: return char(0xd1);
+ case Qt::Key_Ograve: return char(0xd2);
+ case Qt::Key_Oacute: return char(0xd3);
+ case Qt::Key_Ocircumflex: return char(0xd4);
+ case Qt::Key_Otilde: return char(0xd5);
+ case Qt::Key_Odiaeresis: return char(0xd6);
+ case Qt::Key_multiply: return char(0xd7);
+ case Qt::Key_Ooblique: return char(0xf8);
+ case Qt::Key_Ugrave: return char(0xd9);
+ case Qt::Key_Uacute: return char(0xda);
+ case Qt::Key_Ucircumflex: return char(0xdb);
+ case Qt::Key_Udiaeresis: return char(0xdc);
+ case Qt::Key_Yacute: return char(0xdd);
+ case Qt::Key_THORN: return char(0xde);
+ case Qt::Key_ssharp: return char(0xdf);
+ case Qt::Key_division: return char(0xf7);
+ case Qt::Key_ydiaeresis: return char(0xff);
+
+ // multimedia/internet keys - ignored by default - see QKeyEvent c'tor
+
+ case Qt::Key_Back : return 0; // = 0x1061,
+ case Qt::Key_Forward : return 0; // = 0x1062,
+ case Qt::Key_Stop : return 0; // = 0x1063,
+ case Qt::Key_Refresh : return 0; // = 0x1064,
+
+ case Qt::Key_VolumeDown: return 0; // = 0x1070,
+ case Qt::Key_VolumeMute : return 0; // = 0x1071,
+ case Qt::Key_VolumeUp: return 0; // = 0x1072,
+ case Qt::Key_BassBoost: return 0; // = 0x1073,
+ case Qt::Key_BassUp: return 0; // = 0x1074,
+ case Qt::Key_BassDown: return 0; // = 0x1075,
+ case Qt::Key_TrebleUp: return 0; // = 0x1076,
+ case Qt::Key_TrebleDown: return 0; // = 0x1077,
+
+ case Qt::Key_MediaPlay : return 0; // = 0x1080,
+ case Qt::Key_MediaStop : return 0; // = 0x1081,
+ case Qt::Key_MediaPrevious : return 0; // = 0x1082,
+ case Qt::Key_MediaNext : return 0; // = 0x1083,
+ case Qt::Key_MediaRecord: return 0; // = 0x1084,
+
+ case Qt::Key_HomePage : return 0; // = 0x1090,
+ case Qt::Key_Favorites : return 0; // = 0x1091,
+ case Qt::Key_Search : return 0; // = 0x1092,
+ case Qt::Key_Standby: return 0; // = 0x1093,
+ case Qt::Key_OpenUrl: return 0; // = 0x1094,
+
+ case Qt::Key_LaunchMail : return 0; // = 0x10a0,
+ case Qt::Key_LaunchMedia: return 0; // = 0x10a1,
+ case Qt::Key_Launch0 : return 0; // = 0x10a2,
+ case Qt::Key_Launch1 : return 0; // = 0x10a3,
+ case Qt::Key_Launch2 : return 0; // = 0x10a4,
+ case Qt::Key_Launch3 : return 0; // = 0x10a5,
+ case Qt::Key_Launch4 : return 0; // = 0x10a6,
+ case Qt::Key_Launch5 : return 0; // = 0x10a7,
+ case Qt::Key_Launch6 : return 0; // = 0x10a8,
+ case Qt::Key_Launch7 : return 0; // = 0x10a9,
+ case Qt::Key_Launch8 : return 0; // = 0x10aa,
+ case Qt::Key_Launch9 : return 0; // = 0x10ab,
+ case Qt::Key_LaunchA : return 0; // = 0x10ac,
+ case Qt::Key_LaunchB : return 0; // = 0x10ad,
+ case Qt::Key_LaunchC : return 0; // = 0x10ae,
+ case Qt::Key_LaunchD : return 0; // = 0x10af,
+ case Qt::Key_LaunchE : return 0; // = 0x10b0,
+ case Qt::Key_LaunchF : return 0; // = 0x10b1,
+
+ default: return 0;
+ }
+}
+
+/*! \internal
+ Convert an variant value to a Qt Key value.
+ If the key is unknown a 0 is returned.
+ */
+
+Qt::Key QtUiTest::variantToKey(const QVariant &keyValue)
+{
+ Qt::Key key = (Qt::Key)0;
+ switch(keyValue.type()) {
+ default:
+ key = (Qt::Key)keyValue.toInt();
+ break;
+ case QVariant::Char:
+ key = QtUiTest::asciiToKey(keyValue.toChar().toAscii());
+ break;
+ case QVariant::String:
+ if (keyValue.toString().length() == 1)
+ key = QtUiTest::asciiToKey(keyValue.toString()[0].toAscii());
+ break;
+ }
+ return key;
+}
diff --git a/src/remote/slave/lib/qeventwatcher.cpp b/src/remote/slave/lib/qeventwatcher.cpp
new file mode 100644
index 0000000..4092a07
--- /dev/null
+++ b/src/remote/slave/lib/qeventwatcher.cpp
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "qeventwatcher_p.h"
+
+#include <QSet>
+#include <QPointer>
+#include <QCoreApplication>
+#include <QtSystemTest/QstDebug>
+
+struct QEventWatcherPrivate
+{
+ QSet<QObject*> objects;
+ QList<QEventWatcherFilter*> filters;
+ int count;
+};
+
+QEventWatcher::QEventWatcher(QObject* parent)
+ : QObject(parent),
+ d(new QEventWatcherPrivate)
+{
+ QTT_TRACE_FUNCTION();
+ d->count = 0;
+}
+
+QEventWatcher::~QEventWatcher()
+{
+ QTT_TRACE_FUNCTION();
+ qDeleteAll(d->filters);
+ delete d;
+ d = 0;
+}
+
+void QEventWatcher::addObject(QObject* obj)
+{
+ QTT_TRACE_FUNCTION();
+ d->objects << obj;
+ qApp->installEventFilter(this);
+}
+
+void QEventWatcher::addFilter(QEventWatcherFilter* filter)
+{
+ QTT_TRACE_FUNCTION();
+ d->filters << filter;
+}
+
+int QEventWatcher::count() const
+{
+ QTT_TRACE_FUNCTION();
+ return d->count;
+}
+
+QString QEventWatcher::toString() const
+{
+ QTT_TRACE_FUNCTION();
+ QString ret;
+ QString sep;
+ for (int i = d->filters.count()-1; i >= 0; --i) {
+ ret += sep + d->filters.at(i)->toString();
+ sep = ", ";
+ }
+ return ret;
+}
+
+bool QEventWatcher::eventFilter(QObject* obj, QEvent* e)
+{
+ QTT_TRACE_FUNCTION();
+ if (!d->objects.contains(obj)) return false;
+
+ bool accept = (d->filters.count() ? false : true);
+ for (int i = d->filters.count()-1; i >= 0 && !accept; --i) {
+ accept = d->filters.at(i)->accept(obj,e);
+ }
+
+ if (accept) {
+ ++d->count;
+ emit event(obj, e->type());
+ }
+
+ return false;
+}
+
diff --git a/src/remote/slave/lib/qeventwatcher_p.h b/src/remote/slave/lib/qeventwatcher_p.h
new file mode 100644
index 0000000..c6e6809
--- /dev/null
+++ b/src/remote/slave/lib/qeventwatcher_p.h
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QEVENTWATCHER_H
+#define QEVENTWATCHER_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtUiTest API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QObject>
+#include <QEvent>
+
+struct QEventWatcherPrivate;
+class QEventWatcherFilter;
+
+class QEventWatcher : public QObject
+{
+ Q_OBJECT
+
+public:
+ explicit QEventWatcher(QObject* parent =0);
+ virtual ~QEventWatcher();
+
+ void addObject(QObject*);
+ void addFilter(QEventWatcherFilter*);
+
+ int count() const;
+
+ QString toString() const;
+
+signals:
+ void event(QObject*,int);
+
+protected:
+ bool eventFilter(QObject *obj, QEvent *event);
+
+private:
+ QEventWatcherPrivate* d;
+};
+
+class QEventWatcherFilter
+{
+public:
+ virtual ~QEventWatcherFilter() {}
+
+protected:
+ virtual bool accept(QObject*,QEvent*) const =0;
+ virtual QString toString() const =0;
+
+ friend class QEventWatcher;
+};
+
+#endif
+
diff --git a/src/remote/slave/lib/qinputgenerator.cpp b/src/remote/slave/lib/qinputgenerator.cpp
new file mode 100644
index 0000000..c97ca24
--- /dev/null
+++ b/src/remote/slave/lib/qinputgenerator.cpp
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "qinputgenerator_p.h"
+
+#include <QPoint>
+#include <QtSystemTest/QstDebug>
+
+QInputGenerator::QInputGenerator(QObject* parent)
+ : QObject(parent)
+{
+ QTT_TRACE_FUNCTION();
+}
+
+QInputGenerator::~QInputGenerator()
+{
+ QTT_TRACE_FUNCTION();
+}
+
+void QInputGenerator::keyPress (Qt::Key, Qt::KeyboardModifiers, bool) {};
+void QInputGenerator::keyRelease(Qt::Key, Qt::KeyboardModifiers) {};
+void QInputGenerator::keyClick (Qt::Key, Qt::KeyboardModifiers) {};
+
+void QInputGenerator::touchPress (const QVariantList&) {};
+void QInputGenerator::touchUpdate (const QVariantList&) {};
+void QInputGenerator::touchRelease (const QVariantList&) {};
+
+void QInputGenerator::mousePress (const QPoint&, Qt::MouseButtons) {};
+void QInputGenerator::mouseRelease(const QPoint&, Qt::MouseButtons) {};
+void QInputGenerator::mouseClick (const QPoint&, Qt::MouseButtons) {};
+void QInputGenerator::mouseDClick (const QPoint&, Qt::MouseButtons) {};
+void QInputGenerator::mouseMove (const QPoint&) {};
+
+
+Qt::KeyboardModifier const QInputGenerator::AllModifiers[] =
+ { Qt::ShiftModifier, Qt::ControlModifier, Qt::AltModifier, Qt::MetaModifier };
+
+Qt::Key QInputGenerator::modifierToKey(Qt::KeyboardModifier mod)
+{
+ QTT_TRACE_FUNCTION();
+ switch (mod) {
+ case Qt::ShiftModifier:
+ return Qt::Key_Shift;
+ case Qt::ControlModifier:
+ return Qt::Key_Control;
+ case Qt::AltModifier:
+ return Qt::Key_Alt;
+ case Qt::MetaModifier:
+ return Qt::Key_Meta;
+ default:
+ break;
+ }
+ return Qt::Key(0);
+}
diff --git a/src/remote/slave/lib/qinputgenerator_generic.cpp b/src/remote/slave/lib/qinputgenerator_generic.cpp
new file mode 100644
index 0000000..dd616ed
--- /dev/null
+++ b/src/remote/slave/lib/qinputgenerator_generic.cpp
@@ -0,0 +1,192 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "qinputgenerator_generic_p.h"
+#include "qtuitestnamespace.h"
+
+static QWidget *focusWidget()
+{
+ QTT_TRACE_FUNCTION();
+ QWidget *ret = QApplication::focusWidget();
+ if (!ret) {
+ QWidgetList topLevel = QApplication::topLevelWidgets();
+ if (!topLevel.isEmpty())
+ return topLevel.first();
+ }
+ return ret;
+}
+
+QInputGeneratorGeneric::QInputGeneratorGeneric(QObject* parent)
+ : QInputGenerator(parent),
+ currentPos(),
+ currentButtons(0)
+{
+ QTT_TRACE_FUNCTION();
+}
+
+QInputGeneratorGeneric::~QInputGeneratorGeneric()
+{
+ QTT_TRACE_FUNCTION();
+}
+
+void QInputGeneratorGeneric::keyPress(Qt::Key key, Qt::KeyboardModifiers mod, bool autoRepeat)
+{
+ QTT_TRACE_FUNCTION();
+ qttDebug() << "keyPress" << key << mod << autoRepeat;
+ Q_UNUSED(autoRepeat);
+ keyEvent(Press, focusWidget(), key, mod);
+}
+
+void QInputGeneratorGeneric::keyRelease(Qt::Key key, Qt::KeyboardModifiers mod)
+{
+ QTT_TRACE_FUNCTION();
+ qttDebug() << "keyRelease" << key << mod;
+ keyEvent(Release, focusWidget(), key, mod);
+}
+
+void QInputGeneratorGeneric::keyClick(Qt::Key key, Qt::KeyboardModifiers mod)
+{
+ QTT_TRACE_FUNCTION();
+ qttDebug() << "keyClick" << key << mod;
+ keyEvent(Click, focusWidget(), key, mod);
+}
+
+void QInputGeneratorGeneric::touchPress(const QVariantList& points)
+{
+ Q_UNUSED(points);
+ QTT_TRACE_FUNCTION();
+}
+
+void QInputGeneratorGeneric::touchUpdate(const QVariantList& points)
+{
+ Q_UNUSED(points);
+ QTT_TRACE_FUNCTION();
+}
+
+void QInputGeneratorGeneric::touchRelease(const QVariantList& points)
+{
+ Q_UNUSED(points);
+ QTT_TRACE_FUNCTION();
+}
+
+void QInputGeneratorGeneric::mousePress(const QPoint& pos, Qt::MouseButtons state)
+{
+ QTT_TRACE_FUNCTION();
+ const Qt::MouseButton buttons[] = {Qt::LeftButton, Qt::RightButton, Qt::MidButton, Qt::XButton1, Qt::XButton2};
+ QWidget *widget=QApplication::widgetAt(pos);
+ if (pos != currentPos) {
+ mouseEvent(MouseMove, widget, Qt::NoButton, currentButtons, 0, widget->mapFromGlobal(pos));
+ currentPos = pos;
+ }
+ for (unsigned int i=0; i<sizeof(buttons)/sizeof(Qt::MouseButton); i++) {
+ if (state.testFlag(buttons[i])) {
+ qttDebug() << "mousePress" << pos << buttons[i] << currentButtons;
+ currentButtons |= buttons[i];
+ mouseEvent(MousePress, widget, buttons[i], buttons[i], 0, widget->mapFromGlobal(pos));
+ }
+ }
+}
+
+void QInputGeneratorGeneric::mouseRelease(const QPoint& pos, Qt::MouseButtons state)
+{
+ QTT_TRACE_FUNCTION();
+ const Qt::MouseButton buttons[] = {Qt::LeftButton, Qt::RightButton, Qt::MidButton, Qt::XButton1, Qt::XButton2};
+ QWidget *widget=QApplication::widgetAt(pos);
+ qttDebug() << "widget:" << widget;
+ if (pos != currentPos) {
+ mouseEvent(MouseMove, widget, Qt::NoButton, currentButtons, 0, widget->mapFromGlobal(pos));
+ currentPos = pos;
+ }
+ for (unsigned int i=0; i<sizeof(buttons)/sizeof(Qt::MouseButton); i++) {
+ if (state.testFlag(buttons[i])) {
+ qttDebug() << "mouseRelease" << pos << buttons[i] << currentButtons;
+ currentButtons ^= buttons[i];
+ mouseEvent(MouseRelease, widget, buttons[i], currentButtons, 0, widget->mapFromGlobal(pos));
+ }
+ }
+}
+
+void QInputGeneratorGeneric::mouseClick(const QPoint& pos, Qt::MouseButtons state)
+{
+ QTT_TRACE_FUNCTION();
+ const Qt::MouseButton buttons[] = {Qt::LeftButton, Qt::RightButton, Qt::MidButton, Qt::XButton1, Qt::XButton2};
+ QWidget *widget=QApplication::widgetAt(pos);
+ if (pos != currentPos) {
+ mouseEvent(MouseMove, widget, Qt::NoButton, currentButtons, 0, widget->mapFromGlobal(pos));
+ currentPos = pos;
+ }
+ for (unsigned int i=0; i<sizeof(buttons)/sizeof(Qt::MouseButton); i++) {
+ if (state.testFlag(buttons[i])) {
+ qttDebug() << "mouseClick" << pos << buttons[i];
+ mouseEvent(MouseClick, widget, buttons[i], state, 0, widget->mapFromGlobal(pos));
+ }
+ }
+}
+
+void QInputGeneratorGeneric::mouseDClick(const QPoint& pos, Qt::MouseButtons state)
+{
+ QTT_TRACE_FUNCTION();
+ const Qt::MouseButton buttons[] = {Qt::LeftButton, Qt::RightButton, Qt::MidButton, Qt::XButton1, Qt::XButton2};
+ QWidget *widget=QApplication::widgetAt(pos);
+ if (pos != currentPos) {
+ mouseEvent(MouseMove, widget, Qt::NoButton, currentButtons, 0, widget->mapFromGlobal(pos));
+ currentPos = pos;
+ }
+ for (unsigned int i=0; i<sizeof(buttons)/sizeof(Qt::MouseButton); i++) {
+ if (state.testFlag(buttons[i])) {
+ qttDebug() << "mouseClick" << pos << buttons[i];
+ mouseEvent(MouseDClick, widget, buttons[i], state, 0, widget->mapFromGlobal(pos));
+ }
+ }
+}
+
+void QInputGeneratorGeneric::mouseMove(const QPoint& pos)
+{
+ QTT_TRACE_FUNCTION();
+ qttDebug() << "mouseMove" << pos;
+ QWidget *widget=QApplication::widgetAt(pos);
+ if (pos != currentPos) {
+ currentPos = pos;
+ }
+ mouseEvent(MouseMove, widget, Qt::NoButton, currentButtons, 0, widget->mapFromGlobal(pos));
+}
+
diff --git a/src/remote/slave/lib/qinputgenerator_generic_p.h b/src/remote/slave/lib/qinputgenerator_generic_p.h
new file mode 100644
index 0000000..a44de33
--- /dev/null
+++ b/src/remote/slave/lib/qinputgenerator_generic_p.h
@@ -0,0 +1,236 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QINPUTGENERATORGENERIC_P_H
+#define QINPUTGENERATORGENERIC_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtUiTest API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtGlobal>
+#include <QWidget>
+#include <QMouseEvent>
+#include <QPoint>
+#include <QPointer>
+#include <QApplication>
+#include <QtSystemTest/qstglobal.h>
+#include <qinputgenerator_p.h>
+#include <QtSystemTest/QstDebug>
+#include <QtTest/qtestspontaneevent.h>
+
+enum MouseAction { MousePress, MouseRelease, MouseClick, MouseDClick, MouseMove };
+
+static void mouseEvent(MouseAction action, QWidget *widget, Qt::MouseButton button, Qt::MouseButtons buttons,
+ Qt::KeyboardModifiers stateKey, QPoint pos)
+{
+ QTT_TRACE_FUNCTION();
+ if (pos.isNull())
+ pos = widget->rect().center();
+
+ if (action == MouseClick) {
+ mouseEvent(MousePress, widget, button, buttons, stateKey, pos);
+ mouseEvent(MouseRelease, widget, button, 0, stateKey, pos);
+ return;
+ }
+
+ stateKey &= static_cast<unsigned int>(Qt::KeyboardModifierMask);
+
+ QMouseEvent me(QEvent::User, QPoint(), Qt::LeftButton, button, stateKey);
+ switch (action)
+ {
+ case MousePress:
+ me = QMouseEvent(QEvent::MouseButtonPress, pos, widget->mapToGlobal(pos), button, buttons, stateKey);
+ break;
+ case MouseRelease:
+ me = QMouseEvent(QEvent::MouseButtonRelease, pos, widget->mapToGlobal(pos), button, buttons, stateKey);
+ break;
+ case MouseDClick:
+ me = QMouseEvent(QEvent::MouseButtonDblClick, pos, widget->mapToGlobal(pos), button, buttons, stateKey);
+ break;
+ case MouseMove:
+ me = QMouseEvent(QEvent::MouseMove, pos, widget->mapToGlobal(pos), Qt::NoButton, buttons, stateKey);
+ break;
+ default:
+ break;
+ }
+ QSpontaneKeyEvent::setSpontaneous(&me);
+ if (!qApp->notify(widget, &me)) {
+ static const char *mouseActionNames[] =
+ { "MousePress", "MouseRelease", "MouseClick", "MouseDClick", "MouseMove" };
+ QString warning = QString::fromLatin1("Mouse event \"%1\" not accepted by receiving widget");
+ qWarning() << warning.arg(QString::fromLatin1(mouseActionNames[static_cast<int>(action)]));
+ }
+
+}
+
+enum KeyAction { Press, Release, Click };
+
+static void simulateEvent(QWidget *widget, bool press, int code,
+ Qt::KeyboardModifiers modifier, QString text, bool repeat)
+{
+ QTT_TRACE_FUNCTION();
+ QKeyEvent a(press ? QEvent::KeyPress : QEvent::KeyRelease, code, modifier, text, repeat);
+ QSpontaneKeyEvent::setSpontaneous(&a);
+ if (!qApp->notify(widget, &a))
+ qWarning() << "Keyboard event not accepted by receiving widget";
+}
+
+static void sendKeyEvent(KeyAction action, QWidget *widget, Qt::Key code,
+ QString text, Qt::KeyboardModifiers modifier)
+{
+ QTT_TRACE_FUNCTION();
+ if (!widget)
+ widget = QWidget::keyboardGrabber();
+ if (!widget) {
+ if (QWidget *apw = QApplication::activePopupWidget())
+ widget = apw->focusWidget() ? apw->focusWidget() : apw;
+ else
+ widget = QApplication::focusWidget();
+ }
+ if (!widget)
+ widget = QApplication::activeWindow();
+
+ if (action == Click) {
+ QPointer<QWidget> ptr(widget);
+ sendKeyEvent(Press, widget, code, text, modifier);
+ if (!ptr) {
+ // if we send key-events to embedded widgets, they might be destroyed
+ // when the user presses Return
+ return;
+ }
+ sendKeyEvent(Release, widget, code, text, modifier);
+ return;
+ }
+
+ bool repeat = false;
+
+ if (action == Press) {
+ if (modifier & Qt::ShiftModifier)
+ simulateEvent(widget, true, Qt::Key_Shift, 0, QString(), false);
+
+ if (modifier & Qt::ControlModifier)
+ simulateEvent(widget, true, Qt::Key_Control, modifier & Qt::ShiftModifier, QString(), false);
+
+ if (modifier & Qt::AltModifier)
+ simulateEvent(widget, true, Qt::Key_Alt,
+ modifier & (Qt::ShiftModifier | Qt::ControlModifier), QString(), false);
+ if (modifier & Qt::MetaModifier)
+ simulateEvent(widget, true, Qt::Key_Meta, modifier & (Qt::ShiftModifier
+ | Qt::ControlModifier | Qt::AltModifier), QString(), false);
+ simulateEvent(widget, true, code, modifier, text, repeat);
+ } else if (action == Release) {
+ simulateEvent(widget, false, code, modifier, text, repeat);
+
+ if (modifier & Qt::MetaModifier)
+ simulateEvent(widget, false, Qt::Key_Meta, modifier, QString(), false);
+ if (modifier & Qt::AltModifier)
+ simulateEvent(widget, false, Qt::Key_Alt, modifier &
+ (Qt::ShiftModifier | Qt::ControlModifier | Qt::AltModifier), QString(), false);
+
+ if (modifier & Qt::ControlModifier)
+ simulateEvent(widget, false, Qt::Key_Control,
+ modifier & (Qt::ShiftModifier | Qt::ControlModifier), QString(), false);
+
+ if (modifier & Qt::ShiftModifier)
+ simulateEvent(widget, false, Qt::Key_Shift, modifier & Qt::ShiftModifier, QString(), false);
+ }
+}
+
+// Convenience function
+static void sendKeyEvent(KeyAction action, QWidget *widget, Qt::Key code,
+ char ascii, Qt::KeyboardModifiers modifier)
+{
+ QTT_TRACE_FUNCTION();
+ QString text;
+ if (ascii)
+ text = QString(QChar::fromLatin1(ascii));
+ sendKeyEvent(action, widget, code, text, modifier);
+}
+
+inline static void keyEvent(KeyAction action, QWidget *widget, Qt::Key key,
+ Qt::KeyboardModifiers modifier = Qt::NoModifier)
+{
+ QTT_TRACE_FUNCTION();
+ if (modifier & Qt::ShiftModifier)
+ sendKeyEvent(action, widget, key, QChar(key).toUpper().unicode(), modifier);
+ else
+ sendKeyEvent(action, widget, key, QChar(key).toLower().unicode(), modifier);
+}
+
+
+class QTUITEST_EXPORT QInputGeneratorGeneric : public QInputGenerator
+{
+Q_OBJECT
+public:
+ explicit QInputGeneratorGeneric(QObject* =0);
+ virtual ~QInputGeneratorGeneric();
+
+ virtual void keyPress (Qt::Key, Qt::KeyboardModifiers, bool=false);
+ virtual void keyRelease(Qt::Key, Qt::KeyboardModifiers);
+ virtual void keyClick (Qt::Key, Qt::KeyboardModifiers);
+
+ virtual void touchPress (const QVariantList&);
+ virtual void touchUpdate (const QVariantList&);
+ virtual void touchRelease(const QVariantList&);
+
+ virtual void mousePress (const QPoint&, Qt::MouseButtons);
+ virtual void mouseRelease(const QPoint&, Qt::MouseButtons);
+ virtual void mouseClick (const QPoint&, Qt::MouseButtons);
+ virtual void mouseDClick (const QPoint&, Qt::MouseButtons);
+ virtual void mouseMove (const QPoint&);
+
+protected:
+ QPoint currentPos;
+ Qt::MouseButtons currentButtons;
+
+};
+
+#endif
+
diff --git a/src/remote/slave/lib/qinputgenerator_p.h b/src/remote/slave/lib/qinputgenerator_p.h
new file mode 100644
index 0000000..26df042
--- /dev/null
+++ b/src/remote/slave/lib/qinputgenerator_p.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QKEYGENERATOR_P_H
+#define QKEYGENERATOR_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtUiTest API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtGlobal>
+#include <QObject>
+#include <QVariantList>
+#include <QtSystemTest/qstglobal.h>
+
+class QPoint;
+class QInputGeneratorPrivate;
+
+class QTUITEST_EXPORT QInputGenerator : public QObject
+{
+Q_OBJECT
+public:
+ explicit QInputGenerator(QObject* =0);
+ virtual ~QInputGenerator();
+
+ virtual void keyPress (Qt::Key, Qt::KeyboardModifiers, bool=false);
+ virtual void keyRelease(Qt::Key, Qt::KeyboardModifiers);
+ virtual void keyClick (Qt::Key, Qt::KeyboardModifiers);
+
+ virtual void touchPress (const QVariantList&);
+ virtual void touchUpdate (const QVariantList&);
+ virtual void touchRelease(const QVariantList&);
+
+ virtual void mousePress (const QPoint&, Qt::MouseButtons);
+ virtual void mouseRelease(const QPoint&, Qt::MouseButtons);
+ virtual void mouseClick (const QPoint&, Qt::MouseButtons);
+ virtual void mouseDClick (const QPoint&, Qt::MouseButtons);
+ virtual void mouseMove (const QPoint&);
+
+protected:
+ QInputGeneratorPrivate* d;
+ friend class QInputGeneratorPrivate;
+
+ static Qt::Key modifierToKey(Qt::KeyboardModifier);
+ static Qt::KeyboardModifier const AllModifiers[4];
+};
+
+#endif
+
diff --git a/src/remote/slave/lib/qinputgenerator_qwindow.cpp b/src/remote/slave/lib/qinputgenerator_qwindow.cpp
new file mode 100644
index 0000000..155e9c2
--- /dev/null
+++ b/src/remote/slave/lib/qinputgenerator_qwindow.cpp
@@ -0,0 +1,193 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "qinputgenerator_qwindow_p.h"
+#include "qtuitestnamespace.h"
+
+static QWindow *activeWindow()
+{
+ QTT_TRACE_FUNCTION();
+ QWindow *w=0;
+ if (!qApp->topLevelWindows().isEmpty())
+ w = qApp->topLevelWindows().first();
+
+ return w;
+}
+
+QInputGeneratorGeneric::QInputGeneratorGeneric(QObject* parent)
+ : QInputGenerator(parent),
+ currentPos(),
+ currentButtons(0)
+{
+ QTT_TRACE_FUNCTION();
+}
+
+QInputGeneratorGeneric::~QInputGeneratorGeneric()
+{
+ QTT_TRACE_FUNCTION();
+}
+
+void QInputGeneratorGeneric::keyPress(Qt::Key key, Qt::KeyboardModifiers mod, bool autoRepeat)
+{
+ QTT_TRACE_FUNCTION();
+ qttDebug() << "keyPress" << key << mod << autoRepeat;
+ Q_UNUSED(autoRepeat);
+ keyEvent(Press, activeWindow(), key, mod);
+}
+
+void QInputGeneratorGeneric::keyRelease(Qt::Key key, Qt::KeyboardModifiers mod)
+{
+ QTT_TRACE_FUNCTION();
+ qttDebug() << "keyRelease" << key << mod;
+ keyEvent(Release, activeWindow(), key, mod);
+}
+
+void QInputGeneratorGeneric::keyClick(Qt::Key key, Qt::KeyboardModifiers mod)
+{
+ QTT_TRACE_FUNCTION();
+ qttDebug() << "keyClick" << key << mod;
+ keyEvent(Click, activeWindow(), key, mod);
+}
+
+void QInputGeneratorGeneric::touchPress(const QVariantList& points)
+{
+ QTT_TRACE_FUNCTION();
+ QWindow *window=activeWindow();
+
+ touchEvent(TouchPress, window, points);
+}
+
+void QInputGeneratorGeneric::touchUpdate(const QVariantList& points)
+{
+ QTT_TRACE_FUNCTION();
+ QWindow *window=activeWindow();
+ touchEvent(TouchUpdate, window, points);
+}
+
+void QInputGeneratorGeneric::touchRelease(const QVariantList& points)
+{
+ QTT_TRACE_FUNCTION();
+ QWindow *window=activeWindow();
+ touchEvent(TouchRelease, window, points);
+}
+
+void QInputGeneratorGeneric::mousePress(const QPoint& pos, Qt::MouseButtons state)
+{
+ QTT_TRACE_FUNCTION();
+ const Qt::MouseButton buttons[] = {Qt::LeftButton, Qt::RightButton, Qt::MidButton, Qt::XButton1, Qt::XButton2};
+ QWindow *window=activeWindow();
+ if (pos != currentPos) {
+ mouseEvent(MouseMove, window, Qt::NoButton, currentButtons, 0, window->mapFromGlobal(pos));
+ currentPos = pos;
+ }
+ for (unsigned int i=0; i<sizeof(buttons)/sizeof(Qt::MouseButton); i++) {
+ if (state.testFlag(buttons[i])) {
+ qttDebug() << "mousePress" << pos << buttons[i] << currentButtons;
+ currentButtons |= buttons[i];
+ mouseEvent(MousePress, window, buttons[i], buttons[i], 0, window->mapFromGlobal(pos));
+ }
+ }
+}
+
+void QInputGeneratorGeneric::mouseRelease(const QPoint& pos, Qt::MouseButtons state)
+{
+ QTT_TRACE_FUNCTION();
+ const Qt::MouseButton buttons[] = {Qt::LeftButton, Qt::RightButton, Qt::MidButton, Qt::XButton1, Qt::XButton2};
+ QWindow *window=activeWindow();
+ qttDebug() << "window:" << window;
+ if (pos != currentPos) {
+ mouseEvent(MouseMove, window, Qt::NoButton, currentButtons, 0, window->mapFromGlobal(pos));
+ currentPos = pos;
+ }
+ for (unsigned int i=0; i<sizeof(buttons)/sizeof(Qt::MouseButton); i++) {
+ if (state.testFlag(buttons[i])) {
+ qttDebug() << "mouseRelease" << pos << buttons[i] << currentButtons;
+ currentButtons ^= buttons[i];
+ mouseEvent(MouseRelease, window, buttons[i], currentButtons, 0, window->mapFromGlobal(pos));
+ }
+ }
+}
+
+void QInputGeneratorGeneric::mouseClick(const QPoint& pos, Qt::MouseButtons state)
+{
+ QTT_TRACE_FUNCTION();
+ const Qt::MouseButton buttons[] = {Qt::LeftButton, Qt::RightButton, Qt::MidButton, Qt::XButton1, Qt::XButton2};
+ QWindow *window=activeWindow();
+ if (pos != currentPos) {
+ mouseEvent(MouseMove, window, Qt::NoButton, currentButtons, 0, window->mapFromGlobal(pos));
+ currentPos = pos;
+ }
+ for (unsigned int i=0; i<sizeof(buttons)/sizeof(Qt::MouseButton); i++) {
+ if (state.testFlag(buttons[i])) {
+ qttDebug() << "mouseClick" << pos << buttons[i];
+ mouseEvent(MouseClick, window, buttons[i], state, 0, window->mapFromGlobal(pos));
+ }
+ }
+}
+
+void QInputGeneratorGeneric::mouseDClick(const QPoint& pos, Qt::MouseButtons state)
+{
+ QTT_TRACE_FUNCTION();
+ const Qt::MouseButton buttons[] = {Qt::LeftButton, Qt::RightButton, Qt::MidButton, Qt::XButton1, Qt::XButton2};
+ QWindow *window=activeWindow();
+ if (pos != currentPos) {
+ mouseEvent(MouseMove, window, Qt::NoButton, currentButtons, 0, window->mapFromGlobal(pos));
+ currentPos = pos;
+ }
+ for (unsigned int i=0; i<sizeof(buttons)/sizeof(Qt::MouseButton); i++) {
+ if (state.testFlag(buttons[i])) {
+ qttDebug() << "mouseClick" << pos << buttons[i];
+ mouseEvent(MouseDClick, window, buttons[i], state, 0, window->mapFromGlobal(pos));
+ }
+ }
+}
+
+void QInputGeneratorGeneric::mouseMove(const QPoint& pos)
+{
+ QTT_TRACE_FUNCTION();
+ qttDebug() << "mouseMove" << pos;
+ QWindow *window=activeWindow();
+ if (pos != currentPos) {
+ currentPos = pos;
+ }
+ mouseEvent(MouseMove, window, Qt::NoButton, currentButtons, 0, window->mapFromGlobal(pos));
+}
diff --git a/src/remote/slave/lib/qinputgenerator_qwindow_p.h b/src/remote/slave/lib/qinputgenerator_qwindow_p.h
new file mode 100644
index 0000000..705de44
--- /dev/null
+++ b/src/remote/slave/lib/qinputgenerator_qwindow_p.h
@@ -0,0 +1,288 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QINPUTGENERATORQWINDOW_P_H
+#define QINPUTGENERATORQWINDOW_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtUiTest API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtGlobal>
+#include <QMouseEvent>
+#include <QPoint>
+#include <QPointer>
+#include <QApplication>
+#include <QtSystemTest/qstglobal.h>
+#include <qinputgenerator_p.h>
+#include <qtuitestnamespace.h>
+#include <QtTest/qtestspontaneevent.h>
+#include <QtGui/qwindowsysteminterface_qpa.h>
+#include <QtSystemTest/QstDebug>
+
+enum MouseAction { MousePress, MouseRelease, MouseClick, MouseDClick, MouseMove };
+enum TouchAction { TouchPress, TouchRelease, TouchUpdate };
+
+static void mouseEvent(MouseAction action, QWindow *widget, Qt::MouseButton button, Qt::MouseButtons buttons,
+ Qt::KeyboardModifiers stateKey, QPoint pos)
+{
+ QTT_TRACE_FUNCTION();
+ if (pos.isNull())
+ pos = widget->geometry().center();
+
+ if (action == MouseClick) {
+ mouseEvent(MousePress, widget, button, buttons, stateKey, pos);
+ mouseEvent(MouseRelease, widget, button, 0, stateKey, pos);
+ return;
+ }
+
+ stateKey &= static_cast<unsigned int>(Qt::KeyboardModifierMask);
+
+ QMouseEvent me(QEvent::User, QPoint(), Qt::LeftButton, button, stateKey);
+ switch (action)
+ {
+ case MousePress:
+ me = QMouseEvent(QEvent::MouseButtonPress, pos, widget->mapToGlobal(pos), button, buttons, stateKey);
+ break;
+ case MouseRelease:
+ me = QMouseEvent(QEvent::MouseButtonRelease, pos, widget->mapToGlobal(pos), button, buttons, stateKey);
+ break;
+ case MouseDClick:
+ me = QMouseEvent(QEvent::MouseButtonDblClick, pos, widget->mapToGlobal(pos), button, buttons, stateKey);
+ break;
+ case MouseMove:
+ me = QMouseEvent(QEvent::MouseMove, pos, widget->mapToGlobal(pos), Qt::NoButton, buttons, stateKey);
+ break;
+ default:
+ break;
+ }
+ QSpontaneKeyEvent::setSpontaneous(&me);
+ if (!qApp->notify(widget, &me)) {
+ static const char *mouseActionNames[] =
+ { "MousePress", "MouseRelease", "MouseClick", "MouseDClick", "MouseMove" };
+ QString warning = QString::fromLatin1("Mouse event \"%1\" not accepted by receiving widget");
+ qWarning() << warning.arg(QString::fromLatin1(mouseActionNames[static_cast<int>(action)]));
+ }
+
+}
+
+static QWindowSystemInterface::TouchPoint touchPoint(const QTouchEvent::TouchPoint &pt)
+{
+ QWindowSystemInterface::TouchPoint p;
+ p.id = pt.id();
+ p.flags = pt.flags();
+ p.normalPosition = pt.normalizedPos();
+ p.area = pt.screenRect();
+ p.pressure = pt.pressure();
+ p.state = pt.state();
+ p.velocity = pt.velocity();
+ p.rawPositions = pt.rawScreenPositions();
+ return p;
+}
+
+static QList<struct QWindowSystemInterface::TouchPoint> touchPointList(const QList<QTouchEvent::TouchPoint> &pointList)
+{
+ QList<struct QWindowSystemInterface::TouchPoint> newList;
+
+ Q_FOREACH (QTouchEvent::TouchPoint p, pointList)
+ {
+ newList.append(touchPoint(p));
+ }
+ return newList;
+}
+
+static void touchEvent(TouchAction action, QWindow *widget, const QVariantList &points)
+{
+ QTT_TRACE_FUNCTION();
+
+ const QTouchDevice *dev = 0;
+ QList<const QTouchDevice *> devices = QTouchDevice::devices();
+ if (devices.size())
+ dev = devices.at(0);
+
+ QList<QTouchEvent::TouchPoint> newList;
+
+ for (int i = 0; i < points.size(); ++i) {
+ QTouchEvent::TouchPoint p(i);
+ p.setPos(points[i].toPoint());
+ p.setScreenPos(widget->mapToGlobal(points[i].toPoint()));
+
+ switch (action)
+ {
+ case TouchPress:
+ p.setState(Qt::TouchPointPressed);
+ break;
+ case TouchRelease:
+ p.setState(Qt::TouchPointReleased);
+ break;
+ default:
+ p.setState(Qt::TouchPointMoved);
+ break;
+ }
+
+ newList.append(p);
+ }
+
+ QWindowSystemInterface::handleTouchEvent(widget, const_cast<QTouchDevice*>(dev), touchPointList(newList));
+}
+
+enum KeyAction { Press, Release, Click };
+
+static void simulateEvent(QWindow *window, bool press, int code,
+ Qt::KeyboardModifiers modifier, QString text, bool repeat, int delay=-1)
+{
+ QTT_TRACE_FUNCTION();
+ QEvent::Type type;
+ type = press ? QEvent::KeyPress : QEvent::KeyRelease;
+ QWindowSystemInterface::handleKeyEvent(window, type, code, modifier, text, repeat, delay);
+}
+
+static void sendKeyEvent(KeyAction action, QWindow *window, Qt::Key code,
+ QString text, Qt::KeyboardModifiers modifier, int delay=-1)
+{
+ QTT_TRACE_FUNCTION();
+ if (action == Click) {
+ sendKeyEvent(Press, window, code, text, modifier, delay);
+ sendKeyEvent(Release, window, code, text, modifier, delay);
+ return;
+ }
+
+ bool repeat = false;
+
+ if (action == Press) {
+ if (modifier & Qt::ShiftModifier)
+ simulateEvent(window, true, Qt::Key_Shift, 0, QString(), false, delay);
+
+ if (modifier & Qt::ControlModifier)
+ simulateEvent(window, true, Qt::Key_Control, modifier & Qt::ShiftModifier, QString(), false, delay);
+
+ if (modifier & Qt::AltModifier)
+ simulateEvent(window, true, Qt::Key_Alt,
+ modifier & (Qt::ShiftModifier | Qt::ControlModifier), QString(), false, delay);
+ if (modifier & Qt::MetaModifier)
+ simulateEvent(window, true, Qt::Key_Meta, modifier & (Qt::ShiftModifier
+ | Qt::ControlModifier | Qt::AltModifier), QString(), false, delay);
+ simulateEvent(window, true, code, modifier, text, repeat, delay);
+ } else if (action == Release) {
+ simulateEvent(window, false, code, modifier, text, repeat, delay);
+
+ if (modifier & Qt::MetaModifier)
+ simulateEvent(window, false, Qt::Key_Meta, modifier, QString(), false, delay);
+ if (modifier & Qt::AltModifier)
+ simulateEvent(window, false, Qt::Key_Alt, modifier &
+ (Qt::ShiftModifier | Qt::ControlModifier | Qt::AltModifier), QString(), false, delay);
+
+ if (modifier & Qt::ControlModifier)
+ simulateEvent(window, false, Qt::Key_Control,
+ modifier & (Qt::ShiftModifier | Qt::ControlModifier), QString(), false, delay);
+
+ if (modifier & Qt::ShiftModifier)
+ simulateEvent(window, false, Qt::Key_Shift, modifier & Qt::ShiftModifier, QString(), false, delay);
+ }
+}
+
+static void sendKeyEvent(KeyAction action, QWindow *window, Qt::Key code,
+ char ascii, Qt::KeyboardModifiers modifier, int delay=-1)
+{
+ QTT_TRACE_FUNCTION();
+ QString text;
+ if (ascii)
+ text = QString(QChar::fromLatin1(ascii));
+ sendKeyEvent(action, window, code, text, modifier, delay);
+}
+
+inline static void keyEvent(KeyAction action, QWindow *window, char ascii,
+ Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
+{
+ QTT_TRACE_FUNCTION();
+ sendKeyEvent(action, window, QtUiTest::asciiToKey(ascii), ascii, modifier, delay);
+}
+
+inline static void keyEvent(KeyAction action, QWindow *window, Qt::Key key,
+ Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
+{
+ QTT_TRACE_FUNCTION();
+ if (modifier & Qt::ShiftModifier)
+ sendKeyEvent(action, window, key, QChar(key).toUpper().unicode(), modifier, delay);
+ else
+ sendKeyEvent(action, window, key, QChar(key).toLower().unicode(), modifier, delay);
+}
+
+
+class QTUITEST_EXPORT QInputGeneratorGeneric : public QInputGenerator
+{
+Q_OBJECT
+public:
+ explicit QInputGeneratorGeneric(QObject* =0);
+ virtual ~QInputGeneratorGeneric();
+
+ virtual void keyPress (Qt::Key, Qt::KeyboardModifiers, bool=false);
+ virtual void keyRelease(Qt::Key, Qt::KeyboardModifiers);
+ virtual void keyClick (Qt::Key, Qt::KeyboardModifiers);
+
+ virtual void touchPress (const QVariantList&);
+ virtual void touchUpdate (const QVariantList&);
+ virtual void touchRelease(const QVariantList&);
+
+ virtual void mousePress (const QPoint&, Qt::MouseButtons);
+ virtual void mouseRelease(const QPoint&, Qt::MouseButtons);
+ virtual void mouseClick (const QPoint&, Qt::MouseButtons);
+ virtual void mouseDClick (const QPoint&, Qt::MouseButtons);
+ virtual void mouseMove (const QPoint&);
+
+protected:
+ void registerDevice();
+
+ QPoint currentPos;
+ Qt::MouseButtons currentButtons;
+ QTouchDevice *device;
+};
+
+#endif
+
diff --git a/src/remote/slave/lib/qsensorgenerator.cpp b/src/remote/slave/lib/qsensorgenerator.cpp
new file mode 100644
index 0000000..7c62b59
--- /dev/null
+++ b/src/remote/slave/lib/qsensorgenerator.cpp
@@ -0,0 +1,355 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "qsensorgenerator_p.h"
+#include <qtuitestnamespace.h>
+#include <QtSystemTest/QstDebug>
+#include <QTimerEvent>
+#include <QTimer>
+#include <QDateTime>
+#include <QMetaObject>
+#include <QMetaProperty>
+
+static void copySensorProperties(QObject *source, QObject *dest)
+{
+ const QMetaObject *meta = source->metaObject();
+ for (int i = QSensor::staticMetaObject.propertyOffset(); i < meta->propertyCount(); i++) {
+ QMetaProperty prop = meta->property(i);
+ // Not these ones...
+ if (prop.name() == QLatin1String("type") ||
+ prop.name() == QLatin1String("sensorid") ||
+ prop.name() == QLatin1String("connectedToBackend") ||
+ prop.name() == QLatin1String("availableDataRates") ||
+ prop.name() == QLatin1String("dataRate") ||
+ prop.name() == QLatin1String("reading") ||
+ prop.name() == QLatin1String("busy") ||
+ prop.name() == QLatin1String("active") ||
+ prop.name() == QLatin1String("outputRanges") ||
+ prop.name() == QLatin1String("outputRange") ||
+ prop.name() == QLatin1String("description") ||
+ prop.name() == QLatin1String("error")) {
+ continue;
+ }
+ dest->setProperty(prop.name(), prop.read(source));
+ }
+}
+
+QtUiTestSensorBackend::QtUiTestSensorBackend(QSensor *sensor, const QByteArray &sensorId, const QByteArray &fallThroughId)
+ : QSensorBackend(sensor), m_fallThrough(0), m_mode(PassThrough), m_timerId(0)
+{
+ // see if we have a fall-through sensor
+ if (!fallThroughId.isEmpty()) {
+ QList<QByteArray> list = sensor->sensorsForType(sensor->type());
+ if (list.contains(fallThroughId)) {
+ m_fallThrough = new QSensor(sensor->type(), this);
+ m_fallThrough->setIdentifier(fallThroughId);
+
+ // Connect to the fallthrough sensor
+ bool connectedToFallThrough = m_fallThrough->connectToBackend();
+ Q_ASSERT(connectedToFallThrough);
+
+ // Set informative properties
+ setDescription(m_fallThrough->description());
+ setDataRates(m_fallThrough);
+ foreach (const qoutputrange &r, m_fallThrough->outputRanges()) {
+ addOutputRange(r.minimum, r.maximum, r.accuracy);
+ }
+
+ // Set any other properties from the fallthrough sensor
+ copySensorProperties(m_fallThrough, sensor);
+
+ // Handle signals from the fallthrough sensor
+ connect(m_fallThrough, SIGNAL(readingChanged()), this, SLOT(forwardFallthroughReading()));
+ connect(m_fallThrough, SIGNAL(sensorError(int)), sensor, SIGNAL(sensorError(int)));
+ connect(m_fallThrough, SIGNAL(busyChanged()), sensor, SIGNAL(busyChanged()));
+ }
+ }
+
+ // set the mode to match any existing active backends
+ setMode(mode(sensorId));
+
+ if (!m_fallThrough) {
+ addDataRate(100, 100);
+ }
+
+ // add ourselves to the list of backends.
+ activeBackends().append(this);
+}
+
+QtUiTestSensorBackend::~QtUiTestSensorBackend()
+{
+ activeBackends().removeAll(this);
+}
+
+int QtUiTestSensorBackend::interval() const
+{
+ int dataRate, interval;
+ dataRate = sensor()->dataRate();
+ if (dataRate == 0) {
+ if (sensor()->availableDataRates().count())
+ // Use the first available rate when -1 is chosen
+ dataRate = sensor()->availableDataRates().first().first;
+ else
+ dataRate = 1;
+ }
+
+ interval = 1000 / dataRate;
+ return interval;
+}
+
+void QtUiTestSensorBackend::start()
+{
+ if (m_timerId)
+ return;
+
+ switch (m_mode) {
+ case PassThrough:
+ case Record:
+ if (m_fallThrough) {
+ m_fallThrough->setDataRate(sensor()->dataRate());
+ m_fallThrough->setOutputRange(sensor()->outputRange());
+ // Set extra properties onto the fallthrough sensor
+ copySensorProperties(sensor(), m_fallThrough);
+ m_fallThrough->start();
+ if (!m_fallThrough->isActive())
+ sensorStopped();
+ }
+ m_timerId = -1;
+ break;
+ case Generate:
+ m_timerId = startTimer(interval());
+ break;
+ }
+}
+
+void QtUiTestSensorBackend::stop()
+{
+ if (!m_timerId)
+ return;
+
+ switch (m_mode) {
+ case PassThrough:
+ case Record:
+ if (m_fallThrough)
+ m_fallThrough->stop();
+ m_timerId = 0;
+ case Generate:
+ killTimer(m_timerId);
+ m_timerId = 0;
+ }
+}
+
+void QtUiTestSensorBackend::timerEvent(QTimerEvent *event)
+{
+ if (event->timerId() != m_timerId)
+ return;
+ switch (m_mode) {
+ case PassThrough:
+ case Record:
+ break;
+ case Generate:
+ if (m_testData.count() > 1)
+ setCurrentTestData(m_testData.takeFirst());
+ else if (!m_testData.isEmpty())
+ setCurrentTestData(m_testData.first());
+ break;
+ }
+}
+
+void QtUiTestSensorBackend::setMode(Mode mode)
+{
+ if (m_mode == mode)
+ return;
+ // test data shouldn't survive mode changes
+ // as it has diffeerent meanings in each mode
+ m_testData.clear();
+ // check if we need to turn timers on/off
+ if (m_timerId) {
+ if (m_mode == Generate) {
+ killTimer(m_timerId);
+ m_timerId = -1;
+ } else if (mode == Generate) {
+ m_timerId = startTimer(interval());
+ }
+ }
+ m_mode = mode;
+ // some sensors are not noisy, get at least one value updated
+ // for new mode.
+ forwardFallthroughReading();
+}
+
+void QtUiTestSensorBackend::queueTestData(const QList<QVariant> &data)
+{
+ m_testData = data;
+}
+
+void QtUiTestSensorBackend::forwardFallthroughReading()
+{
+ if (!m_fallThrough->reading())
+ return;
+
+ QVariant data;
+ QList<QVariant> parts;
+ int i;
+ switch (m_mode) {
+ case PassThrough:
+ case Record:
+ // copy sensor reading to reading
+ parts << m_fallThrough->reading()->timestamp();
+ for (i = 0; i < m_fallThrough->reading()->valueCount(); ++i)
+ parts << m_fallThrough->reading()->value(i);
+ data = QVariant(parts);
+ setCurrentTestData(data);
+ if (m_mode == Record) {
+ // from above, + store the value
+ m_testData.append(data);
+ }
+ break;
+ case Generate:
+ break;
+ }
+}
+
+void QtUiTestSensorBackend::setMode(const QByteArray &id, Mode mode)
+{
+ backendModes().insert(id, mode);
+ foreach (QtUiTestSensorBackend *backend, activeBackends()) {
+ if (backend->identity() == id)
+ backend->setMode(mode);
+ }
+}
+
+QtUiTestSensorBackend::Mode QtUiTestSensorBackend::mode(const QByteArray &id)
+{
+ return backendModes().value(id, PassThrough);
+}
+
+void QtUiTestSensorBackend::queueTestData(const QByteArray &id, const QList<QVariant> &data)
+{
+ foreach (QtUiTestSensorBackend *backend, activeBackends()) {
+ if (backend->identity() == id)
+ backend->queueTestData(data);
+ }
+}
+
+QList<QVariant> QtUiTestSensorBackend::testData(const QByteArray &id)
+{
+ foreach (QtUiTestSensorBackend *backend, activeBackends()) {
+ if (backend->identity() == id)
+ return backend->testData();
+ }
+ return QList<QVariant>();
+}
+
+QList<QtUiTestSensorBackend *> &QtUiTestSensorBackend::activeBackends()
+{
+ static QList<QtUiTestSensorBackend *> list;
+ return list;
+}
+
+QMap<QByteArray, QtUiTestSensorBackend::Mode> &QtUiTestSensorBackend::backendModes()
+{
+ static QMap<QByteArray, Mode> map;
+ return map;
+}
+
+const char * QAccelerometerGenerator::id("com.nokia.qtuitest.sensor.accelerometer");
+
+QAccelerometerGenerator::QAccelerometerGenerator(QSensor *sensor, const QByteArray &fallThroughId)
+ : QtUiTestSensorBackend(sensor, identity(), fallThroughId)
+{
+ m_reading.setTimestamp(0);
+ m_reading.setX(0.0);
+ m_reading.setY(0.0);
+ m_reading.setZ(0.0);
+ setReading(&m_reading);
+}
+
+QAccelerometerGenerator::~QAccelerometerGenerator()
+{
+}
+
+void QAccelerometerGenerator::setCurrentTestData(const QVariant &value)
+{
+ QVariantList list = value.toList();
+ if (list.count() == 4) {
+ m_reading.setTimestamp(list.at(0).value<quint64>());
+ m_reading.setX(list.at(1).toReal());
+ m_reading.setY(list.at(2).toReal());
+ m_reading.setZ(list.at(3).toReal());
+ newReadingAvailable();
+ } else if (list.count() == 3) {
+ m_reading.setTimestamp(QDateTime::currentMSecsSinceEpoch());
+ m_reading.setX(list.at(0).toReal());
+ m_reading.setY(list.at(1).toReal());
+ m_reading.setZ(list.at(2).toReal());
+ newReadingAvailable();
+ }
+}
+
+const char * QOrientationGenerator::id("com.nokia.qtuitest.sensor.orientation");
+
+QOrientationGenerator::QOrientationGenerator(QSensor *sensor, const QByteArray &fallThroughId)
+ : QtUiTestSensorBackend(sensor, identity(), fallThroughId)
+{
+ m_reading.setTimestamp(0);
+ m_reading.setOrientation(QOrientationReading::Undefined);
+ setReading(&m_reading);
+}
+
+QOrientationGenerator::~QOrientationGenerator()
+{
+}
+
+void QOrientationGenerator::setCurrentTestData(const QVariant &value)
+{
+ QVariantList list = value.toList();
+ if (list.count() == 2) {
+ m_reading.setTimestamp(list.at(0).value<quint64>());
+ m_reading.setOrientation(static_cast<QOrientationReading::Orientation>(list.at(1).toInt()));
+ newReadingAvailable();
+ } else if (list.count() == 1) {
+ m_reading.setTimestamp(QDateTime::currentMSecsSinceEpoch());
+ m_reading.setOrientation(static_cast<QOrientationReading::Orientation>(list.at(0).toInt()));
+ newReadingAvailable();
+ }
+}
diff --git a/src/remote/slave/lib/qsensorgenerator_p.h b/src/remote/slave/lib/qsensorgenerator_p.h
new file mode 100644
index 0000000..568bfe9
--- /dev/null
+++ b/src/remote/slave/lib/qsensorgenerator_p.h
@@ -0,0 +1,187 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QSENSORGENERATOR_P_H
+#define QSENSORGENERATOR_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtUiTest API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtGlobal>
+#include <QtSystemTest/qstglobal.h>
+
+#include <QSensorBackend>
+#include <QAccelerometerReading>
+#include <QOrientationReading>
+#include <QSensorBackendFactory>
+#include <QList>
+
+class QTUITEST_EXPORT QtUiTestSensorBackend : public QSensorBackend
+{
+Q_OBJECT
+public:
+ QtUiTestSensorBackend(QSensor *sensor, const QByteArray &sensorId, const QByteArray &fallThroughId);
+ ~QtUiTestSensorBackend();
+
+ void start();
+ void stop();
+
+ enum Mode {
+ PassThrough = 0,
+ Generate = 1,
+ Record = 2
+ };
+
+ static void setMode(const QByteArray &id, Mode mode);
+ static Mode mode(const QByteArray &);
+ static void queueTestData(const QByteArray &, const QList<QVariant> &);
+ static QList<QVariant> testData(const QByteArray &);
+
+ virtual QByteArray identity() const = 0;
+
+protected:
+ void timerEvent(QTimerEvent *);
+
+ void setMode(Mode mode);
+ Mode mode() const { return m_mode; }
+ void queueTestData(const QList<QVariant> &);
+ QList<QVariant> testData() { return m_testData; }
+
+ virtual void setCurrentTestData(const QVariant &) = 0;
+
+private slots:
+ void forwardFallthroughReading();
+
+private:
+ int interval() const;
+
+ QSensor *m_fallThrough;
+ QList<QVariant> m_testData;
+ Mode m_mode;
+ int m_timerId;
+
+ static QList<QtUiTestSensorBackend *> &activeBackends();
+ static QMap<QByteArray, Mode> &backendModes();
+};
+
+class QTUITEST_EXPORT QAccelerometerGenerator : public QtUiTestSensorBackend
+{
+Q_OBJECT
+public:
+ QAccelerometerGenerator(QSensor *sensor, const QByteArray &fallThroughId = QByteArray());
+ ~QAccelerometerGenerator();
+
+ QByteArray identity() const { return id; }
+ static const char *id;
+
+protected:
+ void setCurrentTestData(const QVariant &);
+
+private:
+ QAccelerometerReading m_reading;
+};
+
+class QTUITEST_EXPORT QOrientationGenerator : public QtUiTestSensorBackend
+{
+Q_OBJECT
+public:
+ QOrientationGenerator(QSensor *sensor, const QByteArray &fallThroughId = QByteArray());
+ ~QOrientationGenerator();
+
+ QByteArray identity() const { return id; }
+ static const char *id;
+
+protected:
+ void setCurrentTestData(const QVariant &);
+
+private:
+ QOrientationReading m_reading;
+};
+
+class QTUITEST_EXPORT QSensorGeneratorFactory : public QSensorBackendFactory
+{
+public:
+ QSensorGeneratorFactory()
+ {}
+
+ void registerSensors() {
+ m_previousDefaultSensors.insert(QAccelerometer::type,
+ QSensor::defaultSensorForType(QAccelerometer::type));
+ m_previousDefaultSensors.insert(QOrientationSensor::type,
+ QSensor::defaultSensorForType(QOrientationSensor::type));
+
+ QSensorManager::registerBackend(QAccelerometer::type, QAccelerometerGenerator::id, this);
+ QSensorManager::registerBackend(QOrientationSensor::type, QOrientationGenerator::id, this);
+
+ QSensorManager::setDefaultBackend(QAccelerometer::type, QAccelerometerGenerator::id);
+ QSensorManager::setDefaultBackend(QOrientationSensor::type, QOrientationGenerator::id);
+ }
+
+ QSensorBackend *createBackend(QSensor *sensor)
+ {
+ QByteArray wrapped = m_previousDefaultSensors.value(sensor->type(), QByteArray());
+ if (sensor->identifier() == QAccelerometerGenerator::id) {
+ if (wrapped == QAccelerometerGenerator::id)
+ return 0;
+ return new QAccelerometerGenerator(sensor, wrapped);
+ }
+ if (sensor->identifier() == QOrientationGenerator::id) {
+ if (wrapped == QOrientationGenerator::id)
+ return 0;
+ return new QOrientationGenerator(sensor, wrapped);
+ }
+ return 0;
+ }
+private:
+ QMap<QByteArray, QByteArray> m_previousDefaultSensors;
+};
+
+#endif // QSENSORGENERATOR_P_H
+
diff --git a/src/remote/slave/lib/qtestslave.cpp b/src/remote/slave/lib/qtestslave.cpp
new file mode 100644
index 0000000..ccbd5ba
--- /dev/null
+++ b/src/remote/slave/lib/qtestslave.cpp
@@ -0,0 +1,1678 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <qtestslave.h>
+#include <qtestwidgets.h>
+#include <qtuitestnamespace.h>
+#include <qtuitestconnectionmanager_p.h>
+
+#include <QImage>
+#include <QCoreApplication>
+#include <QVariant>
+#include <QMetaProperty>
+#include <QMetaObject>
+#include <QMetaType>
+#include <QPoint>
+#include <QLocale>
+#include <QtSystemTest/QstDebug>
+#include <QElapsedTimer>
+#include <QtGui/QPlatformIntegration>
+
+#include <QDir>
+#include <QPluginLoader>
+
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
+ #include <private/qguiapplication_p.h>
+// #include <qsensorgenerator_p.h>
+ #include <qplatforminputcontext_qpa.h>
+#endif
+
+#ifdef QTUITEST_CPU_TICKS
+# include <QtTest/private/cycle_p.h>
+#endif
+
+#define qLog() if(1); else QtUiTest::debug()
+
+using namespace QtUiTest;
+
+class QtUiTestSignalReceiver : public QObject
+{
+public:
+ QtUiTestSignalReceiver(QTestSlavePrivate* = 0);
+
+ bool connectSignal(QObject *sender, const char *signal);
+ QVariantList argValues() const { return m_argValues; }
+ int qt_metacall(QMetaObject::Call call, int methodId, void **a);
+ virtual void signalReceived();
+
+protected:
+ QTestSlavePrivate *m_slave;
+ QObject *m_sender;
+ QString m_signal;
+ bool m_received;
+ QList<int> m_args;
+ QVariantList m_argValues;
+};
+
+class QtUiTestSignalWaiter : public QtUiTestSignalReceiver
+{
+public:
+ QtUiTestSignalWaiter(QTestSlavePrivate* = 0);
+
+ bool setExpectedSignal(QObject *sender, const char *signal);
+ void clear();
+ bool waitForSignal( int timeout = 10000 );
+ virtual void signalReceived();
+ int elapsed() const { return m_elapsed; }
+
+private:
+ QEventLoop m_eventLoop;
+ QTime m_time;
+ int m_elapsed;
+};
+
+typedef QPair<QObject*,QString> ReceiverKey;
+
+// Handler for test messages
+class QTestSlavePrivate : public QObject
+{
+Q_OBJECT
+public:
+ QTestSlavePrivate(QTestSlave *parent)
+ : p(parent)
+ {
+ }
+
+ QPoint mousePointForMessage(const QstMessage&);
+ QVariantList touchPointsForMessage(const QstMessage&);
+
+ void signalReceived(QObject *sender, const QString &signal, const QVariantList &argValues);
+
+ void resetBenchmarks();
+ qint64 cpuTicks();
+
+ QTestSlave *p;
+ QtUiTestSignalWaiter m_signalWaiter;
+ QMap<ReceiverKey,QtUiTestSignalReceiver*> m_signalReceivers;
+
+#ifdef QTUITEST_CPU_TICKS
+ CycleCounterTicks startTicks;
+#endif
+
+public slots:
+ QstMessage appName (const QstMessage&);
+ QstMessage isVisible (const QstMessage&);
+ QstMessage hasContents (const QstMessage&);
+
+ QstMessage grabImage (const QstMessage&);
+ QstMessage window (const QstMessage&);
+ QstMessage getCenter (const QstMessage&);
+ QstMessage enterText (const QstMessage&);
+ QstMessage isHigher (const QstMessage&);
+
+ QstMessage inputMethod (const QstMessage&);
+
+ QstMessage activeWidgetInfo (const QstMessage&);
+ QstMessage getObjects (const QstMessage&);
+
+ QstMessage applicationData (const QstMessage&);
+ QstMessage applicationWindows (const QstMessage&);
+ QstMessage windowProperty (const QstMessage&);
+ QstMessage invokeMethod (const QstMessage&);
+ QstMessage setProperty (const QstMessage&);
+ QstMessage getProperty (const QstMessage&);
+ QstMessage getProperties (const QstMessage&);
+ QstMessage queryProperties (const QstMessage&);
+
+ QstMessage getGeometry (const QstMessage&);
+
+ QstMessage keyPress (const QstMessage&);
+ QstMessage keyRelease (const QstMessage&);
+ QstMessage keyClick (const QstMessage&);
+
+ QstMessage touchPress (const QstMessage&);
+ QstMessage touchUpdate (const QstMessage&);
+ QstMessage touchRelease (const QstMessage&);
+
+ QstMessage mousePress (const QstMessage&);
+ QstMessage mouseRelease (const QstMessage&);
+ QstMessage mouseClick (const QstMessage&);
+ QstMessage mouseDoubleClick (const QstMessage&);
+ QstMessage mouseMove (const QstMessage&);
+
+ QstMessage translate (const QstMessage&);
+ QstMessage trId (const QstMessage&);
+ QstMessage getLocale (const QstMessage&);
+ QstMessage setConfig (const QstMessage&);
+ QstMessage rescan (const QstMessage&);
+ QstMessage typeOf (const QstMessage&);
+ QstMessage inheritance (const QstMessage&);
+ QstMessage queuedMessage (const QstMessage&);
+
+ QstMessage getMethods (const QstMessage&);
+ QstMessage expectSignal (const QstMessage&);
+ QstMessage waitForSignal (const QstMessage&);
+
+ QstMessage connectSignal (const QstMessage&);
+ QstMessage disconnectSignal (const QstMessage&);
+ QstMessage cleanup (const QstMessage&);
+
+/*
+ QstMessage setSensorMode (const QstMessage&);
+ QstMessage getSensorMode (const QstMessage&);
+ QstMessage queueSensorValues (const QstMessage&);
+ QstMessage getSensorValues (const QstMessage&);
+*/
+protected slots:
+ void disconnectAllSignals(QObject*);
+
+};
+
+#include "qtestslave.moc"
+
+QTestSlave::QTestSlave()
+ : QstProtocol()
+ , d(new QTestSlavePrivate(this))
+{
+ QTT_TRACE_FUNCTION();
+ QtUiTest::testInputOption(QtUiTest::NoOptions);
+ refreshPlugins();
+}
+
+QTestSlave::~QTestSlave()
+{
+ QTT_TRACE_FUNCTION();
+ delete d;
+ disconnect();
+}
+
+void QTestSlave::onConnected()
+{
+ QTT_TRACE_FUNCTION();
+ QstProtocol::onConnected();
+ QstMessage msg("APP_NAME");
+ msg["appName"] = qApp->applicationName();
+ msg["appVersion"] = qApp->applicationVersion();
+ msg["qtVersion"] = QT_VERSION_STR;
+ postMessage( msg );
+}
+
+QtUiTestSignalReceiver::QtUiTestSignalReceiver(QTestSlavePrivate *slave)
+ : m_slave(slave)
+ , m_sender(0)
+ , m_received(false)
+{
+}
+
+bool QtUiTestSignalReceiver::connectSignal(QObject *sender, const char *signal)
+{
+ m_sender = sender;
+ m_signal = QString(signal);
+
+ const QMetaObject* const senderMo = sender->metaObject();
+ static const int memberOffset = QObject::staticMetaObject.methodCount();
+
+ int signalIndex = senderMo->indexOfSignal(signal);
+ if (signalIndex < 0) {
+ signalIndex = senderMo->indexOfSignal(QMetaObject::normalizedSignature(signal));
+ }
+ if (signalIndex < 0) {
+ return false;
+ }
+
+ QMetaMethod method = senderMo->method(signalIndex);
+ QList<QByteArray> params = method.parameterTypes();
+ for (int i = 0; i < params.count(); ++i) {
+ m_args << QMetaType::type(params.at(i).constData());
+ }
+
+ QtUiTestConnectionManager::instance()->connect(sender, signalIndex, this, memberOffset);
+ return true;
+}
+
+int QtUiTestSignalReceiver::qt_metacall(QMetaObject::Call call, int methodId, void **a)
+{
+ methodId = QObject::qt_metacall(call, methodId, a);
+ if (methodId < 0)
+ return methodId;
+
+ if (call == QMetaObject::InvokeMetaMethod) {
+ if (methodId == 0) {
+ m_argValues.clear();
+ for (int i = 0; i < m_args.count(); ++i) {
+ QMetaType::Type type = static_cast<QMetaType::Type>(m_args.at(i));
+ m_argValues << QVariant(type, a[i + 1]);
+ }
+ m_received = true;
+ signalReceived();
+
+ if (m_slave) {
+ m_slave->signalReceived(m_sender, m_signal, m_argValues);
+ }
+ }
+ --methodId;
+ }
+ return methodId;
+}
+
+void QtUiTestSignalReceiver::signalReceived()
+{
+}
+
+QtUiTestSignalWaiter::QtUiTestSignalWaiter(QTestSlavePrivate *slave)
+ : QtUiTestSignalReceiver(slave), m_elapsed(0)
+{
+}
+
+bool QtUiTestSignalWaiter::setExpectedSignal(QObject *sender, const char *signal)
+{
+ clear();
+ if (!connectSignal(sender, signal)) {
+ return false;
+ }
+ m_time.start();
+ return true;
+}
+
+void QtUiTestSignalWaiter::clear()
+{
+ if (m_sender) {
+ QtUiTestConnectionManager::instance()->disconnect(m_sender, -1, this, -1);
+ m_sender = 0;
+ }
+ m_received = false;
+ m_args.clear();
+ m_argValues.clear();
+ m_elapsed = 0;
+}
+
+void QtUiTestSignalWaiter::signalReceived()
+{
+ m_elapsed = m_time.elapsed();
+
+ if (m_eventLoop.isRunning())
+ m_eventLoop.quit();
+}
+
+bool QtUiTestSignalWaiter::waitForSignal(int timeout)
+{
+ if (m_received)
+ return true;
+
+ QTimer timer;
+ timer.setInterval(timeout);
+ timer.setSingleShot(true);
+ QObject::connect(&timer, SIGNAL(timeout()), &m_eventLoop, SLOT(quit()));
+ timer.start();
+ m_eventLoop.exec();
+
+ return m_received;
+}
+
+QstMessage QTestSlavePrivate::grabImage(const QstMessage &message)
+{
+ QTT_TRACE_FUNCTION();
+ QstMessage reply;
+ QImage img;
+
+ Widget *tw = 0;
+ if (!message["widgetSpecifier"].toString().isEmpty()) {
+ tw = findTestWidget<Widget>(message);
+ }
+
+ if (!tw) {
+ if (QtUiTest::errorString().isEmpty()) {
+ setErrorString(QLatin1String("Widget not found"));
+ }
+ return reply;
+ }
+
+ tw->grabImage(img);
+ reply["grabImage"] = img;
+ return reply;
+}
+
+QstMessage QTestSlavePrivate::window(const QstMessage &message)
+{
+ QTT_TRACE_FUNCTION();
+ QstMessage reply;
+ Widget *w = findTestWidget<Widget>(message);
+ qDebug() << "Finding window for " << w;
+ if (w) {
+ QObject *window = w->window();
+ qDebug() << "window " << window;
+ if (window) {
+ QActiveTestWidget::instance()->registerTestWidget(window);
+ reply["window"] = QTestSlave::objectToMap(window);
+ }
+ }
+
+ return reply;
+}
+
+QstMessage QTestSlavePrivate::activeWidgetInfo(const QstMessage &message)
+{
+ QTT_TRACE_FUNCTION();
+ Q_UNUSED(message);
+ QstMessage reply;
+ QString error;
+ if (!QActiveTestWidget::instance()->rescan()) {
+ return reply;
+ }
+
+ QString ret = QString("applicationIdentifier = '%1'\n\n").arg(QTestWidgets::windowProperty(QLatin1String("applicationIdentifier")).toString());
+ ret += QActiveTestWidget::instance()->descendantTree(QTestWidgets::activeWidget()).join(QLatin1String("\n"));
+
+ reply["activeWidgetInfo"] = ret;
+ return reply;
+}
+
+QstMessage QTestSlavePrivate::getObjects(const QstMessage &message)
+{
+ QTT_TRACE_FUNCTION();
+ QstMessage reply;
+ reply["getObjects"] = QActiveTestWidget::instance()->getObjects(message["widgetSpecifier"].toString());
+ return reply;
+}
+
+QstMessage QTestSlavePrivate::isVisible(const QstMessage &message)
+{
+ QTT_TRACE_FUNCTION();
+ QstMessage reply;
+ Widget *w = findTestWidget<Widget>(message);
+ if (w) {
+ reply["isVisible"] = w->isVisible();
+ } else {
+ reply["isVisible"] = false;
+ }
+
+ return reply;
+}
+
+QstMessage QTestSlavePrivate::hasContents(const QstMessage &message)
+{
+ QTT_TRACE_FUNCTION();
+ QstMessage reply;
+ QtUiTest::Object *w = findTestWidget<QtUiTest::Object>(message);
+ if (w) {
+ reply["hasContents"] = w->hasContents();
+ } else {
+ reply["hasContents"] = false;
+ }
+
+ return reply;
+}
+
+QstMessage QTestSlavePrivate::getCenter(const QstMessage &message)
+{
+ QTT_TRACE_FUNCTION();
+ QstMessage reply;
+ Widget *qw = findTestWidget<Widget>(message);
+ if (qw) {
+ QPoint pos = qw->center();
+ reply["getCenter"] = QVariant::fromValue(pos);
+ }
+
+ return reply;
+}
+
+QstMessage QTestSlavePrivate::inputMethod(const QstMessage &message)
+{
+ QTT_TRACE_FUNCTION();
+ Q_UNUSED(message);
+ QstMessage reply;
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
+ QObject *obj = qGuiApp->inputMethod();
+ if (obj) {
+ QActiveTestWidget::instance()->registerTestWidget(obj);
+ reply["inputMethod"] = QTestSlave::objectToMap(obj);
+ } else {
+ QtUiTest::setErrorString("Could not find inputMethod");
+ }
+#else
+ QtUiTest::setErrorString("inputMethod() requires Qt 5");
+#endif
+ return reply;
+}
+
+QstMessage QTestSlavePrivate::appName(const QstMessage &message)
+{
+ QTT_TRACE_FUNCTION();
+ Q_UNUSED(message);
+ QstMessage reply;
+ reply["appName"] = qApp->applicationName();
+ return reply;
+}
+
+QstMessage QTestSlavePrivate::applicationData(const QstMessage &message)
+{
+ QTT_TRACE_FUNCTION();
+ Q_UNUSED(message);
+ QstMessage reply;
+ QVariantMap appData;
+ appData["rootItem"] = QTestSlave::objectToMap(QTestWidgets::activeWidget());
+ appData["appObject"] = QTestSlave::objectToMap(qApp);
+ appData["appId"] = QTestWidgets::windowProperty(QLatin1String("applicationIdentifier"));
+ appData["appName"] = qApp->applicationName();
+ reply["applicationData"] = appData;
+ return reply;
+}
+
+QstMessage QTestSlavePrivate::applicationWindows(const QstMessage &message)
+{
+ QTT_TRACE_FUNCTION();
+ Q_UNUSED(message);
+ QstMessage reply;
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
+ QWindow *focusWindow = qApp->focusWindow();
+
+ QVariantList topLevel;
+ foreach (QWindow* window, qApp->topLevelWindows()) {
+ QActiveTestWidget::instance()->registerTestWidget(window);
+ topLevel << QTestSlave::objectToMap(window);
+ }
+ QVariantList allWindows;
+ foreach (QWindow* window, qApp->allWindows()) {
+ QActiveTestWidget::instance()->registerTestWidget(window);
+ allWindows << QTestSlave::objectToMap(window);
+ }
+
+ QVariantMap windowData;
+ QActiveTestWidget::instance()->registerTestWidget(focusWindow);
+ windowData["focusWindow"] = QTestSlave::objectToMap(qApp->focusWindow());
+ windowData["topLevelWindows"] = topLevel;
+ windowData["allWindows"] = allWindows;
+ reply["applicationWindows"] = windowData;
+#endif
+ return reply;
+}
+
+//FIXME: This should require a window to be specified, should be handled in
+// window handler code
+QstMessage QTestSlavePrivate::windowProperty(const QstMessage &message)
+{
+ QTT_TRACE_FUNCTION();
+ Q_UNUSED(message);
+ QstMessage reply;
+ QString property = message["property"].toString();
+ QVariant value = QTestWidgets::windowProperty(property);
+ reply["windowProperty"] = value;
+ return reply;
+}
+
+static QByteArray methodSignature(const QMetaMethod &method)
+{
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
+ return method.methodSignature();
+#else
+ return QByteArray::fromRawData(method.signature(), qstrlen(method.signature()));
+#endif
+}
+
+QstMessage QTestSlavePrivate::invokeMethod(const QstMessage &message)
+{
+ QTT_TRACE_FUNCTION();
+ QObject *o;
+ QString error;
+ QstMessage reply;
+ if (!QActiveTestWidget::instance()->findWidget( message["widgetSpecifier"].toString(), o, error))
+ return MESSAGE_ERROR(reply,error);
+
+ QString method = message["method"].toString();
+ bool returns = message["returns"].toBool();
+ Qt::ConnectionType connType = (Qt::ConnectionType)message["conntype"].toInt();
+
+ method = QMetaObject::normalizedSignature(qPrintable(method));
+
+ QVariantList argList = message["args"].toList();
+
+ QMetaObject const *mo = o->metaObject();
+
+ int m = mo->indexOfMethod(QMetaObject::normalizedSignature(qPrintable(method)));
+ if (-1 == m) {
+ (void) MESSAGE_ERROR(reply, "ERROR_NO_METHOD");
+ reply["warning"] = QString("method '%1' is not valid").arg(method);
+ return reply;
+ }
+ QMetaMethod mm = mo->method(m);
+ QList<QByteArray> paramTypes = mm.parameterTypes();
+ QList<QByteArray> paramNames = mm.parameterNames();
+
+ if (paramTypes.count() != argList.count()) {
+ (void)MESSAGE_ERROR(reply, "ERROR_WRONG_ARG_COUNT");
+ reply["warning"] = QString("method '%1' invoked with actual args %2, expected args %3")
+ .arg(QString::fromLatin1(methodSignature(mm))).arg(argList.count()).arg(paramTypes.count());
+ return reply;
+ }
+ QString retType = mm.typeName();
+ if (returns && retType.isEmpty()) {
+ (void)MESSAGE_ERROR(reply, "ERROR_NO_RETURN");
+ reply["warning"] = QString("method '%1' does not return a value").arg(QString::fromLatin1(methodSignature(mm)));
+ return reply;
+ }
+
+ QGenericArgument args[10];
+ for (int index = 0;index < argList.count(); index++) {
+ int typeId = QMetaType::type(paramTypes[index]);
+ if (typeId != QMetaType::QVariant) {
+ if (argList[index].canConvert(static_cast<QVariant::Type>(typeId))) {
+ argList[index].convert(static_cast<QVariant::Type>(typeId));
+ } else {
+ (void) MESSAGE_ERROR(reply, "ERROR_IN_INVOKE");
+ reply["warning"] = QString("invalid parameter type for parameter %1 (was %2 but expected %3)")
+ .arg(index).arg(argList[index].typeName()).arg(qPrintable(paramTypes[index]));
+ return reply;
+ }
+ }
+
+ args[index] = QGenericArgument(paramTypes[index].constData(), argList[index].constData());
+ }
+
+ QString methodName = method.left(method.indexOf('('));
+ if (retType != QLatin1String("void")) {
+ QVariant returnValue;
+ int typeId = QMetaType::type(mm.typeName());
+
+ if (!typeId) {
+ (void) MESSAGE_ERROR(reply, "ERROR_IN_INVOKE");
+ reply["warning"] = QString("could not look up type id for type %1)")
+ .arg(mm.typeName());
+ return reply;
+ } else if (typeId != QMetaType::QVariant) {
+ returnValue = QVariant(typeId, (const void*)NULL);
+ }
+
+ if (!mm.invoke(o, connType,
+ QGenericReturnArgument(mm.typeName(), returnValue.data()), args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], args[9])) {
+ (void) MESSAGE_ERROR(reply, "ERROR_IN_INVOKE");
+ reply["warning"] = QString("invoke of method '%1' with %2 args and a return type of '%3' failed")
+ .arg(method).arg(paramTypes.count()).arg(retType);
+ return reply;
+ }
+ reply["returns"] = returnValue;
+ } else {
+ if (!QMetaObject::invokeMethod(o, qPrintable(methodName), connType,
+ args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], args[9])) {
+ (void) MESSAGE_ERROR(reply, "ERROR_IN_INVOKE");
+ reply["warning"] = QString("invoke of method '%1' with %2 args failed").arg(method).arg(paramTypes.count());
+ return reply;
+ }
+ }
+
+ return reply;
+}
+
+QstMessage QTestSlavePrivate::setProperty(const QstMessage &message)
+{
+ QTT_TRACE_FUNCTION();
+ QstMessage reply;
+ QtUiTest::Object *w = findTestWidget<Object>(message);
+ if (w) {
+ QString property = message["property"].toString();
+ QVariant value = message["value"];
+ if (!w->setProperty(property, value) && QtUiTest::errorString().isEmpty()) {
+ // was a dynamic property created?
+ if (!w->getProperties().contains(property)) {
+ return MESSAGE_ERROR(reply, "ERROR_SETTING_PROPERTY");
+ }
+ }
+ }
+
+ return reply;
+}
+
+QstMessage QTestSlavePrivate::getProperty(const QstMessage &message)
+{
+ QTT_TRACE_FUNCTION();
+ QstMessage reply;
+ QtUiTest::Object *w = findTestWidget<Object>(message);
+ if (w) {
+ QString property = message["property"].toString();
+ QVariant value = QTestSlave::getObjectProperty(w, property);
+ reply["getProperty"] = value;
+ if (!value.isValid()) {
+ QtUiTest::setErrorString("Failed to retrieve property from object");
+ }
+ }
+
+ return reply;
+}
+
+QVariant QTestSlave::getObjectProperty(QtUiTest::Object *w, const QString &property)
+{
+ QVariant value;
+ if (!w) {
+ QtUiTest::setErrorString(QString("Cannot retrieve property '%1' from null object").arg(property));
+ return value;
+ }
+ value = w->getProperty(property);
+ if (!value.isValid()) {
+ QtUiTest::setErrorString(QString("Failed to retrieve property '%1' from object").arg(property));
+ return value;
+ }
+
+ return QTestSlave::updateVariant(value);
+}
+
+QVariant QTestSlave::updateVariant(const QVariant &value)
+{
+ if (value.userType() == QMetaType::QObjectStar) {
+ if (QObject *obj = value.value<QObject*>()) {
+ QActiveTestWidget::instance()->registerTestWidget(obj);
+ return QTestSlave::objectToMap(obj);
+ } else {
+ return QLatin1String("<Null Object>");
+ }
+ } else if (value.userType() == QVariant::List) {
+ QVariantList valueList;
+ foreach (const QVariant &item, value.toList()) {
+ valueList << QTestSlave::updateVariant(item);
+ }
+ return valueList;
+ } else if (value.type() == QVariant::Map) {
+ QVariantMap map = value.toMap();
+ QVariantMap::iterator i;
+ for (i = map.begin(); i != map.end(); ++i) {
+ i.value() = QTestSlave::updateVariant(i.value());
+ }
+ return map;
+ } else if ((int)value.type() == QMetaType::QVariant) {
+ return QTestSlave::updateVariant(value.value<QVariant>());
+ } else if ((value.type() == QVariant::Hash)
+ || (value.type() == QVariant::UserType)
+ || (value.type() == QMetaType::VoidStar)) {
+ return QString("<%1>").arg(value.typeName());
+ }
+
+ return value;
+}
+
+QVariantMap QTestSlave::objectToMap(const QObject *obj, const QStringList &properties)
+{
+ QVariantMap map;
+ map["_signature_"] = QTestWidgets::signature(obj);
+ QtUiTest::Object *qw = qtuitest_cast<Object*>(obj);
+ if (qw) {
+ map["_type_"] = qw->typeOf();
+ if (!properties.isEmpty()) {
+ QVariantMap prefetch;
+ foreach (const QString &property, properties) {
+ QVariant value = QTestSlave::getObjectProperty(qw, property);
+ prefetch[property] = value;
+ }
+ map["_prefetch_"] = prefetch;
+ }
+ }
+ return map;
+}
+
+QstMessage QTestSlavePrivate::getProperties(const QstMessage &message)
+{
+ QTT_TRACE_FUNCTION();
+ QstMessage reply;
+ QtUiTest::Object *w = findTestWidget<Object>(message);
+
+ if (!w) {
+ QtUiTest::setErrorString(QLatin1String("Unable to find specified widget"));
+ return reply;
+ }
+
+ QVariantMap map = w->getProperties();
+ if (map.isEmpty()) {
+ QtUiTest::setErrorString(QLatin1String("Failed to retrieve properties from object"));
+ }
+
+ foreach (const QString &key, map.keys()) {
+ map[key] = QTestSlave::updateVariant(map[key]);
+ }
+
+ reply[QLatin1String("getProperties")] = map;
+ return reply;
+}
+
+QstMessage QTestSlavePrivate::queryProperties(const QstMessage &message)
+{
+ QTT_TRACE_FUNCTION();
+ QstMessage reply;
+ QString error;
+
+ QVariantMap searchValues = message["searchvalues"].toMap();
+ if ( searchValues.isEmpty() ) {
+ QtUiTest::setErrorString(QLatin1String("ERROR_MISSING_PARAMETERS"));
+ return reply;
+ }
+
+ int flags = message["flags"].toInt();
+ QObjectList ol = QActiveTestWidget::instance()->queryProperties( searchValues, static_cast<QtUiTest::QueryFlags>(flags) );
+
+ if (!QtUiTest::errorString().isEmpty())
+ return reply;
+
+ if (!(flags & QtUiTest::NoSort)) {
+ // Sort the list by widget position
+ qStableSort(ol.begin(), ol.end(), QTestWidgets::lessThan);
+ }
+
+ QStringList properties = message["properties"].toStringList();
+ QVariantList matches;
+ foreach (QObject *o, ol) {
+ QActiveTestWidget::instance()->registerTestWidget(o);
+ matches << QTestSlave::objectToMap(o, properties);
+ }
+
+ reply["queryProperties"] = matches;
+ return reply;
+}
+
+QstMessage QTestSlavePrivate::getGeometry(const QstMessage &message)
+{
+ QTT_TRACE_FUNCTION();
+ QstMessage reply;
+ Widget *w = findTestWidget<Widget>(message);
+ if (w) {
+ QRect ret = w->geometry();
+ reply["getGeometry"] = ret;
+ }
+
+ return reply;
+}
+
+void QTestSlavePrivate::resetBenchmarks()
+{
+#ifdef QTUITEST_CPU_TICKS
+ startTicks = getticks();
+#endif
+}
+
+qint64 QTestSlavePrivate::cpuTicks()
+{
+#ifdef QTUITEST_CPU_TICKS
+ CycleCounterTicks now = getticks();
+ return qRound64(elapsed(now, startTicks));
+#else
+ return -1;
+#endif
+}
+
+Q_DECLARE_METATYPE(QVariant);
+
+void QTestSlave::processMessage( QstMessage *msg )
+{
+ QTT_TRACE_FUNCTION();
+ QtUiTest::setErrorString(QString());
+ QstMessage reply = constructReplyToMessage(*msg);
+ if (reply.state() != QstMessage::MessageEmpty) {
+ replyMessage(msg, reply);
+ }
+}
+
+void QTestSlave::registerHandler(QtUiTest::MessageHandler *handler)
+{
+ m_messageHandlers[handler->handlerName()] = handler;
+ qDebug() << "registered handler " << handler->handlerName() << handler;
+}
+
+void QTestSlave::refreshPlugins()
+{
+ QTT_TRACE_FUNCTION();
+
+ QSet<QString> pluginsToLoad;
+ QList<QDir> pluginDirs;
+
+ const QString pluginType("qtuitest");
+ QSet<QString> libPaths = QCoreApplication::libraryPaths().toSet();
+
+ foreach (const QString& libPath, libPaths) {
+ QDir dir(libPath + "/" + pluginType);
+ if (!dir.exists()) {
+ continue;
+ }
+ pluginDirs << dir;
+ }
+
+ foreach (QDir const& dir, pluginDirs) {
+ foreach (const QString& file, dir.entryList(QDir::Files|QDir::NoDotAndDotDot)) {
+ QString filename = dir.canonicalPath() + "/" + file;
+ if (!QLibrary::isLibrary(filename)) continue;
+ pluginsToLoad << filename;
+ }
+ }
+ QPluginLoader pluginLoader;
+ QSet<QString> lastPluginsToLoad;
+ QStringList errors;
+
+ // dumb dependency handling: keep trying to load plugins until we
+ // definitely can't progress.
+ while (lastPluginsToLoad != pluginsToLoad) {
+ lastPluginsToLoad = pluginsToLoad;
+ errors.clear();
+ foreach (const QString& plugin, pluginsToLoad) {
+ pluginLoader.setFileName(plugin);
+ // enable RTLD_GLOBAL, so plugins can access each other's symbols.
+ pluginLoader.setLoadHints(QLibrary::ExportExternalSymbolsHint);
+ pluginLoader.load();
+
+ QObject *instance = pluginLoader.instance();
+ QString error;
+ if (!instance)
+ error = "cannot resolve 'qt_plugin_instance': " + pluginLoader.errorString();
+
+ QtUiTest::MessageHandler *handler = qobject_cast<QtUiTest::MessageHandler*>(instance);
+ if (!handler) {
+ if (error.isEmpty()) error = pluginLoader.errorString();
+ QString formattedError;
+ QDebug(&formattedError)
+ << "QtUitest: failed to load qtuitest widgets plugin"
+ << "\n plugin" << plugin
+ << "\n instance" << instance
+ << "\n error" << error;
+ errors << formattedError;
+ } else {
+ pluginsToLoad -= plugin;
+ registerHandler(handler);
+ }
+ }
+ }
+
+ foreach (const QString& error, errors)
+ qWarning() << qPrintable(error);
+}
+
+QstMessage QTestSlave::constructReplyToMessage( const QstMessage &_msg )
+{
+ QTT_TRACE_FUNCTION();
+ QstMessage reply;
+ QstMessage msg(_msg);
+
+// TO HANDLE A NEW SYSTEM TEST EVENT:
+// implement a function with signature:
+// QstMessage QTestSlavePrivate::eventName(const QstMessage &message)
+
+ QString event = msg.event();
+ int pos = event.lastIndexOf(QChar('/'));
+ if (pos != -1) {
+ QtUiTest::MessageHandler *handler = m_messageHandlers[event.left(pos)];
+ if (handler) {
+ msg.setEvent(event.mid(pos+1));
+ reply = handler->handleMessage(msg);
+ }
+ // TODO: Ensure correct plugin is loaded
+ // and call constructReplyToMessage there (handleMessage?)
+ } else {
+ d->resetBenchmarks();
+ if (!QMetaObject::invokeMethod(d, msg.event().toLatin1().constData(), Qt::DirectConnection,
+ Q_RETURN_ARG(QstMessage, reply),
+ Q_ARG(QstMessage, msg))) {
+ (void)MESSAGE_ERROR(reply, "ERROR: Unhandled event '" + msg.event() + "'");
+ }
+
+#ifdef QTUITEST_CPU_TICKS
+ reply["cpuTicks"] = d->cpuTicks();
+#endif
+ }
+
+ if (!QtUiTest::debugOutput().isEmpty()) {
+ reply["debug"] = QtUiTest::debugOutput();\
+ }
+
+ if (!QtUiTest::errorString().isEmpty()) {
+ reply.setState(QstMessage::MessageError);
+ return MESSAGE_ERROR(reply, QtUiTest::errorString());
+ }
+
+ if (reply.state() == QstMessage::MessageEmpty) {
+ reply.setState(QstMessage::MessageSuccess);
+ }
+ return reply;
+}
+
+/*
+ Return true if first item is higher than second item, based on z-order.
+ This does not mean that the higher item obscures the other, as they may
+ not be overlapping, or the higher item may be transparent.
+
+ See http://doc.qt.nokia.com/qt5-snapshot/qml-qtquick2-item.html#z-prop
+
+ * Find nearestCommonAncestor (common ancestor closest to both items)
+
+ Neither item is ancestor of other ¦ One item is ancestor of another
+ ¦
+ root ¦ root
+ +-- ... ¦ +-- ...
+ +-- nearestCommonAncestor ¦ +-- o1 == keyAncestor1 *
+ +-- ... ¦ +-- keyAncestor2
+ +-- keyAncestor1 ¦ +-- ...
+ ¦ +-- ... ¦ +-- o2
+ ¦ +-- o1 ¦
+ +-- keyAncestor2 ¦ * nearestCommonAncestor == o1
+ +-- ... ¦
+ +-- o2 ¦
+
+ * There should always be at least one common ancestor
+ * The nearestCommonAncestor may be o1 or o2 (if one item is an ancestor
+ of the other). If nearestCommonAncestor == o1 then keyAncestor1 == o1,
+ (and similarly for o2)
+ * z1 is keyAncestor1's z property, z2 == keyAncestor2's z property
+ * If neither item is an ancestor of the other, then keyAncestors will be
+ siblings. Their z values (z1 and z2) are compared:
+ (z1 > z2) --> o1 is above o2 (return true)
+ (z1 < z2) --> o2 is above o1 (return false)
+ If (z1 == z2), use the position of each keyAncestor in the
+ nearestCommonAncestor's child list (later sibling is above the earlier)
+ * If o1 is an ancestor of o2, then o2 will be above o1 UNLESS z2 is negative
+ * If o2 is an ancestor of o1, then o1 will be above o2 UNLESS z1 is negative
+
+*/
+QstMessage QTestSlavePrivate::isHigher( const QstMessage &message )
+{
+ QTT_TRACE_FUNCTION();
+ QstMessage reply;
+ QString error;
+
+ QString sig1 = message["widgetSpecifier"].toString();
+ QObject *o1;
+ if (!QActiveTestWidget::instance()->findWidget( sig1, o1, error)) {
+ return reply;
+ }
+ QtUiTest::Object *w1 = qtuitest_cast<QtUiTest::Object*>(o1);
+
+ QString sig2 = message["otherwidget"].toString();
+ QObject *o2;
+ if (!QActiveTestWidget::instance()->findWidget( sig2, o2, error)) {
+ return reply;
+ }
+ QtUiTest::Object *w2 = qtuitest_cast<QtUiTest::Object*>(o2);
+
+ if (!(w1 && w2)) {
+ if (!QtUiTest::errorString().isEmpty())
+ return reply;
+ QtUiTest::setErrorString(QLatin1String("Widget not found"));
+ return reply;
+ }
+
+ QObjectList ancestors1 = w1->ancestors();
+ QObjectList ancestors2 = w2->ancestors();
+ ancestors1.prepend(o1);
+ ancestors2.prepend(o2);
+
+ QObject *nearestCommonAncestor = 0;
+ QObject *keyAncestor1 = 0;
+ QObject *keyAncestor2 = 0;
+ int al1 = ancestors1.length();
+ int al2 = ancestors2.length();
+ int alength = ((al1 > al2) ? al2 : al1);
+
+ // Work from end of list (root item) to start (the item)
+ for (int i=0; i< alength; i++) {
+ QObject *a1 = ancestors1.takeLast();
+ QObject *a2 = ancestors2.takeLast();
+ if (a1 == a2) {
+ nearestCommonAncestor = a1;
+ } else {
+ keyAncestor1 = a1;
+ keyAncestor2 = a2;
+ break;
+ }
+ }
+ if (keyAncestor1 == 0) {
+ if (ancestors1.isEmpty()) {
+ keyAncestor1 = o1;
+ } else {
+ keyAncestor1 = ancestors1.takeLast();
+ }
+ }
+ if (keyAncestor2 == 0) {
+ if (ancestors2.isEmpty()) {
+ keyAncestor2 = o2;
+ } else {
+ keyAncestor2 = ancestors2.takeLast();
+ }
+ }
+ if (nearestCommonAncestor == 0) {
+ // no common ancestor, this should not be possible
+ reply["ishigher"] = false;
+ QtUiTest::setErrorString(QLatin1String("Cannot find a common ancestor item"));
+ return reply;
+ }
+
+ bool ok;
+ double z1 = keyAncestor1->property("z").toDouble(&ok);
+ if (!ok) {
+ z1 = 0;
+ }
+
+ double z2 = keyAncestor2->property("z").toDouble(&ok);
+ if (!ok) {
+ z2 = 0;
+ }
+
+ QtUiTest::Object *nca = qtuitest_cast<QtUiTest::Object*>(nearestCommonAncestor);
+ bool ret = false;
+ if (nearestCommonAncestor == keyAncestor1) {
+ // first item is ancestor of second item, so can only be
+ // above it if z2 < 0
+ ret = (z2 < 0);
+ } else if (nearestCommonAncestor == keyAncestor2) {
+ // second item is ancestor of first item
+ ret = (z1 >= 0);
+ } else if (z1 > z2) {
+ ret = true;
+ } else if (z1 == z2) {
+ // The z values are equal, so which item is on top depends
+ // on the position in list of children
+ QObjectList ncaChildren = nca->children();
+ ret = (ncaChildren.indexOf(keyAncestor1) > ncaChildren.indexOf(keyAncestor2));
+ }
+
+ reply["isHigher"] = ret;
+ return reply;
+}
+
+QstMessage QTestSlavePrivate::enterText(const QstMessage &message)
+{
+ QTT_TRACE_FUNCTION();
+ QstMessage reply;
+ if (!message["text"].isValid()) {
+ return MESSAGE_ERROR(reply, "ERROR_MISSING_PARAMETERS");
+ }
+ QString text = message["text"].toString();
+
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
+ QPlatformInputContext *ic = QGuiApplicationPrivate::platformIntegration()->inputContext();
+ foreach (const QChar& c, text) {
+ Qt::KeyboardModifiers modifiers = asciiToModifiers(c.toLatin1());
+ QKeyEvent pressEvent(QEvent::KeyPress, c.unicode(), modifiers, QString(c), false, 1);
+ QKeyEvent releaseEvent(QEvent::KeyRelease, c.unicode(), modifiers, QString(c), false, 1);
+ QMetaObject::invokeMethod(ic, "sendKeyEvent", Qt::DirectConnection, Q_ARG(QKeyEvent*, &pressEvent));
+ QMetaObject::invokeMethod(ic, "sendKeyEvent", Qt::DirectConnection, Q_ARG(QKeyEvent*, &releaseEvent));
+ }
+#endif
+ return reply;
+}
+
+QstMessage QTestSlavePrivate::keyPress(const QstMessage &message)
+{
+ QTT_TRACE_FUNCTION();
+ QstMessage reply;
+ if (!message["key"].isValid()) {
+ return MESSAGE_ERROR(reply, "ERROR_MISSING_KEY");
+ }
+
+ Qt::Key key = QtUiTest::variantToKey(message["key"]);
+
+ if (!key) return MESSAGE_ERROR(reply, "ERROR_ZERO_KEY");
+
+ QtUiTest::keyPress(key);
+
+ if (message["duration"].isValid()) {
+ int duration = message["duration"].toInt();
+ if (duration >= 500) {
+ QtUiTest::wait(500);
+ duration -= 500;
+ bool keyRepeat=QtUiTest::testInputOption(QtUiTest::KeyRepeat);
+ QtUiTest::setInputOption(QtUiTest::KeyRepeat, true);
+ QtUiTest::keyPress(key);
+ while (duration > 0) {
+ QtUiTest::wait(150);
+ duration -= 150;
+ QtUiTest::keyPress(key);
+ }
+ QtUiTest::setInputOption(QtUiTest::KeyRepeat, keyRepeat);
+ } else {
+ QtUiTest::wait(duration);
+ }
+ }
+
+ return reply;
+}
+
+QstMessage QTestSlavePrivate::keyRelease(const QstMessage &message)
+{
+ QTT_TRACE_FUNCTION();
+ QstMessage reply;
+ if (!message["key"].isValid()) {
+ return MESSAGE_ERROR(reply, "ERROR_MISSING_KEY");
+ }
+
+ Qt::Key key = QtUiTest::variantToKey(message["key"]);
+
+ if (!key) return MESSAGE_ERROR(reply, "ERROR_ZERO_KEY");
+ QtUiTest::keyRelease(key);
+ return reply;
+}
+
+QstMessage QTestSlavePrivate::keyClick(const QstMessage &message)
+{
+ QTT_TRACE_FUNCTION();
+ QstMessage reply;
+ if (!message["key"].isValid()) {
+ return MESSAGE_ERROR(reply, "ERROR_MISSING_KEY");
+ }
+
+ Qt::Key key = QtUiTest::variantToKey(message["key"]);
+
+ if (!key) return MESSAGE_ERROR(reply, "ERROR_ZERO_KEY");
+ QtUiTest::keyClick(key);
+ return reply;
+}
+
+QstMessage QTestSlavePrivate::touchPress(const QstMessage &message)
+{
+ QTT_TRACE_FUNCTION();
+ QstMessage reply;
+
+ QVariantList points(touchPointsForMessage(message));
+ if (!QtUiTest::errorString().isEmpty())
+ return reply;
+
+ QtUiTest::touchPress(points);
+ return reply;
+}
+
+QstMessage QTestSlavePrivate::touchUpdate(const QstMessage &message)
+{
+ QTT_TRACE_FUNCTION();
+ QstMessage reply;
+
+ QVariantList points(touchPointsForMessage(message));
+ if (!QtUiTest::errorString().isEmpty())
+ return reply;
+
+ QtUiTest::touchUpdate(points);
+ return reply;
+}
+
+QstMessage QTestSlavePrivate::touchRelease(const QstMessage &message)
+{
+ QTT_TRACE_FUNCTION();
+ QstMessage reply;
+
+ QVariantList points(touchPointsForMessage(message));
+ if (!QtUiTest::errorString().isEmpty())
+ return reply;
+
+ QtUiTest::touchRelease(points);
+ return reply;
+}
+
+
+QstMessage QTestSlavePrivate::mousePress(const QstMessage &message)
+{
+ QTT_TRACE_FUNCTION();
+ QstMessage reply;
+ bool ok;
+ Qt::MouseButtons buttons = (Qt::MouseButtons)(message["buttons"].toInt(&ok));
+ if (!ok) buttons = Qt::LeftButton;
+
+ QPoint pos(mousePointForMessage(message));
+ if (!QtUiTest::errorString().isEmpty())
+ return reply;
+
+ QtUiTest::mousePress(pos, buttons);
+ return reply;
+}
+
+QstMessage QTestSlavePrivate::mouseRelease(const QstMessage &message)
+{
+ QTT_TRACE_FUNCTION();
+ QstMessage reply;
+ bool ok;
+ Qt::MouseButtons buttons = (Qt::MouseButtons)(message["buttons"].toInt(&ok));
+ if (!ok) buttons = Qt::LeftButton;
+
+ QPoint pos(mousePointForMessage(message));
+ if (!QtUiTest::errorString().isEmpty())
+ return reply;
+
+ QtUiTest::mouseRelease(pos, buttons);
+ return reply;
+}
+
+QstMessage QTestSlavePrivate::mouseClick(const QstMessage &message)
+{
+ QTT_TRACE_FUNCTION();
+ QstMessage reply;
+ bool ok;
+ Qt::MouseButtons buttons = (Qt::MouseButtons)(message["buttons"].toInt(&ok));
+ if (!ok) buttons = Qt::LeftButton;
+
+ QPoint pos(mousePointForMessage(message));
+ if (!QtUiTest::errorString().isEmpty())
+ return reply;
+
+ QtUiTest::mouseClick(pos, buttons);
+ return reply;
+}
+
+QstMessage QTestSlavePrivate::mouseDoubleClick(const QstMessage &message)
+{
+ QTT_TRACE_FUNCTION();
+ QstMessage reply;
+ bool ok;
+ Qt::MouseButtons buttons = (Qt::MouseButtons)(message["buttons"].toInt(&ok));
+ if (!ok) buttons = Qt::LeftButton;
+
+ QPoint pos(mousePointForMessage(message));
+ if (!QtUiTest::errorString().isEmpty())
+ return reply;
+
+ QtUiTest::mouseDClick(pos, buttons);
+ return reply;
+}
+
+QstMessage QTestSlavePrivate::mouseMove(const QstMessage &message)
+{
+ QTT_TRACE_FUNCTION();
+ QstMessage reply;
+ QPoint pos(mousePointForMessage(message));
+
+ if (!QtUiTest::errorString().isEmpty())
+ return reply;
+
+ QtUiTest::mouseMove(pos);
+ return reply;
+}
+
+QVariantList QTestSlavePrivate::touchPointsForMessage(const QstMessage &message)
+{
+ QTT_TRACE_FUNCTION();
+ if (message["points"].isValid())
+ return message["points"].toList();
+
+ QVariantList ret;
+ Widget *w = findTestWidget<Widget>(message);
+ if (w)
+ ret += w->geometry().center();
+
+ return ret;
+}
+
+QPoint QTestSlavePrivate::mousePointForMessage(const QstMessage &message)
+{
+ QTT_TRACE_FUNCTION();
+ if (message["pos"].isValid())
+ return message["pos"].value<QPoint>();
+
+ QPoint ret;
+ Widget *w = findTestWidget<Widget>(message);
+ if (w) {
+ ret = w->geometry().center();
+ }
+
+ return ret;
+}
+
+QstMessage QTestSlavePrivate::translate( const QstMessage &message )
+{
+ QTT_TRACE_FUNCTION();
+ QstMessage reply;
+ QByteArray context = message["context"].toString().toLatin1();
+ QByteArray text = message["text"].toString().toLatin1();
+ QByteArray comment = message["comment"].toString().toLatin1();
+ int n = message["number"].toInt();
+ reply["translate"] = QCoreApplication::translate(context, text, comment, QCoreApplication::CodecForTr, n);
+ return reply;
+}
+
+QstMessage QTestSlavePrivate::trId( const QstMessage &message )
+{
+ QTT_TRACE_FUNCTION();
+ QstMessage reply;
+ QByteArray id = message["id"].toString().toLatin1();
+ int n = message["number"].toInt();
+ reply["trId"] = qtTrId(id, n);
+ return reply;
+}
+
+QstMessage QTestSlavePrivate::getLocale( const QstMessage &message )
+{
+ QTT_TRACE_FUNCTION();
+ Q_UNUSED(message);
+ QstMessage reply;
+ reply["getLocale"] = QLocale::system();
+ return reply;
+}
+
+QstMessage QTestSlavePrivate::setConfig(const QstMessage &message)
+{
+ QTT_TRACE_FUNCTION();
+ Q_UNUSED(message);
+ QstMessage reply;
+ if (message["autoScan"].isValid()) {
+ QActiveTestWidget::instance()->setAutoScan(message["autoScan"].toBool());
+ }
+
+ return reply;
+}
+
+QstMessage QTestSlavePrivate::rescan(const QstMessage &message)
+{
+ QTT_TRACE_FUNCTION();
+ Q_UNUSED(message);
+ QstMessage reply;
+ QString error;
+ QActiveTestWidget::instance()->forceRescan();
+ return reply;
+}
+
+QstMessage QTestSlavePrivate::typeOf( const QstMessage &message )
+{
+ QTT_TRACE_FUNCTION();
+ QstMessage reply;
+ QtUiTest::Object *w = findTestWidget<QtUiTest::Object>(message);
+ if (w) {
+ reply["typeOf"] = w->typeOf();
+ }
+ return reply;
+}
+
+QstMessage QTestSlavePrivate::inheritance( const QstMessage &message )
+{
+ QTT_TRACE_FUNCTION();
+ QstMessage reply;
+ QtUiTest::Object *w = findTestWidget<QtUiTest::Object>(message);
+ if (w) {
+ reply["inheritance"] = w->inheritance();
+ }
+ return reply;
+}
+
+QstMessage QTestSlavePrivate::queuedMessage( const QstMessage &message )
+{
+ QTT_TRACE_FUNCTION();
+ QstMessage reply;
+ bool ok;
+ int count = message["count"].toInt(&ok);
+ if (ok) {
+ for (int i=0; i<count; i++) {
+ QString event = message[QString("event_%1").arg(i)].toString();
+ QVariantMap map = message[QString("map_%1").arg(i)].toMap();
+ if (event == "wait") {
+ QtUiTest::wait(map["delay"].toInt());
+ } else {
+ QstMessage msg(event, map);
+ QstMessage reply = p->constructReplyToMessage(msg);
+ if (reply.state() != QstMessage::MessageSuccess) {
+ return reply;
+ }
+ }
+ }
+ }
+
+ return reply;
+}
+
+QstMessage QTestSlavePrivate::getMethods(const QstMessage &message)
+{
+ QObject *o;
+ QString error;
+ QstMessage reply;
+ if (!QActiveTestWidget::instance()->findWidget( message["widgetSpecifier"].toString(), o, error))
+ return MESSAGE_ERROR(reply, error);
+
+ QMetaObject const *mo = o->metaObject();
+ int count = mo->methodCount();
+ QVariantList methods;
+ for (int i=0; i<count; i++) {
+ QMetaMethod mm = mo->method(i);
+ QVariantMap methodMap;
+ methodMap["signature"] = methodSignature(mm);
+ methodMap["methodType"] = mm.methodType();
+ QStringList paramNames;
+ foreach (const QByteArray &param, mm.parameterNames()) {
+ paramNames << param;
+ }
+ if (!paramNames.isEmpty()) {
+ methodMap["paramNames"] = paramNames;
+ }
+ QStringList paramTypes;
+ foreach (const QByteArray &paramType, mm.parameterTypes()) {
+ paramTypes << paramType;
+ }
+ if (!paramTypes.isEmpty()) {
+ methodMap["paramTypes"] = paramTypes;
+ }
+ QString typeName(mm.typeName());
+ if (!typeName.isEmpty()) {
+ methodMap["returnType"] = typeName;
+ }
+ methods << methodMap;
+ }
+
+ reply[QLatin1String("getMethods")] = methods;
+ return reply;
+}
+
+QstMessage QTestSlavePrivate::expectSignal( const QstMessage &message )
+{
+ QstMessage reply;
+ QString error;
+
+ QString object = message["widgetSpecifier"].toString();
+ QString signal = message["signal"].toString();
+ if (object.isEmpty() || signal.isEmpty()) {
+ return MESSAGE_ERROR(reply, "ERROR_MISSING_PARAMETERS");
+ }
+
+ QObject *o;
+ if (!QActiveTestWidget::instance()->findWidget(object, o, error))
+ return MESSAGE_ERROR(reply, error);
+ QMetaObject const *mo = o->metaObject();
+ int m = mo->indexOfMethod(QMetaObject::normalizedSignature(qPrintable(signal)));
+ QMetaMethod mm = mo->method(m);
+ if (mm.methodType() != QMetaMethod::Signal) {
+ return MESSAGE_ERROR(reply, "Method is not a signal");
+ }
+
+ if (!m_signalWaiter.setExpectedSignal(o, signal.toLatin1())) {
+ return MESSAGE_ERROR(reply, "Unable to connect signal");
+ }
+
+ return reply;
+}
+
+QstMessage QTestSlavePrivate::waitForSignal( const QstMessage &message )
+{
+ QstMessage reply;
+ QString error;
+
+ int timeout = message["timeout"].toInt();
+ bool received = m_signalWaiter.waitForSignal(timeout);
+
+ if (!received) {
+ return MESSAGE_ERROR(reply, "Signal not received");
+ }
+
+ reply["args"] = QTestSlave::updateVariant(m_signalWaiter.argValues());
+ reply["elapsed"] = m_signalWaiter.elapsed();
+ return reply;
+}
+
+QstMessage QTestSlavePrivate::connectSignal( const QstMessage &message )
+{
+ QstMessage reply;
+ QString error;
+
+ QString object = message["widgetSpecifier"].toString();
+ QString signal = message["signal"].toString();
+ if (object.isEmpty() || signal.isEmpty()) {
+ return MESSAGE_ERROR(reply, "ERROR_MISSING_PARAMETERS");
+ }
+
+ QObject *o;
+ if (!QActiveTestWidget::instance()->findWidget(object, o, error))
+ return MESSAGE_ERROR(reply, error);
+ QMetaObject const *mo = o->metaObject();
+ int m = mo->indexOfMethod(QMetaObject::normalizedSignature(qPrintable(signal)));
+ QMetaMethod mm = mo->method(m);
+ if (mm.methodType() != QMetaMethod::Signal) {
+ return MESSAGE_ERROR(reply, "Method is not a signal");
+ }
+
+ ReceiverKey key(o, signal);
+ if (m_signalReceivers.contains(key)) {
+ // Already connected to this signal
+ return reply;
+ }
+ QtUiTestSignalReceiver* signalReceiver = new QtUiTestSignalReceiver(this);
+ m_signalReceivers[key] = signalReceiver;
+
+ if (!signalReceiver->connectSignal(o, signal.toLatin1())) {
+ delete signalReceiver;
+ return MESSAGE_ERROR(reply, "Unable to connect signal");
+ }
+
+ connect(o, SIGNAL(destroyed(QObject*)), this, SLOT(disconnectAllSignals(QObject*)), Qt::DirectConnection);
+ return reply;
+}
+
+QstMessage QTestSlavePrivate::disconnectSignal( const QstMessage &message )
+{
+ QstMessage reply;
+ QString error;
+
+ QString object = message["widgetSpecifier"].toString();
+ QString signal = message["signal"].toString();
+ if (object.isEmpty()) {
+ return MESSAGE_ERROR(reply, "ERROR_MISSING_PARAMETERS");
+ }
+
+ QObject *o;
+ if (!QActiveTestWidget::instance()->findWidget(object, o, error))
+ return MESSAGE_ERROR(reply, error);
+
+ if (signal.isEmpty()) {
+ disconnectAllSignals(o);
+ return reply;
+ }
+
+ ReceiverKey key(o, signal);
+ if (!m_signalReceivers.contains(key)) {
+ return MESSAGE_ERROR(reply, "Not connected to signal");
+ }
+
+ delete m_signalReceivers[key];
+ m_signalReceivers.remove(key);
+ return reply;
+}
+
+void QTestSlavePrivate::disconnectAllSignals(QObject *o)
+{
+ foreach (ReceiverKey key, m_signalReceivers.keys()) {
+ if (key.first == o) {
+ delete m_signalReceivers[key];
+ m_signalReceivers.remove(key);
+ }
+ }
+}
+
+QstMessage QTestSlavePrivate::cleanup( const QstMessage &message )
+{
+ Q_UNUSED(message);
+
+ foreach (QtUiTestSignalReceiver *receiver, m_signalReceivers.values()) {
+ delete receiver;
+ }
+ m_signalReceivers.clear();
+ QstMessage reply;
+ return reply;
+}
+
+void QTestSlavePrivate::signalReceived(QObject *sender, const QString &signal, const QVariantList &argValues)
+{
+ QstMessage msg("SIGNAL_RECEIVED");
+ msg["signal"] = signal;
+ msg["sender"] = QTestSlave::updateVariant(QVariant::fromValue(sender));
+ msg["args"] = QTestSlave::updateVariant(argValues);
+ p->postMessage( msg );
+}
+
+/*
+QstMessage QTestSlavePrivate::setSensorMode( const QstMessage &message )
+{
+ QTT_TRACE_FUNCTION();
+ QstMessage reply;
+
+ QByteArray sensorId = message["sensorId"].toByteArray();
+ QtUiTestSensorBackend::Mode mode = (QtUiTestSensorBackend::Mode)message["sensorMode"].toInt();
+
+ QtUiTestSensorBackend::setMode(sensorId, mode);
+
+ return reply;
+}
+
+QstMessage QTestSlavePrivate::getSensorMode( const QstMessage &message )
+{
+ QTT_TRACE_FUNCTION();
+ QstMessage reply;
+
+ QByteArray sensorId = message["sensorId"].toByteArray();
+ QtUiTestSensorBackend::Mode mode = QtUiTestSensorBackend::mode(sensorId);
+ reply["sensorMode"] = (int)mode;
+
+ return reply;
+}
+
+QstMessage QTestSlavePrivate::queueSensorValues( const QstMessage &message )
+{
+ QTT_TRACE_FUNCTION();
+ QstMessage reply;
+
+ QByteArray sensorId = message["sensorId"].toByteArray();
+ QList<QVariant> values = message["sensorValues"].toList();
+
+ QtUiTestSensorBackend::queueTestData(sensorId, values);
+
+ return reply;
+}
+
+QstMessage QTestSlavePrivate::getSensorValues( const QstMessage &message )
+{
+ QstMessage reply;
+
+ QByteArray sensorId = message["sensorId"].toByteArray();
+
+ reply["values"] = QVariant(QtUiTestSensorBackend::testData(sensorId));
+
+ return reply;
+}
+*/
diff --git a/src/remote/slave/lib/qtestslave.h b/src/remote/slave/lib/qtestslave.h
new file mode 100644
index 0000000..2f245fe
--- /dev/null
+++ b/src/remote/slave/lib/qtestslave.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QTESTSLAVE_H
+#define QTESTSLAVE_H
+
+#include "qtestwidgets.h"
+#include "qtuitestmessagehandler.h"
+
+#include <QtSystemTest/QstProtocol>
+
+class QTestSlavePrivate;
+
+class QTSLAVE_EXPORT QTestSlave : public QstProtocol
+{
+ Q_OBJECT
+public:
+ QTestSlave();
+ virtual ~QTestSlave();
+
+ virtual void processMessage(QstMessage*);
+ virtual QstMessage constructReplyToMessage(const QstMessage&);
+
+ static QVariant getObjectProperty(QtUiTest::Object *w, const QString &property);
+ static QVariant updateVariant(const QVariant &value);
+ static QVariantMap objectToMap(const QObject *obj, const QStringList& = QStringList());
+
+public slots:
+ virtual void onConnected();
+
+protected:
+ void registerHandler(QtUiTest::MessageHandler *handler);
+ void refreshPlugins();
+
+private:
+ QTestSlavePrivate *d;
+ QMap<QString,QtUiTest::MessageHandler*> m_messageHandlers;
+};
+
+template <typename T>
+T* findTestWidget(const QstMessage& message)
+{
+ using namespace QtUiTest;
+ T* ret = 0;
+ QstMessage reply;
+ QString error;
+ QString qp = message["widgetSpecifier"].toString();
+ QObject *o;
+ if (!QActiveTestWidget::instance()->findWidget( qp, o, error)) {
+ setErrorString(error);
+ return ret;
+ }
+
+ ret = qtuitest_cast<T*>(o);
+ if (!ret) {
+ setErrorString(QString("Error: %1 is not of type %2").arg(qp).arg(static_cast<T*>(0)->_q_interfaceName()));
+ } else {
+ setErrorString(QString());
+ }
+
+ return ret;
+}
+
+#endif
diff --git a/src/remote/slave/lib/qtestwidgets.cpp b/src/remote/slave/lib/qtestwidgets.cpp
new file mode 100644
index 0000000..f2e9077
--- /dev/null
+++ b/src/remote/slave/lib/qtestwidgets.cpp
@@ -0,0 +1,623 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <qtestwidgets.h>
+#include <QtSystemTest/QstDebug>
+#include <QRect>
+
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
+ #include <QGuiApplication>
+ #include <QWindow>
+#else
+ #include <QApplication>
+ #include <QWidget>
+#endif
+
+#include <QPlatformNativeInterface>
+
+#define qLog() if (1); else QtUiTest::debug()
+
+uint qHash(QPointer<QObject> o)
+{ return qHash((QObject*)o); }
+
+/*!
+ Returns a unique string identifier for \a object.
+*/
+QString QTestWidgets::signature( const QObject *o )
+{
+ if (!o) {
+ return QLatin1String("ERROR_NO_OBJECT");
+ }
+ QString ret = QActiveTestWidget::instance()->signature(o);
+ if (!ret.isEmpty()) {
+ return ret;
+ }
+
+ QtUiTest::Object* w = qtuitest_cast<QtUiTest::Object*>(o);
+ QString typeName;
+ if (w) {
+ typeName = w->typeOf();
+ } else {
+ typeName = o->metaObject()->className();
+ }
+
+ return QString("%1[%2]").arg(typeName).arg((long)(void*)o,0,32).replace(QLatin1Char(' '), QLatin1Char('_'));
+}
+
+/*!
+ Returns the testWidget that is associated with the given \a signature.
+*/
+QObject *QTestWidgets::testWidget( const QString &signature )
+{
+ QTT_TRACE_FUNCTION();
+ return QActiveTestWidget::instance()->testWidget(signature);
+}
+
+QObject *QActiveTestWidget::testWidget( const QString &signature )
+{
+ QTT_TRACE_FUNCTION();
+ QObject *rec = d->testWidgetsBySignature.value( signature, 0 );
+ return rec;
+}
+
+QString QActiveTestWidget::signature( const QObject *o ) const
+{
+ return d->signaturesByObject.value(o);
+}
+
+void QActiveTestWidget::registerTestWidget( QObject *ao )
+{
+ QTT_TRACE_FUNCTION();
+ QString new_signature = QTestWidgets::signature( ao );
+ if (d->testWidgetsBySignature.contains(new_signature)) {
+ return;
+ }
+ d->testWidgetsBySignature[new_signature] = ao;
+ d->signaturesByObject[ao] = new_signature;
+ connect( ao, SIGNAL(destroyed(QObject*)), this, SLOT(onDestroyed(QObject*)), Qt::DirectConnection );
+}
+
+void QActiveTestWidget::onDestroyed(QObject *o)
+{
+ QTT_TRACE_FUNCTION();
+ if (o) {
+ d->removeTestWidget(o);
+ }
+}
+
+QVariant QTestWidgets::windowProperty(const QString &property)
+{
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
+ QTT_TRACE_FUNCTION();
+ QWindow *rootWindow = qobject_cast<QWindow*>(activeWidget());
+ if (qGuiApp && rootWindow && qGuiApp->platformNativeInterface() && rootWindow->handle()) {
+ return qGuiApp->platformNativeInterface()->windowProperty(rootWindow->handle(), property);
+ }
+#endif
+ return QVariant();
+}
+
+/*!
+ Returns the current activeWindow, activePopupWidget or activeModalWidget.
+*/
+QObject* QTestWidgets::activeWidget()
+{
+ QTT_TRACE_FUNCTION();
+ QObject *w = 0;
+
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
+ w = qApp->focusWindow();
+
+ if (!w && !qApp->topLevelWindows().isEmpty())
+ w = qApp->topLevelWindows().first();
+#else
+ if (w == 0) w = qApp->activeModalWidget();
+ if (w == 0) w = qApp->activePopupWidget();
+ if (w == 0) w = qApp->activeWindow();
+ if (w == 0) w = qApp->focusWidget();
+#endif
+
+ return w;
+}
+
+QStringList QTestWidgets::objectListToSignatures(const QObjectList& ol)
+{
+ QTT_TRACE_FUNCTION();
+ QStringList ret;
+ foreach (QObject *obj, ol) {
+ ret << QTestWidgets::signature(obj);
+ }
+ return ret;
+}
+
+
+QActiveTestWidgetData::QActiveTestWidgetData()
+{
+ QTT_TRACE_FUNCTION();
+}
+
+QActiveTestWidgetData::~QActiveTestWidgetData()
+{
+ QTT_TRACE_FUNCTION();
+}
+
+void QActiveTestWidgetData::clear()
+{
+ QTT_TRACE_FUNCTION();
+ testWidgetsBySignature.clear();
+ signaturesByObject.clear();
+ m_scannedItems.clear();
+}
+
+void QActiveTestWidgetData::removeTestWidget( QObject *w )
+{
+ QTT_TRACE_FUNCTION();
+ m_scannedItems.remove(w);
+ testWidgetsBySignature.remove( QTestWidgets::signature(w) );
+ signaturesByObject.remove(w);
+}
+
+bool QActiveTestWidgetData::scan( QObject *ao, QtUiTest::QueryFlags flags )
+{
+ QTT_TRACE_FUNCTION();
+ if (!ao) return false;
+
+ QActiveTestWidget::instance()->registerTestWidget(ao);
+ QtUiTest::Object* aw = qtuitest_cast<QtUiTest::Object*>(ao);
+ if (aw == 0) return false;
+ bool any_appended = false;
+ foreach(QObject *o, aw->children()) {
+ QActiveTestWidget::instance()->registerTestWidget(o);
+
+ QtUiTest::Widget* qw = qtuitest_cast<QtUiTest::Widget*>(o);
+
+ if (!qw->isVisible() && !(flags & QtUiTest::ScanInvisible)) {
+ continue;
+ }
+
+ if (!qw->ignoreScan() || (flags & QtUiTest::ScanDisabledItems)) {
+ // Recursively scan child widgets
+ any_appended |= scan(o, flags);
+ }
+
+ if (!m_scannedItems.contains(o)) {
+ any_appended = true;
+ m_scannedItems.insert(o);
+ }
+ }
+
+ return any_appended;
+}
+
+
+QActiveTestWidget::QActiveTestWidget()
+{
+ QTT_TRACE_FUNCTION();
+ d = new QActiveTestWidgetData();
+ auto_scan = true;
+}
+
+QActiveTestWidget::~QActiveTestWidget()
+{
+ QTT_TRACE_FUNCTION();
+ delete d;
+}
+
+QActiveTestWidget* QActiveTestWidget::instance()
+{
+ static QActiveTestWidget qatw;
+ return &qatw;
+}
+
+void QActiveTestWidget::clear()
+{
+ QTT_TRACE_FUNCTION();
+ if (d == 0) {
+ d = new QActiveTestWidgetData();
+ } else
+ d->clear();
+}
+
+const QLatin1String QActiveTestWidget::NoActiveWidgetError("ERROR: No active widget available");
+
+bool QActiveTestWidget::rescan(QtUiTest::QueryFlags flags)
+{
+ QTT_TRACE_FUNCTION();
+ if (!auto_scan) return true;
+
+ if (d == 0) d = new QActiveTestWidgetData();
+ d->m_scannedItems.clear();
+
+ QObject *activeWidget = QTestWidgets::activeWidget();
+ if (activeWidget == 0) {
+ QtUiTest::setErrorString(NoActiveWidgetError);
+ return false;
+ }
+
+ d->scan(qApp, flags);
+ return true;
+}
+
+QStringList QActiveTestWidget::descendantTree(QObject *obj)
+{
+ QStringList ret;
+ QtUiTest::Object *tw = qtuitest_cast<QtUiTest::Object*>(obj);
+ if (!tw) {
+ return ret;
+ }
+ ret << QString("%1 [ %2 ]").arg(QTestWidgets::signature(obj)).arg(tw->debugString());
+ QObjectList children = tw->children();
+ int length = children.length();
+ for (int i=0; i<length; ++i) {
+ QObject *child = children[i];
+ QStringList childTree = descendantTree(child);
+ ret << QString("+- %1").arg(childTree.takeFirst());
+ foreach (const QString &row, childTree) {
+ if (i < length-1) {
+ ret << QString("| %1").arg(row);
+ } else {
+ ret << QString(" %1").arg(row);
+ }
+ }
+ }
+ return ret;
+}
+
+void QActiveTestWidget::setAutoScan(bool doScan)
+{
+ auto_scan = doScan;
+}
+
+bool QActiveTestWidget::forceRescan()
+{
+ bool prev = auto_scan;
+ auto_scan = true;
+ bool ret = rescan();
+ auto_scan = prev;
+ return ret;
+}
+
+bool QActiveTestWidget::findWidget( const QString &signature, QObject *&buddy, QString &error )
+{
+ QTT_TRACE_FUNCTION();
+ if (signature.isEmpty()) {
+ error = QLatin1String("ERROR: No widget specified\n");
+ return false;
+ }
+ buddy = QTestWidgets::testWidget(signature);
+ return (buddy != 0);
+}
+
+/*!
+ Returns a QVariantMap containing details of object specified by \a signature
+ and descendants. This is used by the Object Browser.
+*/
+QVariantMap QActiveTestWidget::getObjects(const QString &signature)
+{
+ QTT_TRACE_FUNCTION();
+ QVariantMap map;
+ QObject *baseObject = QTestWidgets::testWidget(signature);
+
+ //FIXME: For now:
+ baseObject = qApp;
+
+ if (!baseObject) {
+ return map;
+ }
+
+ QtUiTest::Object *tw = qtuitest_cast<QtUiTest::Object*>(baseObject);
+ if (!tw) {
+ return map;
+ }
+
+ QObjectList objects;
+ objects << baseObject << tw->descendants();
+
+ QVariantMap idMap;
+ QVariantMap geometryMap;
+ QVariantMap childMap;
+ QVariantMap typeMap;
+ QVariantMap objectNameMap;
+ QVariantMap visibleMap;
+ QVariantMap textMap;
+ QVariantMap windowMap;
+
+ foreach (QObject *obj, objects) {
+ QActiveTestWidget::instance()->registerTestWidget(obj);
+ QtUiTest::Object *to = qtuitest_cast<QtUiTest::Object*>(obj);
+
+ if (to) {
+ QString sig = QTestWidgets::signature(obj);
+ QObjectList children = to->children();
+ if (!children.isEmpty()) {
+ childMap[sig] = QTestWidgets::objectListToSignatures(to->children());
+ }
+ objectNameMap[sig] = to->getProperty("objectName");
+ typeMap[sig] = to->typeOf();
+ QtUiTest::Widget *tw = qtuitest_cast<QtUiTest::Widget*>(obj);
+ if (tw) {
+ geometryMap[sig] = tw->geometry();
+ idMap[sig] = to->getProperty("QMLID");
+ visibleMap[sig] = to->getProperty("visible");
+ textMap[sig] = to->getProperty("text");
+ windowMap[sig] = QTestWidgets::signature(tw->window());
+ }
+ }
+ }
+
+ map["geometry"] = geometryMap;
+ map["qmlid"] = idMap;
+ map["children"] = childMap;
+ map["type"] = typeMap;
+ map["objectName"] = objectNameMap;
+ map["visible"] = visibleMap;
+ map["text"] = textMap;
+ map["window"] = windowMap;
+
+ return map;
+}
+
+const QLatin1String QActiveTestWidget::childOfProperty("CHILD_OF");
+const QLatin1String QActiveTestWidget::descendantOfProperty("DESCENDANT_OF");
+const QLatin1String QActiveTestWidget::ancestorOfProperty("ANCESTOR_OF");
+const QLatin1String QActiveTestWidget::parentOfProperty("PARENT_OF");
+const QLatin1String QActiveTestWidget::resourceOfProperty("RESOURCE_OF");
+
+QObjectList QActiveTestWidget::findObjectsByProperty( const QString &property, const QVariant &searchValue, const QObjectList &searchList )
+{
+ QTT_TRACE_FUNCTION();
+ QObjectList foundList;
+ QString propertyUpper = property.toUpper();
+
+ bool ok;
+ PropertyMatcher matcher(searchValue, ok);
+ if (!ok) {
+ QtUiTest::setErrorString(QString("Unable to match for property '%1'").arg(property));
+ return foundList;
+ }
+
+ foreach (QObject *obj, searchList) {
+ QtUiTest::Object *qo = qtuitest_cast<QtUiTest::Object*>(obj);
+ if (!qo) {
+ continue;
+ }
+
+ QVariant value = qo->getProperty(property);
+ if (value.isValid()) {
+ if (QObject *obj = value.value<QObject*>()) {
+ value = QTestWidgets::signature(obj);
+ }
+
+ // Allow enums to match by value or by string
+ if (value.type() == QVariant::Map
+ && value.toMap().contains(QLatin1String("_value_"))) {
+ if (searchValue.type() == QVariant::String
+ || searchValue.type() == QVariant::ByteArray) {
+ value = value.toMap().value(QLatin1String("_enum_"));
+ } else {
+ value = value.toMap().value(QLatin1String("_value_"));
+ }
+ }
+
+ if (matcher.match(value)) {
+ foundList << obj;
+ }
+ continue;
+ }
+
+ if (qo->matchProperty(propertyUpper, searchValue)) {
+ foundList << obj;
+ continue;
+ }
+ }
+
+ return foundList;
+}
+
+QObjectList QActiveTestWidget::queryProperties( const QVariantMap &searchValues, QtUiTest::QueryFlags flags )
+{
+ QTT_TRACE_FUNCTION();
+ QSet<QObject*> initObjects;
+ QObjectList searchList;
+
+ if (!((flags & QtUiTest::NoScan) || (flags & QtUiTest::IgnoreScanned))) {
+ if (!rescan(flags)) {
+ return searchList;
+ }
+ }
+
+ if (!(flags & QtUiTest::IgnoreScanned)) {
+ initObjects << QTestWidgets::activeWidget();
+ initObjects.unite(d->m_scannedItems);
+ }
+
+ static QStringList filterProperties(QStringList()
+ << ancestorOfProperty << childOfProperty << descendantOfProperty
+ << parentOfProperty << resourceOfProperty);
+
+ QVariantMap::const_iterator i = searchValues.constBegin();
+ while (i != searchValues.constEnd()) {
+ QString property = i.key().toUpper();
+ if (filterProperties.contains(property)) {
+ QObjectList filterList;
+ QString signature;
+ if (i.value().type() == QVariant::Map) {
+ signature = i.value().toMap().value(QLatin1String("_signature_")).toString();
+ } else {
+ signature = i.value().toString();
+ }
+
+ QString error;
+ QObject *w;
+
+ if (findWidget(signature, w, error)) {
+ QtUiTest::Object *qw = qtuitest_cast<QtUiTest::Object*>(w);
+ if (!qw) {
+ QtUiTest::setErrorString(QString("Can't find widget '%1' for property '%2'").arg(signature).arg(property));
+ return searchList;
+ }
+ if (property == childOfProperty) {
+ filterList << qw->children();
+ } else if (property == descendantOfProperty) {
+ filterList << qw->descendants();
+ } else if (property == ancestorOfProperty) {
+ filterList << qw->ancestors();
+ } else if (property == parentOfProperty) {
+ filterList << qw->parent();
+ } else if (property == resourceOfProperty) {
+ QVariantList resources = qw->resources();
+ foreach (const QVariant resource, resources) {
+ if (QObject *obj = resource.value<QObject*>()) {
+ filterList << obj;
+ }
+ }
+ }
+ }
+
+ if (initObjects.isEmpty()) {
+ initObjects = QSet<QObject*>::fromList(filterList);
+ } else {
+ foreach (QObject *obj, initObjects) {
+ if (!filterList.contains(obj)) {
+ initObjects.remove(obj);
+ }
+ }
+ if (initObjects.isEmpty()) {
+ return searchList;
+ }
+ }
+ }
+ ++i;
+ }
+
+ searchList = initObjects.toList();
+
+ i = searchValues.constBegin();
+ while (i != searchValues.constEnd()) {
+ if (!filterProperties.contains(i.key().toUpper())) {
+ searchList = findObjectsByProperty(i.key(), i.value(), searchList);
+ if (searchList.isEmpty())
+ break;
+ }
+ ++i;
+ }
+
+ return searchList;
+}
+
+PropertyMatcher::PropertyMatcher(const QVariant &searchValue, bool &ok)
+ : m_matchFunction(0)
+ , m_searchDouble(0)
+{
+ ok = true;
+ if (searchValue.type() == QVariant::Map) {
+ QVariantMap map = searchValue.toMap();
+ m_searchValue = map["_value_"];
+ QString op = map["_op_"].toString();
+ if (op == QLatin1String("eq")) {
+ m_matchFunction = &PropertyMatcher::equals;
+ } else if (op == QLatin1String("ne")) {
+ m_matchFunction = &PropertyMatcher::notEquals;
+ } else if (op == QLatin1String("in")) {
+ m_matchFunction = &PropertyMatcher::containedIn;
+ ok = m_searchValue.canConvert(QVariant::StringList);
+ if (ok)
+ m_searchList = m_searchValue.toStringList();
+ } else if (op == QLatin1String("gt")) {
+ m_matchFunction = &PropertyMatcher::greaterThan;
+ ok = m_searchValue.canConvert(QVariant::Double);
+ if (ok)
+ m_searchDouble = m_searchValue.toDouble();
+ } else if (op == QLatin1String("lt")) {
+ m_matchFunction = &PropertyMatcher::lessThan;
+ ok = m_searchValue.canConvert(QVariant::Double);
+ if (ok)
+ m_searchDouble = m_searchValue.toDouble();
+ } else {
+ ok = false;
+ }
+ return;
+ } else if (searchValue.type() == QVariant::RegExp) {
+ m_searchRegExp = searchValue.toRegExp();
+ m_matchFunction = &PropertyMatcher::regExpMatch;
+ ok = m_searchRegExp.isValid();
+ return;
+ }
+
+ m_matchFunction = &PropertyMatcher::equals;
+ m_searchValue = searchValue;
+}
+
+bool PropertyMatcher::match(const QVariant &value) const
+{
+ return (const_cast<const PropertyMatcher*>(this)->*m_matchFunction)(value);
+}
+
+bool PropertyMatcher::equals(const QVariant &value) const
+{
+ return value == m_searchValue;
+}
+
+bool PropertyMatcher::notEquals(const QVariant &value) const
+{
+ return value != m_searchValue;
+}
+
+bool PropertyMatcher::containedIn(const QVariant &value) const
+{
+ return m_searchList.contains(value.toString());
+}
+
+bool PropertyMatcher::greaterThan(const QVariant &value) const
+{
+ return value.toDouble() > m_searchDouble;
+}
+
+bool PropertyMatcher::lessThan(const QVariant &value) const
+{
+ return value.toDouble() < m_searchDouble;
+}
+
+bool PropertyMatcher::regExpMatch(const QVariant &value) const
+{
+ return m_searchRegExp.exactMatch(value.toString());
+}
diff --git a/src/remote/slave/lib/qtestwidgets.h b/src/remote/slave/lib/qtestwidgets.h
new file mode 100644
index 0000000..bc74432
--- /dev/null
+++ b/src/remote/slave/lib/qtestwidgets.h
@@ -0,0 +1,158 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QTESTWIDGETS_H
+#define QTESTWIDGETS_H
+
+#include <QHash>
+#include <QMetaType>
+#include <QObject>
+#include <QPointer>
+#include <QString>
+#include <QStringList>
+#include <QVariantMap>
+
+#include <QtSystemTest/qstglobal.h>
+
+#include "qtuitestnamespace.h"
+
+class QTestWidget;
+
+class QTSLAVE_EXPORT QActiveTestWidgetData : public QObject
+{
+public:
+ QActiveTestWidgetData();
+ ~QActiveTestWidgetData();
+
+ void clear();
+ void removeTestWidget( QObject* );
+ bool scan( QObject* aw, QtUiTest::QueryFlags flags=0 );
+
+ QHash<QString, QObject*> testWidgetsBySignature;
+ QHash<const QObject*, QString> signaturesByObject;
+ QSet<QObject*> m_scannedItems;
+};
+
+class QTSLAVE_EXPORT QActiveTestWidget : public QObject
+{
+ Q_OBJECT
+
+public:
+ static QActiveTestWidget* instance();
+ void clear();
+ bool rescan( QtUiTest::QueryFlags flags=0 );
+ QStringList descendantTree(QObject *obj);
+ bool findWidget( const QString &signature, QObject *&widget, QString &error );
+ QObjectList findObjectsByProperty( const QString&, const QVariant&, const QObjectList& = QObjectList() );
+ QObjectList queryProperties( const QVariantMap&, QtUiTest::QueryFlags flags );
+ QVariantMap getObjects(const QString&);
+ QObject* testWidget( const QString &signature );
+ QString signature( const QObject *) const;
+ void registerTestWidget( QObject *ao );
+ void setAutoScan(bool);
+ bool forceRescan();
+
+ static const QLatin1String NoActiveWidgetError;
+
+ static const QLatin1String ancestorOfProperty;
+ static const QLatin1String childOfProperty;
+ static const QLatin1String descendantOfProperty;
+ static const QLatin1String parentOfProperty;
+ static const QLatin1String resourceOfProperty;
+
+protected slots:
+ void onDestroyed(QObject*);
+
+private:
+ QActiveTestWidget();
+ ~QActiveTestWidget();
+
+ bool auto_scan;
+ QActiveTestWidgetData *d;
+};
+
+//
+// This is the class that manages the test widgets and handles queries about them.
+//
+class QTSLAVE_EXPORT QTestWidgets
+{
+public:
+ static QObject* activeWidget();
+ static QVariant windowProperty(const QString&);
+ static QObject* testWidget( const QString &signature );
+ static QString signature( const QObject* object );
+ static QStringList objectListToSignatures(const QObjectList&);
+
+ static bool lessThan(QObject *a, QObject *b) {
+ QtUiTest::Widget *wa = qtuitest_cast<QtUiTest::Widget*>(a);
+ QtUiTest::Widget *wb = qtuitest_cast<QtUiTest::Widget*>(b);
+ if (!wa) return true;
+ if (!wb) return false;
+ if (wa->y() == wb->y())
+ return wa->x() < wb->x();
+ else
+ return wa->y() < wb->y();
+ }
+};
+
+class PropertyMatcher
+{
+public:
+ PropertyMatcher(const QVariant &searchValue, bool &ok);
+ bool match(const QVariant &value) const;
+
+private:
+ bool equals(const QVariant &value) const;
+ bool notEquals(const QVariant &value) const;
+ bool containedIn(const QVariant &value) const;
+ bool greaterThan(const QVariant &value) const;
+ bool lessThan(const QVariant &value) const;
+ bool regExpMatch(const QVariant &value) const;
+
+ QVariant m_searchValue;
+ QStringList m_searchList;
+ QRegExp m_searchRegExp;
+ bool (PropertyMatcher::*m_matchFunction)(const QVariant&) const;
+ double m_searchDouble;
+};
+
+#endif
diff --git a/src/remote/slave/lib/qtuitestconnectionmanager.cpp b/src/remote/slave/lib/qtuitestconnectionmanager.cpp
new file mode 100644
index 0000000..dbb95b6
--- /dev/null
+++ b/src/remote/slave/lib/qtuitestconnectionmanager.cpp
@@ -0,0 +1,180 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "qtuitestconnectionmanager_p.h"
+
+#include <QCoreApplication>
+#include <QObject>
+#include <QThread>
+
+// from qobject_p.h
+struct QSignalSpyCallbackSet
+{
+ typedef void (*BeginCallback)(QObject*,int,void**);
+ typedef void (*EndCallback)(QObject*,int);
+ BeginCallback signal_begin_callback,
+ slot_begin_callback;
+ EndCallback signal_end_callback,
+ slot_end_callback;
+};
+extern void Q_CORE_EXPORT qt_register_signal_spy_callbacks(QSignalSpyCallbackSet const&);
+void qtuitest_signal_begin(QObject*,int,void**);
+
+Q_GLOBAL_STATIC(QtUiTestConnectionManager,_q_qtUiTestConnectionManager);
+
+QtUiTestConnectionManager::~QtUiTestConnectionManager()
+{
+ unregisterCallback();
+}
+
+QtUiTestConnectionManager* QtUiTestConnectionManager::instance()
+{
+ return _q_qtUiTestConnectionManager();
+}
+
+void qtuitest_signal_begin(QObject* sender, int signal, void** argv)
+{
+ QtUiTestConnectionManager* cm = QtUiTestConnectionManager::instance();
+
+ // Should only ever be null when the application is shutting down, but in that case,
+ // this callback should already have been unregistered.
+ Q_ASSERT(cm);
+
+ // During the destructor it isn't safe to check which thread we are.
+ // We'll just ignore all signals during this time.
+ if (QCoreApplication::closingDown()) return;
+
+ // Connections are only supported in the main thread.
+ if (QThread::currentThread() != QCoreApplication::instance()->thread()) return;
+
+ cm->activateConnections(sender,signal,argv);
+}
+
+void QtUiTestConnectionManager::connect(const QObject* sender, int senderMethod,
+ const QObject* receiver, int receiverMethod)
+{
+ Q_ASSERT(QThread::currentThread() == QCoreApplication::instance()->thread());
+
+ registerCallback();
+
+ Connection c = {
+ const_cast<QObject*>(sender), senderMethod,
+ const_cast<QObject*>(receiver), receiverMethod
+ };
+ m_connections << c;
+}
+
+bool QtUiTestConnectionManager::disconnect(const QObject* sender, int senderMethod,
+ const QObject* receiver, int receiverMethod)
+{
+ Q_ASSERT(QThread::currentThread() == QCoreApplication::instance()->thread());
+
+ bool ret = false;
+
+ QList<Connection>::iterator iter = m_connections.begin();
+ while (iter != m_connections.end())
+ {
+ bool remove = true;
+
+ if (sender && (sender != iter->sender)) remove = false;
+ if ((senderMethod != -1) && (senderMethod != iter->senderMethod)) remove = false;
+ if (receiver && (receiver != iter->receiver)) remove = false;
+ if ((receiverMethod != -1) && (receiverMethod != iter->receiverMethod)) remove = false;
+
+ if (remove) {
+ ret = true;
+ iter = m_connections.erase(iter);
+ }
+ else {
+ ++iter;
+ }
+ }
+
+ unregisterCallback();
+
+ return ret;
+}
+
+void QtUiTestConnectionManager::registerCallback()
+{
+ // If this is the first connect, then register the callback function
+ if (m_connections.isEmpty()) {
+ QSignalSpyCallbackSet callbacks = { qtuitest_signal_begin, 0, 0, 0 };
+ qt_register_signal_spy_callbacks(callbacks);
+ }
+}
+
+void QtUiTestConnectionManager::unregisterCallback()
+{
+ // If everything has been disconnected, remove the callback function
+ if (m_connections.isEmpty()) {
+ QSignalSpyCallbackSet callbacks = { 0, 0, 0, 0 };
+ qt_register_signal_spy_callbacks(callbacks);
+ }
+}
+
+void QtUiTestConnectionManager::activateConnections(QObject* sender, int senderMethod, void** argv)
+{
+ static const int destroyedMethod = QObject::staticMetaObject.indexOfSignal("destroyed(QObject*)");
+ const bool destroyed = (senderMethod == destroyedMethod);
+
+ // Find all of the connections we need to activate.
+ QList<Connection> toActivate;
+ QList<Connection>::iterator iter = m_connections.begin();
+ while (iter != m_connections.end())
+ {
+ if (sender == iter->sender && senderMethod == iter->senderMethod)
+ toActivate << *iter;
+
+ // Remove this connection if either the sender or receiver is being destroyed
+ if (destroyed && (sender == iter->sender || sender == iter->receiver)) {
+ iter = m_connections.erase(iter);
+ unregisterCallback();
+ }
+ else
+ ++iter;
+ }
+
+ foreach (Connection const& c, toActivate)
+ { if (c.receiver) c.receiver->qt_metacall(QMetaObject::InvokeMetaMethod, c.receiverMethod, argv); }
+}
+
diff --git a/src/remote/slave/lib/qtuitestconnectionmanager_p.h b/src/remote/slave/lib/qtuitestconnectionmanager_p.h
new file mode 100644
index 0000000..7a25b2b
--- /dev/null
+++ b/src/remote/slave/lib/qtuitestconnectionmanager_p.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QTUITESTCONNECTIONMANAGER_P_H
+#define QTUITESTCONNECTIONMANAGER_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtUiTest API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QList>
+#include <QtSystemTest/qstglobal.h>
+
+class QObject;
+
+class QTUITEST_EXPORT QtUiTestConnectionManager
+{
+public:
+ static QtUiTestConnectionManager* instance();
+
+ void connect (const QObject*,int,const QObject*,int);
+ bool disconnect(const QObject*,int,const QObject*,int);
+
+ QtUiTestConnectionManager() {}
+ ~QtUiTestConnectionManager();
+ void registerCallback();
+ void unregisterCallback();
+
+ void activateConnections(QObject*,int,void**);
+
+ struct Connection {
+ QObject* sender;
+ int senderMethod;
+ QObject* receiver;
+ int receiverMethod;
+ };
+ QList<Connection> m_connections;
+};
+
+#endif
+
diff --git a/src/remote/slave/lib/qtuitestmessagehandler.h b/src/remote/slave/lib/qtuitestmessagehandler.h
new file mode 100644
index 0000000..2a34b6c
--- /dev/null
+++ b/src/remote/slave/lib/qtuitestmessagehandler.h
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QTUITEST_MESSAGE_HANDLER_INTERFACE_H
+#define QTUITEST_MESSAGE_HANDLER_INTERFACE_H
+
+#include <QtSystemTest/QstProtocol>
+
+class QTestSlavePrivate;
+
+namespace QtUiTest {
+
+ class QTSLAVE_EXPORT MessageHandler
+ {
+ QTUITEST_INTERFACE(MessageHandler)
+
+ public:
+ virtual QString handlerName() const = 0;
+ virtual QstMessage handleMessage(const QstMessage&) = 0;
+ };
+
+};
+
+Q_DECLARE_INTERFACE(QtUiTest::MessageHandler, "com.nokia.qt.QtUiTest.MessageHandler/1.0")
+
+#endif
diff --git a/src/remote/slave/lib/qtuitestnamespace.cpp b/src/remote/slave/lib/qtuitestnamespace.cpp
new file mode 100644
index 0000000..3500300
--- /dev/null
+++ b/src/remote/slave/lib/qtuitestnamespace.cpp
@@ -0,0 +1,1038 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "qtuitestnamespace.h"
+
+#include "qeventwatcher_p.h"
+#include "qtuitestconnectionmanager_p.h"
+#include "qtuitestwidgets_p.h"
+
+#include <QtSystemTest/QstDebug>
+#include <QEventLoop>
+#include <QKeyEvent>
+#include <QKeySequence>
+#include <QPointer>
+#include <QTimer>
+
+/*
+ A simple auto pointer class which deletes the pointed-to QObject
+ later via deleteLater()
+*/
+template <typename T>
+class QDelayedAutoPointer
+{
+public:
+ inline QDelayedAutoPointer(T* thing)
+ : raw(thing)
+ {}
+ inline ~QDelayedAutoPointer()
+ {
+ QObject::disconnect(raw, 0, 0, 0);
+ raw->deleteLater();
+ }
+
+ inline T* operator->()
+ { return raw; }
+
+ inline operator T*()
+ { return raw; }
+
+private:
+ T* raw;
+};
+
+/*
+ A helper class to encapsulate generation of input events
+*/
+struct QtUiTestInput
+{
+ virtual ~QtUiTestInput() {}
+ virtual void post() const =0;
+ virtual QString toString() const =0;
+};
+
+
+namespace QtUiTest {
+ QString toString(QObject* obj)
+ {
+ if (!obj) return "QObject(0x0)";
+ return QString("%1(0x%2 \"%3\")")
+ .arg(obj->metaObject()->className())
+ .arg(QString::number(qptrdiff(obj), 16))
+ .arg(obj->objectName())
+ ;
+ }
+
+ QString toString(QEvent::Type type)
+ {
+#define DO(A) if (type == QEvent::A) return #A
+ DO(KeyPress);
+ DO(KeyRelease);
+ DO(MouseButtonPress);
+ DO(MouseButtonRelease);
+ DO(Show);
+ DO(Hide);
+ DO(FocusIn);
+ DO(FocusOut);
+ DO(WindowBlocked);
+#undef DO
+ return QString::number(int(type));
+ }
+
+ QString toString(QList<QEvent::Type> const& types)
+ {
+ QString ret;
+ QString sep;
+ foreach (QEvent::Type type, types) {
+ ret += sep + toString(type);
+ sep = ",";
+ }
+ return ret;
+ }
+
+ QString toString(Qt::Key key)
+ { return QKeySequence(key).toString(); }
+
+ QString toString(const QPoint& pos)
+ { return QString("(%1,%2)").arg(pos.x()).arg(pos.y()); }
+
+ QString toString(Qt::MouseButtons const& buttons)
+ {
+ QStringList ret;
+#define DO(A) if (buttons & Qt::A) ret << #A
+ DO(LeftButton);
+ DO(RightButton);
+ DO(MidButton);
+ DO(XButton1);
+ DO(XButton2);
+#undef DO
+ return ret.join(",");
+ }
+
+ bool keyClick(QObject*, QList<QEvent::Type> const&, int, Qt::KeyboardModifiers, QtUiTest::InputOption);
+ bool mouseClick(QObject*, QList<QEvent::Type> const&, const QPoint&, Qt::MouseButtons, QtUiTest::InputOption);
+ bool mouseDClick(QObject*, QList<QEvent::Type> const&, const QPoint&, Qt::MouseButtons, QtUiTest::InputOption);
+ bool inputWithEvent(QObject*, QList<QEventWatcherFilter*> const&, QtUiTestInput const&);
+ bool inputWithSignal(QObject*, const QByteArray&, QtUiTestInput const&);
+};
+
+struct QtUiTestKeyClick : public QtUiTestInput
+{
+ QtUiTestKeyClick(Qt::Key key, Qt::KeyboardModifiers modifiers, QtUiTest::InputOption options)
+ : m_key(key), m_modifiers(modifiers), m_options(options)
+ {}
+
+ virtual void post() const
+ { QtUiTest::keyClick(m_key, m_modifiers, m_options); }
+
+ virtual QString toString() const
+ { return QString("Key click \"%1\"").arg(QtUiTest::toString(m_key)); }
+
+ Qt::Key m_key;
+ Qt::KeyboardModifiers m_modifiers;
+ QtUiTest::InputOption m_options;
+};
+
+struct QtUiTestMouseClick : public QtUiTestInput
+{
+ QtUiTestMouseClick(const QPoint& pos, Qt::MouseButtons buttons, QtUiTest::InputOption options)
+ : m_pos(pos), m_buttons(buttons), m_options(options)
+ {}
+
+ virtual void post() const
+ { QtUiTest::mouseClick(m_pos, m_buttons, m_options); }
+
+ virtual QString toString() const
+ {
+ return QString("Mouse click \"%1\" at %2")
+ .arg(QtUiTest::toString(m_buttons))
+ .arg(QtUiTest::toString(m_pos))
+ ;
+ }
+
+ const QPoint& m_pos;
+ Qt::MouseButtons m_buttons;
+ QtUiTest::InputOption m_options;
+};
+
+struct QtUiTestMouseDClick : public QtUiTestInput
+{
+ QtUiTestMouseDClick(const QPoint& pos, Qt::MouseButtons buttons, QtUiTest::InputOption options)
+ : m_pos(pos), m_buttons(buttons), m_options(options)
+ {}
+
+ virtual void post() const
+ { QtUiTest::mouseDClick(m_pos, m_buttons, m_options); }
+
+ virtual QString toString() const
+ {
+ return QString("Mouse click \"%1\" at %2")
+ .arg(QtUiTest::toString(m_buttons))
+ .arg(QtUiTest::toString(m_pos))
+ ;
+ }
+
+ const QPoint& m_pos;
+ Qt::MouseButtons m_buttons;
+ QtUiTest::InputOption m_options;
+};
+
+/*
+ Filter which implements watching for events of a specific type.
+*/
+class QEventWatcherTypeFilter : public QEventWatcherFilter
+{
+public:
+ QEventWatcherTypeFilter(QEvent::Type type)
+ : m_type(type)
+ {}
+
+protected:
+ virtual bool accept(QObject*,QEvent* e) const
+ { return e->type() == m_type; }
+
+ virtual QString toString() const
+ { return QString("event of type %1").arg(QtUiTest::toString(m_type)); }
+
+private:
+ QEvent::Type m_type;
+};
+
+/*
+ Filter which implements watching for specific key events.
+*/
+
+class QEventWatcherKeyFilter : public QEventWatcherTypeFilter
+{
+public:
+ QEventWatcherKeyFilter(Qt::Key key, QEvent::Type type)
+ : QEventWatcherTypeFilter(type)
+ , m_key(key)
+ {}
+
+ static QEvent::Type keyPressType()
+ { static int ret = QEvent::registerEventType(); return QEvent::Type(ret); }
+
+ static QEvent::Type keyReleaseType()
+ { static int ret = QEvent::registerEventType(); return QEvent::Type(ret); }
+
+protected:
+ virtual bool accept(QObject* o, QEvent* e) const
+ {
+ if (!QEventWatcherTypeFilter::accept(o,e))
+ return false;
+ if (e->type() != QEvent::KeyPress && e->type() != QEvent::KeyRelease)
+ return false;
+ return static_cast<QKeyEvent*>(e)->key() == m_key;
+ }
+
+ virtual QString toString() const
+ {
+ return QString("%1 (key:%2)")
+ .arg(QEventWatcherTypeFilter::toString())
+ .arg(QtUiTest::toString(m_key));
+ }
+
+private:
+ Qt::Key m_key;
+};
+
+
+/*!
+ \preliminary
+ \namespace QtUiTest
+ \inpublicgroup QtUiTestModule
+
+ \brief The QtUiTest namespace provides the plugin interfaces used for
+ customizing the behaviour of QtUiTest.
+*/
+
+/*!
+ \fn T QtUiTest::qtuitest_cast_helper(QObject* object,T dummy)
+ \internal
+*/
+
+/*!
+ \relates QtUiTest
+ \fn T qtuitest_cast(const QObject *object)
+
+ Casts \a object to the specified QtUiTest test widget interface \c{T}.
+
+ If \a object already implements \c{T}, it is simply casted and returned.
+ Otherwise, QtUiTest will attempt to find or create a test widget to
+ wrap \a object, using all loaded QtUiTest::WidgetFactory plugins.
+ If a test widget cannot be created to wrap \a object, 0 is returned.
+
+ In either case, the returned value must not be deleted by the caller.
+*/
+
+
+/*!
+ \enum QtUiTest::InputOption
+
+ This enum type specifies the options to be used when simulating key
+ and mouse events.
+
+ \value NoOptions no options.
+ \value KeyRepeat when simulating key press events, simulate auto-repeat
+ key press events. The default is to simulate regular key
+ press events.
+*/
+
+/*!
+ \enum QtUiTest::Key
+
+ This enum provides mappings for high-level conceptual keys to platform-specific
+ values of Qt::Key.
+
+ \value Key_Activate Key used to activate generic UI elements.
+ \value Key_ActivateButton Key used to activate buttons.
+ \value Key_Select Key used to select an item from lists.
+*/
+
+/*!
+ Set or clear the specified \a option for subsequent simulated input
+ events. The option is set if \a on is true, otherwise it is cleared.
+*/
+void QtUiTest::setInputOption(QtUiTest::InputOption option, bool on)
+{
+ QTT_TRACE_FUNCTION();
+ QtUiTestWidgets::instance()->setInputOption(option, on);
+}
+
+/*!
+ Returns true if \a option is currently set.
+*/
+bool QtUiTest::testInputOption(QtUiTest::InputOption option)
+{
+ QTT_TRACE_FUNCTION();
+ return QtUiTestWidgets::instance()->testInputOption(option);
+}
+
+/*!
+ Simulate a mouse press event at the co-ordinates given by \a pos,
+ for the specified \a buttons. \a options are applied to the simulated
+ event.
+
+ \a pos is interpreted as local co-ordinates for the currently active
+ window in this application.
+*/
+void QtUiTest::mousePress(const QPoint& pos, Qt::MouseButtons buttons,
+ QtUiTest::InputOption options)
+{
+ QTT_TRACE_FUNCTION();
+ QtUiTestWidgets::instance()->mousePress(pos, buttons, options);
+}
+
+void QtUiTest::touchPress(const QVariantList &points)
+{
+ QTT_TRACE_FUNCTION();
+ QtUiTestWidgets::instance()->touchPress(points);
+}
+
+void QtUiTest::touchUpdate(const QVariantList &points)
+{
+ QTT_TRACE_FUNCTION();
+ QtUiTestWidgets::instance()->touchUpdate(points);
+}
+
+void QtUiTest::touchRelease(const QVariantList &points)
+{
+ QTT_TRACE_FUNCTION();
+ QtUiTestWidgets::instance()->touchRelease(points);
+}
+
+/*!
+ Simulate a mouse release event at the global co-ordinates given by \a pos,
+ for the specified \a buttons. \a options are applied to the simulated
+ event.
+
+ \a pos is interpreted as local co-ordinates for the currently active
+ window in this application.
+*/
+void QtUiTest::mouseRelease(const QPoint& pos, Qt::MouseButtons buttons,
+ QtUiTest::InputOption options)
+{
+ QTT_TRACE_FUNCTION();
+ QtUiTestWidgets::instance()->mouseRelease(pos, buttons, options);
+}
+
+/*!
+ Simulate a mouse click event at the global co-ordinates given by \a pos,
+ for the specified \a buttons. \a options are applied to the simulated
+ event.
+
+ \a pos is interpreted as local co-ordinates for the currently active
+ window in this application.
+*/
+void QtUiTest::mouseClick(const QPoint& pos, Qt::MouseButtons buttons,
+ QtUiTest::InputOption options)
+{
+ QTT_TRACE_FUNCTION();
+ QtUiTestWidgets::instance()->mouseClick(pos, buttons, options);
+}
+
+/*!
+ Simulate a mouse double-click event at the global co-ordinates given by \a pos,
+ for the specified \a buttons. \a options are applied to the simulated
+ event.
+
+ \a pos is interpreted as local co-ordinates for the currently active
+ window in this application.
+*/
+void QtUiTest::mouseDClick(const QPoint& pos, Qt::MouseButtons buttons,
+ QtUiTest::InputOption options)
+{
+ QTT_TRACE_FUNCTION();
+ QtUiTestWidgets::instance()->mouseDClick(pos, buttons, options);
+}
+
+/*!
+ \overload
+ Simulate a mouse click event.
+ Returns true if the event appears to be delivered to \a object within maximumUiTimeout()
+ milliseconds.
+ If it does not, the errorString() will be set accordingly.
+*/
+bool QtUiTest::mouseClick(QObject* object, const QPoint& pos, Qt::MouseButtons buttons,
+ QtUiTest::InputOption options)
+{
+ QTT_TRACE_FUNCTION();
+ return mouseClick(object,
+ QList<QEvent::Type>() << QEvent::MouseButtonRelease << QEvent::Hide << QEvent::WindowBlocked,
+ pos, buttons, options
+ );
+}
+
+/*!
+ \overload
+ Simulate a mouse double-click event.
+ Returns true if the event appears to be delivered to \a object within maximumUiTimeout()
+ milliseconds.
+ If it does not, the errorString() will be set accordingly.
+*/
+bool QtUiTest::mouseDClick(QObject* object, const QPoint& pos, Qt::MouseButtons buttons,
+ QtUiTest::InputOption options)
+{
+ QTT_TRACE_FUNCTION();
+ return mouseDClick(object,
+ QList<QEvent::Type>() << QEvent::MouseButtonRelease << QEvent::Hide << QEvent::WindowBlocked,
+ pos, buttons, options
+ );
+}
+
+/*!
+ Simulate moving the mouse pointer to the global co-ordinates given by \a pos.
+ \a options are applied to the simulated event.
+*/
+void QtUiTest::mouseMove(const QPoint& pos, QtUiTest::InputOption options)
+{
+ QTT_TRACE_FUNCTION();
+ QtUiTestWidgets::instance()->mouseMove(pos, options);
+}
+
+/*!
+ \internal
+*/
+bool QtUiTest::mouseClick(QObject* object, QList<QEvent::Type> const& types, const QPoint& pos,
+ Qt::MouseButtons buttons, QtUiTest::InputOption options)
+{
+ QTT_TRACE_FUNCTION();
+ QList<QEventWatcherFilter*> filters;
+ foreach (QEvent::Type type, types) {
+ filters << new QEventWatcherTypeFilter(type);
+ }
+ return inputWithEvent(object, filters, QtUiTestMouseClick(pos, buttons, options));
+}
+
+/*!
+ \internal
+*/
+bool QtUiTest::mouseDClick(QObject* object, QList<QEvent::Type> const& types, const QPoint& pos,
+ Qt::MouseButtons buttons, QtUiTest::InputOption options)
+{
+ QTT_TRACE_FUNCTION();
+ QList<QEventWatcherFilter*> filters;
+ foreach (QEvent::Type type, types) {
+ filters << new QEventWatcherTypeFilter(type);
+ }
+ return inputWithEvent(object, filters, QtUiTestMouseDClick(pos, buttons, options));
+}
+
+/*!
+ \overload
+ Simulate a mouse click event.
+ Returns true if the event causes \a object to emit \a signal within maximumUiTimeout()
+ milliseconds.
+ If it does not, the errorString() will be set accordingly.
+*/
+bool QtUiTest::mouseClick(QObject* object, const QByteArray& signal, const QPoint& pos,
+ Qt::MouseButtons buttons, QtUiTest::InputOption options)
+{
+ QTT_TRACE_FUNCTION();
+ return inputWithSignal(object, signal, QtUiTestMouseClick(pos, buttons, options));
+}
+
+/*!
+ \overload
+ Simulate a mouse double-click event.
+ Returns true if the event causes \a object to emit \a signal within maximumUiTimeout()
+ milliseconds.
+ If it does not, the errorString() will be set accordingly.
+*/
+bool QtUiTest::mouseDClick(QObject* object, const QByteArray& signal, const QPoint& pos,
+ Qt::MouseButtons buttons, QtUiTest::InputOption options)
+{
+ QTT_TRACE_FUNCTION();
+ return inputWithSignal(object, signal, QtUiTestMouseDClick(pos, buttons, options));
+}
+
+/*!
+ Simulate a key press event, using the given \a key and \a modifiers.
+ \a key must be a valid Qt::Key or QtUiTest::Key.
+ \a options are applied to the simulated event.
+*/
+void QtUiTest::keyPress(int key, Qt::KeyboardModifiers modifiers,
+ QtUiTest::InputOption options)
+{
+ QTT_TRACE_FUNCTION();
+ QtUiTestWidgets::instance()->keyPress(static_cast<Qt::Key>(key), modifiers, options);
+}
+
+/*!
+ Simulate a key release event, using the given \a key and \a modifiers.
+ \a key must be a valid Qt::Key or QtUiTest::Key.
+ \a options are applied to the simulated event.
+*/
+void QtUiTest::keyRelease(int key, Qt::KeyboardModifiers modifiers,
+ QtUiTest::InputOption options)
+{
+ QTT_TRACE_FUNCTION();
+ QtUiTestWidgets::instance()->keyRelease(static_cast<Qt::Key>(key), modifiers, options);
+}
+
+/*!
+ Simulate a key click event, using the given \a key and \a modifiers.
+ \a key must be a valid Qt::Key or QtUiTest::Key.
+ \a options are applied to the simulated event.
+*/
+void QtUiTest::keyClick(int key, Qt::KeyboardModifiers modifiers,
+ QtUiTest::InputOption options)
+{
+ QTT_TRACE_FUNCTION();
+ QtUiTestWidgets::instance()->keyClick(static_cast<Qt::Key>(key), modifiers, options);
+}
+
+/*!
+ \overload
+ Simulate a key click event.
+ Returns true if the event appears to be delivered to \a object within maximumUiTimeout()
+ milliseconds.
+ If it does not, the errorString() will be set accordingly.
+*/
+bool QtUiTest::keyClick(QObject* object, int key, Qt::KeyboardModifiers modifiers,
+ QtUiTest::InputOption options)
+{
+ QTT_TRACE_FUNCTION();
+ return keyClick(object,
+ QList<QEvent::Type>() << QEventWatcherKeyFilter::keyReleaseType()
+ << QEvent::Hide << QEvent::WindowBlocked << QEvent::Show,
+ key, modifiers, options
+ );
+}
+
+/*!
+ \internal
+*/
+bool QtUiTest::inputWithEvent(QObject* object, QList<QEventWatcherFilter*> const& filters,
+ QtUiTestInput const& event)
+{
+ QTT_TRACE_FUNCTION();
+ QPointer<QObject> sender = object;
+ QDelayedAutoPointer<QEventWatcher> w = new QEventWatcher;
+ w->addObject(sender);
+ foreach (QEventWatcherFilter* filter, filters)
+ w->addFilter(filter);
+
+ event.post();
+
+ if (!w->count() && !QtUiTest::waitForSignal(w, SIGNAL(event(QObject*,int)))) {
+ setErrorString(QString(
+ "%1 was expected to result in %2 receiving an event matching one of the following, "
+ "but it didn't:\n%3")
+ .arg(event.toString())
+ .arg(toString(sender))
+ .arg(w->toString()));
+ return false;
+ }
+ return true;
+}
+
+/*!
+ \internal
+*/
+bool QtUiTest::inputWithSignal(QObject* object, const QByteArray& signal,
+ QtUiTestInput const& event)
+{
+ QTT_TRACE_FUNCTION();
+ if (signal.isEmpty()) return false;
+ QPointer<QObject> sender = object;
+
+ QTimer dummy;
+ dummy.setInterval(1000);
+ if (!QtUiTest::connectFirst(sender, signal, &dummy, SLOT(start()))) {
+ setErrorString(QString("Object %1 has no signal %2").arg(toString(sender)).arg(&signal.constData()[1]));
+ return false;
+ }
+
+ // Ensure connectNotify is called
+ if (!QObject::connect(sender, signal, &dummy, SLOT(start())))
+ Q_ASSERT(0);
+
+ event.post();
+
+ if (!dummy.isActive() && !QtUiTest::waitForSignal(sender, signal)) {
+ setErrorString(QString(
+ "%1 was expected to result in %2 emitting the signal %3, "
+ "but it didn't.")
+ .arg(event.toString())
+ .arg(toString(sender))
+ .arg(&signal.constData()[1]));
+ return false;
+ }
+ return true;
+}
+
+/*!
+ \internal
+ \overload
+ Simulate a key click event.
+ Returns true if \a object receives any event of the given \a types within maximumUiTimeout()
+ milliseconds.
+ If it does not, the errorString() will be set accordingly.
+*/
+bool QtUiTest::keyClick(QObject* object, QList<QEvent::Type> const& types, int key,
+ Qt::KeyboardModifiers modifiers, QtUiTest::InputOption options)
+{
+ QTT_TRACE_FUNCTION();
+ QList<QEventWatcherFilter*> filters;
+ foreach (QEvent::Type type, types) {
+ // These cases result in waiting for specific key events rather than just "any key press".
+ if (type == QEventWatcherKeyFilter::keyPressType()) {
+ filters << new QEventWatcherKeyFilter(Qt::Key(key), QEvent::KeyPress);
+ } else if (type == QEventWatcherKeyFilter::keyReleaseType()) {
+ filters << new QEventWatcherKeyFilter(Qt::Key(key), QEvent::KeyRelease);
+ } else {
+ filters << new QEventWatcherTypeFilter(type);
+ }
+ }
+ return inputWithEvent(object, filters, QtUiTestKeyClick(Qt::Key(key), modifiers, options));
+}
+
+/*!
+ \overload
+ Simulate a key click event.
+ Returns true if \a object emits \a signal within maximumUiTimeout()
+ milliseconds.
+ If it does not, the errorString() will be set accordingly.
+*/
+bool QtUiTest::keyClick(QObject* object, const QByteArray& signal, int key, Qt::KeyboardModifiers modifiers,
+ QtUiTest::InputOption options)
+{
+ QTT_TRACE_FUNCTION();
+ return inputWithSignal(object, signal, QtUiTestKeyClick(Qt::Key(key), modifiers, options));
+}
+
+/*!
+ Returns the maximum amount of time, in milliseconds, the user interface is allowed to take
+ to generate some response to a user's action.
+
+ This value is useful to determine how long test widgets should wait for certain events to occur
+ after simulating key/mouse events. The value may be device-specific.
+*/
+int QtUiTest::maximumUiTimeout()
+{ return 2000; }
+
+/*!
+ Returns the Qt::Key corresponding to \a c.
+
+ This function is commonly used in conjunction with keyClick() to enter
+ a string of characters using the keypad.
+
+ Example:
+ \code
+ using namespace QtUiTest;
+ QString text = "hello world";
+ // ...
+ foreach (QChar c, text) {
+ keyClick( asciiToKey(c.toLatin1()), asciiToModifiers(c.toLatin1()) );
+ }
+ \endcode
+*/
+// Now implemented in qasciikey.cpp
+
+/*!
+ Returns any Qt::KeyboardModifiers which would be required to input \a c.
+
+ This function is commonly used in conjunction with keyClick() to enter
+ a string of characters using the keypad.
+
+ Example:
+ \code
+ using namespace QtUiTest;
+ QString text = "hello world";
+ // ...
+ foreach (QChar c, text) {
+ keyClick( asciiToKey(c.toLatin1()), asciiToModifiers(c.toLatin1()) );
+ }
+ \endcode
+*/
+Qt::KeyboardModifiers QtUiTest::asciiToModifiers(char c)
+{
+ QTT_TRACE_FUNCTION();
+ Qt::KeyboardModifiers ret = Qt::NoModifier;
+ if (QChar(c).isUpper()) ret |= Qt::ShiftModifier;
+ return ret;
+}
+
+/*!
+ Returns a human-readable error string describing the last error which
+ occurred while accessing a testwidget.
+
+ The error string is used to report directly to a tester any unexpected
+ errors. The string will typically be used as a test failure message.
+
+ \sa setErrorString()
+*/
+QString QtUiTest::errorString()
+{
+ return QtUiTestWidgets::instance()->errorString();
+}
+
+/*!
+ Returns a QDebug object which can be used as an output stream for debugging
+ information. The debug information is sent to the test runner for output.
+ This ensures a consistent handling of debugging information on different
+ test platforms.
+
+ Example:
+ \code
+ QtUiTest::debug() << "This is a debug message";
+ \endcode
+*/
+QDebug QtUiTest::debug()
+{
+ return QtUiTestWidgets::instance()->debug();
+}
+
+/*!
+ \internal
+*/
+QString QtUiTest::debugOutput()
+{
+ return QtUiTestWidgets::instance()->debugOutput();
+}
+
+/*!
+ Sets the human-readable \a error string describing the last error which
+ occurred while accessing a testwidget.
+
+ \sa errorString()
+*/
+void QtUiTest::setErrorString(const QString& error)
+{
+ QtUiTestWidgets::instance()->setErrorString(error);
+}
+
+/*!
+ \internal
+ Returns a test widget wrapper for \a object which implements
+ \a interface.
+*/
+QObject* QtUiTest::testWidget(QObject* object, const char* interface)
+{
+ return QtUiTestWidgets::instance()->testWidget(object, interface);
+}
+
+/*!
+ Causes the process to wait for \a ms milliseconds. While waiting, events will be processed.
+*/
+void QtUiTest::wait(int ms)
+{
+ QTT_TRACE_FUNCTION();
+ QEventLoop loop;
+ QTimer::singleShot(ms, &loop, SLOT(quit()));
+ loop.exec();
+}
+
+#include <QDebug>
+
+/*!
+ Causes the process to wait for \a ms milliseconds or until \a signal is
+ emitted from \a object, whichever comes first.
+
+ While waiting, events will be processed.
+
+ Returns true if \a signal was emitted from \a object before timing out.
+ When false is returned, errorString() is set accordingly.
+
+ If \a connectionType specifies a direct connection, this function will return
+ immediately when the signal occurs, possibly before some objects have
+ received the signal. If \a connectionType specifies a queued connection, this
+ function will return once the event loop has run following the emit.
+*/
+bool QtUiTest::waitForSignal(QObject* object, const char* signal, int ms, Qt::ConnectionType connectionType)
+{
+ QTT_TRACE_FUNCTION();
+ if (ms < 0) return false;
+ if (!signal || !signal[0]) return false;
+
+ QPointer<QObject> sender = object;
+
+ // Dummy variable to detect signal emission.
+ QTimer dummy;
+ dummy.setInterval(1000);
+ if (!QtUiTest::connectFirst(sender, signal, &dummy, SLOT(start())))
+ return false;
+
+ // Ensure connectNotify is called
+ if (!QObject::connect(sender, signal, &dummy, SLOT(start())))
+ Q_ASSERT(0);
+
+ QEventLoop loop;
+ if (!QObject::connect(sender, signal, &loop, SLOT(quit())))
+ return false;
+ QTimer::singleShot(ms, &loop, SLOT(quit()));
+
+ loop.exec();
+
+ return dummy.isActive();
+}
+
+/*!
+ Causes the process to wait for \a ms milliseconds or until an event of
+ any of the given \a types is received by \a object, whichever comes first.
+
+ While waiting, events will be processed.
+
+ Returns true if the event was received by \a object before timing out.
+ When false is returned, errorString() is set accordingly.
+
+ If \a connectionType specifies a direct connection, this function will return
+ immediately before the event is processed by \a object.
+ If \a connectionType specifies a queued connection, this function will return
+ once the event loop has run following the processing of the event.
+*/
+bool QtUiTest::waitForEvent(QObject* object, QList<QEvent::Type> const& types, int ms, Qt::ConnectionType connectionType)
+{
+ QTT_TRACE_FUNCTION();
+ QPointer<QObject> sender = object;
+ QDelayedAutoPointer<QEventWatcher> w = new QEventWatcher;
+ w->setObjectName("qtuitest_waitForEvent_watcher");
+ w->addObject(sender);
+ foreach (QEvent::Type type, types)
+ w->addFilter(new QEventWatcherTypeFilter(type));
+
+ if (!QtUiTest::waitForSignal(w, SIGNAL(event(QObject*,int)), ms, connectionType)) {
+ setErrorString(QString("Object %1 was expected to receive an event of type(s) %2 within "
+ "%3 milliseconds, but it didn't.")
+ .arg(toString(sender))
+ .arg(toString(types))
+ .arg(ms)
+ );
+ return false;
+ }
+ return true;
+}
+
+/*!
+ \overload
+ Waits for an event of the given \a type.
+*/
+bool QtUiTest::waitForEvent(QObject* object, QEvent::Type type, int ms, Qt::ConnectionType connectionType)
+{
+ QTT_TRACE_FUNCTION();
+ return waitForEvent(object, QList<QEvent::Type>() << type, ms, connectionType);
+}
+
+/*!
+ Creates a connection from the \a signal in the \a sender object to
+ the \a method in the \a receiver object. Returns true if the connection succeeds;
+ otherwise returns false.
+
+ This function behaves similarly to QObject::connect() with the following
+ important differences.
+ \list
+ \o The connection is guaranteed to be activated before
+ any connections made with QObject::connect().
+ \o The connection type is always Qt::DirectConnection.
+ \o The connection cannot be disconnected using QObject::disconnect()
+ (QtUiTest::disconnectFirst() must be used instead).
+ \o The connection does not affect the return value of QObject::receivers().
+ \o While \a method is being executed, the return value of
+ QObject::sender() is undefined.
+ \o QObject::connectNotify() is not called on the sending object.
+ \endlist
+
+ This function is primarily used in conjunction with QtUiTestRecorder to
+ ensure events are recorded in the correct order.
+
+ Note that this function cannot be used in a program which uses QSignalSpy.
+
+ \sa QObject::connect(), QtUiTest::disconnectFirst()
+*/
+bool QtUiTest::connectFirst(const QObject* sender, const char* signal,
+ const QObject* receiver, const char* method)
+{
+ QTT_TRACE_FUNCTION();
+ // On failure, we use QObject::connect to get the same error message as
+ // we normally would.
+ if (sender == 0 || receiver == 0 || signal == 0 || method == 0) {
+ return QObject::connect(sender,signal,receiver,method);
+ }
+ if (qstrlen(signal) < 1 || qstrlen(method) < 1) {
+ return QObject::connect(sender,signal,receiver,method);
+ }
+
+ const QMetaObject* const senderMo = sender->metaObject();
+
+ QByteArray normalSignal = QByteArray::fromRawData(signal+1, qstrlen(signal)-1);
+ int signal_index = senderMo->indexOfSignal(normalSignal);
+
+ if (signal_index < 0) {
+ // See if we can find the signal after normalizing.
+ normalSignal = QMetaObject::normalizedSignature(normalSignal);
+ signal_index = senderMo->indexOfSignal(normalSignal);
+ }
+ if (signal_index < 0) {
+ // Nope, bail out.
+ return QObject::connect(sender,signal,receiver,method);
+ }
+
+ const QMetaObject* const receiverMo = receiver->metaObject();
+
+ QByteArray normalMethod = QByteArray::fromRawData(method+1, qstrlen(method)-1);
+ int method_index = receiverMo->indexOfMethod(normalMethod);
+
+ if (method_index < 0) {
+ // See if we can find the method after normalizing.
+ normalMethod = QMetaObject::normalizedSignature(normalMethod);
+ method_index = senderMo->indexOfMethod(normalMethod);
+ }
+ if (method_index < 0) {
+ // Nope, bail out.
+ return QObject::connect(sender,signal,receiver,method);
+ }
+
+ // Ensure signal and slot are compatible.
+ if (!QMetaObject::checkConnectArgs(normalSignal.constData(), normalMethod.constData())) {
+ return QObject::connect(sender,signal,receiver,method);
+ }
+
+ // If we get here, then everything is valid.
+ QtUiTestConnectionManager::instance()->connect(sender, signal_index, receiver, method_index);
+ return true;
+}
+
+/*!
+ Disconnects \a signal in object \a sender from \a method in object \a receiver. Returns true if the connection is successfully broken; otherwise returns false.
+
+ The connection must have been established with QtUiTest::connectFirst().
+
+ Passing null arguments has the same wildcard effects as documented in QObject::disconnect().
+
+ If the same connection has been established multiple times, disconnectFirst() will disconnect
+ all instances of the connection. There is no way to disconnect a single instance of a
+ connection. This behavior matches QObject::disconnect().
+
+ \sa QObject::disconnect(), QtUiTest::connectFirst()
+*/
+bool QtUiTest::disconnectFirst(const QObject* sender, const char* signal,
+ const QObject* receiver, const char* method)
+{
+ QTT_TRACE_FUNCTION();
+ // On failure, we use QObject::disconnect to get the same error message as
+ // we normally would.
+ if (sender == 0) {
+ return QObject::disconnect(sender,signal,receiver,method);
+ }
+
+ const QMetaObject* const senderMo = sender->metaObject();
+
+ QByteArray normalSignal = (signal)
+ ? QByteArray::fromRawData(signal+1, qstrlen(signal)-1)
+ : QByteArray();
+ int signal_index = (signal) ? senderMo->indexOfSignal(normalSignal) : -1;
+ if (signal && (signal_index < 0)) {
+ // See if we can find the signal after normalizing.
+ normalSignal = QMetaObject::normalizedSignature(signal);
+ signal_index = senderMo->indexOfSignal(normalSignal);
+ }
+ if (signal && (signal_index < 0)) {
+ // Nope, bail out.
+ return QObject::disconnect(sender,signal,receiver,method);
+ }
+
+ if (method && !receiver) {
+ return QObject::disconnect(sender,signal,receiver,method);
+ }
+
+ const QMetaObject* const receiverMo = (receiver) ? receiver->metaObject() : 0;
+
+ QByteArray normalMethod = (method)
+ ? QByteArray::fromRawData(method+1, qstrlen(method)-1)
+ : QByteArray();
+ int method_index = (method) ? receiverMo->indexOfMethod(normalMethod) : -1;
+
+ if (method && (method_index < 0)) {
+ // See if we can find the method after normalizing.
+ normalMethod = QMetaObject::normalizedSignature(method);
+ method_index = senderMo->indexOfMethod(normalMethod);
+ }
+ if (method && (method_index < 0)) {
+ // Nope, bail out.
+ return QObject::disconnect(sender,signal,receiver,method);
+ }
+
+ return QtUiTestConnectionManager::instance()->disconnect(sender,signal_index,receiver,method_index);
+}
+
diff --git a/src/remote/slave/lib/qtuitestnamespace.h b/src/remote/slave/lib/qtuitestnamespace.h
new file mode 100644
index 0000000..c142cee
--- /dev/null
+++ b/src/remote/slave/lib/qtuitestnamespace.h
@@ -0,0 +1,172 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QTUITESTNAMESPACE_H
+#define QTUITESTNAMESPACE_H
+
+#include <QtSystemTest/qstglobal.h>
+
+#include <QEvent>
+#include <QObject>
+#include <Qt>
+#include <QVariant>
+
+class QPoint;
+
+namespace QtUiTest
+{
+ enum InputOption {
+ NoOptions = 0x0,
+ KeyRepeat = 0x1
+ };
+
+ enum Key {
+#ifdef Q_WS_QWS
+ Key_Activate = Qt::Key_Select,
+#else
+ Key_Activate = Qt::Key_Enter,
+#endif
+
+#ifdef Q_WS_QWS
+ Key_Select = Qt::Key_Select,
+#else
+ Key_Select = Qt::Key_Space,
+#endif
+
+#if defined(Q_WS_QWS) || defined (Q_OS_SYMBIAN)
+ Key_ActivateButton = Qt::Key_Select
+#else
+ Key_ActivateButton = Qt::Key_Space
+#endif
+ };
+
+ enum QueryFlag
+ {
+ NoSort = 0x01,
+ NoScan = 0x02,
+ ScanInvisible = 0x04,
+ ScanDisabledItems = 0x08,
+ IgnoreScanned = 0x10
+ };
+ Q_DECLARE_FLAGS(QueryFlags, QueryFlag);
+
+ QTUITEST_EXPORT void setInputOption(InputOption,bool = true);
+ QTUITEST_EXPORT bool testInputOption(InputOption);
+
+ QTUITEST_EXPORT QString errorString();
+ QTUITEST_EXPORT void setErrorString(const QString&);
+ QTUITEST_EXPORT QDebug debug();
+ QTUITEST_EXPORT QString debugOutput();
+
+ QTUITEST_EXPORT void touchPress(const QVariantList&);
+ QTUITEST_EXPORT void touchUpdate(const QVariantList&);
+ QTUITEST_EXPORT void touchRelease(const QVariantList&);
+
+ QTUITEST_EXPORT void mousePress (const QPoint&,Qt::MouseButtons = Qt::LeftButton,
+ InputOption = NoOptions);
+ QTUITEST_EXPORT void mouseRelease(const QPoint&,Qt::MouseButtons = Qt::LeftButton,
+ InputOption = NoOptions);
+ QTUITEST_EXPORT void mouseClick (const QPoint&,Qt::MouseButtons = Qt::LeftButton,
+ InputOption = NoOptions);
+ QTUITEST_EXPORT bool mouseClick (QObject*,const QPoint&,Qt::MouseButtons = Qt::LeftButton,
+ InputOption = NoOptions);
+ QTUITEST_EXPORT bool mouseClick (QObject*,const QByteArray&,const QPoint&,
+ Qt::MouseButtons = Qt::LeftButton, InputOption = NoOptions);
+ QTUITEST_EXPORT void mouseDClick (const QPoint&,Qt::MouseButtons = Qt::LeftButton,
+ InputOption = NoOptions);
+ QTUITEST_EXPORT bool mouseDClick (QObject*,const QPoint&,Qt::MouseButtons = Qt::LeftButton,
+ InputOption = NoOptions);
+ QTUITEST_EXPORT bool mouseDClick (QObject*,const QByteArray&,const QPoint&,
+ Qt::MouseButtons = Qt::LeftButton, InputOption = NoOptions);
+ QTUITEST_EXPORT void mouseMove (const QPoint&, InputOption = NoOptions);
+
+ QTUITEST_EXPORT void keyPress (int,Qt::KeyboardModifiers = 0,
+ InputOption = NoOptions);
+ QTUITEST_EXPORT void keyRelease(int,Qt::KeyboardModifiers = 0,
+ InputOption = NoOptions);
+ QTUITEST_EXPORT void keyClick (int,Qt::KeyboardModifiers = 0,
+ InputOption = NoOptions);
+ QTUITEST_EXPORT bool keyClick (QObject*,int,Qt::KeyboardModifiers = 0,
+ InputOption = NoOptions);
+ QTUITEST_EXPORT bool keyClick (QObject*,const QByteArray&,int,Qt::KeyboardModifiers = 0,
+ InputOption = NoOptions);
+
+ QTUITEST_EXPORT int maximumUiTimeout();
+
+ QTUITEST_EXPORT Qt::Key asciiToKey(char);
+ QTUITEST_EXPORT Qt::Key variantToKey(const QVariant &);
+ QTUITEST_EXPORT Qt::KeyboardModifiers asciiToModifiers(char);
+
+ QTUITEST_EXPORT QObject* testWidget(QObject*,const char*);
+
+ QTUITEST_EXPORT bool connectFirst (const QObject*, const char*, const QObject*, const char*);
+ QTUITEST_EXPORT bool disconnectFirst(const QObject*, const char*, const QObject*, const char*);
+
+ template<class T> inline T qtuitest_cast_helper(QObject* object, T)
+ {
+ T ret;
+ if ((ret = qobject_cast<T>(object))) {}
+ else {
+ ret = qobject_cast<T>(QtUiTest::testWidget(object,
+ static_cast<T>(0)->_q_interfaceName()));
+ }
+ return ret;
+ }
+
+ QTUITEST_EXPORT void wait(int);
+ QTUITEST_EXPORT bool waitForSignal(QObject*, const char*, int = QtUiTest::maximumUiTimeout(), Qt::ConnectionType = Qt::QueuedConnection);
+ QTUITEST_EXPORT bool waitForEvent(QObject*, QEvent::Type, int = QtUiTest::maximumUiTimeout(), Qt::ConnectionType = Qt::QueuedConnection);
+ QTUITEST_EXPORT bool waitForEvent(QObject*, QList<QEvent::Type> const&, int = QtUiTest::maximumUiTimeout(), Qt::ConnectionType = Qt::QueuedConnection);
+
+ QTUITEST_EXPORT char keyToAscii(Qt::Key key);
+};
+
+template<class T> inline
+T qtuitest_cast(const QObject* object)
+{
+ return QtUiTest::qtuitest_cast_helper<T>(const_cast<QObject*>(object),0);
+}
+
+#include "qtuitestwidgetinterface.h"
+
+#endif
+
diff --git a/src/remote/slave/lib/qtuitestwidgetinterface.cpp b/src/remote/slave/lib/qtuitestwidgetinterface.cpp
new file mode 100644
index 0000000..126efcd
--- /dev/null
+++ b/src/remote/slave/lib/qtuitestwidgetinterface.cpp
@@ -0,0 +1,398 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "qtuitestwidgetinterface.h"
+#include "qtuitestnamespace.h"
+
+#include <QRect>
+#include <QRegion>
+#include <QVariant>
+
+/*!
+ \preliminary
+ \class QtUiTest::WidgetFactory
+ \inpublicgroup QtUiTestModule
+ \brief The WidgetFactory class provides a factory interface
+ for QtUiTest widget wrapper classes.
+
+ QtUiTest::WidgetFactory is an abstract base class which enables the
+ creation of QtUiTest wrapper objects around Qt widgets.
+
+ Customizing QtUiTest behaviour for particular widgets is achieved by
+ implementing one or more test widget classes which inherit from
+ one or more QtUiTest widget interfaces,
+ subclassing QtUiTest::WidgetFactory, reimplementing the pure virtual
+ keys() and create() functions to create instances of the custom test
+ widget classes, and exporting the factory class using the
+ Q_EXPORT_PLUGIN2() macro.
+*/
+
+/*!
+ \fn QtUiTest::WidgetFactory::create(QObject* object)
+
+ Attempts to create a test widget to wrap \a object. Returns the created
+ test widget. Returns 0 if this factory does not support wrapping
+ \a object.
+
+ The returned object is suitable for use with
+ \l{QtUiTest}{qtuitest_cast}.
+
+ This function will only be called for objects which inherit one of the
+ classes returned by keys().
+*/
+
+/*!
+ \fn QtUiTest::WidgetFactory::keys() const
+
+ Returns the list of C++ class names this factory can generate test widgets
+ for.
+
+ Note that returning a class from this function does not guarantee that the
+ factory will always be able to generate a test widget for that class.
+*/
+
+/*!
+ \preliminary
+ \class QtUiTest::Widget
+ \inpublicgroup QtUiTestModule
+ \brief The Widget class provides an abstract base class
+ for all test widgets.
+
+ QtUiTest::Widget encapsulates important information
+ and functionality related to two-dimensional GUI elements.
+
+ All test widgets should implement the QtUiTest::Widget interface,
+ using multiple inheritance to implement other QtUiTest interfaces
+ where suitable.
+*/
+
+/*!
+ \fn const QRect& QtUiTest::Widget::geometry() const
+
+ Returns the geometry of this widget in parent coordinates.
+*/
+
+/*!
+ Returns the left of the widget, in global coordinates.
+
+ \sa mapToGlobal()
+*/
+int QtUiTest::Widget::x() const
+{
+ return mapToGlobal(QPoint()).x();
+}
+
+/*!
+ Returns the top of the widget, in global coordinates.
+
+ \sa mapToGlobal()
+*/
+int QtUiTest::Widget::y() const
+{
+ return mapToGlobal(QPoint()).y();
+}
+
+/*!
+ Returns the width of the widget.
+
+ \sa geometry()
+*/
+int QtUiTest::Widget::width() const
+{
+ return geometry().width();
+}
+
+/*!
+ Returns the height of the widget.
+
+ \sa geometry()
+*/
+int QtUiTest::Widget::height() const
+{
+ return geometry().height();
+}
+
+/*!
+ \fn bool QtUiTest::Widget::isVisible() const
+
+ Returns true if this widget is currently visible.
+*/
+
+/*!
+ \fn QObject* QtUiTest::Widget::parent() const
+
+ Returns the parent of this widget, or 0 if this widget has no parent.
+
+ The returned object may be an actual widget, or may be a wrapping
+ test widget. Therefore, the only safe way to use the returned value
+ of this function is to cast it to the desired QtUiTest interface
+ using \l{QtUiTest}{qtuitest_cast}.
+
+ \sa QObject::parent(), children()
+*/
+
+/*!
+ \fn const QObjectList& QtUiTest::Widget::children() const
+
+ Returns all children of this widget.
+
+ The returned objects may be actual widget instances, or may be wrapping
+ test widgets. Therefore, the only safe way to use the returned objects
+ are to cast them to the desired QtUiTest interface using
+ \l{QtUiTest}{qtuitest_cast}.
+
+ Reimplementing this function allows widgets which are conceptually
+ widgets but are not QObject subclasses to be wrapped. This can be
+ achieved by returning a list of test widgets which do not necessarily
+ have underlying widget instances.
+
+ \sa QObject::children(), parent()
+*/
+
+/*!
+ \internal
+
+ Returns all ancestors of this widget.
+
+ \sa children(), parent()
+*/
+QObjectList QtUiTest::Object::ancestors() const
+{
+ QObjectList found;
+ QObject *p = parent();
+ if (p) {
+ QtUiTest::Object* qw = qtuitest_cast<QtUiTest::Object*>(p);
+ found << p << qw->ancestors();
+ }
+ return found;
+}
+
+/*!
+ \internal
+
+ Returns all descendants of this widget. The results are appended to \a descendants.
+
+ \sa children(), parent()
+*/
+void QtUiTest::Object::descendants(QSet<QObject*> &descendants) const
+{
+ foreach (QObject *child, children()) {
+ if (!descendants.contains(child)) {
+ descendants.insert(child);
+ QtUiTest::Object* qw = qtuitest_cast<QtUiTest::Object*>(child);
+ if (qw)
+ qw->descendants(descendants);
+ }
+ }
+}
+
+/*!
+ \internal
+
+ Convenience function to return descendants as QObjectList.
+
+ \sa ancestors()
+*/
+QObjectList QtUiTest::Object::descendants() const
+{
+ QSet<QObject*> found;
+ descendants(found);
+ return QObjectList::fromSet(found);
+}
+
+/*!
+ \fn QPoint QtUiTest::Widget::mapToGlobal(const QPoint& pos) const
+
+ Maps \a pos from widget coordinates to global screen coordinates and
+ returns the result.
+*/
+
+/*!
+ \fn QPoint QtUiTest::Widget::mapFromGlobal(const QPoint& pos) const
+
+ Maps \a pos from global screen coordinates to widget coordinates and
+ returns the result.
+*/
+
+/*!
+ Returns the center point of the widget. The base implementation
+ returns geometry().center().
+
+ \sa QtUiTest::Widget::geometry()
+*/
+QPoint QtUiTest::Widget::center() const
+{
+ QPoint ret;
+ ret = mapToGlobal( geometry().center() );
+ return ret;
+}
+
+/*!
+ \fn bool QtUiTest::Widget::hasFocus() const
+ Returns true if this widget currently has keyboard focus.
+*/
+
+/*!
+ Returns the focus proxy of this widget, or 0 if this widget has no focus proxy.
+ A widget may "have focus", but have a child widget that actually handles the
+ focus.
+
+ The returned object may be an actual widget, or may be a wrapping
+ test widget. Therefore, the only safe way to use the returned value
+ of this function is to cast it to the desired QtUiTest interface
+ using \l{QtUiTest}{qtuitest_cast}.
+
+*/
+QObject* QtUiTest::Widget::focusProxy() const
+{
+ return 0;
+}
+
+/*!
+ Sets \a img to image of the widget. Returns true on success.
+
+ The base implementation always returns false.
+*/
+bool QtUiTest::Widget::grabImage(QImage &img) const
+{ Q_UNUSED(img); return false; }
+
+/*!
+ Returns true if this widget should be ignored by QtUiTest. If
+ a widget is ignored, any child widgets will still be processed.
+
+ The base implementation always returns false.
+
+ \sa {Widget Specifiers}, {Querying Objects}
+*/
+bool QtUiTest::Widget::ignoreScan() const
+{ return false; }
+
+/*!
+ Returns the widget's window.
+*/
+QObject* QtUiTest::Widget::window() const
+{
+ return 0;
+}
+/*!
+ Returns the value of this widget's property specified by \a property.
+
+ \sa setProperty()
+*/
+QVariant QtUiTest::Object::getProperty(const QString& property) const
+{
+ Q_UNUSED(property)
+ return QVariant();
+}
+
+/*!
+ Sets the value of this widget's property specified by \a property to \a value.
+ Returns true on success, and false if the property could not be set.
+
+ \sa getProperty()
+*/
+bool QtUiTest::Object::setProperty(const QString &property, const QVariant &value)
+{
+ Q_UNUSED(property)
+ Q_UNUSED(value)
+ return false;
+}
+
+/*!
+ Return true if this widget matches the \a value of pseudo-property \a property.
+
+ \sa getProperty()
+*/
+bool QtUiTest::Object::matchProperty(const QString &property, const QVariant &value) const
+{
+ Q_UNUSED(property)
+ Q_UNUSED(value)
+ return false;
+}
+
+/*!
+ Returns a map containing all the widget's properties.
+
+ \sa getProperty()
+*/
+QVariantMap QtUiTest::Object::getProperties() const
+{
+ return QVariantMap();
+}
+
+QVariantList QtUiTest::Object::resources() const
+{
+ QVariantList ret;
+ return ret;
+}
+
+/*!
+ Returns the type of widget.
+*/
+QString QtUiTest::Object::typeOf() const
+{
+ return QString();
+}
+
+/*!
+ Returns the widget's list of superclasses.
+*/
+QStringList QtUiTest::Object::inheritance() const
+{
+ return QStringList();
+}
+
+/*!
+ Returns true if the item has displayable contents.
+*/
+bool QtUiTest::Object::hasContents() const
+{
+ return false;
+}
+
+/*!
+ Returns a string value for debugging purposes.
+*/
+QString QtUiTest::Object::debugString() const
+{
+ return QString();
+}
diff --git a/src/remote/slave/lib/qtuitestwidgetinterface.h b/src/remote/slave/lib/qtuitestwidgetinterface.h
new file mode 100644
index 0000000..1e5e5b9
--- /dev/null
+++ b/src/remote/slave/lib/qtuitestwidgetinterface.h
@@ -0,0 +1,133 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QTUITESTWIDGETINTERFACE_H
+#define QTUITESTWIDGETINTERFACE_H
+
+#include <QStringList>
+#include <QVariantList>
+#include <QSet>
+#include <QtGlobal>
+
+#include <QtSystemTest/qstglobal.h>
+
+#include "qtuitestnamespace.h"
+
+class QRect;
+class QRegion;
+class QPoint;
+class QWindow;
+
+namespace QtUiTest
+{
+ template<class T> T qtuitest_cast_helper(QObject*,T);
+
+#define QTUITEST_INTERFACE(Klass) \
+ public: \
+ virtual ~Klass() {} \
+ static const char* _q_interfaceName() { return #Klass; } \
+ private: \
+ template<class T> friend T qtuitest_cast_helper(QObject*,T);
+
+ class QTUITEST_EXPORT WidgetFactory
+ {
+ QTUITEST_INTERFACE(WidgetFactory)
+ public:
+ virtual QObject* create(QObject*) = 0;
+ virtual QStringList keys() const = 0;
+ };
+
+ class QTUITEST_EXPORT Object
+ {
+ QTUITEST_INTERFACE(Object)
+ public:
+ virtual QObject* parent() const = 0;
+ virtual const QObjectList children() const = 0;
+ QObjectList ancestors() const;
+ virtual void descendants(QSet<QObject*> &descendants) const;
+ QObjectList descendants() const;
+ virtual QVariant getProperty(const QString&) const;
+ virtual bool setProperty(const QString&, const QVariant&);
+ virtual bool matchProperty(const QString&, const QVariant&) const;
+ virtual QVariantMap getProperties() const;
+ virtual QString typeOf() const;
+ virtual QStringList inheritance() const;
+ virtual QVariantList resources() const;
+ virtual bool hasContents() const;
+ virtual QString debugString() const;
+ };
+
+ class QTUITEST_EXPORT Widget
+ {
+ QTUITEST_INTERFACE(Widget)
+ public:
+ virtual QRect geometry() const = 0;
+ virtual int x() const;
+ virtual int y() const;
+ virtual int width() const;
+ virtual int height() const;
+ virtual bool isVisible() const = 0;
+ virtual QPoint mapToGlobal(const QPoint&) const = 0;
+ virtual QPoint mapFromGlobal(const QPoint&) const = 0;
+ virtual QRect mapToGlobal(const QRect&) const = 0;
+ virtual QRect mapFromGlobal(const QRect&) const = 0;
+ virtual QPoint center() const;
+ virtual bool hasFocus() const = 0;
+ virtual QObject* focusProxy() const;
+ virtual bool grabImage(QImage &img) const;
+ virtual bool ignoreScan() const;
+ virtual QObject* window() const;
+ };
+
+};
+
+Q_DECLARE_INTERFACE(
+ QtUiTest::WidgetFactory,
+ "com.nokia.qt.QtUiTest.WidgetFactory/1.0")
+Q_DECLARE_INTERFACE(
+ QtUiTest::Object,
+ "com.nokia.qt.QtUiTest.Object/1.0")
+Q_DECLARE_INTERFACE(
+ QtUiTest::Widget,
+ "com.nokia.qt.QtUiTest.Widget/1.0")
+#endif
+
diff --git a/src/remote/slave/lib/qtuitestwidgets.cpp b/src/remote/slave/lib/qtuitestwidgets.cpp
new file mode 100644
index 0000000..b27e6f5
--- /dev/null
+++ b/src/remote/slave/lib/qtuitestwidgets.cpp
@@ -0,0 +1,648 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "qinputgenerator_p.h"
+#include "qtuitestwidgetinterface.h"
+#include "qtuitestwidgets_p.h"
+#include "testquickfactory.h"
+
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
+ #include "qinputgenerator_qwindow_p.h"
+#else
+ #include "qinputgenerator_generic_p.h"
+#endif
+
+#include <QtSystemTest/QstDebug>
+
+/*
+ If the QTUITEST_INPUT_DELAY environment variable is set, all calls to keyClick etc will
+ immediately return but the resulting event won't be generated until QTUITEST_INPUT_DELAY
+ milliseconds have passed.
+ This can be used to simulate a slow system to catch race conditions.
+ For example, setting QTUITEST_INPUT_DELAY to 500 roughly simulates running with a remote X
+ server over a link with a round trip time of 250ms.
+*/
+
+#include <QDir>
+#include <QPluginLoader>
+#include <QPointer>
+#include <QStringList>
+#include <QTimer>
+#include <QPoint>
+
+/*!
+ \internal
+ \class QtUiTestWidgets
+ \brief The QtUiTestWidgets class provides an interface for creating and managing QtUiTest widgets.
+
+ QtUiTestWidgets manages the lifetime of all test widgets and allows
+ test widgets to simulate user interaction with the application.
+*/
+
+enum QtUiTestInputType { QtUiTestPress, QtUiTestRelease, QtUiTestClick, QtUiTestDClick, QtUiTestMove };
+struct QtUiTestKeyEvent
+{
+ QtUiTestInputType type;
+ Qt::Key key;
+ Qt::KeyboardModifiers mod;
+ QtUiTest::InputOption opt;
+};
+struct QtUiTestMouseEvent
+{
+ QtUiTestInputType type;
+ QPoint pos;
+ Qt::MouseButtons state;
+ QtUiTest::InputOption opt;
+};
+struct QtUiTestTouchEvent
+{
+ QtUiTestInputType type;
+ QVariantList points;
+};
+static int qtUiTestGetInputDelay()
+{
+ bool ok;
+ QByteArray value(qgetenv("QTUITEST_INPUT_DELAY"));
+ int ret = value.toInt(&ok);
+ if (!ok || ret < 0) ret = 0;//-1;
+ return ret;
+}
+static int qtUiTestInputDelay()
+{ static int ret = qtUiTestGetInputDelay(); return ret; }
+
+
+class QtUiTestWidgetsPrivate
+{
+public:
+ QtUiTestWidgetsPrivate(QtUiTestWidgets* parent);
+
+ static QList<QByteArray> allImplementedInterfaces(QObject *o);
+
+ void _q_objectDestroyed();
+
+ QString currentInputMethod() const;
+
+ QtUiTestWidgets* q;
+
+ QHash< QByteArray, QSet<QtUiTest::WidgetFactory*> > factories;
+ QHash< QObject*, QHash<QByteArray, QPointer<QObject> > > testWidgets;
+ QSet< QtUiTest::WidgetFactory* > factorySet;
+
+ int inputOptions;
+
+ QString errorString;
+ QString debugBuffer;
+
+ QInputGenerator *input;
+
+ QList<QtUiTestKeyEvent> pendingKeyEvents;
+ QList<QtUiTestMouseEvent> pendingMouseEvents;
+ QList<QtUiTestTouchEvent> pendingTouchEvents;
+ void _q_postNextKeyEvent();
+ void _q_postNextMouseEvent();
+ void _q_postNextTouchEvent();
+};
+
+class QTWOptStack
+{
+public:
+ QTWOptStack(QtUiTestWidgetsPrivate* obj,
+ QtUiTest::InputOption opt)
+ : d(obj), option(opt)
+ {
+ if (opt && (!(d->inputOptions & opt))) {
+ d->inputOptions |= opt;
+ } else {
+ d = 0;
+ }
+ }
+
+ ~QTWOptStack()
+ {
+ if (d) {
+ d->inputOptions &= ~option;
+ }
+ }
+
+ QtUiTestWidgetsPrivate *d;
+ QtUiTest::InputOption option;
+};
+
+QtUiTestWidgetsPrivate::QtUiTestWidgetsPrivate(QtUiTestWidgets* parent)
+ : q(parent),input(0),
+ inputOptions(QtUiTest::NoOptions)
+{
+ QTT_TRACE_FUNCTION();
+}
+
+QtUiTestWidgets::QtUiTestWidgets()
+ : QObject(),
+ d(new QtUiTestWidgetsPrivate(this))
+{
+ QTT_TRACE_FUNCTION();
+ d->input = new QInputGeneratorGeneric();
+ refreshPlugins();
+}
+
+QtUiTestWidgets::~QtUiTestWidgets()
+{
+ QTT_TRACE_FUNCTION();
+ delete d->input;
+ delete d;
+ d = 0;
+}
+
+/*!
+ Returns a static instance of QtUiTestWidgets.
+*/
+QtUiTestWidgets* QtUiTestWidgets::instance()
+{
+ static QtUiTestWidgets instance;
+ return &instance;
+}
+
+/*!
+ When an object is destroyed, deletes all test widgets pointing
+ to that object.
+*/
+void QtUiTestWidgetsPrivate::_q_objectDestroyed()
+{
+ QTT_TRACE_FUNCTION();
+ QHash< QByteArray, QPointer<QObject> > toDestroy
+ = testWidgets.take(q->sender());
+
+ foreach (QPointer<QObject> tw, toDestroy.values()) {
+ if (tw) delete tw;
+ }
+}
+
+/*!
+ \internal
+ Destroy all test widgets and unregister all factories.
+ After calling this, refreshPlugins() must be called to be able to
+ construct testwidgets from factories.
+
+ For testing purposes only.
+*/
+void QtUiTestWidgets::clear()
+{
+ QTT_TRACE_FUNCTION();
+ d->factories.clear();
+ d->factorySet.clear();
+
+ foreach (QObject *o, d->testWidgets.keys()) {
+ foreach (QPointer<QObject> tw, d->testWidgets[o].values()) {
+ if (tw && tw != o) delete tw;
+ }
+ }
+ d->testWidgets.clear();
+}
+
+void QtUiTestWidgets::refreshPlugins()
+{
+ registerFactory(new TestQuickFactory());
+}
+
+/*!
+ Registers \a factory as a factory class for constructing test widgets.
+
+ It is not necessary to explicitly call this from QtUiTest widget plugins.
+ This function should only be called if a QtUiTest::WidgetFactory has been
+ created without using the standard plugin interface.
+*/
+void
+QtUiTestWidgets::registerFactory(QtUiTest::WidgetFactory* factory)
+{
+ QTT_TRACE_FUNCTION();
+ if (!factory) return;
+
+ d->factorySet << factory;
+ foreach(QString k, factory->keys()) {
+ d->factories[k.toLatin1()].insert(factory);
+ }
+}
+
+/*!
+ Returns a human-readable error string describing the last error which
+ occurred while accessing a testwidget.
+
+ The error string is used to report directly to a tester any unexpected
+ errors. The string will typically be used as a test failure message.
+
+ \sa setErrorString()
+*/
+QString QtUiTestWidgets::errorString() const
+{ return d->errorString; }
+
+/*!
+ Sets the human-readable \a error string describing the last error which
+ occurred while accessing a testwidget.
+
+ \sa errorString()
+*/
+void QtUiTestWidgets::setErrorString(const QString& error)
+{
+ if (error == d->errorString) return;
+ d->errorString = error;
+}
+
+/*!
+ Returns a QDebug object which can be used as an output stream for debugging
+ information. The debug information is sent to the test runner for output.
+ This ensures a consistent handling of debugging information on different
+ test platforms.
+*/
+QDebug QtUiTestWidgets::debug() const
+{
+ return QDebug(&d->debugBuffer) << '\n';
+}
+
+/*!
+ \internal
+*/
+QString QtUiTestWidgets::debugOutput()
+{
+ QString ret = d->debugBuffer;
+ d->debugBuffer.clear();
+ return ret;
+}
+
+/*!
+ Returns a list of all QtUiTest widget interfaces implemented by \a o .
+*/
+QList<QByteArray> QtUiTestWidgetsPrivate::allImplementedInterfaces(QObject *o)
+{
+ QTT_TRACE_FUNCTION();
+ // FIXME this function should not have to be explicitly implemented.
+ // Find some way to automatically handle all interfaces.
+ QList<QByteArray> ret;
+ if (qobject_cast<QtUiTest::Object*>(o)) ret << "Object";
+ if (qobject_cast<QtUiTest::Widget*>(o)) ret << "Widget";
+ return ret;
+}
+
+/*!
+ Returns a test widget wrapper for \a object implementing the given
+ \a interface. If a test widget implementing \a interface is already
+ wrapping \a object, that test widget will be returned. Otherwise,
+ a new test widget may be constructed using registered factories.
+
+ Returns 0 if the given \a interface is not implemented on \a object
+ or on any test widget which wraps \a object.
+
+ The returned object should not be deleted by the caller. QtUiTestWidgets
+ retains ownership of the returned test widget and deletes it when \a object
+ is destroyed.
+
+ \sa registerFactory()
+*/
+QObject* QtUiTestWidgets::testWidget(QObject* object, const QByteArray &interface)
+{
+ if (!object) return 0;
+
+ QMetaObject const *mo = object->metaObject();
+ QObject *ret = d->testWidgets.value( object ).value( interface );
+
+ bool watchingDestroyed = false;
+
+ if (!ret) {
+ QSet<QtUiTest::WidgetFactory*> usedFactories;
+ while (mo) {
+ foreach (QtUiTest::WidgetFactory *factory,
+ d->factories.value(mo->className()) - usedFactories) {
+
+ QObject *testWidget = factory->create(object);
+ usedFactories.insert(factory);
+ if (testWidget) {
+ bool isValuable = false;
+ foreach (const QByteArray& thisIface,
+ d->allImplementedInterfaces(testWidget)) {
+ QHash<QByteArray, QPointer<QObject> > &subhash
+ = d->testWidgets[object];
+ if (!subhash[thisIface]) {
+ isValuable = true;
+ subhash.insert( thisIface, testWidget );
+ watchingDestroyed = watchingDestroyed
+ || connect(object, SIGNAL(destroyed()),
+ this, SLOT(_q_objectDestroyed()));
+ }
+ }
+ if (!isValuable) {
+ delete testWidget;
+ }
+ }
+ }
+ mo = mo->superClass();
+ }
+ ret = d->testWidgets.value( object ).value( interface );
+ }
+ return ret;
+}
+
+/*!
+ Simulate a mouse press event at the global co-ordinates given by \a pos,
+ for the buttons in \a state. \a opt is applied to the simulated event.
+*/
+void QtUiTestWidgets::mousePress(const QPoint &pos, Qt::MouseButtons state,
+ QtUiTest::InputOption opt)
+{
+ QTT_TRACE_FUNCTION();
+ int delay;
+ if ((delay = qtUiTestInputDelay()) != -1) {
+ QtUiTestMouseEvent event = {QtUiTestPress, pos, state, opt};
+ d->pendingMouseEvents << event;
+ QTimer::singleShot(delay, this, SLOT(_q_postNextMouseEvent()));
+ return;
+ }
+
+ QTWOptStack st(d, opt);
+ d->input->mousePress(pos, state);
+}
+
+void QtUiTestWidgets::touchPress(const QVariantList &points)
+{
+ QTT_TRACE_FUNCTION();
+ int delay;
+ if ((delay = qtUiTestInputDelay()) != -1) {
+ QtUiTestTouchEvent event = {QtUiTestPress, points };
+ d->pendingTouchEvents << event;
+ QTimer::singleShot(delay, this, SLOT(_q_postNextTouchEvent()));
+ return;
+ }
+
+ d->input->touchPress(points);
+}
+
+void QtUiTestWidgets::touchUpdate(const QVariantList &points)
+{
+ QTT_TRACE_FUNCTION();
+ int delay;
+ if ((delay = qtUiTestInputDelay()) != -1) {
+ QtUiTestTouchEvent event = {QtUiTestMove, points};
+ d->pendingTouchEvents << event;
+ QTimer::singleShot(delay, this, SLOT(_q_postNextTouchEvent()));
+ return;
+ }
+
+ d->input->touchUpdate(points);
+}
+
+void QtUiTestWidgets::touchRelease(const QVariantList &points)
+{
+ QTT_TRACE_FUNCTION();
+ int delay;
+ if ((delay = qtUiTestInputDelay()) != -1) {
+ QtUiTestTouchEvent event = {QtUiTestRelease, points};
+ d->pendingTouchEvents << event;
+ QTimer::singleShot(delay, this, SLOT(_q_postNextTouchEvent()));
+ return;
+ }
+
+ d->input->touchRelease(points);
+}
+
+/*!
+ Simulate a mouse release event at the global co-ordinates given by \a pos,
+ for the buttons in \a state. \a opt is applied to the simulated event.
+*/
+void QtUiTestWidgets::mouseRelease(const QPoint &pos, Qt::MouseButtons state,
+ QtUiTest::InputOption opt)
+{
+ QTT_TRACE_FUNCTION();
+ int delay;
+ if ((delay = qtUiTestInputDelay()) != -1) {
+ QtUiTestMouseEvent event = {QtUiTestRelease, pos, state, opt};
+ d->pendingMouseEvents << event;
+ QTimer::singleShot(delay, this, SLOT(_q_postNextMouseEvent()));
+ return;
+ }
+
+ QTWOptStack st(d, opt);
+ d->input->mouseRelease(pos, state);
+}
+
+/*!
+ Simulate a mouse click event at the global co-ordinates given by \a pos,
+ for the buttons in \a state. \a opt is applied to the simulated event.
+*/
+void QtUiTestWidgets::mouseClick(const QPoint &pos, Qt::MouseButtons state,
+ QtUiTest::InputOption opt)
+{
+ QTT_TRACE_FUNCTION();
+ int delay;
+ if ((delay = qtUiTestInputDelay()) != -1) {
+ QtUiTestMouseEvent event = {QtUiTestClick, pos, state, opt};
+ d->pendingMouseEvents << event;
+ QTimer::singleShot(delay, this, SLOT(_q_postNextMouseEvent()));
+ return;
+ }
+
+ QTWOptStack st(d, opt);
+ d->input->mouseClick(pos, state);
+}
+
+/*!
+ Simulate a mouse double-click event at the global co-ordinates given by \a pos,
+ for the buttons in \a state. \a opt is applied to the simulated event.
+*/
+void QtUiTestWidgets::mouseDClick(const QPoint &pos, Qt::MouseButtons state,
+ QtUiTest::InputOption opt)
+{
+ QTT_TRACE_FUNCTION();
+ int delay;
+ if ((delay = qtUiTestInputDelay()) != -1) {
+ QtUiTestMouseEvent event = {QtUiTestDClick, pos, state, opt};
+ d->pendingMouseEvents << event;
+ QTimer::singleShot(delay, this, SLOT(_q_postNextMouseEvent()));
+ return;
+ }
+
+ QTWOptStack st(d, opt);
+ d->input->mouseDClick(pos, state);
+}
+
+/*!
+ Simulate moving the mouse pointer to global co-ordinates given by \a pos,
+ \a opt is applied to the simulated event.
+*/
+void QtUiTestWidgets::mouseMove(const QPoint &pos, QtUiTest::InputOption opt)
+{
+ QTT_TRACE_FUNCTION();
+ int delay;
+ if ((delay = qtUiTestInputDelay()) != -1) {
+ QtUiTestMouseEvent event = {QtUiTestMove, pos, 0, opt};
+ d->pendingMouseEvents << event;
+ QTimer::singleShot(delay, this, SLOT(_q_postNextMouseEvent()));
+ return;
+ }
+
+ QTWOptStack st(d, opt);
+ d->input->mouseMove(pos);
+}
+
+/*!
+ Simulate a key press event, using the given \a key and \a mod.
+ \a opt is applied to the simulated event.
+*/
+void QtUiTestWidgets::keyPress(Qt::Key key, Qt::KeyboardModifiers mod,
+ QtUiTest::InputOption opt)
+{
+ QTT_TRACE_FUNCTION();
+ int delay;
+ if ((delay = qtUiTestInputDelay()) != -1) {
+ QtUiTestKeyEvent event = {QtUiTestPress, key, mod, opt};
+ d->pendingKeyEvents << event;
+ QTimer::singleShot(delay, this, SLOT(_q_postNextKeyEvent()));
+ return;
+ }
+
+ QTWOptStack st(d, opt);
+ d->input->keyPress(key, mod, opt & QtUiTest::KeyRepeat);
+}
+
+/*!
+ Simulate a key release event, using the given \a key and \a mod.
+ \a opt is applied to the simulated event.
+*/
+void QtUiTestWidgets::keyRelease(Qt::Key key, Qt::KeyboardModifiers mod,
+ QtUiTest::InputOption opt)
+{
+ QTT_TRACE_FUNCTION();
+ int delay;
+ if ((delay = qtUiTestInputDelay()) != -1) {
+ QtUiTestKeyEvent event = {QtUiTestRelease, key, mod, opt};
+ d->pendingKeyEvents << event;
+ QTimer::singleShot(delay, this, SLOT(_q_postNextKeyEvent()));
+ return;
+ }
+
+ QTWOptStack st(d, opt);
+ d->input->keyRelease(key, mod);
+}
+
+/*!
+ Simulate a key click event, using the given \a key and \a mod.
+ \a opt is applied to the simulated event.
+*/
+void QtUiTestWidgets::keyClick(Qt::Key key, Qt::KeyboardModifiers mod,
+ QtUiTest::InputOption opt)
+{
+ QTT_TRACE_FUNCTION();
+ int delay;
+ if ((delay = qtUiTestInputDelay()) != -1) {
+ QtUiTestKeyEvent event = {QtUiTestClick, key, mod, opt};
+ d->pendingKeyEvents << event;
+ QTimer::singleShot(delay, this, SLOT(_q_postNextKeyEvent()));
+ return;
+ }
+
+ QTWOptStack st(d, opt);
+ d->input->keyClick(key, mod);
+}
+
+void QtUiTestWidgetsPrivate::_q_postNextMouseEvent()
+{
+ QTT_TRACE_FUNCTION();
+ QtUiTestMouseEvent const event = pendingMouseEvents.takeAt(0);
+ QTWOptStack st(this, event.opt);
+ if (event.type == QtUiTestPress)
+ input->mousePress(event.pos, event.state);
+ else if (event.type == QtUiTestRelease)
+ input->mouseRelease(event.pos, event.state);
+ else if (event.type == QtUiTestClick)
+ input->mouseClick(event.pos, event.state);
+ else if (event.type == QtUiTestDClick)
+ input->mouseDClick(event.pos, event.state);
+ else if (event.type == QtUiTestMove)
+ input->mouseMove(event.pos);
+}
+
+void QtUiTestWidgetsPrivate::_q_postNextTouchEvent()
+{
+ QTT_TRACE_FUNCTION();
+ QtUiTestTouchEvent const event = pendingTouchEvents.takeAt(0);
+ if (event.type == QtUiTestPress)
+ input->touchPress(event.points);
+ else if (event.type == QtUiTestRelease)
+ input->touchRelease(event.points);
+ else if (event.type == QtUiTestMove)
+ input->touchUpdate(event.points);
+}
+
+void QtUiTestWidgetsPrivate::_q_postNextKeyEvent()
+{
+ QTT_TRACE_FUNCTION();
+ QtUiTestKeyEvent const event = pendingKeyEvents.takeAt(0);
+ QTWOptStack st(this, event.opt);
+ if (event.type == QtUiTestPress)
+ input->keyPress(event.key, event.mod);
+ else if (event.type == QtUiTestRelease)
+ input->keyRelease(event.key, event.mod);
+ else if (event.type == QtUiTestClick)
+ input->keyClick(event.key, event.mod);
+}
+
+/*!
+ Set or clear the specified \a option for subsequent simulated input
+ events. The option is set if \a on is true, otherwise it is cleared.
+*/
+void QtUiTestWidgets::setInputOption(QtUiTest::InputOption option, bool on)
+{
+ QTT_TRACE_FUNCTION();
+ if (on)
+ d->inputOptions |= option;
+ else
+ d->inputOptions &= (~option);
+ qttDebug() << "Set input options to" << d->inputOptions;
+}
+
+/*!
+ Returns true if \a option is currently set.
+*/
+bool QtUiTestWidgets::testInputOption(QtUiTest::InputOption option) const
+{
+ QTT_TRACE_FUNCTION();
+ return (option == d->inputOptions)
+ || (option & d->inputOptions);
+}
+
+#include "moc_qtuitestwidgets_p.cpp"
diff --git a/src/remote/slave/lib/qtuitestwidgets_p.h b/src/remote/slave/lib/qtuitestwidgets_p.h
new file mode 100644
index 0000000..422f3aa
--- /dev/null
+++ b/src/remote/slave/lib/qtuitestwidgets_p.h
@@ -0,0 +1,126 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QTUITESTWIDGETS_P_H
+#define QTUITESTWIDGETS_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtUiTest API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QObject>
+#include <QMetaType>
+#include <QHash>
+#include <Qt>
+
+#include "qtuitestnamespace.h"
+
+class QtUiTestWidgetsPrivate;
+class QPoint;
+
+class QTUITEST_EXPORT QtUiTestWidgets : public QObject
+{
+ Q_OBJECT
+
+public:
+ static QtUiTestWidgets* instance();
+
+ virtual ~QtUiTestWidgets();
+
+ void setInputOption(QtUiTest::InputOption,bool = true);
+ bool testInputOption(QtUiTest::InputOption) const;
+
+ QString errorString() const;
+ void setErrorString(const QString&);
+ QDebug debug() const;
+ QString debugOutput();
+
+ void registerFactory(QtUiTest::WidgetFactory*);
+
+ void touchPress(const QVariantList &);
+ void touchUpdate(const QVariantList &);
+ void touchRelease(const QVariantList &);
+
+ void mousePress (const QPoint&,Qt::MouseButtons = Qt::LeftButton,
+ QtUiTest::InputOption = QtUiTest::NoOptions);
+ void mouseRelease(const QPoint&,Qt::MouseButtons = Qt::LeftButton,
+ QtUiTest::InputOption = QtUiTest::NoOptions);
+ void mouseClick (const QPoint&,Qt::MouseButtons = Qt::LeftButton,
+ QtUiTest::InputOption = QtUiTest::NoOptions);
+ void mouseDClick (const QPoint&,Qt::MouseButtons = Qt::LeftButton,
+ QtUiTest::InputOption = QtUiTest::NoOptions);
+ void mouseMove (const QPoint&, QtUiTest::InputOption = QtUiTest::NoOptions);
+
+ void keyPress (Qt::Key,Qt::KeyboardModifiers = 0,QtUiTest::InputOption = QtUiTest::NoOptions);
+ void keyRelease(Qt::Key,Qt::KeyboardModifiers = 0,QtUiTest::InputOption = QtUiTest::NoOptions);
+ void keyClick (Qt::Key,Qt::KeyboardModifiers = 0,QtUiTest::InputOption = QtUiTest::NoOptions);
+
+private:
+ Q_DISABLE_COPY(QtUiTestWidgets)
+
+ friend class QtUiTestWidgetsPrivate;
+
+ QtUiTestWidgetsPrivate* d;
+
+ QtUiTestWidgets();
+ QObject* testWidget(QObject*,const QByteArray&);
+
+ void refreshPlugins();
+ void clear();
+
+ Q_PRIVATE_SLOT(d, void _q_objectDestroyed())
+ Q_PRIVATE_SLOT(d, void _q_postNextKeyEvent())
+ Q_PRIVATE_SLOT(d, void _q_postNextMouseEvent())
+ Q_PRIVATE_SLOT(d, void _q_postNextTouchEvent())
+
+ friend QObject* QtUiTest::testWidget(QObject*,const char*);
+};
+
+#endif
+
diff --git a/src/remote/slave/lib/testapplication.cpp b/src/remote/slave/lib/testapplication.cpp
new file mode 100644
index 0000000..c179da5
--- /dev/null
+++ b/src/remote/slave/lib/testapplication.cpp
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "testapplication.h"
+
+#include <QDebug>
+#include <QApplication>
+#include <QWidget>
+#include <QScreen>
+
+TestApplication::TestApplication(QApplication* _q)
+ : TestObject(_q)
+{}
+
+TestApplication::~TestApplication()
+{
+}
+
+const QObjectList TestApplication::children() const
+{
+ QObjectList ret;
+
+ foreach (QWidget *w, qApp->topLevelWidgets()) {
+ if (!w->parent())
+ ret << w;
+ }
+
+ return ret;
+}
diff --git a/src/remote/slave/lib/testapplication.h b/src/remote/slave/lib/testapplication.h
new file mode 100644
index 0000000..4d50da7
--- /dev/null
+++ b/src/remote/slave/lib/testapplication.h
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef TEST_APPLICATION_H
+#define TEST_APPLICATION_H
+
+#include "testobject.h"
+#include "qtuitestwidgetinterface.h"
+
+class QApplication;
+
+class TestApplication : public TestObject
+{
+ Q_OBJECT
+ Q_INTERFACES(QtUiTest::Object)
+
+public:
+ TestApplication(QApplication*);
+ ~TestApplication();
+
+ virtual const QObjectList children() const;
+ virtual QObject* parent() const { return 0; }
+
+protected:
+ QApplication *q;
+
+};
+
+#endif
+
diff --git a/src/remote/slave/lib/testobject.cpp b/src/remote/slave/lib/testobject.cpp
new file mode 100644
index 0000000..6aef76d
--- /dev/null
+++ b/src/remote/slave/lib/testobject.cpp
@@ -0,0 +1,110 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "testobject.h"
+
+#include <QMetaObject>
+#include <QMetaProperty>
+
+const QLatin1String TestObject::classNameProperty("CLASSNAME");
+const QLatin1String TestObject::hasContentsProperty("HAS_CONTENTS");
+const QLatin1String TestObject::inheritsProperty("INHERITS");
+const QLatin1String TestObject::propertyProperty("PROPERTY");
+
+TestObject::TestObject(QObject* _q)
+ : q(_q)
+{
+}
+
+QObject* TestObject::parent() const
+{
+ return 0;
+}
+
+QVariant TestObject::getProperty(const QString& name) const
+{
+ return q->property(name.toLocal8Bit());
+}
+
+bool TestObject::setProperty(const QString& name, const QVariant& value)
+{
+ return q->setProperty(name.toAscii(), value);
+}
+
+bool TestObject::matchProperty(const QString& propertyUpper, const QVariant &value) const
+{
+ return (propertyUpper == propertyProperty && getProperty(value.toString()).isValid())
+ || (propertyUpper == classNameProperty && q->metaObject()->className() == value)
+ || (propertyUpper == inheritsProperty && q->inherits(value.toString().toLatin1()));
+}
+
+QVariantMap TestObject::getProperties() const
+{
+ QVariantMap map;
+ const QMetaObject *mo = q->metaObject();
+ for (int i=0; i<mo->propertyCount(); i++) {
+ map[mo->property(i).name()] = getProperty(mo->property(i).name());
+ }
+ foreach (const QByteArray &prop, q->dynamicPropertyNames()) {
+ map[prop] = getProperty(prop);
+ }
+ return map;
+}
+
+QString TestObject::typeOf() const
+{
+ return q->metaObject()->className();
+}
+
+QStringList TestObject::inheritance() const
+{
+ QStringList ret;
+
+ const QMetaObject *mo = q->metaObject();
+
+ while (mo) {
+ ret << mo->className();
+ mo = mo->superClass();
+ }
+
+ return ret;
+} \ No newline at end of file
diff --git a/src/remote/slave/lib/testobject.h b/src/remote/slave/lib/testobject.h
new file mode 100644
index 0000000..4c909c3
--- /dev/null
+++ b/src/remote/slave/lib/testobject.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef TEST_OBJECT_H
+#define TEST_OBJECT_H
+
+#include "qtuitestwidgetinterface.h"
+
+class TestObject : public QObject,
+ public QtUiTest::Object
+{
+ Q_OBJECT
+ Q_INTERFACES(QtUiTest::Object)
+
+public:
+
+ TestObject(QObject*);
+
+ virtual QObject* parent() const;
+ virtual QVariant getProperty(const QString&) const;
+ virtual bool setProperty(const QString&, const QVariant&);
+ virtual bool matchProperty(const QString&, const QVariant&) const;
+ virtual QVariantMap getProperties() const;
+ virtual QString typeOf() const;
+ virtual QStringList inheritance() const;
+
+protected:
+ static const QLatin1String classNameProperty;
+ static const QLatin1String hasContentsProperty;
+ static const QLatin1String inheritsProperty;
+ static const QLatin1String propertyProperty;
+
+ QObject* q;
+};
+
+#endif
diff --git a/src/remote/slave/lib/testquickfactory.cpp b/src/remote/slave/lib/testquickfactory.cpp
new file mode 100644
index 0000000..b4dd2a5
--- /dev/null
+++ b/src/remote/slave/lib/testquickfactory.cpp
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "testapplication.h"
+#include "testquickfactory.h"
+
+#include "testwidget.h"
+#include <QWidget>
+#include <QApplication>
+
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
+ #include "testquickitem.h"
+ #include "testquickobject.h"
+ #include "testquickview.h"
+ #include "testwindow.h"
+ #include <QQuickView>
+ #include <QQuickItem>
+ #include <QWindow>
+#endif
+
+TestQuickFactory::TestQuickFactory()
+{
+}
+
+QObject* TestQuickFactory::create(QObject* o)
+{
+ if (o->isWidgetType()) return new TestWidget(qobject_cast<QWidget*>(o));
+
+ QApplication *app = qobject_cast<QApplication*>(o);
+ if (app) return new TestApplication(app);
+
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
+ QQuickView *view = qobject_cast<QQuickView*>(o);
+ if (view) return new TestQuickView(view);
+
+ QQuickItem *item = qobject_cast<QQuickItem*>(o);
+ if (item) return new TestQuickItem(item);
+
+ QWindow *window = qobject_cast<QWindow*>(o);
+ if (window) return new TestWindow(window);
+
+ return new TestQuickObject(o);
+#else
+ // FIXME: Need support for Quick 1!
+ return 0;
+#endif
+}
+
+QStringList TestQuickFactory::keys() const
+{
+ return QStringList()
+ << "QQuickItem"
+ << "QQuickView"
+ << "QWindow"
+ << "QGuiApplication"
+ << "QObject"
+ ;
+}
diff --git a/src/remote/slave/lib/testquickfactory.h b/src/remote/slave/lib/testquickfactory.h
new file mode 100644
index 0000000..7bc5286
--- /dev/null
+++ b/src/remote/slave/lib/testquickfactory.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef TEST_QUICK_FACTORY_H
+#define TEST_QUICK_FACTORY_H
+
+#include <QObject>
+
+#include "qtuitestwidgetinterface.h"
+
+class TestQuickFactory : public QObject, public QtUiTest::WidgetFactory
+{
+ Q_OBJECT
+ Q_INTERFACES(QtUiTest::WidgetFactory)
+
+public:
+ TestQuickFactory();
+
+ virtual QObject* create(QObject*);
+ virtual QStringList keys() const;
+};
+
+#endif
+
diff --git a/src/remote/slave/lib/testquickitem.cpp b/src/remote/slave/lib/testquickitem.cpp
new file mode 100644
index 0000000..844efbc
--- /dev/null
+++ b/src/remote/slave/lib/testquickitem.cpp
@@ -0,0 +1,268 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "testquickitem.h"
+
+#include <QQuickItem>
+#include <QQuickCanvas>
+#include <QMetaObject>
+#include <QImage>
+#include <QMetaProperty>
+#include <private/qqmlmetatype_p.h>
+#include <designersupport.h>
+#include <QDebug>
+#include <QQmlProperty>
+
+TestQuickItem::TestQuickItem(QQuickItem* _q)
+ : TestQuickObject(_q)
+{
+}
+
+QRect TestQuickItem::geometry() const
+{
+ return mapToGlobal(quickItem()->boundingRect().toRect());
+}
+
+QPoint TestQuickItem::mapToGlobal(const QPoint& pos) const
+{
+ return quickItem()->canvas()->mapToGlobal(quickItem()->mapToScene(pos).toPoint());
+}
+
+QPoint TestQuickItem::mapFromGlobal(const QPoint& pos) const
+{
+ return quickItem()->mapFromScene(quickItem()->canvas()->mapFromGlobal(pos)).toPoint();
+}
+
+QRect TestQuickItem::mapToGlobal(const QRect& local) const
+{
+ QRect result = quickItem()->mapRectToScene(local).toRect();
+ result.moveTopLeft(quickItem()->canvas()->mapToGlobal(result.topLeft()));
+ return result;
+}
+
+QRect TestQuickItem::mapFromGlobal(const QRect& global) const
+{
+ QRect result = global;
+ result.moveTopLeft(quickItem()->canvas()->mapFromGlobal(result.topLeft()));
+ return quickItem()->mapRectFromScene(result).toRect();
+}
+
+bool TestQuickItem::grabImage(QImage &img) const
+{
+ if (quickItem()->width() <= 0 || quickItem()->height() <= 0
+ || !quickItem()->canvas())
+ return false;
+
+ QRect geo(geometry());
+ geo.moveTopLeft(geo.topLeft() - quickItem()->canvas()->pos());
+
+ QImage fb = quickItem()->canvas()->grabFrameBuffer();
+ img = fb.copy(geo);
+ return true;
+}
+
+bool TestQuickItem::isVisible() const
+{
+ return quickItem()->isVisible() && (quickItem()->opacity() > 0);
+}
+
+bool TestQuickItem::hasContents() const
+{
+ return quickItem()->flags() & QQuickItem::ItemHasContents;
+}
+
+QObject* TestQuickItem::parent() const
+{
+ QObject *ret = quickItem()->parentItem();
+ if (!ret)
+ ret = quickItem()->canvas();
+
+ return ret;
+}
+
+bool TestQuickItem::hasFocus() const
+{
+ return quickItem()->hasFocus();
+}
+
+bool isValidAnchorName(const QString &name)
+{
+ static QStringList anchorNameList(QStringList() << QLatin1String("anchors.top")
+ << QLatin1String("anchors.left")
+ << QLatin1String("anchors.right")
+ << QLatin1String("anchors.bottom")
+ << QLatin1String("anchors.verticalCenter")
+ << QLatin1String("anchors.horizontalCenter")
+ << QLatin1String("anchors.fill")
+ << QLatin1String("anchors.centerIn")
+ << QLatin1String("anchors.baseline"));
+
+ return anchorNameList.contains(name);
+}
+
+QVariant TestQuickItem::objectProperty(const QString& name) const
+{
+ if (name.startsWith(QLatin1String("anchors."))) {
+ if (isValidAnchorName(name)) {
+ QQmlContext *context = qmlContext(q);
+ if (!context) {
+ return QVariant();
+ }
+
+ QPair<QString, QObject*> pair = DesignerSupport::anchorLineTarget(quickItem(), name, context);
+ if (pair.second) {
+ if (pair.first.isEmpty()) {
+ return nameForObject(pair.second);
+ } else {
+ return QString("%1.%2").arg(nameForObject(pair.second)).arg(pair.first);
+ }
+ } else {
+ return QVariant();
+ }
+ } else {
+ QObject *anchors = QQmlMetaType::toQObject(quickItem()->property("anchors"));
+ if (anchors) {
+ return anchors->property(name.mid(8).toLatin1());
+ }
+ }
+ }
+
+ QQmlProperty qmlProperty(q, name);
+ QVariant ret = qmlProperty.read();
+
+ if (!ret.isValid()) {
+ ret = TestQuickObject::objectProperty(name);
+ }
+
+ return ret;
+}
+
+const QLatin1String TestQuickItem::containedInProperty("CONTAINED_IN");
+const QLatin1String TestQuickItem::containsProperty("CONTAINS");
+const QLatin1String TestQuickItem::intersectsProperty("INTERSECTS");
+const QLatin1String TestQuickItem::labelProperty("LABEL");
+
+bool TestQuickItem::matchProperty(const QString& propertyUpper, const QVariant &value) const
+{
+ static QStringList rectProperties(QStringList()
+ << containedInProperty << containsProperty << intersectsProperty);
+
+ if (rectProperties.contains(propertyUpper)) {
+ QRect rect = value.toRect();
+ if (rect.isValid()) {
+ QRect geom = geometry();
+ if ((propertyUpper == intersectsProperty && geom.intersects(rect)) ||
+ (propertyUpper == containedInProperty && rect.contains(geom)) ||
+ (propertyUpper == containsProperty && geom.contains(rect))) {
+ return true;
+ }
+ } else {
+ QtUiTest::setErrorString(QString("Invalid QRect specified for property '%1'").arg(propertyUpper));
+ return false;
+ }
+ } else if (propertyUpper == labelProperty) {
+ // Slightly nasty logic to support legacy LABEL functionality
+ foreach (const QObject *child, children()) {
+ if (child->inherits("QQuickText") && child->property("text") == value) {
+ return true;
+ } else if (child->inherits("QQuickRow")) {
+ QtUiTest::Object *qo = qtuitest_cast<QtUiTest::Object*>(child);
+ if (qo) {
+ foreach (const QObject *gChild, qo->children()) {
+ if (gChild->inherits("QQuickText") && gChild->property("text") == value) {
+ return true;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return TestQuickObject::matchProperty(propertyUpper, value);
+}
+
+QVariantMap TestQuickItem::getProperties() const
+{
+ QVariantMap map = TestQuickObject::getProperties();
+
+ // Include attached anchors properties
+ QObject *anchors = QQmlMetaType::toQObject(quickItem()->property("anchors"));
+ if (anchors) {
+ const QMetaObject *amo = anchors->metaObject();
+ for (int i=0; i<amo->propertyCount(); i++) {
+ QString anchorProperty = QString("anchors.%1").arg(amo->property(i).name());
+ QVariant value = getProperty(anchorProperty);
+ if (value.isValid()) {
+ map[anchorProperty] = value;
+ }
+ }
+ }
+
+ return map;
+}
+
+bool TestQuickItem::ignoreScan() const
+{
+ return !(quickItem()->isEnabled());
+}
+
+QString TestQuickItem::nameForObject(QObject* object) const
+{
+ if (object == quickItem()->parentItem()) {
+ return QLatin1String("parent");
+ }
+ return TestQuickObject::nameForObject(object);
+}
+
+QObject *TestQuickItem::window() const
+{
+ return quickItem()->canvas();
+}
+
+QString TestQuickItem::debugString() const
+{
+ QRect g(geometry());
+ QString name(nameForObject(q));
+ QString text = getProperty("text").toString();
+
+ return QString("%1x:%2 y:%3 w:%4 h:%5%6%7").arg(name.isEmpty() ? QString() : QString("id:%1 ").arg(name)).arg(g.x()).arg(g.y()).arg(g.width()).arg(g.height()).arg(isVisible() ? QLatin1String(" visible") : QString()).arg(text.isEmpty() ? QString() : QString(" text('%1')").arg(text));
+}
diff --git a/src/remote/slave/lib/testquickitem.h b/src/remote/slave/lib/testquickitem.h
new file mode 100644
index 0000000..fb62504
--- /dev/null
+++ b/src/remote/slave/lib/testquickitem.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef TEST_QUICK_ITEM_H
+#define TEST_QUICK_ITEM_H
+
+#include "testquickobject.h"
+#include "qtuitestwidgetinterface.h"
+#include <QQuickItem>
+
+class QRect;
+
+class TestQuickItem : public TestQuickObject,
+ public QtUiTest::Widget
+{
+ Q_OBJECT
+ Q_INTERFACES(QtUiTest::Widget)
+
+public:
+ TestQuickItem(QQuickItem*);
+
+ virtual QRect geometry() const;
+ virtual QPoint mapToGlobal(const QPoint&) const;
+ virtual QPoint mapFromGlobal(const QPoint&) const;
+ virtual QRect mapToGlobal(const QRect&) const;
+ virtual QRect mapFromGlobal(const QRect&) const;
+ virtual bool grabImage(QImage &img) const;
+
+ virtual bool isVisible() const;
+ virtual bool hasContents() const;
+ virtual QObject* parent() const;
+ virtual bool hasFocus() const;
+ virtual bool matchProperty(const QString&, const QVariant&) const;
+ virtual QVariantMap getProperties() const;
+
+ virtual bool ignoreScan() const;
+ virtual QObject* window() const;
+ virtual QString debugString() const;
+
+protected:
+ virtual QString nameForObject(QObject*) const;
+
+ inline QQuickItem *quickItem() const { return static_cast<QQuickItem*>(q); }
+
+ virtual QVariant objectProperty(const QString& name) const;
+
+ static const QLatin1String containedInProperty;
+ static const QLatin1String containsProperty;
+ static const QLatin1String intersectsProperty;
+ static const QLatin1String labelProperty;
+};
+
+#endif
diff --git a/src/remote/slave/lib/testquickobject.cpp b/src/remote/slave/lib/testquickobject.cpp
new file mode 100644
index 0000000..cbf961c
--- /dev/null
+++ b/src/remote/slave/lib/testquickobject.cpp
@@ -0,0 +1,259 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "testquickobject.h"
+
+#include <QQuickItem>
+#include <QQmlContext>
+#include <QQmlListProperty>
+#include <QMetaObject>
+#include <QMetaProperty>
+#include <private/qqmlmetatype_p.h>
+
+const QLatin1String TestQuickObject::classNameProperty("CLASSNAME");
+const QLatin1String TestQuickObject::hasContentsProperty("HAS_CONTENTS");
+const QLatin1String TestQuickObject::inheritsProperty("INHERITS");
+const QLatin1String TestQuickObject::propertyProperty("PROPERTY");
+
+const QLatin1String TestQuickObject::qmlTypeProperty("QMLTYPE");
+const QLatin1String TestQuickObject::qmlIdProperty("QMLID");
+const QLatin1String TestQuickObject::qmlInheritsProperty("QMLINHERITS");
+
+TestQuickObject::TestQuickObject(QObject* _q)
+ : q(_q)
+{
+}
+
+const QObjectList TestQuickObject::children() const
+{
+ QObjectList ret;
+ QQuickItem *item = qobject_cast<QQuickItem*>(q);
+ if (item) {
+ foreach (QQuickItem *child, item->childItems()) {
+ ret << child;
+ }
+ }
+
+ return ret;
+}
+
+QObject* TestQuickObject::parent() const
+{
+ return 0;
+}
+
+QVariant TestQuickObject::objectProperty(const QString& name) const
+{
+ return q->property(name.toLocal8Bit());
+}
+
+QVariant TestQuickObject::getProperty(const QString& name) const
+{
+ // Do QtUiTest property type check
+ if (name.toUpper() == qmlTypeProperty) {
+ return typeOf();
+ } else if (name.toUpper() == qmlIdProperty) {
+ return nameForObject(q);
+ }
+
+ // Get the property and convert it to QtUiTest compatible format
+ QVariant ret = objectProperty(name);
+
+ if (!ret.isValid()) {
+ return ret;
+ }
+
+ if (ret.canConvert<QQmlListReference>()) {
+ QQmlListReference ref = ret.value<QQmlListReference>();
+ QVariantList list;
+ for (int i=0; i<ref.count(); ++i) {
+ list << QVariant::fromValue(ref.at(i));
+ }
+ ret = list;
+ } else {
+ const QMetaObject *mo = q->metaObject();
+ QMetaProperty mp = mo->property(mo->indexOfProperty(name.toLocal8Bit()));
+ if (mp.isEnumType())
+ {
+ QVariantMap map;
+ int value = ret.toInt();
+ map["_enum_"] = mp.enumerator().valueToKeys(value);
+ map["_value_"] = value;
+ ret = map;
+ }
+ }
+
+ if (ret.type() == QVariant::UserType) {
+ bool ok;
+ QObject *obj = QQmlMetaType::toQObject(ret, &ok);
+ if (ok) {
+ return QVariant::fromValue(obj);
+ }
+ }
+
+ return ret;
+}
+
+bool TestQuickObject::setProperty(const QString& name, const QVariant& value)
+{
+ return q->setProperty(name.toAscii(), value);
+}
+
+bool TestQuickObject::matchProperty(const QString& propertyUpper, const QVariant &value) const
+{
+ return (propertyUpper == propertyProperty && getProperty(value.toString()).isValid())
+ || (propertyUpper == classNameProperty && q->metaObject()->className() == value)
+ || (propertyUpper == inheritsProperty && q->inherits(value.toString().toLatin1()))
+ || (propertyUpper == hasContentsProperty && hasContents() == value.toBool())
+ || (propertyUpper == qmlInheritsProperty && inheritsQmlType(value.toString()));
+}
+
+QVariantMap TestQuickObject::getProperties() const
+{
+ QVariantMap map;
+ const QMetaObject *mo = q->metaObject();
+ for (int i=0; i<mo->propertyCount(); i++) {
+ map[mo->property(i).name()] = getProperty(mo->property(i).name());
+ }
+ foreach (const QByteArray &prop, q->dynamicPropertyNames()) {
+ map[prop] = getProperty(prop);
+ }
+ return map;
+}
+
+QVariantList TestQuickObject::resources() const
+{
+ return getProperty(QLatin1String("resources")).toList();
+}
+
+QString TestQuickObject::typeOf() const
+{
+ return getTypeName();
+}
+
+bool TestQuickObject::inheritsQmlType(const QString &typeName) const
+{
+ const QMetaObject *mo = q->metaObject();
+
+ while (mo) {
+ if (typeNameForMetaObject(mo) == typeName) {
+ return true;
+ }
+ if (mo == &QQuickItem::staticMetaObject) {
+ break;
+ }
+ mo = mo->superClass();
+ }
+
+ return false;
+}
+
+QString TestQuickObject::getTypeName() const
+{
+ return typeNameForMetaObject(q->metaObject());
+}
+
+QString TestQuickObject::typeNameForMetaObject(const QMetaObject *mo) const
+{
+ QString typeName;
+ if (!mo) return typeName;
+
+ QQmlType *type = QQmlMetaType::qmlType(mo);
+
+ // This logic is copied from QQmlInfo
+ if (type) {
+ typeName = type->qmlTypeName();
+ int lastSlash = typeName.lastIndexOf(QLatin1Char('/'));
+ if (lastSlash != -1)
+ typeName = typeName.mid(lastSlash+1);
+ } else {
+ typeName = QString::fromUtf8(mo->className());
+ int marker = typeName.indexOf(QLatin1String("_QMLTYPE_"));
+ if (marker != -1)
+ typeName = typeName.left(marker);
+
+ marker = typeName.indexOf(QLatin1String("_QML_"));
+ if (marker != -1) {
+ typeName = typeName.left(marker);
+ typeName += QLatin1Char('*');
+ type = QQmlMetaType::qmlType(QMetaType::type(typeName.toLatin1()));
+ if (type) {
+ typeName = type->qmlTypeName();
+ int lastSlash = typeName.lastIndexOf(QLatin1Char('/'));
+ if (lastSlash != -1)
+ typeName = typeName.mid(lastSlash+1);
+ }
+ }
+ }
+
+ if (typeName.isNull()) {
+ return mo->className();
+ }
+
+ return typeName;
+}
+
+QString TestQuickObject::nameForObject(QObject* object) const
+{
+ QQmlContext *context = qmlContext(q);
+ if (!object || !context) {
+ return QString();
+ }
+ return context->nameForObject(object);
+}
+
+QStringList TestQuickObject::inheritance() const
+{
+ QStringList ret;
+
+ const QMetaObject *mo = q->metaObject();
+
+ while (mo) {
+ ret << typeNameForMetaObject(mo);
+ if (mo == &QQuickItem::staticMetaObject) {
+ break;
+ }
+ mo = mo->superClass();
+ }
+
+ return ret;
+} \ No newline at end of file
diff --git a/src/remote/slave/lib/testquickobject.h b/src/remote/slave/lib/testquickobject.h
new file mode 100644
index 0000000..dfc62cb
--- /dev/null
+++ b/src/remote/slave/lib/testquickobject.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef TEST_QUICK_OBJECT_H
+#define TEST_QUICK_OBJECT_H
+
+#include "qtuitestwidgetinterface.h"
+
+class QQmlContext;
+
+class TestQuickObject : public QObject,
+ public QtUiTest::Object
+{
+ Q_OBJECT
+ Q_INTERFACES(QtUiTest::Object)
+
+public:
+
+ TestQuickObject(QObject*);
+
+ virtual const QObjectList children() const;
+ virtual QObject* parent() const;
+ virtual QVariant getProperty(const QString&) const;
+ virtual bool setProperty(const QString&, const QVariant&);
+ virtual bool matchProperty(const QString&, const QVariant&) const;
+ virtual QVariantMap getProperties() const;
+ virtual QVariantList resources() const;
+ virtual QString typeOf() const;
+ virtual QStringList inheritance() const;
+
+protected:
+ bool inheritsQmlType(const QString&) const;
+ virtual QString getTypeName() const;
+ QString typeNameForMetaObject(const QMetaObject *mo) const;
+ virtual QString nameForObject(QObject*) const;
+ virtual QVariant objectProperty(const QString& name) const;
+
+ static const QLatin1String qmlTypeProperty;
+ static const QLatin1String qmlIdProperty;
+ static const QLatin1String qmlInheritsProperty;
+
+ static const QLatin1String classNameProperty;
+ static const QLatin1String hasContentsProperty;
+ static const QLatin1String inheritsProperty;
+ static const QLatin1String propertyProperty;
+
+ QObject* q;
+};
+
+#endif
diff --git a/src/remote/slave/lib/testquickview.cpp b/src/remote/slave/lib/testquickview.cpp
new file mode 100644
index 0000000..e8abde8
--- /dev/null
+++ b/src/remote/slave/lib/testquickview.cpp
@@ -0,0 +1,130 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "testquickview.h"
+
+#include <QDebug>
+#include <QQuickView>
+#include <QQuickItem>
+#include <QImage>
+
+TestQuickView::TestQuickView(QQuickView* _q)
+ : TestQuickObject(_q)
+{}
+
+TestQuickView::~TestQuickView()
+{
+}
+
+QRect TestQuickView::geometry() const
+{
+ return static_cast<QQuickView*>(q)->geometry();
+}
+
+bool TestQuickView::isVisible() const
+{
+ return true;
+}
+
+bool TestQuickView::hasContents() const
+{
+ return true;
+}
+
+QObject* TestQuickView::parent() const
+{
+ return static_cast<QQuickView*>(q)->parent();
+}
+
+QPoint TestQuickView::mapToGlobal(const QPoint &local) const
+{
+ return static_cast<QQuickView*>(q)->mapToGlobal(local);
+}
+
+QPoint TestQuickView::mapFromGlobal(const QPoint &global) const
+{
+ return static_cast<QQuickView*>(q)->mapFromGlobal(global);
+}
+
+QRect TestQuickView::mapToGlobal(const QRect &local) const
+{
+ QRect result = local;
+ result.moveTopLeft(mapToGlobal(result.topLeft()));
+ return result;
+}
+
+QRect TestQuickView::mapFromGlobal(const QRect &global) const
+{
+ QRect result = global;
+ result.moveTopLeft(mapFromGlobal(result.topLeft()));
+ return result;
+}
+
+bool TestQuickView::grabImage(QImage &img) const
+{
+ img = static_cast<QQuickView*>(q)->grabFrameBuffer();
+ return !img.isNull();
+}
+
+const QObjectList TestQuickView::children() const
+{
+ QObjectList ret;
+
+ QObject *rootObject = static_cast<QQuickView*>(q)->rootObject();
+ if (rootObject)
+ ret << rootObject;
+
+ return ret;
+}
+
+bool TestQuickView::hasFocus() const
+{
+ return true;
+}
+
+QString TestQuickView::debugString() const
+{
+ QRect g(geometry());
+ QString name(nameForObject(q));
+
+ return QString("%1x:%2 y:%3 w:%4 h:%5%6").arg(name.isEmpty() ? QString() : QString("id:%1 ").arg(name)).arg(g.x()).arg(g.y()).arg(g.width()).arg(g.height()).arg(isVisible() ? QLatin1String(" visible") : QString());
+}
diff --git a/src/remote/slave/lib/testquickview.h b/src/remote/slave/lib/testquickview.h
new file mode 100644
index 0000000..32409c5
--- /dev/null
+++ b/src/remote/slave/lib/testquickview.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef TEST_QUICK_VIEW_H
+#define TEST_QUICK_VIEW_H
+
+#include "testquickobject.h"
+#include "qtuitestwidgetinterface.h"
+#include <QRect>
+
+class QQuickView;
+
+class TestQuickView : public TestQuickObject,
+ public QtUiTest::Widget
+{
+ Q_OBJECT
+ Q_INTERFACES(QtUiTest::Object)
+ Q_INTERFACES(QtUiTest::Widget)
+
+public:
+ TestQuickView(QQuickView*);
+ ~TestQuickView();
+
+ virtual QRect geometry() const;
+ virtual bool isVisible() const;
+ virtual bool hasContents() const;
+ virtual QObject* parent() const;
+ virtual QPoint mapToGlobal(const QPoint&) const;
+ virtual QPoint mapFromGlobal(const QPoint&) const;
+ virtual QRect mapToGlobal(const QRect&) const;
+ virtual QRect mapFromGlobal(const QRect&) const;
+ virtual bool grabImage(QImage &img) const;
+ virtual bool hasFocus() const;
+ virtual const QObjectList children() const;
+ virtual QString debugString() const;
+};
+
+#endif
+
diff --git a/src/remote/slave/lib/testslaveserver.cpp b/src/remote/slave/lib/testslaveserver.cpp
new file mode 100644
index 0000000..90d1f2c
--- /dev/null
+++ b/src/remote/slave/lib/testslaveserver.cpp
@@ -0,0 +1,222 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "testslaveserver.h"
+// #include "qsensorgenerator_p.h"
+#include <qtestslave.h>
+#include <QCoreApplication>
+#include <QStringList>
+#include <QLocalSocket>
+#include <QtSystemTest/QstDebug>
+
+#ifdef Q_OS_SYMBIAN
+# include <sys/socket.h>
+# include <net/if.h>
+#endif
+
+#if defined(Q_WS_WIN) || defined(Q_WS_MAC)
+extern Q_GUI_EXPORT bool qt_use_native_dialogs;
+#endif
+
+TestSlaveServer::TestSlaveServer()
+ : QTcpServer(), showDebug(false), started(false), m_useDaemon(false)
+{
+ QTT_TRACE_FUNCTION();
+}
+
+TestSlaveServer::~TestSlaveServer()
+{
+ QTT_TRACE_FUNCTION();
+ close();
+}
+
+void TestSlaveServer::incomingConnection(int sd)
+{
+ QTT_TRACE_FUNCTION();
+ slave.setSocket(sd);
+}
+
+quint16 TestSlaveServer::queryDaemonForPort() const
+{
+ QTT_TRACE_FUNCTION();
+ QLocalSocket socket;
+ socket.connectToServer(QString::fromLocal8Bit(QTUITEST_PORT_PATH));
+ qDebug() << "qtuitest: Getting port...";
+ if (!socket.waitForConnected(500)) {
+ return 0;
+ }
+
+ char buf[32];
+ qDebug() << "qtuitest: Got local socket..." << &socket;
+ if (!socket.waitForReadyRead(5000)) {
+ socket.close();
+ return 0;
+ }
+
+ qint64 length = socket.readLine(buf, sizeof(buf));
+ socket.close();
+
+ if (length == -1) {
+ return 0;
+ }
+
+ bool ok = false;
+ quint16 port = QString(buf).toUShort(&ok);
+ if (!ok) {
+ return 0;
+ }
+
+ qDebug() << "qtuitest: Received Port" << port;
+ return port;
+}
+
+void TestSlaveServer::initSlave(bool useDaemon)
+{
+ QTT_TRACE_FUNCTION();
+ m_useDaemon = useDaemon;
+
+// QSensorGeneratorFactory *factory = new QSensorGeneratorFactory;
+// factory->registerSensors();
+
+ QTimer::singleShot(100, this, SLOT(startService()));
+}
+
+void TestSlaveServer::startService()
+{
+ QTT_TRACE_FUNCTION();
+ bool parseOk;
+ QStringList args = QCoreApplication::arguments();
+ QByteArray debugEnvBa = qgetenv("QTUITEST_DEBUG");
+ QString debugEnv = QString(debugEnvBa);
+
+#ifndef QTUITEST_DEBUG
+ int debugValue = debugEnv.toInt(&parseOk);
+ if (parseOk && (debugValue > 0))
+ showDebug = true;
+#else
+ showDebug = true;
+#endif
+
+ if (showDebug)
+ qWarning("QtUiTest: Start service");
+
+ for (int index = 0; index < args.count(); index++){
+ if (args[index].endsWith("qtuitestrunner")) {
+ if (showDebug)
+ qWarning() << "QtUiTest: Not starting TestSlaveServer::startService for qtuitestrunner";
+ return;
+ }
+ }
+
+ if (started) {
+ if (showDebug)
+ qWarning() << "QtUiTest: Closing TestSlaveServer connection";
+
+ close();
+ }
+
+ quint16 aut_port = DEFAULT_AUT_PORT;
+
+ if (m_useDaemon) {
+ aut_port = queryDaemonForPort();
+ if (!aut_port) {
+ qDebug() << "Not received port, will retry in 2000ms";
+ QTimer::singleShot(2000, this, SLOT(startService()));
+ return;
+ }
+ } else {
+ QString autPortEnv = QString::fromLocal8Bit(qgetenv("QTUITEST_PORT"));
+
+ if (!autPortEnv.isEmpty()) {
+ aut_port = autPortEnv.toUShort(&parseOk);
+ if (!parseOk) {
+ aut_port = DEFAULT_AUT_PORT;
+ qWarning() << "QtUiTest: Unable to parse QTUITEST_PORT" << autPortEnv;
+ } else {
+ if (showDebug)
+ qWarning() << "QtUiTest: Set port via QTUITEST_PORT to" << aut_port;
+ }
+ }
+ for (int index = 0; index < args.count(); index++) {
+ if ((args[index] == QLatin1String("-autport")) && (index + 1 < args.count())) {
+ aut_port = args[index + 1].toUShort(&parseOk);
+ if (!parseOk) {
+ aut_port = DEFAULT_AUT_PORT;
+ qWarning() << "QtUiTest: Unable to parse -autport" << args[index];
+ } else {
+ if (showDebug)
+ qWarning() << "QtUiTest: Set port via -autport to" << aut_port;
+ }
+ }
+ }
+ }
+
+ m_port = aut_port;
+
+ QTimer::singleShot(0, this, SLOT(initConnection()));
+}
+
+void TestSlaveServer::initConnection()
+{
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
+ if (!listen(QHostAddress::AnyIPv4, m_port)) {
+#else
+ if (!listen(QHostAddress::Any, m_port)) {
+#endif
+ qWarning() << "QtUiTest: couldn't listen for connections on " << m_port << ":" << errorString();
+ return;
+ }
+
+ started = true;
+ if (showDebug)
+ qWarning() << "QtUiTest: listening for connections on" << m_port;
+}
+
+void TestSlaveServer::stopService()
+{
+ QTT_TRACE_FUNCTION();
+ if (showDebug)
+ qWarning("QtUiTest : Stoping service");
+
+ close();
+ started = false;
+}
diff --git a/src/remote/slave/lib/testslaveserver.h b/src/remote/slave/lib/testslaveserver.h
new file mode 100644
index 0000000..1043b4b
--- /dev/null
+++ b/src/remote/slave/lib/testslaveserver.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QTESTSLAVESERVER_H
+#define QTESTSLAVESERVER_H
+
+#include <QTcpServer>
+#include "qtestslave.h"
+
+class TestSlaveServer : public QTcpServer
+{
+Q_OBJECT
+
+public:
+ TestSlaveServer();
+ ~TestSlaveServer();
+ void incomingConnection(int);
+ void initSlave(bool useDaemon=false);
+ void stopService();
+
+private slots:
+ void initConnection();
+ void startService();
+
+private:
+ quint16 queryDaemonForPort() const;
+ QTestSlave slave;
+ bool showDebug;
+ bool started;
+ bool m_useDaemon;
+ quint16 m_port;
+};
+
+#endif
diff --git a/src/remote/slave/lib/testwidget.cpp b/src/remote/slave/lib/testwidget.cpp
new file mode 100644
index 0000000..f2340f4
--- /dev/null
+++ b/src/remote/slave/lib/testwidget.cpp
@@ -0,0 +1,179 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "testwidget.h"
+
+#include <QDebug>
+#include <QWidget>
+#include <QPixmap>
+#include <QAction>
+#include <QMetaProperty>
+
+const QLatin1String TestWidget::actionsProperty("QACTIONS");
+const QLatin1String TestWidget::classNameProperty("CLASSNAME");
+const QLatin1String TestWidget::hasContentsProperty("HAS_CONTENTS");
+const QLatin1String TestWidget::inheritsProperty("INHERITS");
+const QLatin1String TestWidget::propertyProperty("PROPERTY");
+
+TestWidget::TestWidget(QWidget* _q)
+ : TestObject(_q)
+{}
+
+TestWidget::~TestWidget()
+{
+}
+
+QRect TestWidget::geometry() const
+{
+ QWidget *w = widget();
+ QRect geo(w->geometry());
+ geo.moveTopLeft(w->mapToGlobal(w->mapFromParent(geo.topLeft())));
+ return geo;
+}
+
+bool TestWidget::isVisible() const
+{
+ return widget()->isVisible();
+}
+
+bool TestWidget::hasContents() const
+{
+ return true;
+}
+
+QObject* TestWidget::parent() const
+{
+ return q->parent();
+}
+
+QPoint TestWidget::mapToGlobal(const QPoint &local) const
+{
+ return widget()->mapToGlobal(local);
+}
+
+QPoint TestWidget::mapFromGlobal(const QPoint &global) const
+{
+ return widget()->mapFromGlobal(global);
+}
+
+QRect TestWidget::mapToGlobal(const QRect &local) const
+{
+ QRect result = local;
+ result.moveTopLeft(mapToGlobal(result.topLeft()));
+ return result;
+}
+
+QRect TestWidget::mapFromGlobal(const QRect &global) const
+{
+ QRect result = global;
+ result.moveTopLeft(mapFromGlobal(result.topLeft()));
+ return result;
+}
+
+bool TestWidget::grabImage(QImage &img) const
+{
+ img = QPixmap::grabWidget(widget()).toImage();
+ return !img.isNull();
+}
+
+const QObjectList TestWidget::children() const
+{
+ QObjectList ret;
+ foreach (QObject *child, q->children()) {
+ if (child->isWidgetType()) {
+ ret << child;
+ }
+ }
+
+ return ret;
+}
+
+bool TestWidget::hasFocus() const
+{
+ return widget()->hasFocus();
+}
+
+QVariantList TestWidget::getActions() const
+{
+ QVariantList ret;
+ foreach (QAction *action, widget()->actions()) {
+ ret << QVariant::fromValue(static_cast<QObject*>(action));
+ }
+ return ret;
+}
+
+QVariant TestWidget::getProperty(const QString& name) const
+{
+ if (name.toUpper() == actionsProperty) {
+ return getActions();
+ } else if (name.toUpper() == QLatin1String("INHERITANCE")) {
+ return inheritance();
+ }
+ return q->property(name.toLocal8Bit());
+}
+
+bool TestWidget::matchProperty(const QString& propertyUpper, const QVariant &value) const
+{
+ return (propertyUpper == propertyProperty && getProperty(value.toString()).isValid())
+ || (propertyUpper == classNameProperty && q->metaObject()->className() == value)
+ || (propertyUpper == inheritsProperty && q->inherits(value.toString().toLatin1()))
+ || (propertyUpper == hasContentsProperty);
+}
+
+
+QVariantList TestWidget::resources() const
+{
+ return getActions();
+}
+
+QObject* TestWidget::window() const
+{
+ return widget()->window();
+}
+
+QString TestWidget::debugString() const
+{
+ QRect g(geometry());
+ QString name;
+
+ return QString("%1x:%2 y:%3 w:%4 h:%5%6").arg(name.isEmpty() ? QString() : QString("id:%1 ").arg(name)).arg(g.x()).arg(g.y()).arg(g.width()).arg(g.height()).arg(isVisible() ? QLatin1String(" visible") : QString());
+}
diff --git a/src/remote/slave/lib/testwidget.h b/src/remote/slave/lib/testwidget.h
new file mode 100644
index 0000000..35e1269
--- /dev/null
+++ b/src/remote/slave/lib/testwidget.h
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef TEST_WIDGET_H
+#define TEST_WIDGET_H
+
+#include "testobject.h"
+#include "qtuitestwidgetinterface.h"
+
+#include <QWidget>
+
+class TestWidget : public TestObject,
+ public QtUiTest::Widget
+{
+ Q_OBJECT
+ Q_INTERFACES(QtUiTest::Object)
+ Q_INTERFACES(QtUiTest::Widget)
+
+public:
+ TestWidget(QWidget*);
+ ~TestWidget();
+
+ virtual bool matchProperty(const QString&, const QVariant&) const;
+ virtual QRect geometry() const;
+ virtual bool isVisible() const;
+ virtual bool hasContents() const;
+ virtual QObject* parent() const;
+ virtual QPoint mapToGlobal(const QPoint&) const;
+ virtual QPoint mapFromGlobal(const QPoint&) const;
+ virtual QRect mapToGlobal(const QRect&) const;
+ virtual QRect mapFromGlobal(const QRect&) const;
+ virtual bool grabImage(QImage &img) const;
+ virtual bool hasFocus() const;
+ virtual const QObjectList children() const;
+ virtual QVariant getProperty(const QString&) const;
+ virtual QVariantList resources() const;
+ virtual QObject* window() const;
+ virtual QString debugString() const;
+
+protected:
+ inline QWidget *widget() const { return static_cast<QWidget*>(q); }
+ QVariantList getActions() const;
+ static const QLatin1String actionsProperty;
+ static const QLatin1String classNameProperty;
+ static const QLatin1String hasContentsProperty;
+ static const QLatin1String inheritsProperty;
+ static const QLatin1String propertyProperty;
+
+};
+
+#endif
+
diff --git a/src/remote/slave/lib/testwindow.cpp b/src/remote/slave/lib/testwindow.cpp
new file mode 100644
index 0000000..517c141
--- /dev/null
+++ b/src/remote/slave/lib/testwindow.cpp
@@ -0,0 +1,142 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "testwindow.h"
+
+#include <QDebug>
+#include <QWindow>
+#include <QScreen>
+
+TestWindow::TestWindow(QWindow* _q)
+ : TestQuickObject(_q)
+{}
+
+TestWindow::~TestWindow()
+{
+}
+
+QRect TestWindow::geometry() const
+{
+ return window()->geometry();
+}
+
+bool TestWindow::isVisible() const
+{
+ return window()->isExposed();
+}
+
+bool TestWindow::hasContents() const
+{
+ return true;
+}
+
+QObject* TestWindow::parent() const
+{
+ return window()->parent();
+}
+
+QPoint TestWindow::mapToGlobal(const QPoint &local) const
+{
+ return window()->mapToGlobal(local);
+}
+
+QPoint TestWindow::mapFromGlobal(const QPoint &global) const
+{
+ return window()->mapFromGlobal(global);
+}
+
+QRect TestWindow::mapToGlobal(const QRect &local) const
+{
+ QRect result = local;
+ result.moveTopLeft(mapToGlobal(result.topLeft()));
+ return result;
+}
+
+QRect TestWindow::mapFromGlobal(const QRect &global) const
+{
+ QRect result = global;
+ result.moveTopLeft(mapFromGlobal(result.topLeft()));
+ return result;
+}
+
+bool TestWindow::grabImage(QImage &img) const
+{
+ Q_UNUSED(img);
+ return false;
+}
+
+const QObjectList TestWindow::children() const
+{
+ QObjectList ret;
+
+ foreach (QObject *child, q->children()) {
+ if (child->isWindowType() || child->isWidgetType()) {
+ ret << child;
+ }
+ }
+
+ // This is all a bit nasty...
+ QObject *rootObject = window()->focusObject();
+ while (rootObject) {
+ QObject *parent = rootObject->parent();
+ if (!parent || parent == q || !parent->isWidgetType())
+ break;
+ rootObject = parent;
+ }
+ if (rootObject)
+ ret << rootObject;
+
+ return ret;
+}
+
+bool TestWindow::hasFocus() const
+{
+ return true;
+}
+
+QString TestWindow::debugString() const
+{
+ QRect g(geometry());
+ QString name(nameForObject(q));
+
+ return QString("%1x:%2 y:%3 w:%4 h:%5%6").arg(name.isEmpty() ? QString() : QString("id:%1 ").arg(name)).arg(g.x()).arg(g.y()).arg(g.width()).arg(g.height()).arg(isVisible() ? QLatin1String(" visible") : QString());
+}
diff --git a/src/remote/slave/lib/testwindow.h b/src/remote/slave/lib/testwindow.h
new file mode 100644
index 0000000..890e9ae
--- /dev/null
+++ b/src/remote/slave/lib/testwindow.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef TEST_WINDOW_H
+#define TEST_WINDOW_H
+
+#include "testquickobject.h"
+#include "qtuitestwidgetinterface.h"
+
+#include <QWindow>
+
+class TestWindow : public TestQuickObject,
+ public QtUiTest::Widget
+{
+ Q_OBJECT
+ Q_INTERFACES(QtUiTest::Object)
+ Q_INTERFACES(QtUiTest::Widget)
+
+public:
+ TestWindow(QWindow*);
+ ~TestWindow();
+
+ virtual QRect geometry() const;
+ virtual bool isVisible() const;
+ virtual bool hasContents() const;
+ virtual QObject* parent() const;
+ virtual QPoint mapToGlobal(const QPoint&) const;
+ virtual QPoint mapFromGlobal(const QPoint&) const;
+ virtual QRect mapToGlobal(const QRect&) const;
+ virtual QRect mapFromGlobal(const QRect&) const;
+ virtual bool grabImage(QImage &img) const;
+ virtual bool hasFocus() const;
+ virtual const QObjectList children() const;
+ virtual QString debugString() const;
+
+protected:
+ inline QWindow *window() const { return static_cast<QWindow*>(q); }
+};
+
+#endif
+
diff --git a/src/remote/slave/slave.pro b/src/remote/slave/slave.pro
new file mode 100644
index 0000000..6ea58af
--- /dev/null
+++ b/src/remote/slave/slave.pro
@@ -0,0 +1,3 @@
+TEMPLATE = subdirs
+CONFIG += ordered
+SUBDIRS = lib styleplugin
diff --git a/src/remote/slave/styleplugin/qtuiteststyleplugin.cpp b/src/remote/slave/styleplugin/qtuiteststyleplugin.cpp
new file mode 100644
index 0000000..f277df7
--- /dev/null
+++ b/src/remote/slave/styleplugin/qtuiteststyleplugin.cpp
@@ -0,0 +1,117 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QApplication>
+#include <QStylePlugin>
+
+#include <QtSystemTest/qtestslave.h>
+#include <QtSystemTest/testslaveserver.h>
+
+#include <QtSystemTest/QstDebug>
+
+class QtUiTestStylePlugin : public QStylePlugin
+{
+ Q_OBJECT
+
+public:
+ QtUiTestStylePlugin();
+ virtual ~QtUiTestStylePlugin();
+
+ QStringList keys() const;
+ QStyle *create(const QString &key);
+
+protected:
+ void initSlave(bool = false);
+
+private:
+ TestSlaveServer *m_testSlaveServer;
+};
+
+QtUiTestStylePlugin::QtUiTestStylePlugin() :
+ m_testSlaveServer(0)
+{
+}
+
+QtUiTestStylePlugin::~QtUiTestStylePlugin()
+{
+ QTT_TRACE_FUNCTION();
+ m_testSlaveServer->stopService();
+ delete m_testSlaveServer;
+}
+
+QStringList QtUiTestStylePlugin::keys() const
+{
+ QTT_TRACE_FUNCTION();
+ return QStringList() << "QtUiTest_NoStyle" << QLatin1String("QtUiTest") << QLatin1String("QtUiTestD");
+}
+
+QStyle *QtUiTestStylePlugin::create(const QString &key)
+{
+ QTT_TRACE_FUNCTION();
+
+ static bool initialised = false;
+
+ if (key.toLower() == "qtuitest_nostyle") {
+ // QApplication::style() has failed to initialise app style
+ // so is trying all styles. In this case we DO NOT want the
+ // QtUiTest style to be initialised unintentionally...
+ initialised = true;
+ }
+
+ if (initialised) return 0;
+ if (key.toLower() == QLatin1String("qtuitest")) {
+ initSlave(false);
+ } else if (key.toLower() == QLatin1String("qtuitestd")) {
+ initSlave(true);
+ }
+ return 0;
+}
+
+void QtUiTestStylePlugin::initSlave(bool useDaemon)
+{
+ m_testSlaveServer = new TestSlaveServer();
+ m_testSlaveServer->initSlave(useDaemon);
+}
+
+#include "qtuiteststyleplugin.moc"
+#include <qplugin.h>
+Q_EXPORT_PLUGIN2(QtUiTestStylePlugin, QtUiTestStylePlugin)
diff --git a/src/remote/slave/styleplugin/styleplugin.pro b/src/remote/slave/styleplugin/styleplugin.pro
new file mode 100644
index 0000000..ca35c8d
--- /dev/null
+++ b/src/remote/slave/styleplugin/styleplugin.pro
@@ -0,0 +1,18 @@
+TEMPLATE=lib
+CONFIG += plugin
+
+TARGET=qststyle
+TARGET=$$qtLibraryTarget($$TARGET)
+
+QT+=network
+
+INCLUDEPATH += ../../../../include
+LIBS += -L../../../../lib
+LIBS += -lQstProtocol -lQstSlave
+
+DESTDIR=../../../../plugins
+
+SOURCES+=qtuiteststyleplugin.cpp
+
+target.path=$$[QT_INSTALL_PLUGINS]/styles
+INSTALLS+=target
diff --git a/src/src.pro b/src/src.pro
new file mode 100644
index 0000000..5a497e2
--- /dev/null
+++ b/src/src.pro
@@ -0,0 +1,13 @@
+TEMPLATE = subdirs
+CONFIG += ordered
+
+isEmpty(PARTS) {
+ SUBDIRS += protocol interpreter remote testapp objectBrowser
+} else {
+ # done this way since order matters
+ contains(PARTS, protocol):SUBDIRS += protocol
+ contains(PARTS, interpreter):SUBDIRS += interpreter
+ contains(PARTS, remote):SUBDIRS += remote
+ contains(PARTS, testapp):SUBDIRS += testapp
+ contains(PARTS, objectBrowser):SUBDIRS += objectBrowser
+}
diff --git a/src/testapp/main.cpp b/src/testapp/main.cpp
new file mode 100644
index 0000000..508d1e7
--- /dev/null
+++ b/src/testapp/main.cpp
@@ -0,0 +1,52 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QApplication>
+#include "mainwindow.h"
+
+int main(int argc, char *argv[])
+{
+ QApplication a(argc, argv);
+ MainWindow w;
+ w.show();
+
+ return a.exec();
+}
diff --git a/src/testapp/mainwindow.cpp b/src/testapp/mainwindow.cpp
new file mode 100644
index 0000000..dc82522
--- /dev/null
+++ b/src/testapp/mainwindow.cpp
@@ -0,0 +1,154 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "mainwindow.h"
+#include "ui_mainwindow.h"
+#include <QStandardItemModel>
+
+MainWindow::MainWindow(QWidget *parent) :
+ QMainWindow(parent),
+ ui(new Ui::MainWindow),
+ m_clicks(0)
+{
+ ui->setupUi(this);
+ connect(ui->actionExit, SIGNAL(triggered()), this, SLOT(close()));
+
+ connect(ui->lineEdit, SIGNAL(textChanged(QString)), ui->textEditDisplay, SLOT(setText(QString)));
+ connect(ui->textEdit, SIGNAL(textChanged()), this, SLOT(updateTextEditDisplay()));
+
+ connect(ui->pushButton, SIGNAL(pressed()), this, SLOT(updatePushButtonDisplay()));
+ connect(ui->pushButton, SIGNAL(released()), this, SLOT(updatePushButtonDisplay()));
+ connect(ui->pushButton, SIGNAL(clicked()), this, SLOT(updateClickCount()));
+ connect(ui->radioButton1, SIGNAL(toggled(bool)), this, SLOT(updateRadioButtonDisplay()));
+ connect(ui->radioButton2, SIGNAL(toggled(bool)), this, SLOT(updateRadioButtonDisplay()));
+ connect(ui->checkBox, SIGNAL(stateChanged(int)), this, SLOT(updateCheckBoxDisplay()));
+ connect(ui->comboBox, SIGNAL(activated(int)), this, SLOT(updateComboBoxDisplay()));
+ connect(ui->horizontalSlider, SIGNAL(valueChanged(int)), this, SLOT(updateHorizontalSliderDisplay()));
+
+ QWidget *contents = new QWidget;
+ contents->setObjectName("contents");
+ contents->setFixedSize(QSize(500, 500));
+ QPushButton *topLeft = new QPushButton(contents);
+ topLeft->setObjectName("topLeft");
+ topLeft->setFixedSize(QSize(20,20));
+ topLeft->move(10, 10);
+ QPushButton *topRight = new QPushButton(contents);
+ topRight->setObjectName("topRight");
+ topRight->setFixedSize(QSize(20,20));
+ topRight->move(470, 10);
+ QPushButton *bottomLeft = new QPushButton(contents);
+ bottomLeft->setObjectName("bottomLeft");
+ bottomLeft->setFixedSize(QSize(20,20));
+ bottomLeft->move(10, 470);
+ QPushButton *bottomRight = new QPushButton(contents);
+ bottomRight->setObjectName("bottomRight");
+ bottomRight->setFixedSize(QSize(20,20));
+ bottomRight->move(470, 470);
+
+ ui->scrollArea->setWidget(contents);
+
+ QStandardItemModel *model = new QStandardItemModel(this);
+ model->setHorizontalHeaderLabels(QStringList() << tr("items"));
+ QStandardItem *parentItem;
+ for (int j = 0; j < 3; ++j) {
+ parentItem = model->invisibleRootItem();
+ for (int i = 0; i < 4; ++i) {
+ QStandardItem *item = new QStandardItem(QString("item %0").arg(i));
+ parentItem->appendRow(item);
+ parentItem = item;
+ }
+ }
+
+ ui->treeView->setModel(model);
+}
+
+MainWindow::~MainWindow()
+{
+ delete ui;
+}
+
+void MainWindow::updateClickCount()
+{
+ m_clicks++;
+ updatePushButtonDisplay();
+}
+
+void MainWindow::updateTextEditDisplay()
+{
+ ui->textEditDisplay->setText(ui->textEdit->document()->toHtml());
+}
+
+void MainWindow::updatePushButtonDisplay()
+{
+ ui->pushButtonDisplay->setText(
+ tr("clicks: %1 isPressed: %2")
+ .arg(m_clicks)
+ .arg(ui->pushButton->isDown()));
+}
+
+void MainWindow::updateRadioButtonDisplay()
+{
+ ui->radioButtonDisplay->setText(
+ tr("1: %1 2: %2")
+ .arg(ui->radioButton1->isChecked())
+ .arg(ui->radioButton2->isChecked()));
+}
+
+void MainWindow::updateCheckBoxDisplay()
+{
+ ui->checkBoxDisplay->setText(
+ tr("state: %1")
+ .arg(ui->checkBox->checkState()));
+}
+
+void MainWindow::updateComboBoxDisplay()
+{
+ ui->checkBoxDisplay->setText(
+ tr("option: %1")
+ .arg(ui->comboBox->currentText()));
+}
+
+void MainWindow::updateHorizontalSliderDisplay()
+{
+ ui->horizontalSliderDisplay->setText(
+ tr("position: %1")
+ .arg(ui->horizontalSlider->value()));
+}
diff --git a/src/testapp/mainwindow.h b/src/testapp/mainwindow.h
new file mode 100644
index 0000000..98bb02a
--- /dev/null
+++ b/src/testapp/mainwindow.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include <QMainWindow>
+
+namespace Ui {
+class MainWindow;
+}
+
+class MainWindow : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ explicit MainWindow(QWidget *parent = 0);
+ ~MainWindow();
+
+private slots:
+ void updateClickCount();
+
+ void updateTextEditDisplay();
+ void updatePushButtonDisplay();
+ void updateRadioButtonDisplay();
+ void updateCheckBoxDisplay();
+ void updateComboBoxDisplay();
+ void updateHorizontalSliderDisplay();
+
+private:
+ Ui::MainWindow *ui;
+
+ int m_clicks;
+};
+
+#endif // MAINWINDOW_H
diff --git a/src/testapp/mainwindow.ui b/src/testapp/mainwindow.ui
new file mode 100644
index 0000000..d53c7e5
--- /dev/null
+++ b/src/testapp/mainwindow.ui
@@ -0,0 +1,291 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>562</width>
+ <height>576</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>MainWindow</string>
+ </property>
+ <widget class="QWidget" name="centralWidget">
+ <layout class="QVBoxLayout" name="verticalLayout_4">
+ <item>
+ <widget class="QTabWidget" name="tabWidget">
+ <property name="currentIndex">
+ <number>0</number>
+ </property>
+ <widget class="QWidget" name="core">
+ <attribute name="title">
+ <string>Core</string>
+ </attribute>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QGroupBox" name="textGroup">
+ <property name="title">
+ <string>Text</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QLineEdit" name="lineEdit"/>
+ </item>
+ <item>
+ <widget class="QLabel" name="lineEditDisplay">
+ <property name="text">
+ <string>initial</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="Line" name="line">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QTextEdit" name="textEdit"/>
+ </item>
+ <item>
+ <widget class="QLabel" name="textEditDisplay">
+ <property name="text">
+ <string>initial</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="controlsGroup">
+ <property name="title">
+ <string>Controls</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <item>
+ <widget class="QPushButton" name="pushButton">
+ <property name="text">
+ <string>PushButton</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="pushButtonDisplay">
+ <property name="text">
+ <string>initial</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="Line" name="line_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="radioButton1">
+ <property name="text">
+ <string>RadioButton</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="radioButton2">
+ <property name="text">
+ <string>RadioButton</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="radioButtonDisplay">
+ <property name="text">
+ <string>initial</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="Line" name="line_3">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="checkBox">
+ <property name="text">
+ <string>CheckBox</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="checkBoxDisplay">
+ <property name="text">
+ <string>initial</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="Line" name="line_4">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="comboBox">
+ <item>
+ <property name="text">
+ <string>one</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>two</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>three</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="comboBoxDisplay">
+ <property name="text">
+ <string>initial</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="Line" name="line_5">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSlider" name="horizontalSlider">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="horizontalSliderDisplay">
+ <property name="text">
+ <string>initial</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="scrollingGroup">
+ <property name="title">
+ <string>Scrolling</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <widget class="QScrollArea" name="scrollArea">
+ <property name="widgetResizable">
+ <bool>true</bool>
+ </property>
+ <widget class="QWidget" name="scrollAreaWidgetContents">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>167</width>
+ <height>233</height>
+ </rect>
+ </property>
+ </widget>
+ </widget>
+ </item>
+ <item>
+ <widget class="QTreeView" name="treeView"/>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <action name="actionNew">
+ <property name="text">
+ <string>&amp;New</string>
+ </property>
+ </action>
+ <action name="actionClose">
+ <property name="text">
+ <string>&amp;Close</string>
+ </property>
+ </action>
+ <action name="actionExit">
+ <property name="text">
+ <string>E&amp;xit</string>
+ </property>
+ </action>
+ <action name="actionCopy">
+ <property name="text">
+ <string>&amp;Copy</string>
+ </property>
+ </action>
+ <action name="actionPaste">
+ <property name="text">
+ <string>&amp;Paste</string>
+ </property>
+ </action>
+ </widget>
+ <layoutdefault spacing="6" margin="11"/>
+ <tabstops>
+ <tabstop>lineEdit</tabstop>
+ <tabstop>textEdit</tabstop>
+ <tabstop>pushButton</tabstop>
+ <tabstop>radioButton1</tabstop>
+ <tabstop>checkBox</tabstop>
+ <tabstop>comboBox</tabstop>
+ <tabstop>horizontalSlider</tabstop>
+ <tabstop>scrollArea</tabstop>
+ <tabstop>treeView</tabstop>
+ </tabstops>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/testapp/testapp.pro b/src/testapp/testapp.pro
new file mode 100644
index 0000000..59ae3d0
--- /dev/null
+++ b/src/testapp/testapp.pro
@@ -0,0 +1,10 @@
+TARGET = testapp_widgets
+TEMPLATE = app
+DESTDIR = ../../bin
+
+SOURCES += main.cpp\
+ mainwindow.cpp
+
+HEADERS += mainwindow.h
+
+FORMS += mainwindow.ui
diff --git a/tests/AllTests.qml b/tests/AllTests.qml
new file mode 100644
index 0000000..cdae596
--- /dev/null
+++ b/tests/AllTests.qml
@@ -0,0 +1,53 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.1
+import QtSystemTest 1.0
+
+TestCollection {
+ id: suite
+ name: 'All tests'
+ description: 'Tests all the cases'
+
+ InterpreterTests {}
+ RemoteTests {}
+
+}
diff --git a/tests/InterpreterTests.qml b/tests/InterpreterTests.qml
new file mode 100644
index 0000000..db3ab8c
--- /dev/null
+++ b/tests/InterpreterTests.qml
@@ -0,0 +1,53 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.1
+import QtSystemTest 1.0
+
+import "interpreter"
+
+TestCollection {
+ name: 'interpreter only tests'
+ description: name
+
+ CoreTests {}
+ RunnerTests {}
+}
diff --git a/tests/MyConfig.qml b/tests/MyConfig.qml
new file mode 100644
index 0000000..905d8a4
--- /dev/null
+++ b/tests/MyConfig.qml
@@ -0,0 +1,53 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtSystemTest 1.0
+
+Config {
+ Remote {
+ id: sut
+ host: 'localhost'
+ port: 5656
+ }
+}
+
+
diff --git a/tests/RemoteTests.qml b/tests/RemoteTests.qml
new file mode 100644
index 0000000..094b5bc
--- /dev/null
+++ b/tests/RemoteTests.qml
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.1
+import QtSystemTest 1.0
+
+import "remote"
+
+TestCollection {
+ name: 'remote (qtuitestd) tests'
+ description: name
+
+ RunProcessTests {}
+ RemoteApiTests{}
+ AssistantTest{}
+ TestAppWidgetTest{}
+ QstObjectApiTests{}
+}
diff --git a/tests/interpreter/CoreTests.qml b/tests/interpreter/CoreTests.qml
new file mode 100644
index 0000000..108f50f
--- /dev/null
+++ b/tests/interpreter/CoreTests.qml
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.1
+import QtSystemTest 1.0
+import "core"
+
+TestCollection {
+ name: 'core api test'
+ description: name
+ Test {
+ name: 'Js api: currentFile'; description: name
+
+ property string expectedFileName: 'CoreTests.qml'
+ function run() {
+ var path = core().Js.Engine.currentFile();
+ var fileName = path.substring(path.lastIndexOf('/')+1);
+ expect(fileName).toBe(expectedFileName);
+ }
+ }
+
+ ExpectApiTests{}
+ SleepTest{}
+ ClassTest{}
+ FailApiTest{}
+ ItemHandlerTests{}
+ ApplicationRegistryTests{}
+}
diff --git a/tests/interpreter/RunnerTests.qml b/tests/interpreter/RunnerTests.qml
new file mode 100644
index 0000000..6046ca2
--- /dev/null
+++ b/tests/interpreter/RunnerTests.qml
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.1
+import QtSystemTest 1.0
+
+import "runner"
+
+TestCollection {
+ name: 'runner logic tests'; description: name
+
+ EmptyTest{}
+ EmptyTests{}
+ SkipTest{}
+ FailTest{}
+ UntestedTest{}
+ UntestedTests{}
+ DefaultConfigTest{}
+}
+
diff --git a/tests/interpreter/core/ApplicationRegistryTests.qml b/tests/interpreter/core/ApplicationRegistryTests.qml
new file mode 100644
index 0000000..67c215b
--- /dev/null
+++ b/tests/interpreter/core/ApplicationRegistryTests.qml
@@ -0,0 +1,52 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.1
+import QtSystemTest 1.0
+import "application"
+
+TestCollection {
+ name: 'Application object test'; description: name
+
+ RegisterUnregisterAppTest{}
+ DefaultApplicationTest{}
+ CustomApplicationTest{}
+}
diff --git a/tests/interpreter/core/ClassTest.qml b/tests/interpreter/core/ClassTest.qml
new file mode 100644
index 0000000..56f3c86
--- /dev/null
+++ b/tests/interpreter/core/ClassTest.qml
@@ -0,0 +1,135 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.1
+import QtSystemTest 1.0
+
+TestCollection {
+ id: root
+ name: 'Javascript Class api test'
+ description: name
+
+ function _() {
+ // dummy
+ // used instead of property var in Qt5
+ }
+
+ function setup() {
+ var Class = core().Class;
+ var Shape = Class.create(function(name) {
+ return {
+ name: function(){ return name; },
+
+ setName: function setName(value) { name = value; }
+ };
+ });
+ _.Class = Class;
+ _.Shape = Shape;
+ }
+
+ Test {
+ name: 'construct objects'; description: name
+ function run() {
+ var Shape = _.Shape;
+
+ var x = null;
+ expect(x).toBe(null);
+
+ x = new Shape('x');
+ expect(x).not.toBe(null);
+ expect(x).instanceOf(Shape);
+ }
+ }
+
+ Test {
+ name: 'invoke methods'; description: name
+ function run() {
+ var x = new _.Shape('x');
+ expect(x.name()).toBe('x');
+ x.setName('y');
+ expect(x.name()).toBe('y');
+ }
+
+ }
+
+ Test {
+ name: 'extend objects'; description: name
+ function run() {
+ var Circle = _.Shape.extend(function(r) {
+ this._super('Circle');
+ return {
+ radius: function(){ return r; }
+ };
+ });
+
+ var c = new Circle(10);
+ expect(c).instanceOf(_.Shape);
+ expect(c).instanceOf(Circle);
+ expect(c.name()).toBe('Circle');
+ expect(c.radius()).toBe(10);
+ }
+ }
+
+ Test {
+ name: 'private calls public'; description: name
+
+ function setup() {
+ var Class = _.Class;
+ var Base = Class.create(function() {
+
+ function bar() {
+ return this.overrideMe();
+ }
+ function foo() {
+ return bar.call(this);
+ }
+ return {
+ overrideMe: function() { return 'Base'},
+ foo: foo
+ };
+ });
+ _.base = new Base();
+ }
+ function run() {
+ expect(_.base.foo()).toBe('Base');
+ }
+ }
+}
diff --git a/tests/interpreter/core/ExpectApiTests.qml b/tests/interpreter/core/ExpectApiTests.qml
new file mode 100644
index 0000000..488d14f
--- /dev/null
+++ b/tests/interpreter/core/ExpectApiTests.qml
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.1
+import QtSystemTest 1.0
+
+TestCollection {
+ name: 'expect api tests'; description: name
+
+ Test {
+ name: 'expect.not'; description: name;
+ function run() {
+ expect(undefined).toBe(undefined);
+ expect(null).not.toBe(undefined);
+ }
+ }
+}
+
+
diff --git a/tests/interpreter/core/FailApiTest.qml b/tests/interpreter/core/FailApiTest.qml
new file mode 100644
index 0000000..a9eba0f
--- /dev/null
+++ b/tests/interpreter/core/FailApiTest.qml
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.1
+import QtSystemTest 1.0
+
+Test {
+ name: 'fail api test'; description: name
+
+ function run() {
+ var error,
+ topOfStack,
+ msg = 'A fail message';
+
+ var Core = core();
+ var Engine = Core.Js.Engine;
+ var currentFile = Core.Js.Engine.currentFile();
+
+ try {
+ var beforeFail = Engine.currentLine();
+ throw new Core.Qtt.Fail(msg);
+ } catch(e) {
+ error = e;
+ topOfStack = e.stack.first();
+ }
+
+ expect(error).instanceOf(Core.Qtt.Error);
+ expect(error).instanceOf(Core.Qtt.Fail);
+
+ expect(error.message).toBe(msg);
+ expect(error.type).toBe('Fail');
+ expect(error.status).toBe(Core.Qtt.Status.Failed);
+
+ expect(topOfStack.fileName).toBe(currentFile);
+ expect(topOfStack.lineNumber).toBe(beforeFail+1);
+ }
+
+}
+
diff --git a/tests/interpreter/core/ItemHandlerTests.qml b/tests/interpreter/core/ItemHandlerTests.qml
new file mode 100644
index 0000000..f904d4b
--- /dev/null
+++ b/tests/interpreter/core/ItemHandlerTests.qml
@@ -0,0 +1,52 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.1
+import QtSystemTest 1.0
+import "itemhandlers"
+
+TestCollection {
+ name: 'item handler tests'; description: name
+
+ RegisterUnregisterHandlerTest{}
+ DefaultItemHandlerTest{}
+ CustomItemHandlerTest{}
+}
diff --git a/tests/interpreter/core/LocalProcessTest.qml b/tests/interpreter/core/LocalProcessTest.qml
new file mode 100644
index 0000000..f324d44
--- /dev/null
+++ b/tests/interpreter/core/LocalProcessTest.qml
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtSystemTest 1.0
+
+Test {
+ name: 'process'; description: name
+ property int timeout: 3000
+ property LocalProcess process: LocalProcess {
+ outputMode: LocalProcess.PropertyOutput
+ }
+
+ function run() {
+ process.start("bc");
+ process.write("p = 3 + 4\n");
+ process.write("p\n");
+ expect(process.waitForReadyRead(timeout)).toBe(true);
+ expect(process.standardOutput).toBe('7\n')
+ process.write("2 * p\n")
+ process.closeWriteChannel();
+ expect(process.waitForFinished(timeout)).toBe(true);
+
+ expect(process.standardOutput).toBe('7\n14\n')
+ expect(process.exitCode).toBe(0);
+ }
+}
diff --git a/tests/interpreter/core/SleepTest.qml b/tests/interpreter/core/SleepTest.qml
new file mode 100644
index 0000000..0483061
--- /dev/null
+++ b/tests/interpreter/core/SleepTest.qml
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.1
+import QtSystemTest 1.0
+
+Test {
+ name: 'sleep'; description: name
+ property int interval: 50
+
+ function run() {
+ var beforeSleep = +(new Date());
+ sleep(interval);
+ var afterSleep = +(new Date());
+ expect(afterSleep - beforeSleep).toBeBetween(interval*0.95, interval*1.05);
+ }
+}
diff --git a/tests/interpreter/core/application/CustomApplicationTest.qml b/tests/interpreter/core/application/CustomApplicationTest.qml
new file mode 100644
index 0000000..177f261
--- /dev/null
+++ b/tests/interpreter/core/application/CustomApplicationTest.qml
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.1
+import QtSystemTest 1.0
+
+Test {
+ id: root
+ name: 'custom app handler'; description: name
+
+ function _() {}
+
+ property string appId: 'MyApp'
+ property string filePath: className + '.qml'
+ property string className: 'MyApplication'
+
+
+ function setup() {
+ var registry = core().ApplicationRegistry;
+ registry.register(appId, filePath);
+ var p = registry.applicationForKey(appId);
+ expect(p).not.toBe(undefined);
+ _.registry = registry;
+ }
+
+ function run() {
+ var registry = _.registry;
+ var component = registry.applicationForKey(appId);
+ var app = component.createObject(root);
+ var handler = app.toString().split('_').first();
+ expect(handler).toBe(className);
+
+ expect(app.name).toBe(className);
+ expect(app.item()).toBe(className);
+ }
+
+ function cleanup() {
+ var registry = _.registry;
+ registry.unregister(appId);
+ }
+}
diff --git a/tests/interpreter/core/application/DefaultApplicationTest.qml b/tests/interpreter/core/application/DefaultApplicationTest.qml
new file mode 100644
index 0000000..277765b
--- /dev/null
+++ b/tests/interpreter/core/application/DefaultApplicationTest.qml
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.1
+import QtSystemTest 1.0
+
+Test {
+ id: root
+ name: 'Default application handler'; description: name
+
+ function _() {}
+ property string defaultHandler: 'Application'
+
+ function setup() {
+ var factory = core().ApplicationRegistry;
+ expect(factory).not.toBe(undefined);
+ _.factory = factory;
+ }
+
+ function run() {
+ var
+ key = 'foobar',
+ factory = _.factory,
+ file,
+ component,
+ appObject,
+ className
+ ;
+
+ file = factory.fileForKey(key);
+ expect(file.endsWith('/'+ defaultHandler + '.qml')).toBe(true);
+
+ component = factory.applicationForKey(key);
+ expect(component).not.toBe(undefined);
+ expect(component).not.toBe(null);
+
+
+ appObject = component.createObject(root);
+ expect(appObject).not.toBe(undefined);
+ expect(appObject).not.toBe(null);
+
+ className = appObject.toString().split('_').first();
+ expect(className).toBe(defaultHandler);
+ }
+}
diff --git a/tests/interpreter/core/application/MyApplication.js b/tests/interpreter/core/application/MyApplication.js
new file mode 100644
index 0000000..07aa821
--- /dev/null
+++ b/tests/interpreter/core/application/MyApplication.js
@@ -0,0 +1,48 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+.pragma library
+.import QtSystemTest 1.0 as Qst
+
+(function() {
+ var Apps = Qst.Core.ApplicationRegistry;
+ Apps.register('myapp', 'MyApplication.qml');
+})();
diff --git a/tests/interpreter/core/application/MyApplication.qml b/tests/interpreter/core/application/MyApplication.qml
new file mode 100644
index 0000000..befd0b7
--- /dev/null
+++ b/tests/interpreter/core/application/MyApplication.qml
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.1
+import QtSystemTest 1.0
+
+Application {
+ property string name: 'MyApplication'
+ function item() {
+ return name;
+ }
+}
diff --git a/tests/interpreter/core/application/RegisterUnregisterAppTest.qml b/tests/interpreter/core/application/RegisterUnregisterAppTest.qml
new file mode 100644
index 0000000..e3771e9
--- /dev/null
+++ b/tests/interpreter/core/application/RegisterUnregisterAppTest.qml
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.1
+import QtSystemTest 1.0
+
+Test {
+ id: root
+ name: 'register and unregister item handler'; description: name
+
+ function _() {}
+ property string defaultHandler: 'Application'
+
+ property string key: 'myapp'
+ property string className: 'MyApplication'
+ property string filePath: className + '.qml'
+
+
+ function setup() {
+ var factory = core().ApplicationRegistry;
+ expect(factory).not.toBe(undefined);
+ _.factory = factory;
+ }
+
+ function expectAppHandler(handlerClassName) {
+ var
+ factory = _.factory,
+ file,
+ component,
+ appObject,
+ className
+ ;
+
+ file = factory.fileForKey(key);
+ expect(file.endsWith('/'+ handlerClassName + '.qml')).toBe(true);
+
+ component = factory.applicationForKey(key);
+ expect(component).not.toBe(undefined);
+ expect(component).not.toBe(null);
+
+
+ appObject = component.createObject(root);
+ expect(appObject).not.toBe(undefined);
+ expect(appObject).not.toBe(null);
+
+ className = appObject.toString().split('_').first();
+ expect(className).toBe(handlerClassName);
+ }
+
+ function run() {
+ var factory = _.factory;
+ expectAppHandler(defaultHandler);
+ factory.register(key, filePath);
+ expectAppHandler(className);
+ factory.unregister(key);
+ expectAppHandler(defaultHandler);
+ }
+}
diff --git a/tests/interpreter/core/itemhandlers/CustomItemHandlerTest.qml b/tests/interpreter/core/itemhandlers/CustomItemHandlerTest.qml
new file mode 100644
index 0000000..8daae69
--- /dev/null
+++ b/tests/interpreter/core/itemhandlers/CustomItemHandlerTest.qml
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.1
+import QtSystemTest 1.0
+
+Test {
+ id: root
+ name: 'custom item handler'; description: name
+
+ property string className: 'QstPushButton'
+ property string filePath: className + '.qml'
+
+ function _() {}
+
+ property Application app: Application {
+ function __inheritanceTree() { return [className, 'QObject']; }
+ }
+
+ function setup() {
+ _.factory = core().ItemFactory
+ _.factory.register(className, filePath);
+ }
+
+ function run() {
+ var pushButton = app.__handlerForObject({_type_: className});
+
+ var handler = pushButton.toString().split('_').first();
+ expect(handler).toBe(className);
+
+ expect(pushButton.name).toBe(className);
+ expect(pushButton.reallyAButton).toBe(true);
+ }
+
+ function cleanup() {
+ _.factory.unregister(className);
+ }
+}
diff --git a/tests/interpreter/core/itemhandlers/DefaultItemHandlerTest.qml b/tests/interpreter/core/itemhandlers/DefaultItemHandlerTest.qml
new file mode 100644
index 0000000..d33947d
--- /dev/null
+++ b/tests/interpreter/core/itemhandlers/DefaultItemHandlerTest.qml
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.1
+import QtSystemTest 1.0
+
+Test {
+ id: root
+ name: 'default item handler'; description: name
+
+ property string className: 'foo'
+ function _() {}
+
+ property Application app: Application {
+ function __inheritanceTree() { return [className, 'QObject']; }
+ }
+
+ function setup() {
+ }
+
+
+ function run() {
+ var component = _.component;
+ var handler = app.__handlerForObject({_type_: className});
+ expect(handler).not.toBe(undefined);
+ expect(handler.__internals._type_).toBe(className);
+ var qmlType = handler.toString().split('_').first();
+ expect(qmlType).toBe('QstObject');
+ }
+}
diff --git a/tests/interpreter/core/itemhandlers/QstPushButton.qml b/tests/interpreter/core/itemhandlers/QstPushButton.qml
new file mode 100644
index 0000000..fd38271
--- /dev/null
+++ b/tests/interpreter/core/itemhandlers/QstPushButton.qml
@@ -0,0 +1,52 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.1
+import QtSystemTest 1.0
+
+QstObject {
+ handles: 'QstPushButton'
+ property string name: 'QstPushButton'
+ property bool reallyAButton: true
+
+ function press() {
+ }
+}
diff --git a/tests/interpreter/core/itemhandlers/RegisterUnregisterHandlerTest.qml b/tests/interpreter/core/itemhandlers/RegisterUnregisterHandlerTest.qml
new file mode 100644
index 0000000..85c1618
--- /dev/null
+++ b/tests/interpreter/core/itemhandlers/RegisterUnregisterHandlerTest.qml
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.1
+import QtSystemTest 1.0
+
+Test {
+ id: root
+ name: 'register and unregister item handler'; description: name
+
+ function _() {}
+ property string className: 'QstPushButton'
+ property string filePath: className + '.qml'
+
+
+ property Application app: Application {
+ function __inheritanceTree() { return [className, 'QObject']; }
+ }
+
+ function setup() {
+ _.factory = core().ItemFactory;
+ expect(_.factory).not.toBe(undefined);
+ }
+
+ function expectItemHandler( handlerClassName) {
+ var factory = _.factory;
+ var handler, handlerClass;
+
+ handler = app.__handlerForObject({ _type_: className });
+ expect(handler).not.toBe(undefined);
+ expect(handler.__internals._type_).toBe(className);
+
+ handlerClass = handler.toString().split('_').first();
+ expect(handlerClass).toBe(handlerClassName);
+ }
+
+ function run() {
+ var factory = _.factory;
+ expectItemHandler('QstObject');
+ factory.register(className, filePath);
+ expectItemHandler(className);
+ factory.unregister(className);
+ expectItemHandler('QstObject');
+ }
+}
diff --git a/tests/interpreter/loggers/data/ExpectTests.qml b/tests/interpreter/loggers/data/ExpectTests.qml
new file mode 100644
index 0000000..d854e5f
--- /dev/null
+++ b/tests/interpreter/loggers/data/ExpectTests.qml
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtSystemTest 1.0
+
+TestCollection {
+ name: 'expect tests'; description: 'A expectation tests'
+
+ Test {
+ name: 'toBe'; description: 'to be'
+
+ function run() {
+ expect(3).toBe(3);
+ expect(2 + 2).toBe(3); // for large values of 3
+ }
+ }
+
+ Test {
+ name: 'not.toBe'; description: 'not to be'
+
+ function run() {
+ expect('Claudius').not.toBe('Polonius');
+ expect('Claudius').not.toBe('Claudius');
+ }
+ }
+
+ Test {
+ name: 'instanceof'; description: 'expect to be instance of'
+
+ function run() {
+ var message = new String('Hello World');
+ expect(message).instanceOf(String);
+ expect(message).not.instanceOf(Number);
+ expect(message).instanceOf(Number);
+ }
+ }
+
+ Test {
+ name: 'between'; description: 'expect to be between'
+
+ function run() {
+ expect(2 + 2).toBeBetween(3,5);
+ expect(2 + 2).toBeBetween(4,6);
+ }
+ }
+
+}
diff --git a/tests/interpreter/loggers/data/FailTest.qml b/tests/interpreter/loggers/data/FailTest.qml
new file mode 100644
index 0000000..fee4713
--- /dev/null
+++ b/tests/interpreter/loggers/data/FailTest.qml
@@ -0,0 +1,52 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtSystemTest 1.0
+
+Test {
+ name: 'fail'; description: 'failure test'
+
+ function run() {
+ fail('reason for failure');
+ }
+}
+
diff --git a/tests/interpreter/loggers/data/PassTest.qml b/tests/interpreter/loggers/data/PassTest.qml
new file mode 100644
index 0000000..352efb1
--- /dev/null
+++ b/tests/interpreter/loggers/data/PassTest.qml
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtSystemTest 1.0
+
+Test {
+ name: 'pass'; description: 'pass test'
+
+ function run() {
+ log('need to actually test something to be a pass');
+ expect(3).toBe(3);
+ }
+}
diff --git a/tests/interpreter/loggers/data/SkipTest.qml b/tests/interpreter/loggers/data/SkipTest.qml
new file mode 100644
index 0000000..732e4b6
--- /dev/null
+++ b/tests/interpreter/loggers/data/SkipTest.qml
@@ -0,0 +1,53 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtSystemTest 1.0
+
+Test {
+ name: 'skip'; description: 'skip test'
+
+ function run() {
+ skip('Skip this test');
+ fail('reason for failure');
+ }
+}
+
diff --git a/tests/interpreter/loggers/data/SubTests.qml b/tests/interpreter/loggers/data/SubTests.qml
new file mode 100644
index 0000000..fed8ba6
--- /dev/null
+++ b/tests/interpreter/loggers/data/SubTests.qml
@@ -0,0 +1,52 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtSystemTest 1.0
+
+TestCollection {
+ name: 'subcollection'; description: 'A sub collection of tests'
+
+ PassTest {}
+ SkipTest {}
+ FailTest {}
+ ExpectTests {}
+}
diff --git a/tests/interpreter/loggers/data/Tests.qml b/tests/interpreter/loggers/data/Tests.qml
new file mode 100644
index 0000000..016f255
--- /dev/null
+++ b/tests/interpreter/loggers/data/Tests.qml
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtSystemTest 1.0
+
+TestCollection {
+ name: 'collection'; description: 'A collection of tests'
+
+ SubTests {
+ name: 'collection 1'
+ }
+ SubTests {
+ name: 'collection 2'
+ }
+ SubTests {
+ name: 'collection 3'
+ }
+}
diff --git a/tests/interpreter/loggers/data/qsystemtest.xsd b/tests/interpreter/loggers/data/qsystemtest.xsd
new file mode 100644
index 0000000..35b852a
--- /dev/null
+++ b/tests/interpreter/loggers/data/qsystemtest.xsd
@@ -0,0 +1,228 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ elementFormDefault="qualified"
+ attributeFormDefault="unqualified">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">QtSystemTest xml test result schema.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:element name="systemtestrun">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">Instance of running the test interpreter over a test file
+ </xs:documentation>
+ </xs:annotation>
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="collection" type="collection"/>
+ <xs:element name="report">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="status" type="Status" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="passed" type="xs:decimal"/>
+ <xs:element name="skipped" type="xs:decimal"/>
+ <xs:element name="untested" type="xs:decimal"/>
+ <xs:element name="failed" type="xs:decimal"/>
+ <xs:element name="error" type="xs:decimal"/>
+ <xs:element name="total" type="xs:decimal"/>
+ <xs:element name="duration" type="xs:decimal" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:complexType name="collection">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">A collection of test and test collections
+ </xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
+ <xs:element name="collection" type="collection"/>
+ <xs:element name="test" type="test"/>
+ </xs:choice>
+ <xs:element name="report" type="report"/>
+ </xs:sequence>
+ <xs:attribute name="name" type="xs:token" use="required">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">Name of the collection</xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="file" type="xs:token" use="required">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">File which defines the collection</xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="line" type="xs:token" use="required">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">Line in the file where the collection is defined</xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="timestamp" type="xs:dateTime" use="required">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">When the collection was executed in UTC time</xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:complexType>
+ <xs:complexType name="test">
+ <xs:sequence>
+ <xs:element name="method" type="method" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="report" type="report"/>
+ </xs:sequence>
+ <xs:attribute name="name" type="xs:token" use="required">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">Name of the collection</xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="file" type="xs:token" use="required">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">File which defines the collection</xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="line" type="xs:token" use="required">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">Line in the file where the collection is defined</xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="timestamp" type="xs:dateTime" use="required">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">When the collection was executed in UTC time</xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:complexType>
+ <xs:complexType name="method">
+ <xs:sequence>
+ <xs:choice>
+ <xs:element name="method" type="method"/>
+ <xs:element name="failed" type="event"/>
+ <xs:element name="passed" type="event"/>
+ <xs:element name="skipped" type="event"/>
+ <xs:element name="error" type="event"/>
+ <xs:element name="untested" type="event"/>
+ <xs:element name="note">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:extension base="event">
+ <xs:attribute name="type" type="xs:token" use="required">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">The type of noted event</xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ </xs:choice>
+ </xs:sequence>
+ <xs:attribute name="name" type="xs:token" use="required">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">Name of the method</xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:complexType>
+ <xs:complexType name="event">
+ <xs:sequence>
+ <xs:element name="reason" type="pre-string"/>
+ <xs:element name="stack" minOccurs="0" maxOccurs="1">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="frame" minOccurs="1" maxOccurs="unbounded">
+ <xs:complexType>
+ <xs:simpleContent>
+ <xs:extension base="pre-string">
+ <xs:attribute name="file" type="xs:token" use="required">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">File for the frame content</xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="line" type="xs:token" use="required">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">Line for the frame content</xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="meta" minOccurs="0" maxOccurs="1">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="property" minOccurs="0" maxOccurs="unbounded">
+ <xs:complexType>
+ <xs:simpleContent>
+ <xs:extension base="pre-string">
+ <xs:attribute name="name" type="xs:token" use="required"/>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+ <xs:complexType name="report">
+ <xs:sequence>
+ <xs:element name="status" type="Status" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="duration" type="xs:decimal" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+ <xs:simpleType name="pre-string">
+ <xs:restriction base="xs:string">
+ <xs:whiteSpace value="preserve"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:simpleType name="Status">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="passed"/>
+ <xs:enumeration value="failed"/>
+ <xs:enumeration value="untested"/>
+ <xs:enumeration value="error"/>
+ <xs:enumeration value="skipped"/>
+ </xs:restriction>
+ </xs:simpleType>
+</xs:schema>
diff --git a/tests/interpreter/runner/DefaultConfigTest.qml b/tests/interpreter/runner/DefaultConfigTest.qml
new file mode 100644
index 0000000..c64e055
--- /dev/null
+++ b/tests/interpreter/runner/DefaultConfigTest.qml
@@ -0,0 +1,53 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.1
+import QtSystemTest 1.0
+
+Test {
+ name: 'default config test'; description: name
+
+ function run() {
+ expect(config.remotes).not.toBe(undefined);
+ expect(config.remotes.localhost).not.toBe(undefined);
+ expect(config.remotes.localhost.address).not.toBe('');
+ }
+}
diff --git a/tests/interpreter/runner/EmptyTest.qml b/tests/interpreter/runner/EmptyTest.qml
new file mode 100644
index 0000000..360a78f
--- /dev/null
+++ b/tests/interpreter/runner/EmptyTest.qml
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.1
+import QtSystemTest 1.0
+
+Test {
+ name: 'an empty teststep'; description: name
+
+ function setup() { }
+ function run() { }
+ function cleanup() { }
+}
diff --git a/tests/interpreter/runner/EmptyTests.qml b/tests/interpreter/runner/EmptyTests.qml
new file mode 100644
index 0000000..26a556e
--- /dev/null
+++ b/tests/interpreter/runner/EmptyTests.qml
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.1
+import QtSystemTest 1.0
+
+TestCollection {
+ name: 'an empty test collection'; description: name
+
+ function setup() { }
+ EmptyTest {}
+ EmptyTest {}
+ EmptyTest {}
+ function cleanup() { }
+}
+
diff --git a/tests/interpreter/runner/FailTest.qml b/tests/interpreter/runner/FailTest.qml
new file mode 100644
index 0000000..76ad7fd
--- /dev/null
+++ b/tests/interpreter/runner/FailTest.qml
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.1
+import QtSystemTest 1.0
+import 'RunnerInternals.js' as Internals
+Test {
+ id: root
+ name: 'fail test'; description: name
+
+ function setup() {
+ Internals.setItem(root);
+ Internals.setRunner(__runner);
+ }
+
+ function run() {
+ fail('Generate a failure');
+ }
+
+ function cleanup() {
+ /// HACK should not be done
+ /// DO NOT screw around with the internals
+ /// it is your fault if things break done
+ var Core = core();
+ if (__status !== Core.Qtt.Status.Failed) {
+ log('Status is not set to Failed ...');
+ Internals.changeReport(Core.Qtt.Status.Failed);
+ } else {
+ Internals.changeReport(Core.Qtt.Status.Passed);
+ }
+ }
+
+}
diff --git a/tests/interpreter/runner/MyUtils.js b/tests/interpreter/runner/MyUtils.js
new file mode 100644
index 0000000..aadb36f
--- /dev/null
+++ b/tests/interpreter/runner/MyUtils.js
@@ -0,0 +1,48 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+.pragma library
+.import QtUiTest 1.0 as QtUiTest
+
+function func() {
+ var tt = QtUiTest.Core.api();
+ tt.fail("hello");
+}
diff --git a/tests/interpreter/runner/RunnerInternals.js b/tests/interpreter/runner/RunnerInternals.js
new file mode 100644
index 0000000..0fedc54
--- /dev/null
+++ b/tests/interpreter/runner/RunnerInternals.js
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+.pragma library
+
+var runner;
+var item;
+
+function changeReport(to, from) {
+ from = from || item.__status;
+
+ var report = runner.report;
+ report[from] --;
+ report[to] ++;
+ runner.report = report;
+ item.__status = to;
+}
+
+function setRunner(r) {
+ runner = r;
+}
+
+function setItem(i) {
+ item = i;
+}
diff --git a/tests/interpreter/runner/SkipTest.qml b/tests/interpreter/runner/SkipTest.qml
new file mode 100644
index 0000000..baffea9
--- /dev/null
+++ b/tests/interpreter/runner/SkipTest.qml
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.1
+import QtSystemTest 1.0
+import 'RunnerInternals.js' as Internals
+
+Test {
+ id: root
+ name: 'skip';
+ description: 'calls skip in run'
+
+ function setup() {
+ Internals.setItem(root);
+ Internals.setRunner(__runner);
+ }
+
+ function run() {
+ skip('Skip this test');
+ }
+
+ function cleanup() {
+ /// HACK should not be done
+ /// DO NOT screw around with the internals
+ /// it is your fault if things break done
+ var Core = core();
+ if (__status !== Core.Qtt.Status.Skipped) {
+ log('Status is not set to skipped ...');
+ Internals.changeReport(Core.Qtt.Status.Failed);
+ } else {
+ Internals.changeReport(Core.Qtt.Status.Passed);
+ }
+ }
+}
diff --git a/tests/interpreter/runner/UntestedTest.qml b/tests/interpreter/runner/UntestedTest.qml
new file mode 100644
index 0000000..f9f0bd0
--- /dev/null
+++ b/tests/interpreter/runner/UntestedTest.qml
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.1
+import QtSystemTest 1.0
+import 'RunnerInternals.js' as Internals
+
+Test {
+ id: root
+ name: 'untested test'
+ description: name
+ property bool runGotExecuted: false;
+ property int untestedTestsBeforeRun: 0
+ function setup() {
+ var Core = core();
+ Internals.setItem(root);
+ Internals.setRunner(__runner);
+ untestedTestsBeforeRun = __runner.report[Core.Qtt.Status.Untested];
+ fail('Generating a failure inside setup');
+ }
+
+ // Not having run shouldn't matter since this shouldn't
+ // be even executed
+ function run() {
+ runGotExecuted = true;
+ }
+
+ function cleanup() {
+ /// HACK should not be done
+ /// DO NOT screw around with the internals
+ /// it is your fault if things break done
+ var Core = core();
+ if (runGotExecuted) {
+ log('Run got executed somehow ...');
+ Internals.changeReport(Core.Qtt.Status.Failed);
+ return;
+ }
+ if (__status !== Core.Qtt.Status.Untested) {
+ log('Status is not set to Untestsed ...');
+ Internals.changeReport(Core.Qtt.Status.Failed);
+ return;
+ }
+ var untestedAfterRun = __runner.report[Core.Qtt.Status.Untested];
+ if ( untestedTestsBeforeRun + 1 !== untestedAfterRun) {
+ log('Wrong count of untested. Untested before run was : ', untestedTestsBeforeRun,
+ ' and after run is : ', untestedAfterRun);
+ Internals.changeReport(Core.Qtt.Status.Failed);
+ return;
+ }
+ Internals.changeReport(Core.Qtt.Status.Passed);
+ }
+}
diff --git a/tests/interpreter/runner/UntestedTests.qml b/tests/interpreter/runner/UntestedTests.qml
new file mode 100644
index 0000000..2e180cd
--- /dev/null
+++ b/tests/interpreter/runner/UntestedTests.qml
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.1
+import QtSystemTest 1.0
+import 'RunnerInternals.js' as Internals
+
+TestCollection {
+ id: root
+ name: 'untested test collection'
+ description: 'tests if failing in the setup '
+ + 'of a test collection sets all child tests to '
+ + ' untested'
+
+ property bool runGotExecuted: false;
+ property int untestedTestsBeforeRun: 0
+ function setup() {
+ var Core = core();
+ Internals.setItem(dummyTest);
+ Internals.setRunner(__runner);
+ untestedTestsBeforeRun = __runner.report[Core.Qtt.Status.Untested];
+ log('Ignore the untested report, done on purpose');
+ fail('Generating a failure inside test collection -> setup');
+ }
+
+ Test {
+ id: dummyTest
+ name: 'a dummy test'; description: name
+
+ // Not having run shouldn't matter since this shouldn't
+ // be even executed
+ function run() {
+ runGotExecuted = true;
+ }
+ }
+
+ function cleanup() {
+ /// HACK should not be done
+ /// DO NOT screw around with the internals
+ /// it is your fault if things break done
+ var Core = core();
+ if (runGotExecuted) {
+ log('Run got executed somehow ...');
+ Internals.changeReport(Core.Qtt.Status.Failed);
+ return;
+ }
+ if (dummyTest.__status !== Core.Qtt.Status.Untested) {
+ log('Status is not set to Untestsed ...');
+ Internals.changeReport(Core.Qtt.Status.Failed);
+ return;
+ }
+ var untestedAfterRun = __runner.report[Core.Qtt.Status.Untested];
+ if ( untestedTestsBeforeRun + 1 !== untestedAfterRun) {
+ log('Wrong count of untested. Untested before run was : ', untestedTestsBeforeRun,
+ ' and after run is : ', untestedAfterRun);
+ Internals.changeReport(Core.Qtt.Status.Failed);
+ return;
+ }
+ Internals.changeReport(Core.Qtt.Status.Passed);
+ }
+}
diff --git a/tests/remote/AssistantTest.qml b/tests/remote/AssistantTest.qml
new file mode 100644
index 0000000..87e0733
--- /dev/null
+++ b/tests/remote/AssistantTest.qml
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.1
+import QtSystemTest 1.0
+import 'common'
+
+ApplicationTest {
+ name: 'Assistant test'
+ executableName: 'assistant'
+
+ function run() {
+ var i,
+ zoomIn = app.item( { toolTip: "Zoom in"} ),
+ zoomOut = app.item( { toolTip: "Zoom out"} );
+
+ app.mouseClick(zoomIn, Qt.RightButton);
+ sleep(1000);
+
+ for (i=0; i<10; i++) {
+ app.mouseClick(zoomIn);
+ }
+
+ for (i=0; i<10; i++) {
+ app.mouseClick(zoomOut);
+ }
+
+ app.keyPress(Qt.Key_H);
+ app.keyPress(Qt.Key_E);
+ app.keyPress(Qt.Key_L);
+ app.keyPress(Qt.Key_L);
+ app.keyPress(Qt.Key_O);
+
+ var p = Qt.point(200,300);
+ app.mouseClick(p);
+ sleep(1000);
+ }
+}
diff --git a/tests/remote/QstObjectApiTests.qml b/tests/remote/QstObjectApiTests.qml
new file mode 100644
index 0000000..e04f1b6
--- /dev/null
+++ b/tests/remote/QstObjectApiTests.qml
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.1
+import QtSystemTest 1.0
+
+import "qstobject"
+
+TestCollection {
+ name: 'QstObject api tests'; description: name
+
+ ItemPropertyTest{}
+ ParentApiTest{}
+ InheritanceBasedItemHandlerTest{}
+}
+
diff --git a/tests/remote/RemoteApiTests.qml b/tests/remote/RemoteApiTests.qml
new file mode 100644
index 0000000..84cb71e
--- /dev/null
+++ b/tests/remote/RemoteApiTests.qml
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.1
+import QtSystemTest 1.0
+import 'common'
+
+TestCollection {
+ name: 'Remote component Test'; description: name
+
+ ApplicationTest {
+ name: 'Same Application object test'; description: name
+ executableName: 'testapp_widgets'
+
+ function run() {
+ var currentApp = remote.currentApplication();
+ expect(currentApp.toString()).toBe(app.toString());
+ expect(currentApp).toBe(app);
+ }
+ }
+
+}
+
diff --git a/tests/remote/RunProcessTests.qml b/tests/remote/RunProcessTests.qml
new file mode 100644
index 0000000..c85ad8f
--- /dev/null
+++ b/tests/remote/RunProcessTests.qml
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.1
+import QtSystemTest 1.0
+
+import "runProcess"
+
+TestCollection {
+ name: 'runProcess tests'; description: name
+
+ RunCommandTest{}
+}
diff --git a/tests/remote/TestAppWidgetTest.qml b/tests/remote/TestAppWidgetTest.qml
new file mode 100644
index 0000000..3cf62ee
--- /dev/null
+++ b/tests/remote/TestAppWidgetTest.qml
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.1
+import QtSystemTest 1.0
+import 'common'
+
+ApplicationTest {
+ name: 'testwidget tests'
+ executableName: 'testapp_widgets'
+
+ function run() {
+ var textEdit = app.item({
+ inherits: 'QLineEdit'
+ } );
+
+ expect(textEdit.property('text')).not.toBe(undefined);
+ expect(textEdit.property('text')).toBe('');
+ app.mouseClick(textEdit);
+
+ app.keyPress(Qt.Key_H);
+ app.keyPress(Qt.Key_E);
+ app.keyPress(Qt.Key_L);
+ app.keyPress(Qt.Key_L);
+ app.keyPress(Qt.Key_O);
+
+ expect(textEdit.property('text')).toBe('hello');
+ }
+
+}
diff --git a/tests/remote/common/ApplicationTest.qml b/tests/remote/common/ApplicationTest.qml
new file mode 100644
index 0000000..5af0acd
--- /dev/null
+++ b/tests/remote/common/ApplicationTest.qml
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.1
+import QtSystemTest 1.0
+
+Test {
+ name: ''; description: name
+
+ property string executableName: ''
+ property Application app
+ property alias remote: host
+
+ remotes: [
+ Remote {
+ id: host
+ host: config.remotes.localhost.address
+ }
+ ]
+
+
+ function setup() {
+ expect(executableName).not.toBe('');
+ app = host.startApplication(executableName);
+ }
+
+ function cleanup() {
+ app.terminate();
+ }
+}
diff --git a/tests/remote/qstobject/InheritanceBasedItemHandlerTest.qml b/tests/remote/qstobject/InheritanceBasedItemHandlerTest.qml
new file mode 100644
index 0000000..83b1fd4
--- /dev/null
+++ b/tests/remote/qstobject/InheritanceBasedItemHandlerTest.qml
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.1
+import QtSystemTest 1.0
+import '../common'
+
+ApplicationTest {
+ name: 'parent api test'
+ executableName: 'testapp_widgets'
+
+ function run() {
+ var textEdit = app.item({
+ inherits: 'QLineEdit'
+ });
+
+ expect(textEdit.type()).toBe('QLineEdit');
+ expect(textEdit.handles).toBe('QWidget');
+
+ core().ItemFactory.register('QLineEdit', 'MyQLineEdit.qml');
+
+ var sameTextEdit = app.item({
+ inherits: 'QLineEdit'
+ });
+ expect(sameTextEdit.type()).toBe('QLineEdit');
+ expect(sameTextEdit.handles).toBe('QLineEdit');
+
+ core().ItemFactory.unregister('QLineEdit');
+ var textEdit3 = app.item({
+ text: '',
+ inherits: 'QLineEdit'
+ } );
+ expect(textEdit3.type()).toBe('QLineEdit');
+ expect(textEdit3.handles).toBe('QWidget');
+
+ }
+}
diff --git a/tests/remote/qstobject/ItemPropertyTest.qml b/tests/remote/qstobject/ItemPropertyTest.qml
new file mode 100644
index 0000000..9022045
--- /dev/null
+++ b/tests/remote/qstobject/ItemPropertyTest.qml
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.1
+import QtSystemTest 1.0
+import '../common'
+
+ApplicationTest {
+ name: 'property setProperty test'
+ executableName: 'testapp_widgets'
+
+ function run() {
+ var textEdit = app.item({
+ text: '',
+ inherits: 'QLineEdit'
+ } );
+
+ expect(textEdit.property('text')).not.toBe(undefined);
+ textEdit.setProperty('text', 'Hello World');
+ expect(textEdit.property('text')).toBe('Hello World');
+ }
+}
diff --git a/tests/remote/qstobject/MyQLineEdit.qml b/tests/remote/qstobject/MyQLineEdit.qml
new file mode 100644
index 0000000..ee1a299
--- /dev/null
+++ b/tests/remote/qstobject/MyQLineEdit.qml
@@ -0,0 +1,49 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.1
+import QtSystemTest 1.0
+
+QstObject {
+ handles: 'QLineEdit'
+ function enter(text) {
+ }
+}
diff --git a/tests/remote/qstobject/ParentApiTest.qml b/tests/remote/qstobject/ParentApiTest.qml
new file mode 100644
index 0000000..59e0008
--- /dev/null
+++ b/tests/remote/qstobject/ParentApiTest.qml
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.1
+import QtSystemTest 1.0
+import '../common'
+
+ApplicationTest {
+ name: 'parent api test'
+ executableName: 'testapp_widgets'
+
+ function run() {
+ var textEdit = app.item({
+ text: '',
+ inherits: 'QLineEdit'
+ } );
+ expect(textEdit.type()).toBe('QLineEdit');
+
+ var parent = textEdit.parent();
+ expect(parent).not.toBe(undefined);
+ expect(parent.__isQmlWrapper).toBe(true);
+ expect(parent.type()).not.toBe(undefined);
+ }
+}
diff --git a/tests/remote/qstobject/QstObjectApiTests.qml b/tests/remote/qstobject/QstObjectApiTests.qml
new file mode 100644
index 0000000..9e42e15
--- /dev/null
+++ b/tests/remote/qstobject/QstObjectApiTests.qml
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtSystemTest 1.0
+import '../common'
+
+ApplicationTest {
+ name: 'parent api test'
+ executableName: 'testapp_widgets'
+
+ function run() {
+ var textEdit = app.item({
+ text: '',
+ inherits: 'QLineEdit'
+ } );
+ expect(textEdit.type()).toBe('QLineEdit');
+
+ var parent = textEdit.parent();
+ expect(parent).not.toBe(undefined);
+ expect(parent.__isQmlWrapper).toBe(true);
+ expect(parent.type()).not.toBe(undefined);
+ }
+}
+
diff --git a/tests/remote/runProcess/RunCommandTest.qml b/tests/remote/runProcess/RunCommandTest.qml
new file mode 100644
index 0000000..22f9f7e
--- /dev/null
+++ b/tests/remote/runProcess/RunCommandTest.qml
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of QtSystemTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtSystemTest 1.0
+
+Test {
+ name: 'run ls'; description: name
+
+ remotes: [
+ Remote {
+ id: host
+ host: config.remotes.localhost.address
+ }
+ ]
+
+ function run() {
+ var output = host.runProcess( { program: "/bin/ls", timeout: 1000 } );
+ expect(output).not.toBe(undefined);
+ expect(output).not.toBe(null);
+ expect(output.length).not.toBe(0);
+ log(output);
+ }
+}
diff --git a/tests/tests.pro b/tests/tests.pro
new file mode 100644
index 0000000..8915388
--- /dev/null
+++ b/tests/tests.pro
@@ -0,0 +1,31 @@
+TEMPLATE = aux
+OTHER_FILES = \
+ AllTests.qml \
+ InterpreterTests.qml \
+ interpreter/RunnerTests.qml \
+ interpreter/runner/EmptyTest.qml \
+ interpreter/runner/FailTest.qml \
+ interpreter/runner/MyUtils.js \
+ interpreter/runner/SkipTest.qml \
+ interpreter/runner/EmptyTests.qml \
+ interpreter/runner/RunnerInternals.js \
+ interpreter/runner/UntestedTests.qml \
+ interpreter/runner/UntestedTest.qml \
+ interpreter/runner/DefaultConfigTest.qml \
+ interpreter/CoreTests.qml \
+ interpreter/core/ClassTest.qml \
+ interpreter/core/FailApiTest.qml \
+ interpreter/core/SleepTest.qml \
+ interpreter/core/ExpectApiTests.qml \
+ interpreter/core/ItemHandlerTests.qml \
+ interpreter/core/itemhandlers/DefaultItemHandler.qml \
+ interpreter/core/itemhandlers/RegisterUnregisterHandlerTest.qml \
+ interpreter/core/itemhandlers/CustomItemHandlerTest.qml \
+ interpreter/core/itemhandlers/QstPushButton.qml \
+ MyConfig.qml \
+ RemoteTests.qml \
+ remote/RunProcessTests.qml \
+ remote/runProcess/RunCommandTest.qml \
+ remote/ItemPropertyTest.qml \
+ remote/assistant/AssistantTest.qml \
+ remote/TestAppWidgetTest.qml