Commit e137af3a authored by Christian Stenger's avatar Christian Stenger Committed by Bill King
Browse files

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: default avatarQt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: default avatarBill King <bill.king@nokia.com>
parent 4bf42e78
......@@ -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)
......@@ -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
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
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)
QT_PLATFORM_PLUGIN=nonesuch
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
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)
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))
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)
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)
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment