From 8500fa9f6ac5de53b6e669f9a4346b14ffcb6c4f Mon Sep 17 00:00:00 2001
From: Christian Stenger <christian.stenger@nokia.com>
Date: Wed, 23 Nov 2011 09:38:31 +0100
Subject: [PATCH] Squish: Improve hook-into sub-processes
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

With this patch it's possible to not only hook into the
QmlApplicationViewer (although nothing else is currently done)
and additionally to not only send the closing event to the
sub-process. You can now define a function that will be executed
on the sub-process.
Both modified tests show an example how to use it.

Change-Id: I39b9959f2cf1d519b8afeb0c479ac2d68ea20ca6
Reviewed-by: Bill King <bill.king@nokia.com>
Reviewed-by: Robert Löhning <robert.loehning@nokia.com>
---
 tests/system/shared/qtquick.py                | 36 ++++++++++++++++---
 .../tst_qtquick_creation/test.py              |  8 ++++-
 .../tst_qtquick_creation2/test.py             | 28 +++++++++++++--
 3 files changed, 64 insertions(+), 8 deletions(-)

diff --git a/tests/system/shared/qtquick.py b/tests/system/shared/qtquick.py
index 6a0bf8cb413..f5a81eb4a85 100644
--- a/tests/system/shared/qtquick.py
+++ b/tests/system/shared/qtquick.py
@@ -83,7 +83,14 @@ def __chooseTargets__(targets=QtQuickConstants.Targets.DESKTOP):
             if mustCheck:
                 test.fail("Failed to check target '%s'" % QtQuickConstants.getStringForTarget(current))
 
-def runAndCloseApp(withHookInto=False, executable=None, port=None):
+# run and close a Qt Quick application
+# withHookInto - if set to True the function tries to attach to the sub-process instead of simply pressing Stop inside Creator
+# executable - must be defined when using hook-into
+# port - must be defined when using hook-into
+# function - can be a string holding a function name or a reference to the function itself - this function will be called on
+# the sub-process when hooking-into has been successful - if its missing simply closing the Qt Quick app will be done
+# ATTENTION! Make sure this function won't fail and the sub-process will end when the function returns
+def runAndCloseApp(withHookInto=False, executable=None, port=None, function=None):
     global processStarted, processExited
     processStarted = processExited = False
     installLazySignalHandler("{type='ProjectExplorer::ApplicationLaucher'}", "processStarted()", "__handleProcessStarted__")
@@ -102,7 +109,7 @@ def runAndCloseApp(withHookInto=False, executable=None, port=None):
         invokeMenuItem("File", "Exit")
         return False
     if withHookInto and not executable in ("", None):
-        __closeSubprocessByHookingIntoQmlApplicationViewer__(executable, port)
+        __closeSubprocessByHookingIntoQmlApplicationViewer__(executable, port, function)
     else:
         __closeSubprocessByPushingStop__()
     return True
@@ -115,7 +122,7 @@ def __closeSubprocessByPushingStop__():
     test.verify(playButton.enabled)
     test.compare(stopButton.enabled, False)
 
-def __closeSubprocessByHookingIntoQmlApplicationViewer__(executable, port):
+def __closeSubprocessByHookingIntoQmlApplicationViewer__(executable, port, function):
     global processExited
     ensureChecked(":Qt Creator_Core::Internal::OutputPaneToggleButton")
     output = waitForObject("{type='Core::OutputWindow' visible='1' windowTitle='Application Output Window'}", 20000)
@@ -124,9 +131,28 @@ def __closeSubprocessByHookingIntoQmlApplicationViewer__(executable, port):
     else:
         waitFor("'Listening on port %d for incoming connectionsdone' in str(output.plainText)" % port, 5000)
     attachToApplication(executable)
-    sendEvent("QCloseEvent", "{type='QmlApplicationViewer' unnamed='1' visible='1'}")
+    if function == None:
+        sendEvent("QCloseEvent", "{type='QmlApplicationViewer' unnamed='1' visible='1'}")
+        setApplicationContext(applicationContext("qtcreator"))
+    else:
+        try:
+            if isinstance(function, (str, unicode)):
+                globals()[function]()
+            else:
+                function()
+        except:
+            test.fatal("Function to execute on sub-process could not be found.",
+                       "Using fallback of pushing STOP inside Creator.")
+            setApplicationContext(applicationContext("qtcreator"))
+            __closeSubprocessByPushingStop__()
     waitFor("processExited==True", 10000)
-    setApplicationContext(applicationContext("qtcreator"))
+    if not processExited:
+        test.warning("Sub-process seems not to have closed properly.")
+        try:
+            setApplicationContext(applicationContext("qtcreator"))
+            __closeSubprocessByPushingStop__()
+        except:
+            pass
     return True
 
 def runAndCloseQtQuickUI():
diff --git a/tests/system/suite_qtquick/tst_qtquick_creation/test.py b/tests/system/suite_qtquick/tst_qtquick_creation/test.py
index ed2a15cef27..46e9d3a1ace 100644
--- a/tests/system/suite_qtquick/tst_qtquick_creation/test.py
+++ b/tests/system/suite_qtquick/tst_qtquick_creation/test.py
@@ -23,7 +23,7 @@ def main():
             result = addExecutableAsAttachableAUT(projectName, 11223)
             allowAppThroughWinFW(workingDir, projectName)
             if result:
-                result = runAndCloseApp(True, projectName, 11223)
+                result = runAndCloseApp(True, projectName, 11223, "subprocessFunction")
             else:
                 result = runAndCloseApp()
             removeExecutableAsAttachableAUT(projectName, 11223)
@@ -35,6 +35,12 @@ def main():
 
     invokeMenuItem("File", "Exit")
 
+def subprocessFunction():
+    helloWorldText = waitForObject("{container={type='QmlApplicationViewer' visible='1' unnamed='1'} "
+                                   "enabled='true' text='Hello World' type='Text' unnamed='1' visible='true'}")
+    test.log("Clicking 'Hello World' Text to close QmlApplicationViewer")
+    mouseClick(helloWorldText, 5, 5, 0, Qt.LeftButton)
+
 def cleanup():
     global workingDir
     # waiting for a clean exit - for a full-remove of the temp directory
diff --git a/tests/system/suite_qtquick/tst_qtquick_creation2/test.py b/tests/system/suite_qtquick/tst_qtquick_creation2/test.py
index 2f84aff6994..018b9ee10e6 100644
--- a/tests/system/suite_qtquick/tst_qtquick_creation2/test.py
+++ b/tests/system/suite_qtquick/tst_qtquick_creation2/test.py
@@ -12,10 +12,11 @@ def main():
     # using a temporary directory won't mess up an eventually exisiting
     workingDir = tempDir()
     prepareTemplate(sourceExample)
-    createNewQtQuickApplication(workingDir, None, templateDir + "/qml/textselection.qml")
+    projectName = createNewQtQuickApplication(workingDir, None, templateDir + "/qml/textselection.qml")
     # wait for parsing to complete
     waitForSignal("{type='CppTools::Internal::CppModelManager' unnamed='1'}", "sourceFilesRefreshed(QStringList)", 30000)
     test.log("Building project")
+    result = modifyRunSettingsForHookInto(projectName, 11223)
     invokeMenuItem("Build","Build All")
     waitForSignal("{type='ProjectExplorer::BuildManager' unnamed='1'}", "buildQueueFinished(bool)", 300000)
     if not checkCompile():
@@ -23,10 +24,33 @@ def main():
     else:
         checkLastBuild()
         test.log("Running project (includes build)")
-        if runAndCloseApp():
+        if result:
+            result = addExecutableAsAttachableAUT(projectName, 11223)
+            allowAppThroughWinFW(workingDir, projectName)
+            if result:
+                result = runAndCloseApp(True, projectName, 11223, subprocessFunction)
+            else:
+                result = runAndCloseApp()
+            removeExecutableAsAttachableAUT(projectName, 11223)
+            deleteAppFromWinFW(workingDir, projectName)
+        else:
+            result = runAndCloseApp()
+        if result:
             logApplicationOutput()
     invokeMenuItem("File", "Exit")
 
+def subprocessFunction():
+    textEdit = waitForObject("{container={type='QmlApplicationViewer' unnamed='1' visible='1'} "
+                             "enabled='true' type='TextEdit' unnamed='1' visible='true'}")
+    test.log("Test dragging")
+    dragItemBy(textEdit, 30, 30, 50, 50, 0, Qt.LeftButton)
+    test.log("Test editing")
+    textEdit.cursorPosition = 0
+    type(textEdit, "This text is entered by Squish...")
+    type(textEdit, "<Return>")
+    test.log("Closing QmlApplicationViewer")
+    sendEvent("QCloseEvent", "{type='QmlApplicationViewer' unnamed='1' visible='1'}")
+
 def prepareTemplate(sourceExample):
     global templateDir
     templateDir = tempDir()
-- 
GitLab