diff options
author | Christian Stenger <christian.stenger@nokia.com> | 2011-09-06 09:12:15 +0200 |
---|---|---|
committer | Bill King <bill.king@nokia.com> | 2011-09-08 10:51:17 +0200 |
commit | e137af3a42be53d723311520b1d5a0a9cc65787f (patch) | |
tree | c936da607e447d59a3e77c5322bf428c51ff99a7 | |
parent | 4bf42e7885acbf52927eb030541ac7b2c8468d75 (diff) | |
download | qt-creator-e137af3a42be53d723311520b1d5a0a9cc65787f.tar.gz |
Added test for creation of QtQuick application
Added more QtQuick tests and did some refactorings according to re-appearing code.
Completed the Qt Quick Wizards test from QtCreatorTestingMatrix.
Change-Id: I857d9f3c3809221e2df3e096b3926a8d5d36b828
Reviewed-on: http://codereview.qt-project.org/4238
Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: Bill King <bill.king@nokia.com>
-rw-r--r-- | tests/system/shared/mainwin.py | 10 | ||||
-rw-r--r-- | tests/system/shared/qtcreator.py | 5 | ||||
-rw-r--r-- | tests/system/shared/qtquick.py | 125 | ||||
-rw-r--r-- | tests/system/shared/utils.py | 7 | ||||
-rw-r--r-- | tests/system/suite_qtquick/envvars | 1 | ||||
-rw-r--r-- | tests/system/suite_qtquick/suite.conf | 12 | ||||
-rw-r--r-- | tests/system/suite_qtquick/tst_qtquick_creation/test.py | 59 | ||||
-rw-r--r-- | tests/system/suite_qtquick/tst_qtquick_creation2/test.py | 72 | ||||
-rw-r--r-- | tests/system/suite_qtquick/tst_qtquick_creation3/test.py | 47 | ||||
-rw-r--r-- | tests/system/suite_qtquick/tst_qtquick_creation4/test.py | 63 |
10 files changed, 399 insertions, 2 deletions
diff --git a/tests/system/shared/mainwin.py b/tests/system/shared/mainwin.py index f4e6479c20..6e5d0b06db 100644 --- a/tests/system/shared/mainwin.py +++ b/tests/system/shared/mainwin.py @@ -21,3 +21,13 @@ def openCmakeProject(projectPath): clickButton(waitForObject(":CMake Wizard.Next_QPushButton", 20000)) clickButton(waitForObject(":CMake Wizard.Run CMake_QPushButton", 20000)) clickButton(waitForObject(":CMake Wizard.Finish_QPushButton", 60000)) + +def logApplicationOutput(): + # make sure application output is shown + toggleAppOutput = waitForObject("{type='Core::Internal::OutputPaneToggleButton' unnamed='1' visible='1' " + "window=':Qt Creator_Core::Internal::MainWindow' occurrence='3'}", 20000) + if not toggleAppOutput.checked: + clickButton(toggleAppOutput) + output = waitForObject("{type='Core::OutputWindow' visible='1' windowTitle='Application Output Window'}", 20000) + test.log("Application Output:\n%s" % output.plainText) + diff --git a/tests/system/shared/qtcreator.py b/tests/system/shared/qtcreator.py index 6434fcc847..ba690a3e69 100644 --- a/tests/system/shared/qtcreator.py +++ b/tests/system/shared/qtcreator.py @@ -13,9 +13,11 @@ testSettings.logScreenshotOnFail = True source("../../shared/utils.py") source("../../shared/build_utils.py") source("../../shared/mainwin.py") +source("../../shared/qtquick.py") def removeTmpSettingsDir(): - snooze(5) + appCtxt = currentApplicationContext() + waitFor("appCtxt.isRunning==False") deleteDirIfExists(os.path.dirname(tmpSettingsDir)) if platform.system() in ('Windows', 'Microsoft'): @@ -34,3 +36,4 @@ shutil.copytree(cwd, tmpSettingsDir) # the following only doesn't work if the test ends in an exception atexit.register(removeTmpSettingsDir) SettingsPath = " -settingspath %s" % tmpSettingsDir + diff --git a/tests/system/shared/qtquick.py b/tests/system/shared/qtquick.py new file mode 100644 index 0000000000..cfd8ee2f28 --- /dev/null +++ b/tests/system/shared/qtquick.py @@ -0,0 +1,125 @@ +processStarted = False +processExited = False + +# for easier re-usage (because Python hasn't an enum type) +class QtQuickConstants: + class Components: + BUILTIN = 1 + SYMBIAN = 2 + MEEGO_HARMATTAN = 4 + EXISTING_QML = 8 + + class Destinations: + DESKTOP = 1 + SIMULATOR = 2 + SYMBIAN = 4 + MAEMO5 = 8 + HARMATTAN = 16 + + @staticmethod + def getStringForComponents(components): + if components==QtQuickConstants.Components.BUILTIN: + return "Built-in elements only (for all platforms)" + elif components==QtQuickConstants.Components.SYMBIAN: + return "Qt Quick Components for Symbian" + elif components==QtQuickConstants.Components.MEEGO_HARMATTAN: + return "Qt Quick Components for Meego/Harmattan" + elif components==QtQuickConstants.Components.EXISTING_QML: + return "Use an existing .qml file" + else: + return None + + @staticmethod + def getStringForDestination(destination): + if destination==QtQuickConstants.Destinations.DESKTOP: + return "Desktop" + elif destination==QtQuickConstants.Destinations.SYMBIAN: + return "Symbian Device" + elif destination==QtQuickConstants.Destinations.MAEMO5: + return "Maemo5" + elif destination==QtQuickConstants.Destinations.SIMULATOR: + return "Qt Simulator" + elif destination==QtQuickConstants.Destinations.HARMATTAN: + return "Harmattan" + else: + return None + +def handleProcessStarted(object): + global processStarted + processStarted = True + +def handleProcessExited(object, exitCode): + global processExited + processExited = True + +# parameter components can only be one of the Constants defined in QtQuickConstants.Components +def chooseComponents(components=QtQuickConstants.Components.BUILTIN): + rbComponentToChoose = waitForObject("{type='QRadioButton' text='%s' visible='1'}" + % QtQuickConstants.getStringForComponents(components), 20000) + if rbComponentToChoose.checked: + test.passes("Selected QRadioButton is '%s'" % QtQuickConstants.getStringForComponents(components)) + else: + clickButton(rbComponentToChoose) + test.verify(rbComponentToChoose.checked, "Selected QRadioButton is '%s'" + % QtQuickConstants.getStringForComponents(components)) + +# parameter destination can be an OR'd value of QtQuickConstants.Destinations +def chooseDestination(destination=QtQuickConstants.Destinations.DESKTOP): + # DESKTOP should be always accessible + destDesktop = waitForObject("{type='QCheckBox' text='%s' visible='1'}" + % QtQuickConstants.getStringForDestination(QtQuickConstants.Destinations.DESKTOP), 20000) + mustCheck = destination & QtQuickConstants.Destinations.DESKTOP==QtQuickConstants.Destinations.DESKTOP + if (mustCheck and not destDesktop.checked) or (not mustCheck and destDesktop.checked): + clickButton(destDesktop) + # following destinations depend on the build environment - added for further/later tests + available = [QtQuickConstants.Destinations.SYMBIAN, QtQuickConstants.Destinations.MAEMO5, + QtQuickConstants.Destinations.SIMULATOR, QtQuickConstants.Destinations.HARMATTAN] + for current in available: + mustCheck = destination & current == current + try: + target = findObject("{type='QCheckBox' text='%s' visible='1'}" % QtQuickConstants.getStringForDestination(current)) + if (mustCheck and not target.checked) or (not mustCheck and target.checked): + clickButton(target) + except LookupError: + if mustCheck: + test.fail("Failed to check destination '%s'" % QtQuickConstants.getStringForDestination(current)) + +def runAndCloseApp(): + global buildSucceeded, buildFinished, processStarted, processExited + buildSucceeded = buildFinished = processStarted = processExited = False + installLazySignalHandler("{type='ProjectExplorer::ApplicationLaucher'}", "processStarted()", "handleProcessStarted") + installLazySignalHandler("{type='ProjectExplorer::ApplicationLaucher'}", "processExited(int)", "handleProcessExited") + runButton = waitForObject("{type='Core::Internal::FancyToolButton' text='Run' visible='1'}", 20000) + clickButton(runButton) + waitForBuildFinished() + waitFor("processStarted==True", 10000) + if not buildSucceeded: + test.log("Build inside run wasn't successful - leaving test") + invokeMenuItem("File", "Exit") + return False + if not processStarted: + test.fatal("Couldn't start application - leaving test") + invokeMenuItem("File", "Exit") + return False + # the following is currently a work-around for not using hooking into subprocesses + setWindowState(waitForObject(":Qt Creator_Core::Internal::MainWindow", 20000), WindowState.Minimize) + nativeType("<Alt+F4>") + waitFor("processExited==True",10000) + setWindowState(waitForObject(":Qt Creator_Core::Internal::MainWindow", 20000), WindowState.Normal) + return True + +def runAndCloseQtQuickUI(): + global processStarted, processExited + processStarted = processExited = False + installLazySignalHandler("{type='ProjectExplorer::ApplicationLaucher'}", "processStarted()", "handleProcessStarted") + installLazySignalHandler("{type='ProjectExplorer::ApplicationLaucher'}", "processExited(int)", "handleProcessExited") + runButton = waitForObject("{type='Core::Internal::FancyToolButton' text='Run' visible='1'}", 20000) + clickButton(runButton) + waitFor("processStarted==True", 10000) + # the following is currently a work-around for not using hooking into subprocesses + setWindowState(waitForObject(":Qt Creator_Core::Internal::MainWindow", 20000), WindowState.Minimize) + nativeType("<Alt+F4>") + waitFor("processExited==True", 10000) + setWindowState(waitForObject(":Qt Creator_Core::Internal::MainWindow", 20000), WindowState.Normal) + return True + diff --git a/tests/system/shared/utils.py b/tests/system/shared/utils.py index 8fec914122..9b59b86510 100644 --- a/tests/system/shared/utils.py +++ b/tests/system/shared/utils.py @@ -1,7 +1,7 @@ import tempfile, shutil, os def tempDir(): - return tempfile.mkdtemp() + return tempfile.mkdtemp(prefix="qtcreator_") def deleteDirIfExists(path): shutil.rmtree(path, True) @@ -62,3 +62,8 @@ def which(program): return None +def replaceLineEditorContent(lineEditor, newcontent): + type(lineEditor, "<Ctrl+A>") + type(lineEditor, "<Delete>") + type(lineEditor, newcontent) + diff --git a/tests/system/suite_qtquick/envvars b/tests/system/suite_qtquick/envvars new file mode 100644 index 0000000000..00aad3eab7 --- /dev/null +++ b/tests/system/suite_qtquick/envvars @@ -0,0 +1 @@ +QT_PLATFORM_PLUGIN=nonesuch diff --git a/tests/system/suite_qtquick/suite.conf b/tests/system/suite_qtquick/suite.conf new file mode 100644 index 0000000000..e2ee6f29d4 --- /dev/null +++ b/tests/system/suite_qtquick/suite.conf @@ -0,0 +1,12 @@ +AUT=qtcreator +CLASS= +CLASSPATH= +CWD= +ENVVARS=envvars +HOOK_SUB_PROCESSES=true +IMPLICITAUTSTART=0 +LANGUAGE=Python +OBJECTMAP=../objects.map +TEST_CASES=tst_qtquick_creation tst_qtquick_creation2 tst_qtquick_creation3 tst_qtquick_creation4 +VERSION=2 +WRAPPERS=Qt diff --git a/tests/system/suite_qtquick/tst_qtquick_creation/test.py b/tests/system/suite_qtquick/tst_qtquick_creation/test.py new file mode 100644 index 0000000000..73a4074a12 --- /dev/null +++ b/tests/system/suite_qtquick/tst_qtquick_creation/test.py @@ -0,0 +1,59 @@ +source("../../shared/qtcreator.py") + +refreshFinishedCount = 0 +workingDir = None + +def handleRefreshFinished(object, fileList): + global refreshFinishedCount + refreshFinishedCount += 1 + +def main(): + global workingDir,buildFinished,buildSucceeded + startApplication("qtcreator" + SettingsPath) + installLazySignalHandler("{type='CppTools::Internal::CppModelManager'}", "sourceFilesRefreshed(QStringList)", "handleRefreshFinished") + # using a temporary directory won't mess up an eventually exisiting + workingDir = tempDir() + createNewQtQuickApplication() + # wait for parsing to complete + waitFor("refreshFinishedCount == 1", 10000) + test.log("Building project") + invokeMenuItem("Build","Build All") + waitForBuildFinished() + test.log("Running project (includes build)") + if runAndCloseApp(): + logApplicationOutput() + invokeMenuItem("File", "Exit") + +def createNewQtQuickApplication(): + global workingDir + invokeMenuItem("File", "New File or Project...") + clickItem(waitForObject("{type='QTreeView' name='templateCategoryView'}", 20000), "Projects.Qt Quick Project", 5, 5, 0, Qt.LeftButton) + clickItem(waitForObject("{name='templatesView' type='QListView'}", 20000), "Qt Quick Application", 5, 5, 0, Qt.LeftButton) + clickButton(waitForObject("{text='Choose...' type='QPushButton' unnamed='1' visible='1'}", 20000)) + baseLineEd = waitForObject("{type='Utils::BaseValidatingLineEdit' unnamed='1' visible='1'}", 20000) + replaceLineEditorContent(baseLineEd, workingDir) + stateLabel = findObject("{type='QLabel' name='stateLabel'}") + labelCheck = stateLabel.text=="" and stateLabel.styleSheet == "" + test.verify(labelCheck, "Project name and base directory without warning or error") + # make sure this is not set as default location + cbDefaultLocation = waitForObject("{type='QCheckBox' name='projectsDirectoryCheckBox' visible='1'}", 20000) + if cbDefaultLocation.checked: + clickButton(cbDefaultLocation) + # now there's the 'untitled' project inside a temporary directory - step forward...! + nextButton = waitForObject("{text='Next' type='QPushButton' visible='1'}", 20000) + clickButton(nextButton) + chooseComponents() + clickButton(nextButton) + chooseDestination(QtQuickConstants.Destinations.DESKTOP) + snooze(1) + clickButton(nextButton) + clickButton(waitForObject("{type='QPushButton' text='Finish' visible='1'}", 20000)) + +def cleanup(): + global workingDir + # waiting for a clean exit - for a full-remove of the temp directory + appCtxt = currentApplicationContext() + waitFor("appCtxt.isRunning==False") + if workingDir!=None: + deleteDirIfExists(workingDir) + diff --git a/tests/system/suite_qtquick/tst_qtquick_creation2/test.py b/tests/system/suite_qtquick/tst_qtquick_creation2/test.py new file mode 100644 index 0000000000..a4ee377d91 --- /dev/null +++ b/tests/system/suite_qtquick/tst_qtquick_creation2/test.py @@ -0,0 +1,72 @@ +source("../../shared/qtcreator.py") + +refreshFinishedCount = 0 +workingDir = None +templateDir = None + +def handleRefreshFinished(object, fileList): + global refreshFinishedCount + refreshFinishedCount += 1 + +def main(): + global workingDir,templateDir,buildFinished,buildSucceeded + startApplication("qtcreator" + SettingsPath) + installLazySignalHandler("{type='CppTools::Internal::CppModelManager'}", "sourceFilesRefreshed(QStringList)", "handleRefreshFinished") + # using a temporary directory won't mess up an eventually exisiting + workingDir = tempDir() + prepareTemplate() + createNewQtQuickApplication() + # wait for parsing to complete + waitFor("refreshFinishedCount == 1", 10000) + test.log("Building project") + invokeMenuItem("Build","Build All") + waitForBuildFinished() + test.log("Running project (includes build)") + if runAndCloseApp(): + logApplicationOutput() + invokeMenuItem("File", "Exit") + +def prepareTemplate(): + global templateDir + templateDir = tempDir() + templateDir = os.path.abspath(templateDir + "/template") + sourceExample = os.path.abspath(SDKPath + "/../Examples/4.7/declarative/text/textselection") + shutil.copytree(sourceExample, templateDir) + +def createNewQtQuickApplication(): + global workingDir,templateDir + invokeMenuItem("File", "New File or Project...") + clickItem(waitForObject("{type='QTreeView' name='templateCategoryView'}", 20000), "Projects.Qt Quick Project", 5, 5, 0, Qt.LeftButton) + clickItem(waitForObject("{name='templatesView' type='QListView'}", 20000), "Qt Quick Application", 5, 5, 0, Qt.LeftButton) + clickButton(waitForObject("{text='Choose...' type='QPushButton' unnamed='1' visible='1'}", 20000)) + baseLineEd = waitForObject("{type='Utils::BaseValidatingLineEdit' unnamed='1' visible='1'}", 20000) + replaceLineEditorContent(baseLineEd, workingDir) + stateLabel = findObject("{type='QLabel' name='stateLabel'}") + labelCheck = stateLabel.text=="" and stateLabel.styleSheet == "" + test.verify(labelCheck, "Project name and base directory without warning or error") + # make sure this is not set as default location + cbDefaultLocation = waitForObject("{type='QCheckBox' name='projectsDirectoryCheckBox' visible='1'}", 20000) + if cbDefaultLocation.checked: + clickButton(cbDefaultLocation) + # now there's the 'untitled' project inside a temporary directory - step forward...! + nextButton = waitForObject("{text='Next' type='QPushButton' visible='1'}", 20000) + clickButton(nextButton) + chooseComponents(QtQuickConstants.Components.EXISTING_QML) + # define the existing qml file to import + baseLineEd = waitForObject("{type='Utils::BaseValidatingLineEdit' unnamed='1' visible='1'}", 20000) + type(baseLineEd, templateDir+"/qml/textselection.qml") + clickButton(nextButton) + chooseDestination() + snooze(1) + clickButton(nextButton) + clickButton(waitForObject("{type='QPushButton' text='Finish' visible='1'}", 20000)) + +def cleanup(): + global workingDir,templateDir + # waiting for a clean exit - for a full-remove of the temp directory + appCtxt = currentApplicationContext() + waitFor("appCtxt.isRunning==False") + if workingDir!=None: + deleteDirIfExists(workingDir) + if templateDir!=None: + deleteDirIfExists(os.path.dirname(templateDir)) diff --git a/tests/system/suite_qtquick/tst_qtquick_creation3/test.py b/tests/system/suite_qtquick/tst_qtquick_creation3/test.py new file mode 100644 index 0000000000..d815306349 --- /dev/null +++ b/tests/system/suite_qtquick/tst_qtquick_creation3/test.py @@ -0,0 +1,47 @@ +source("../../shared/qtcreator.py") + +refreshFinishedCount = 0 +workingDir = None + +def handleRefreshFinished(object, fileList): + global refreshFinishedCount + refreshFinishedCount += 1 + +def main(): + global workingDir,buildFinished,buildSucceeded + startApplication("qtcreator" + SettingsPath) + # using a temporary directory won't mess up an eventually exisiting + workingDir = tempDir() + createNewQtQuickUI() + test.log("Running project") + if runAndCloseQtQuickUI(): + logApplicationOutput() + invokeMenuItem("File", "Exit") + +def createNewQtQuickUI(): + global workingDir + invokeMenuItem("File", "New File or Project...") + clickItem(waitForObject("{type='QTreeView' name='templateCategoryView'}", 20000), "Projects.Qt Quick Project", 5, 5, 0, Qt.LeftButton) + clickItem(waitForObject("{name='templatesView' type='QListView'}", 20000), "Qt Quick UI", 5, 5, 0, Qt.LeftButton) + clickButton(waitForObject("{text='Choose...' type='QPushButton' unnamed='1' visible='1'}", 20000)) + baseLineEd = waitForObject("{type='Utils::BaseValidatingLineEdit' unnamed='1' visible='1'}", 20000) + replaceLineEditorContent(baseLineEd, workingDir) + stateLabel = findObject("{type='QLabel' name='stateLabel'}") + labelCheck = stateLabel.text=="" and stateLabel.styleSheet == "" + test.verify(labelCheck, "Project name and base directory without warning or error") + # make sure this is not set as default location + cbDefaultLocation = waitForObject("{type='QCheckBox' name='projectsDirectoryCheckBox' visible='1'}", 20000) + if cbDefaultLocation.checked: + clickButton(cbDefaultLocation) + # now there's the 'untitled' project inside a temporary directory - step forward...! + clickButton(waitForObject("{text='Next' type='QPushButton' visible='1'}", 20000)) + clickButton(waitForObject("{type='QPushButton' text='Finish' visible='1'}", 20000)) + +def cleanup(): + global workingDir + # waiting for a clean exit - for a full-remove of the temp directory + appCtxt = currentApplicationContext() + waitFor("appCtxt.isRunning==False") + if workingDir!=None: + deleteDirIfExists(workingDir) + diff --git a/tests/system/suite_qtquick/tst_qtquick_creation4/test.py b/tests/system/suite_qtquick/tst_qtquick_creation4/test.py new file mode 100644 index 0000000000..8d450558b4 --- /dev/null +++ b/tests/system/suite_qtquick/tst_qtquick_creation4/test.py @@ -0,0 +1,63 @@ +source("../../shared/qtcreator.py") + +refreshFinishedCount = 0 +workingDir = None + +def handleRefreshFinished(object, fileList): + global refreshFinishedCount + refreshFinishedCount += 1 + +def main(): + global workingDir,buildFinished,buildSucceeded + startApplication("qtcreator" + SettingsPath) + installLazySignalHandler("{type='CppTools::Internal::CppModelManager'}", "sourceFilesRefreshed(QStringList)", "handleRefreshFinished") + # using a temporary directory won't mess up an eventually exisiting + workingDir = tempDir() + createNewQmlExtension() + # wait for parsing to complete + waitFor("refreshFinishedCount == 1", 10000) + test.log("Building project") + invokeMenuItem("Build","Build All") + waitForBuildFinished() + if buildSucceeded: + checkCompile() + invokeMenuItem("File", "Exit") + +def createNewQmlExtension(): + global workingDir + invokeMenuItem("File", "New File or Project...") + clickItem(waitForObject("{type='QTreeView' name='templateCategoryView'}", 20000), "Projects.Qt Quick Project", 5, 5, 0, Qt.LeftButton) + clickItem(waitForObject("{name='templatesView' type='QListView'}", 20000), "Custom QML Extension Plugin", 5, 5, 0, Qt.LeftButton) + clickButton(waitForObject("{text='Choose...' type='QPushButton' unnamed='1' visible='1'}", 20000)) + baseLineEd = waitForObject("{type='Utils::BaseValidatingLineEdit' unnamed='1' visible='1'}", 20000) + replaceLineEditorContent(baseLineEd, workingDir) + stateLabel = findObject("{type='QLabel' name='stateLabel'}") + labelCheck = stateLabel.text=="" and stateLabel.styleSheet == "" + test.verify(labelCheck, "Project name and base directory without warning or error") + # make sure this is not set as default location + cbDefaultLocation = waitForObject("{type='QCheckBox' name='projectsDirectoryCheckBox' visible='1'}", 20000) + if cbDefaultLocation.checked: + clickButton(cbDefaultLocation) + # now there's the 'untitled' project inside a temporary directory - step forward...! + nextButton = waitForObject("{text='Next' type='QPushButton' visible='1'}", 20000) + clickButton(nextButton) + chooseDestination() + clickButton(nextButton) +# buddy = waitForObject("{type='QLabel' text='Object Class-name:' unnamed='1' visible='1'}", 20000) + nameLineEd = waitForObject("{buddy={type='QLabel' text='Object Class-name:' unnamed='1' visible='1'} " + "type='QLineEdit' unnamed='1' visible='1'}", 20000) + replaceLineEditorContent(nameLineEd, "TestItem") + uriLineEd = waitForObject("{buddy={type='QLabel' text='URI:' unnamed='1' visible='1'} " + "type='QLineEdit' unnamed='1' visible='1'}", 20000) + replaceLineEditorContent(uriLineEd, "com.nokia.test.qmlcomponents") + clickButton(nextButton) + clickButton(waitForObject("{type='QPushButton' text='Finish' visible='1'}", 20000)) + +def cleanup(): + global workingDir + # waiting for a clean exit - for a full-remove of the temp directory + appCtxt = currentApplicationContext() + waitFor("appCtxt.isRunning==False") + if workingDir!=None: + deleteDirIfExists(workingDir) + |