diff --git a/tests/system/objects.map b/tests/system/objects.map index d3f3627dcff..ab27210030f 100644 --- a/tests/system/objects.map +++ b/tests/system/objects.map @@ -20,6 +20,7 @@ :Debugger Toolbar.Continue_QToolButton {container=':DebugModeWidget.Debugger Toolbar_QDockWidget' text='Continue' type='QToolButton' unnamed='1' visible='1'} :Debugger Toolbar.Exit Debugger_QToolButton {container=':DebugModeWidget.Debugger Toolbar_QDockWidget' text='Stop Debugger' type='QToolButton' unnamed='1' visible='1'} :Debugger Toolbar.StatusText_Utils::StatusLabel {container=':DebugModeWidget.Debugger Toolbar_QDockWidget' type='Utils::StatusLabel' unnamed='1'} +:Edit Environment_ProjectExplorer::EnvironmentItemsDialog {type='ProjectExplorer::EnvironmentItemsDialog' unnamed='1' visible='1' windowTitle='Edit Environment'} :Failed to start application_QMessageBox {type='QMessageBox' unnamed='1' visible='1' windowTitle='Failed to start application'} :Generator:_QComboBox {buddy=':CMake Wizard.Generator:_QLabel' type='QComboBox' unnamed='1' visible='1'} :New.frame_QFrame {name='frame' type='QFrame' visible='1' window=':New_Core::Internal::NewDialog'} @@ -45,6 +46,7 @@ :Qt Creator_CppEditor::Internal::CPPEditorWidget {type='CppEditor::Internal::CPPEditorWidget' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} :Qt Creator_QTableView {type='QTableView' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} :Qt Creator_SearchResult_Core::Internal::OutputPaneToggleButton {occurrence='2' type='Core::Internal::OutputPaneToggleButton' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} +:Qt Creator_SystemSettings.Details_Utils::DetailsButton {occurrence='4' text='Details' type='Utils::DetailsButton' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} :Qt Creator_Utils::NavigationTreeView {type='Utils::NavigationTreeView' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} :Qt Gui Application.Form file:_QLabel {name='formLabel' text='Form file:' type='QLabel' visible='1' window=':Qt Gui Application_Qt4ProjectManager::Internal::GuiAppWizardDialog'} :Qt Gui Application.Header file:_QLabel {name='headerLabel' text='Header file:' type='QLabel' visible='1' window=':Qt Gui Application_Qt4ProjectManager::Internal::GuiAppWizardDialog'} @@ -67,10 +69,7 @@ :scrollArea.Library not available_QLabel {container=':Qt Creator.scrollArea_QScrollArea' name='qmlDebuggingWarningText' text?='Library not available*' type='QLabel' visible='1'} :scrollArea.Qt 4 for Desktop - (Qt SDK) debug_QCheckBox {container=':Qt Gui Application.scrollArea_QScrollArea' occurrence='1' text='Debug' type='QCheckBox' unnamed='1' visible='1'} :scrollArea.Qt 4 for Desktop - (Qt SDK) release_QCheckBox {container=':Qt Gui Application.scrollArea_QScrollArea' occurrence='1' text='Release' type='QCheckBox' unnamed='1' visible='1'} -:scrollArea.Qt Version:_QComboBox {aboveWidget=':scrollArea.Use Shadow Building_QCheckBox' container=':Qt Gui Application.scrollArea_QScrollArea' leftWidget=':scrollArea.Qt Version:_QLabel' type='QComboBox' unnamed='1' visible='1'} -:scrollArea.Qt Version:_QLabel {container=':Qt Gui Application.scrollArea_QScrollArea' text='Qt Version:' type='QLabel' unnamed='1' visible='1'} :scrollArea.Use Shadow Building_QCheckBox {container=':Qt Gui Application.scrollArea_QScrollArea' text='Shadow build' type='QCheckBox' unnamed='1' visible='1'} :scrollArea.qmlDebuggingLibraryCheckBox_QCheckBox {container=':Qt Gui Application.scrollArea_QScrollArea' name='qmlDebuggingLibraryCheckBox' type='QCheckBox' visible='1'} -:scrollArea.qtVersionComboBox_QComboBox {container=':Qt Creator.scrollArea_QScrollArea' name='qtVersionComboBox' type='QComboBox' visible='1'} -:scrollArea_QTableView {container=':Qt Creator.scrollArea_QScrollArea' type='QTableView' unnamed='1' visible='1'} +:scrollArea_QTableView {type='QTableView' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} :sourceFileLineEdit_Utils::FileNameValidatingLineEdit {buddy=':Qt Gui Application.Source file:_QLabel' name='sourceFileLineEdit' type='Utils::FileNameValidatingLineEdit' visible='1'} diff --git a/tests/system/shared/classes.py b/tests/system/shared/classes.py index 5957ac610fe..f981982bbe5 100644 --- a/tests/system/shared/classes.py +++ b/tests/system/shared/classes.py @@ -122,3 +122,7 @@ class SubprocessType: test.fatal("Could not determine the WindowType for SubprocessType %s" % subprocessType) return None +class QtInformation: + QT_VERSION = 0 + QT_BINPATH = 1 + QT_LIBPATH = 2 diff --git a/tests/system/shared/hook_utils.py b/tests/system/shared/hook_utils.py index 8b7551f0b31..cd73dfaaa3a 100644 --- a/tests/system/shared/hook_utils.py +++ b/tests/system/shared/hook_utils.py @@ -9,44 +9,49 @@ def modifyRunSettingsForHookInto(projectName, port): # this uses the defaultQtVersion currently switchViewTo(ViewConstants.PROJECTS) switchToBuildOrRunSettingsFor(1, 0, ProjectSettings.BUILD) - qtVersionTT = str(waitForObject("{type='QComboBox' name='qtVersionComboBox' visible='1'}").toolTip) - mkspec = __getMkspec__(qtVersionTT) - qmakeVersion = __getQMakeVersion__(qtVersionTT) - qmakeLibPath = __getQMakeLibPath__(qtVersionTT) - qmakeBinPath = __getQMakeBinPath__(qtVersionTT) + qtVersion, mkspec, qtBinPath, qtLibPath = getQtInformationForBuildSettings(True) + if None in (qtVersion, mkspec, qtBinPath, qtLibPath): + test.fatal("At least one of the Qt information returned None - leaving...", + "Qt version: %s, mkspec: %s, Qt BinPath: %s, Qt LibPath: %s" % + (qtVersion, mkspec, qtBinPath, qtLibPath)) + return False + qtVersion = ".".join(qtVersion.split(".")[:2]) switchToBuildOrRunSettingsFor(1, 0, ProjectSettings.RUN) - result = __configureCustomExecutable__(projectName, port, mkspec, qmakeVersion) + result = __configureCustomExecutable__(projectName, port, mkspec, qtVersion) if result: - clickButton(waitForObject("{container=':Qt Creator.scrollArea_QScrollArea' text='Details' " + clickButton(waitForObject("{window=':Qt Creator_Core::Internal::MainWindow' text='Details' " "type='Utils::DetailsButton' unnamed='1' visible='1' " "leftWidget={type='QLabel' text~='Us(e|ing) Build Environment' unnamed='1' visible='1'}}")) envVarsTableView = waitForObject("{type='QTableView' visible='1' unnamed='1'}") model = envVarsTableView.model() + changingVars = [] for row in range(model.rowCount()): # get var name index = model.index(row, 0) envVarsTableView.scrollTo(index) varName = str(model.data(index).toString()) - # if its a special SQUISH var simply unset it + # if its a special SQUISH var simply unset it, SQUISH_LIBQTDIR and PATH will be replaced with Qt paths if varName == "PATH": - currentItem = __doubleClickQTableView__(":scrollArea_QTableView", row, 1) - test.log("replacing PATH with '%s'" % qmakeBinPath) - replaceEditorContent(currentItem, qmakeBinPath) + test.log("Replacing PATH with '%s'" % qtBinPath) + changingVars.append("PATH=%s" % qtBinPath) elif varName.find("SQUISH") == 0: if varName == "SQUISH_LIBQTDIR": - currentItem = __doubleClickQTableView__(":scrollArea_QTableView", row, 1) if platform.system() in ('Microsoft', 'Windows'): - replacement = qmakeBinPath + replacement = qtBinPath else: - replacement = qmakeLibPath - test.log("Changing SQUISH_LIBQTDIR", - "Replacing '%s' with '%s'" % (currentItem.text, replacement)) - replaceEditorContent(currentItem, replacement) + replacement = qtLibPath + test.log("Replacing SQUISH_LIBQTDIR with '%s'" % replacement) + changingVars.append("SQUISH_LIBQTDIR=%s" % replacement) else: - mouseClick(waitForObject("{container=':scrollArea_QTableView' " - "type='QModelIndex' row='%d' column='1'}" % row), 5, 5, 0, Qt.LeftButton) - clickButton(waitForObject("{type='QPushButton' text='Unset' unnamed='1' visible='1'}")) + changingVars.append(varName) #test.log("Unsetting %s for run" % varName) + clickButton(waitForObject("{text='Batch Edit...' type='QPushButton' unnamed='1' visible='1' " + "window=':Qt Creator_Core::Internal::MainWindow'}")) + editor = waitForObject("{type='TextEditor::SnippetEditorWidget' unnamed='1' visible='1' " + "window=':Edit Environment_ProjectExplorer::EnvironmentItemsDialog'}") + typeLines(editor, changingVars) + clickButton(waitForObject("{text='OK' type='QPushButton' unnamed='1' visible='1' " + "window=':Edit Environment_ProjectExplorer::EnvironmentItemsDialog'}")) switchViewTo(ViewConstants.EDIT) return result @@ -214,17 +219,17 @@ def __configureCustomExecutable__(projectName, port, mkspec, qmakeVersion): test.warning("Configured Squish directory seems to be missing - using fallback without hooking into subprocess.", "Failed to find '%s'" % startAUT) return False - addButton = waitForObject("{container=':Qt Creator.scrollArea_QScrollArea' occurrence='2' text='Add' type='QPushButton' unnamed='1' visible='1'}") + addButton = waitForObject("{window=':Qt Creator_Core::Internal::MainWindow' occurrence='2' text='Add' type='QPushButton' unnamed='1' visible='1'}") clickButton(addButton) addMenu = addButton.menu() activateItem(waitForObjectItem(objectMap.realName(addMenu), 'Custom Executable')) - exePathChooser = waitForObject("{buddy={container=':Qt Creator.scrollArea_QScrollArea' text='Command:' type='QLabel'} " + exePathChooser = waitForObject("{buddy={window=':Qt Creator_Core::Internal::MainWindow' text='Command:' type='QLabel' unnamed='1' visible='1'} " "type='Utils::PathChooser' unnamed='1' visible='1'}", 2000) exeLineEd = getChildByClass(exePathChooser, "Utils::BaseValidatingLineEdit") - argLineEd = waitForObject("{buddy={container={type='QScrollArea' name='scrollArea'} " + argLineEd = waitForObject("{buddy={window=':Qt Creator_Core::Internal::MainWindow' " "type='QLabel' text='Arguments:' visible='1'} type='QLineEdit' " "unnamed='1' visible='1'}") - wdPathChooser = waitForObject("{buddy={container=':Qt Creator.scrollArea_QScrollArea' text='Working directory:' type='QLabel'} " + wdPathChooser = waitForObject("{buddy={window=':Qt Creator_Core::Internal::MainWindow' text='Working directory:' type='QLabel'} " "type='Utils::PathChooser' unnamed='1' visible='1'}") replaceEditorContent(exeLineEd, startAUT) # the following is currently only configured for release builds (will be enhanced later) @@ -246,40 +251,6 @@ def getChildByClass(parent, classToSearchFor, occurence=1): else: return children[occurence - 1] -# helper that tries to get the mkspec entry of the QtVersion ToolTip -def __getMkspec__(qtToolTip): - return ___searchInsideQtVersionToolTip___(qtToolTip, "mkspec:") - -# helper that tries to get the qmake version entry of the QtVersion ToolTip -def __getQMakeVersion__(qtToolTip): - return ___searchInsideQtVersionToolTip___(qtToolTip, "Version:") - -# helper that tries to get the path of the qmake libraries of the QtVersion ToolTip -def __getQMakeLibPath__(qtToolTip): - qmake = ___searchInsideQtVersionToolTip___(qtToolTip, "qmake:") - result = getOutputFromCmdline("%s -v" % qmake) - for line in result.splitlines(): - if "Using Qt version" in line: - return line.rsplit(" ", 1)[1] - -# helper that tries to get the path of qmake of the QtVersion ToolTip -def __getQMakeBinPath__(qtToolTip): - qmake = ___searchInsideQtVersionToolTip___(qtToolTip, "qmake:") - endIndex = qmake.find(os.sep + "qmake") - return qmake[:endIndex] - -# helper that does the work for __getMkspec__() and __getQMakeVersion__() -def ___searchInsideQtVersionToolTip___(qtToolTip, what): - result = None - tmp = qtToolTip.split("") - for i in range(len(tmp)): - if i % 2 == 0: - continue - if what in tmp[i]: - result = tmp[i + 1].split("", 1)[0] - break - return result - # get the Squish path that is needed to successfully hook into the compiled app def getSquishPath(mkspec, qmakev): qmakev = ".".join(qmakev.split(".")[0:2]) @@ -309,7 +280,7 @@ def getSquishPath(mkspec, qmakev): if testData.field(record, "qtversion") == qmakev and testData.field(record, "mkspec") == mkspec: path = os.path.expanduser(testData.field(record, "path")) break - if not os.path.exists(path): + if path == None or not os.path.exists(path): test.warning("Path '%s' from fallback test data file does not exist!" % path, "See the README file how to set up your environment.") return None diff --git a/tests/system/shared/project_explorer.py b/tests/system/shared/project_explorer.py index 022727b3123..794ece68b51 100644 --- a/tests/system/shared/project_explorer.py +++ b/tests/system/shared/project_explorer.py @@ -35,30 +35,14 @@ def prepareBuildSettings(targetCount, currentTarget, setReleaseBuild=True, disab for current in range(targetCount): if setForAll or current == currentTarget: switchToBuildOrRunSettingsFor(targetCount, current, ProjectSettings.BUILD) - qtCombo = waitForObject(":scrollArea.qtVersionComboBox_QComboBox") - chooseThis = None - wait = False - try: - if qtCombo.currentText != defaultQtVersion: - selectFromCombo(qtCombo, defaultQtVersion) - if setReleaseBuild: - chooseThis = "%s Release" % defaultQtVersion - else: - chooseThis = "%s Debug" % defaultQtVersion - editBuildCfg = waitForObject("{container={type='QScrollArea' name='scrollArea'} " - "leftWidget={container={type='QScrollArea' name='scrollArea'} " - "text='Edit build configuration:' type='QLabel'}" - "unnamed='1' type='QComboBox' visible='1'}", 20000) - if editBuildCfg.currentText != chooseThis: - wait = True - clickItem(editBuildCfg, chooseThis.replace(".", "\\."), 5, 5, 0, Qt.LeftButton) - else: - wait = False - except: - if current == currentTarget: - success = False - if wait and chooseThis != None: - waitFor("editBuildCfg.currentText==chooseThis") + # TODO: Improve selection of Release/Debug version + if setReleaseBuild: + chooseThis = "Release" + else: + chooseThis = "Debug" + editBuildCfg = waitForObject("{leftWidget={text='Edit build configuration:' type='QLabel' " + "unnamed='1' visible='1'} unnamed='1' type='QComboBox' visible='1'}", 20000) + selectFromCombo(editBuildCfg, chooseThis) ensureChecked("{name='shadowBuildCheckBox' type='QCheckBox' visible='1'}", not disableShadowBuild) # get back to the current target if currentTarget < 0 or currentTarget >= targetCount: @@ -117,3 +101,78 @@ def setRunInTerminal(targetCount, currentTarget, runInTerminal=True): ensureChecked("{window=':Qt Creator_Core::Internal::MainWindow' text='Run in terminal'\ type='QCheckBox' unnamed='1' visible='1'}", runInTerminal) switchViewTo(ViewConstants.EDIT) + +# helper function to get some Qt information for the current (already configured) project +# param alreadyOnProjectsBuildSettings if set to True you have to make sure that you're +# on the Projects view on the Build settings page (otherwise this function will end +# up in a ScriptError) +# param afterSwitchTo if you want to leave the Projects view/Build settings when returning +# from this function you can set this parameter to one of the ViewConstants +# this function returns an array of 4 elements (all could be None): +# * the first element holds the Qt version +# * the second element holds the mkspec +# * the third element holds the Qt bin path +# * the fourth element holds the Qt lib path +# of the current active project +def getQtInformationForBuildSettings(alreadyOnProjectsBuildSettings=False, afterSwitchTo=None): + if not alreadyOnProjectsBuildSettings: + switchViewTo(ViewConstants.PROJECTS) + switchToBuildOrRunSettingsFor(1, 0, ProjectSettings.BUILD) + clickButton(waitForObject(":Qt Creator_SystemSettings.Details_Utils::DetailsButton")) + model = waitForObject(":scrollArea_QTableView").model() + qtDir = None + for row in range(model.rowCount()): + index = model.index(row, 0) + text = str(model.data(index).toString()) + if text == "QTDIR": + qtDir = str(model.data(model.index(row, 1)).toString()) + break + if qtDir == None: + test.fatal("UI seems to have changed - couldn't get QTDIR for this configuration.") + return None, None, None, None + + qmakeCallLabel = waitForObject("{text?='qmake: qmake*' type='QLabel' unnamed='1' visible='1' " + "window=':Qt Creator_Core::Internal::MainWindow'}") + mkspec = __getMkspecFromQMakeCall__(str(qmakeCallLabel.text)) + qtVersion = getQtInformationByQMakeCall(qtDir, QtInformation.QT_VERSION) + qtLibPath = getQtInformationByQMakeCall(qtDir, QtInformation.QT_LIBPATH) + qtBinPath = getQtInformationByQMakeCall(qtDir, QtInformation.QT_BINPATH) + if afterSwitchTo: + if ViewConstants.WELCOME <= afterSwitchTo <= ViewConstans.LAST_AVAILABLE: + switchViewTo(afterSwitchTo) + else: + test.warning("Don't know where you trying to switch to (%s)" % afterSwitchTo) + return qtVersion, mkspec, qtBinPath, qtLibPath + +def __getMkspecFromQMakeCall__(qmakeCall): + qCall = qmakeCall.split("")[1].strip() + tmp = qCall.split() + for i in range(len(tmp)): + if tmp[i] == '-spec' and i + 1 < len(tmp): + return tmp[i + 1] + test.fatal("Couldn't get mkspec from qmake call '%s'" % qmakeCall) + return None + +# this function queries information from qmake +# param qtDir set this to a path that holds a valid Qt +# param which set this to one of the QtInformation "constants" +# the function will return the wanted information or None if something went wrong +def getQtInformationByQMakeCall(qtDir, which): + qmake = os.path.join(qtDir, "bin", "qmake") + if platform.system() in ('Microsoft', 'Windows'): + qmake += ".exe" + if not os.path.exists(qmake): + test.fatal("Given Qt directory does not exist or does not contain bin/qmake.", + "Constructed path: '%s'" % qmake) + return None + query = "" + if which == QtInformation.QT_VERSION: + query = "QT_VERSION" + elif which == QtInformation.QT_BINPATH: + query = "QT_INSTALL_BINS" + elif which == QtInformation.QT_LIBPATH: + query = "QT_INSTALL_LIBS" + else: + test.fatal("You're trying to fetch an unknown information (%s)" % which) + return None + return getOutputFromCmdline("%s -query %s" % (qmake, query)).strip()