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>
This commit is contained in:
Christian Stenger
2011-09-06 09:12:15 +02:00
committed by Bill King
parent 4bf42e7885
commit e137af3a42
10 changed files with 399 additions and 2 deletions

View File

@@ -21,3 +21,13 @@ def openCmakeProject(projectPath):
clickButton(waitForObject(":CMake Wizard.Next_QPushButton", 20000)) clickButton(waitForObject(":CMake Wizard.Next_QPushButton", 20000))
clickButton(waitForObject(":CMake Wizard.Run CMake_QPushButton", 20000)) clickButton(waitForObject(":CMake Wizard.Run CMake_QPushButton", 20000))
clickButton(waitForObject(":CMake Wizard.Finish_QPushButton", 60000)) 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)

View File

@@ -13,9 +13,11 @@ testSettings.logScreenshotOnFail = True
source("../../shared/utils.py") source("../../shared/utils.py")
source("../../shared/build_utils.py") source("../../shared/build_utils.py")
source("../../shared/mainwin.py") source("../../shared/mainwin.py")
source("../../shared/qtquick.py")
def removeTmpSettingsDir(): def removeTmpSettingsDir():
snooze(5) appCtxt = currentApplicationContext()
waitFor("appCtxt.isRunning==False")
deleteDirIfExists(os.path.dirname(tmpSettingsDir)) deleteDirIfExists(os.path.dirname(tmpSettingsDir))
if platform.system() in ('Windows', 'Microsoft'): 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 # the following only doesn't work if the test ends in an exception
atexit.register(removeTmpSettingsDir) atexit.register(removeTmpSettingsDir)
SettingsPath = " -settingspath %s" % tmpSettingsDir SettingsPath = " -settingspath %s" % tmpSettingsDir

View File

@@ -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

View File

@@ -1,7 +1,7 @@
import tempfile, shutil, os import tempfile, shutil, os
def tempDir(): def tempDir():
return tempfile.mkdtemp() return tempfile.mkdtemp(prefix="qtcreator_")
def deleteDirIfExists(path): def deleteDirIfExists(path):
shutil.rmtree(path, True) shutil.rmtree(path, True)
@@ -62,3 +62,8 @@ def which(program):
return None return None
def replaceLineEditorContent(lineEditor, newcontent):
type(lineEditor, "<Ctrl+A>")
type(lineEditor, "<Delete>")
type(lineEditor, newcontent)

View File

@@ -0,0 +1 @@
QT_PLATFORM_PLUGIN=nonesuch

View File

@@ -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

View File

@@ -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)

View File

@@ -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))

View File

@@ -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)

View File

@@ -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)