From 3ad7e50827c1f46ec730e457b9621b227cd35efc Mon Sep 17 00:00:00 2001 From: Christian Stenger <christian.stenger@nokia.com> Date: Fri, 17 Feb 2012 17:10:53 +0100 Subject: [PATCH] Squish: Verify targets for project creation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I3af0e0cde985c4b04bd4ae8181c3b82cda22b2b8 Reviewed-by: Robert Löhning <robert.loehning@nokia.com> --- tests/system/objects.map | 5 + tests/system/shared/classes.py | 22 ++++ tests/system/shared/project.py | 20 ++- tests/system/shared/utils.py | 34 +++++ tests/system/shared/workarounds.py | 5 + tests/system/suite_general/suite.conf | 2 +- .../tst_create_proj_wizard/test.py | 122 ++++++++++++++++++ 7 files changed, 205 insertions(+), 5 deletions(-) create mode 100644 tests/system/suite_general/tst_create_proj_wizard/test.py diff --git a/tests/system/objects.map b/tests/system/objects.map index f3caa2cce2a..689efc6f08c 100644 --- a/tests/system/objects.map +++ b/tests/system/objects.map @@ -17,7 +17,9 @@ :New.templatesView_QListView {name='templatesView' type='QListView' visible='1' window=':New_Core::Internal::NewDialog'} :New_Core::Internal::NewDialog {name='Core__Internal__NewDialog' type='Core::Internal::NewDialog' visible='1' windowTitle='New'} :Next_QPushButton {text~='(Next.*|Continue)' type='QPushButton' visible='1'} +:Options.Cancel_QPushButton {text='Cancel' type='QPushButton' unnamed='1' visible='1' window=':Options_Core::Internal::SettingsDialog'} :Options.OK_QPushButton {text='OK' type='QPushButton' unnamed='1' visible='1' window=':Options_Core::Internal::SettingsDialog'} +:Options.qt_tabwidget_stackedwidget_QStackedWidget {name='qt_tabwidget_stackedwidget' type='QStackedWidget' visible='1' window=':Options_Core::Internal::SettingsDialog'} :Options.qt_tabwidget_tabbar_QTabBar {name='qt_tabwidget_tabbar' type='QTabBar' visible='1' window=':Options_Core::Internal::SettingsDialog'} :Options_Core::Internal::SettingsDialog {type='Core::Internal::SettingsDialog' unnamed='1' visible='1' windowTitle~='(Options|Preferences)'} :Options_QListView {type='QListView' unnamed='1' visible='1' window=':Options_Core::Internal::SettingsDialog'} @@ -43,12 +45,15 @@ :Qt Gui Application.scrollArea_QScrollArea {name='scrollArea' type='QScrollArea' visible='1'} :Qt Gui Application_Qt4ProjectManager::Internal::GuiAppWizardDialog {type='Qt4ProjectManager::Internal::GuiAppWizardDialog' unnamed='1' visible='1' windowTitle='Qt Gui Application'} :QtCreator.MenuBar_ProjectExplorer::Internal::MiniProjectTargetSelector {type='ProjectExplorer::Internal::MiniProjectTargetSelector'} +:QtSupport__Internal__QtVersionManager.QLabel {container=':qt_tabwidget_stackedwidget.QtSupport__Internal__QtVersionManager_QtSupport::Internal::QtOptionsPageWidget' name='errorLabel' type='QLabel' visible='1'} +:QtSupport__Internal__QtVersionManager.qtdirList_QTreeWidget {container=':qt_tabwidget_stackedwidget.QtSupport__Internal__QtVersionManager_QtSupport::Internal::QtOptionsPageWidget' name='qtdirList' type='QTreeWidget' visible='1'} :Symbol Server_Utils::CheckableMessageBox {type='Utils::CheckableMessageBox' unnamed='1' visible='1' windowTitle='Symbol Server'} :addToVersionControlComboBox_QComboBox {name='addToVersionControlComboBox' type='QComboBox' visible='1'} :formFileLineEdit_Utils::FileNameValidatingLineEdit {buddy=':Qt Gui Application.Form file:_QLabel' name='formFileLineEdit' type='Utils::FileNameValidatingLineEdit' visible='1'} :headerFileLineEdit_Utils::FileNameValidatingLineEdit {buddy=':Qt Gui Application.Header file:_QLabel' name='headerFileLineEdit' type='Utils::FileNameValidatingLineEdit' visible='1'} :projects.projects.pro_QModelIndex {column='0' container=':projects_QModelIndex' text='projects.pro' type='QModelIndex'} :projects_QModelIndex {column='0' container=':Qt Creator_Utils::NavigationTreeView' text='projects' type='QModelIndex'} +:qt_tabwidget_stackedwidget.QtSupport__Internal__QtVersionManager_QtSupport::Internal::QtOptionsPageWidget {container=':Options.qt_tabwidget_stackedwidget_QStackedWidget' name='QtSupport__Internal__QtVersionManager' type='QtSupport::Internal::QtOptionsPageWidget' visible='1'} :scrollArea.Create Build Configurations:_QComboBox_2 {container=':Qt Gui Application.scrollArea_QScrollArea' leftWidget=':scrollArea.Create Build Configurations:_QLabel_2' type='QComboBox' unnamed='1' visible='1'} :scrollArea.Create Build Configurations:_QLabel_2 {container=':Qt Gui Application.scrollArea_QScrollArea' text='Create Build Configurations:' type='QLabel' unnamed='1' visible='1'} :scrollArea.Edit build configuration:_QComboBox {container=':Qt Creator.scrollArea_QScrollArea' leftWidget=':scrollArea.Edit build configuration:_QLabel' type='QComboBox' unnamed='1' visible='1'} diff --git a/tests/system/shared/classes.py b/tests/system/shared/classes.py index 689aa0cc0be..81978f59fc0 100644 --- a/tests/system/shared/classes.py +++ b/tests/system/shared/classes.py @@ -41,6 +41,28 @@ class QtQuickConstants: else: return None + @staticmethod + def getAllTargets(): + return [QtQuickConstants.Targets.DESKTOP, QtQuickConstants.Targets.HARMATTAN, + QtQuickConstants.Targets.MAEMO5, QtQuickConstants.Targets.SIMULATOR, + QtQuickConstants.Targets.SYMBIAN] + + @staticmethod + def getAllTargetStrings(): + return QtQuickConstants.getTargetsAsStrings(QtQuickConstants.getAllTargets()) + + @staticmethod + def getTargetsAsStrings(targets): + if not isinstance(targets, (tuple,list)): + test.fatal("Wrong usage... This function handles only tuples or lists.") + return None + result = [] + for target in targets: + result.append(QtQuickConstants.getStringForTarget(target)) + if None in result: + test.fatal("You've passed at least one unknown target!") + return result + # this class holds some constants for easier usage inside the Projects view class ProjectSettings: BUILD = 1 diff --git a/tests/system/shared/project.py b/tests/system/shared/project.py index f4af296902a..e29baf35ce1 100644 --- a/tests/system/shared/project.py +++ b/tests/system/shared/project.py @@ -1,3 +1,5 @@ +import re + processStarted = False processExited = False @@ -75,7 +77,7 @@ def __createProjectSelectType__(category, template): clickItem(templatesView, template, 5, 5, 0, Qt.LeftButton) text = waitForObject("{type='QTextBrowser' name='templateDescription' visible='1'}").plainText clickButton(waitForObject("{text='Choose...' type='QPushButton' unnamed='1' visible='1'}", 20000)) - return __getSupportedPlatforms__(str(text)) + return __getSupportedPlatforms__(str(text))[0] def __createProjectSetNameAndPath__(path, projectName = None, checks = True): directoryEdit = waitForObject("{type='Utils::BaseValidatingLineEdit' unnamed='1' visible='1'}", 20000) @@ -401,7 +403,15 @@ def resetApplicationContextToCreator(): # to figure out which available targets we have # Simulator must be handled in a special way, because this depends on the # configured Qt versions and Toolchains and cannot be looked up the same way -def __getSupportedPlatforms__(text): +# if you set getAsStrings to True this function returns a list of strings instead +# of the constants defined in QtQuickConstants.Targets +def __getSupportedPlatforms__(text, getAsStrings=False): + reqPattern = re.compile("requires qt (?P<version>\d+\.\d+(\.\d+)?)", re.IGNORECASE) + res = reqPattern.search(text) + if res: + version = res.group("version") + else: + version = None if 'Supported Platforms' in text: supports = text[text.find('Supported Platforms'):].split(":")[1].strip().split(" ") result = [] @@ -425,5 +435,7 @@ def __getSupportedPlatforms__(text): else: test.warning("Returning None (__getSupportedPlatforms__())", "Parsed text: '%s'" % text) - return None - return result + return None, None + if getAsStrings: + result = QtQuickConstants.getTargetsAsStrings(result) + return result, version diff --git a/tests/system/shared/utils.py b/tests/system/shared/utils.py index af305beee74..9525e10722a 100644 --- a/tests/system/shared/utils.py +++ b/tests/system/shared/utils.py @@ -260,3 +260,37 @@ def __checkParentAccess__(filePath): test.log("Got execute permission on '%s'" % tmp) else: test.fail("No execute permission on '%s'" % tmp) + +# this function checks for all configured Qt versions inside +# options dialog and returns a dict holding the targets as keys +# and a list of supported versions as value +def getCorrectlyConfiguredTargets(): + result = {} + invokeMenuItem("Tools", "Options...") + waitForObjectItem(":Options_QListView", "Build & Run") + clickItem(":Options_QListView", "Build & Run", 14, 15, 0, Qt.LeftButton) + clickTab(waitForObject(":Options.qt_tabwidget_tabbar_QTabBar"), "Qt Versions") + pattern = re.compile("Qt version (?P<version>.*?) for (?P<target>.*)") + treeWidget = waitForObject(":QtSupport__Internal__QtVersionManager.qtdirList_QTreeWidget") + root = treeWidget.invisibleRootItem() + for childRow in range(root.childCount()): + rootChild = root.child(childRow) + rootChildText = str(rootChild.text(0)).replace(".", "\\.") + for row in range(rootChild.childCount()): + subChild = rootChild.child(row) + subChildText = str(subChild.text(0)).replace(".", "\\.") + clickItem(treeWidget, ".".join([rootChildText,subChildText]), 5, 5, 0, Qt.LeftButton) + currentText = str(waitForObject(":QtSupport__Internal__QtVersionManager.QLabel").text) + matches = pattern.match(currentText) + if matches: + target = matches.group("target") + version = matches.group("version") + if target in result: + oldV = result[target] + if version not in oldV: + oldV.append(version) + result.update({target:oldV}) + else: + result.update({target:[version]}) + clickButton(waitForObject(":Options.OK_QPushButton")) + return result diff --git a/tests/system/shared/workarounds.py b/tests/system/shared/workarounds.py index 81385fdd046..9e69727a902 100644 --- a/tests/system/shared/workarounds.py +++ b/tests/system/shared/workarounds.py @@ -168,6 +168,7 @@ class JIRA: # ALWAYS update this dict when adding a new function for a workaround! def __initBugDict__(self): self.__bugs__= { + 'QTCREATORBUG-6967':self._workaroundCreator6967_, 'QTCREATORBUG-6853':self._workaroundCreator6853_, 'QTCREATORBUG-6918':self._workaroundCreator_MacEditorFocus_, 'QTCREATORBUG-6953':self._workaroundCreator_MacEditorFocus_ @@ -178,6 +179,10 @@ class JIRA: ############### functions that hold workarounds ################################# + def _workaroundCreator6967_(self, *args): + if args[0] == 'Mobile Qt Application': + args[1].remove('Qt Simulator') + def _workaroundCreator6853_(self, *args): if "Release" in args[0] and platform.system() == "Linux": snooze(1) diff --git a/tests/system/suite_general/suite.conf b/tests/system/suite_general/suite.conf index b114c5f47d3..19435bce406 100644 --- a/tests/system/suite_general/suite.conf +++ b/tests/system/suite_general/suite.conf @@ -7,6 +7,6 @@ HOOK_SUB_PROCESSES=false IMPLICITAUTSTART=0 LANGUAGE=Python OBJECTMAP=../objects.map -TEST_CASES=tst_openqt_creator tst_build_speedcrunch tst_cmake_speedcrunch tst_basic_cpp_support tst_select_all +TEST_CASES=tst_openqt_creator tst_build_speedcrunch tst_cmake_speedcrunch tst_basic_cpp_support tst_select_all tst_create_proj_wizard VERSION=2 WRAPPERS=Qt diff --git a/tests/system/suite_general/tst_create_proj_wizard/test.py b/tests/system/suite_general/tst_create_proj_wizard/test.py new file mode 100644 index 00000000000..80ba5ab18f2 --- /dev/null +++ b/tests/system/suite_general/tst_create_proj_wizard/test.py @@ -0,0 +1,122 @@ +source("../../shared/qtcreator.py") + +import re + +def main(): + global templateDir, textChanged + sourceExample = os.path.abspath(sdkPath + "/Examples/4.7/declarative/text/textselection") + if not neededFilePresent(sourceExample): + return + prepareTemplate(sourceExample) + startApplication("qtcreator" + SettingsPath) + overrideInstallLazySignalHandler() + installLazySignalHandler("{type='QTextBrowser' name='templateDescription' visible='1'}", + "textChanged()","__handleTextChanged__") + targets = getCorrectlyConfiguredTargets() + test.log("Collecting potential project types...") + availableProjectTypes = [] + invokeMenuItem("File", "New File or Project...") + categoriesView = waitForObject("{type='QTreeView' name='templateCategoryView' visible='1'}", 20000) + catModel = categoriesView.model() + projects = catModel.index(0, 0) + test.compare("Projects", projects.data()) + comboBox = waitForObject("{name='comboBox' type='QComboBox' visible='1' " + "window=':New_Core::Internal::NewDialog'}") + test.compare(comboBox.currentText, "All templates") + for row in range(catModel.rowCount(projects)): + index = catModel.index(row, 0, projects) + category = str(index.data()).replace(".", "\\.") + # skip non-configurable + if "Import" in category or "Non-Qt" in category: + continue + clickItem(categoriesView, "Projects." + category, 5, 5, 0, Qt.LeftButton) + templatesView = waitForObject("{name='templatesView' type='QListView' visible='1'}", 20000) + # needed because categoriesView and templatesView using same model + tempRootIndex = templatesView.rootIndex() + tempModel = templatesView.model() + for tRow in range(tempModel.rowCount(tempRootIndex)): + tIndex = tempModel.index(tRow, 0, tempRootIndex) + template = str(tempModel.data(tIndex)).replace(".", "\\.") + # skip non-configurable + if "Qt Quick UI" in template or "Plain C" in template: + continue + availableProjectTypes.append({category:template}) + clickButton(waitForObject("{text='Cancel' type='QPushButton' unnamed='1' visible='1'}", 20000)) + for current in availableProjectTypes: + category = current.keys()[0] + template = current.values()[0] + invokeMenuItem("File", "New File or Project...") + categoriesView = waitForObject("{type='QTreeView' name='templateCategoryView' visible='1'}", 20000) + clickItem(categoriesView, "Projects." + category, 5, 5, 0, Qt.LeftButton) + templatesView = waitForObject("{name='templatesView' type='QListView' visible='1'}", 20000) + test.log("Verifying '%s' -> '%s'" % (category.replace("\\.", "."), template.replace("\\.", "."))) + textChanged = False + clickItem(templatesView, template, 5, 5, 0, Qt.LeftButton) + waitFor("textChanged", 2000) + text = waitForObject("{type='QTextBrowser' name='templateDescription' visible='1'}").plainText + displayedPlatforms, requiredVersion = __getSupportedPlatforms__(str(text), True) + clickButton(waitForObject("{text='Choose...' type='QPushButton' unnamed='1' visible='1'}", 20000)) + # don't check because project could exist + __createProjectSetNameAndPath__(os.path.expanduser("~"), 'untitled', False) + try: + waitForObject("{name='mainQmlFileGroupBox' title='Main HTML File' type='QGroupBox' visible='1'}", 1000) + clickButton(waitForObject(":Next_QPushButton")) + except LookupError: + try: + waitForObject("{text='Select Existing QML file' type='QLabel' visible='1'}", 1000) + baseLineEd = waitForObject("{type='Utils::BaseValidatingLineEdit' unnamed='1' visible='1'}", 20000) + type(baseLineEd, templateDir + "/qml/textselection.qml") + clickButton(waitForObject(":Next_QPushButton")) + except LookupError: + pass + availableCheckboxes = [] + waitForObject("{type='QLabel' unnamed='1' visible='1' text='Target Setup'}") + for current in QtQuickConstants.getAllTargetStrings(): + try: + findObject("{type='QCheckBox' text='%s' visible='1'}" % current) + availableCheckboxes.append(current) + except: + pass + JIRA.performWorkaroundIfStillOpen(6967, JIRA.Bug.CREATOR, template, displayedPlatforms) + # verification whether expected, found and configured match + for t in targets: + if requiredVersion: + if max(targets[t]) < requiredVersion: + if t in availableCheckboxes: + test.fail("Target '%s' found as checkbox, but required version (%s) is higher " + "than configured version(s) (%s)!" % (t, requiredVersion, str(targets[t]))) + else: + test.passes("Irrelevant target '%s' not found on 'Target setup' page - " + "required version is '%s', current version(s) are '%s'." % + (t, requiredVersion, str(targets[t]))) + continue + found = False + if t in displayedPlatforms: + if t in availableCheckboxes: + test.passes("Found expected target '%s' on 'Target setup' page." % t) + else: + test.fail("Expected target '%s' missing on 'Target setup' page." % t) + else: + if t in availableCheckboxes: + test.fail("Target '%s' found on 'Target setup' page - but has not been expected!" % t) + else: + test.passes("Irrelevant target '%s' not found on 'Target setup' page." % t) + clickButton(waitForObject("{text='Cancel' type='QPushButton' unnamed='1' visible='1'}", 20000)) + invokeMenuItem("File", "Exit") + +def prepareTemplate(sourceExample): + global templateDir + templateDir = tempDir() + templateDir = os.path.abspath(templateDir + "/template") + shutil.copytree(sourceExample, templateDir) + +def cleanup(): + global templateDir + # waiting for a clean exit - for a full-remove of the temp directory + waitForCleanShutdown() + if templateDir!=None: + deleteDirIfExists(os.path.dirname(templateDir)) + +def __handleTextChanged__(object): + global textChanged + textChanged = True -- GitLab