diff --git a/tests/system/objects.map b/tests/system/objects.map index 563969df75d..54a66f749ab 100644 --- a/tests/system/objects.map +++ b/tests/system/objects.map @@ -11,6 +11,7 @@ :CMake Wizard.Next_QPushButton {name='__qt__passive_wizardbutton1' text~='(Next.*|Continue)' type='QPushButton' visible='1' window=':CMake Wizard_CMakeProjectManager::Internal::CMakeOpenProjectWizard'} :CMake Wizard.Run CMake_QPushButton {text='Run CMake' type='QPushButton' unnamed='1' visible='1' window=':CMake Wizard_CMakeProjectManager::Internal::CMakeOpenProjectWizard'} :CMake Wizard_CMakeProjectManager::Internal::CMakeOpenProjectWizard {type='CMakeProjectManager::Internal::CMakeOpenProjectWizard' unnamed='1' visible='1' windowTitle='CMake Wizard'} +:DebugModeWidget.Debugger Log_QDockWidget {container=':Qt Creator.DebugModeWidget_QSplitter' name='Debugger.Docks.Output' type='QDockWidget' visible='1' windowTitle='Debugger Log'} :Generator:_QComboBox {buddy=':CMake Wizard.Generator:_QLabel' type='QComboBox' unnamed='1' visible='1'} :New.templateCategoryView_QTreeView {name='templateCategoryView' type='QTreeView' visible='1' window=':New_Core::Internal::NewDialog'} :New.templatesView_QListView {name='templatesView' type='QListView' visible='1' window=':New_Core::Internal::NewDialog'} @@ -22,11 +23,13 @@ :Options_QListView {type='QListView' unnamed='1' visible='1' window=':Options_Core::Internal::SettingsDialog'} :Project Setup.scrollArea_QScrollArea {name='scrollArea' type='QScrollArea' visible='1' window=':Project Setup_Qt4ProjectManager::Internal::ProjectLoadWizard'} :Project Setup_Qt4ProjectManager::Internal::ProjectLoadWizard {type='Qt4ProjectManager::Internal::ProjectLoadWizard' unnamed='1' visible='1' windowTitle='Project Setup'} +:Qt Creator.DebugModeWidget_QSplitter {name='DebugModeWidget' type='QSplitter' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} :Qt Creator.QtCreator.MenuBar_QMenuBar {name='QtCreator.MenuBar' type='QMenuBar' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} :Qt Creator.ReRun_QToolButton {toolTip='Re-run this run-configuration' type='QToolButton' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} :Qt Creator.Stop_QToolButton {text='Stop' type='QToolButton' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} :Qt Creator.scrollArea_QScrollArea {name='scrollArea' type='QScrollArea' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} :Qt Creator_AppOutput_Core::Internal::OutputPaneToggleButton {occurrence='3' type='Core::Internal::OutputPaneToggleButton' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} +:Qt Creator_CloseButton {type='CloseButton' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} :Qt Creator_Core::Internal::MainWindow {type='Core::Internal::MainWindow' visible='1' windowTitle?='*Qt Creator'} :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'} @@ -40,6 +43,7 @@ :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'} +: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'} diff --git a/tests/system/shared/debugger.py b/tests/system/shared/debugger.py new file mode 100644 index 00000000000..6ddb2a68eeb --- /dev/null +++ b/tests/system/shared/debugger.py @@ -0,0 +1,33 @@ +def handleDebuggerWarnings(config): + if "MSVC" in config: + try: + popup = waitForObject("{text?='*' type='QLabel' unnamed='1' visible='1' window=':Symbol Server_Utils::CheckableMessageBox'}", 10000) + symServerNotConfiged = ("

The debugger is not configured to use the public " + "Microsoft Symbol Server. " + "This is recommended for retrieval of the symbols of the operating system libraries.

" + "

Note: A fast internet connection is required for this to work smoothly. " + "Also, a delay might occur when connecting for the first time.

" + "

Would you like to set it up?


") + if popup.text == symServerNotConfiged: + test.log("Creator warned about the debugger not being configured to use the public Microsoft Symbol Server.") + else: + test.warning("Creator showed an unexpected warning: " + str(popup.text)) + clickButton(waitForObject("{text='No' type='QPushButton' unnamed='1' visible='1' window=':Symbol Server_Utils::CheckableMessageBox'}", 10000)) + except LookupError: + pass # No warning. Fine. + else: + if "Release" in config and platform.system() != "Darwin": + message = waitForObject("{container=':Qt Creator.DebugModeWidget_QSplitter' name='qt_msgbox_label' type='QLabel' visible='1'}", 20000) + test.compare(message.text, "This does not seem to be a \"Debug\" build.\nSetting breakpoints by file name and line number may fail.") + clickButton("{container=':Qt Creator.DebugModeWidget_QSplitter' text='OK' type='QPushButton' unnamed='1' visible='1'}") + +def takeDebuggerLog(): + invokeMenuItem("Window", "Views", "Debugger Log") + debuggerLogWindow = waitForObject("{container=':DebugModeWidget.Debugger Log_QDockWidget' type='Debugger::Internal::CombinedPane' unnamed='1' visible='1'}", 20000) + debuggerLog = str(debuggerLogWindow.plainText) + mouseClick(debuggerLogWindow, 5, 5, 0, Qt.LeftButton) + activateItem(waitForObjectItem(openContextMenuOnTextCursorPosition(debuggerLogWindow), + "Clear Contents")) + waitFor("str(debuggerLogWindow.plainText)==''", 5000) + invokeMenuItem("Window", "Views", "Debugger Log") + return debuggerLog diff --git a/tests/system/shared/project.py b/tests/system/shared/project.py index d855ff33e3d..7818cf8af4f 100644 --- a/tests/system/shared/project.py +++ b/tests/system/shared/project.py @@ -164,7 +164,13 @@ def createProject_Qt_GUI(path, projectName, qtVersion = None, checks = True): waitForSignal("{type='CppTools::Internal::CppModelManager' unnamed='1'}", "sourceFilesRefreshed(QStringList)", 20000) __verifyFileCreation__(path, expectedFiles) -def createProject_Qt_Console(path, projectName, qtVersion, checks): +# Creates a Qt Console project +# param path specifies where to create the project +# param projectName is the name for the new project +# param qtVersion is the name of a Qt version. In the project, build configurations will be +# created for this version. If it is None, all Qt versions will be used +# param checks turns tests in the function on if set to True +def createProject_Qt_Console(path, projectName, qtVersion = None, checks = True): __createProjectSelectType__("Other Qt Project", "Qt Console Application") __createProjectSetNameAndPath__(path, projectName, checks) __selectQtVersionDesktop__(qtVersion, checks) diff --git a/tests/system/shared/qtcreator.py b/tests/system/shared/qtcreator.py index 564e0331249..7e7841afafd 100644 --- a/tests/system/shared/qtcreator.py +++ b/tests/system/shared/qtcreator.py @@ -21,6 +21,7 @@ source("../../shared/project.py") source("../../shared/editor_utils.py") source("../../shared/project_explorer.py") source("../../shared/hook_utils.py") +source("../../shared/debugger.py") def waitForCleanShutdown(timeOut=10): appCtxt = currentApplicationContext() diff --git a/tests/system/shared/utils.py b/tests/system/shared/utils.py index 34c8a443138..e5b12f6a524 100644 --- a/tests/system/shared/utils.py +++ b/tests/system/shared/utils.py @@ -221,3 +221,10 @@ def addHelpDocumentationFromSDK(): clickButton(waitForObject("{type='QPushButton' name='addButton' visible='1' text='Add...'}")) selectFromFileDialog("%s/Documentation/qt.qch" % sdkPath) clickButton(waitForObject(":Options.OK_QPushButton")) + +def verifyOutput(string, substring, outputFrom, outputIn): + index = string.find(substring) + if (index == -1): + test.fail("Output from " + outputFrom + " could not be found in " + outputIn) + else: + test.passes("Output from " + outputFrom + " found at position " + str(index) + " of " + outputIn) diff --git a/tests/system/suite_debugger/suite.conf b/tests/system/suite_debugger/suite.conf index 441033d6127..d776d72c7a0 100644 --- a/tests/system/suite_debugger/suite.conf +++ b/tests/system/suite_debugger/suite.conf @@ -7,6 +7,6 @@ HOOK_SUB_PROCESSES=false IMPLICITAUTSTART=0 LANGUAGE=Python OBJECTMAP=../objects.map -TEST_CASES=tst_build_new_project +TEST_CASES=tst_build_new_project tst_cli_output_console VERSION=2 WRAPPERS=Qt diff --git a/tests/system/suite_debugger/tst_cli_output_console/test.py b/tests/system/suite_debugger/tst_cli_output_console/test.py new file mode 100644 index 00000000000..7ae75ddc5e5 --- /dev/null +++ b/tests/system/suite_debugger/tst_cli_output_console/test.py @@ -0,0 +1,89 @@ +source("../../shared/qtcreator.py") + +projectsPath = tempDir() +project = "untitled" + +def __handlerunControlFinished__(object, runControlP): + global runControlFinished + runControlFinished = True + +def main(): + global runControlFinished + outputQDebug = "Output from qDebug()." + outputStdOut = "Output from std::cout." + outputStdErr = "Output from std::cerr." + startApplication("qtcreator" + SettingsPath) + installLazySignalHandler("{type='ProjectExplorer::Internal::ProjectExplorerPlugin' unnamed='1'}", + "runControlFinished(ProjectExplorer::RunControl*)", "__handlerunControlFinished__") + createProject_Qt_Console(projectsPath, project) + + mainEditor = waitForObject(":Qt Creator_CppEditor::Internal::CPPEditorWidget") + replaceEditorContent(mainEditor, "") + typeLines(mainEditor, ["#include ", + "#include ", + "int main(int, char *argv[])", + "{", + ' std::cout << \"' + outputStdOut + '\" << std::endl;', + ' std::cerr << \"' + outputStdErr + '\" << std::endl;', + ' qDebug() << \"' + outputQDebug + '\";']) + # Rely on code completion for closing bracket + invokeMenuItem("File", "Save All") + selectFromLocator(project + ".pro") + proEditor = waitForObject("{type='Qt4ProjectManager::Internal::ProFileEditorWidget' unnamed='1' visible='1'" + "window=':Qt Creator_Core::Internal::MainWindow'}", 20000) + test.verify("CONFIG += console" in str(proEditor.plainText), "Verifying that program is configured with console") + setRunInTerminal(1, 0, False) + + for config in iterateBuildConfigs(1, 0): + selectBuildConfig(1, 0, config) + test.log("Testing build configuration: " + config) + + test.log("Running application") + runControlFinished = False + clickButton(waitForObject("{type='Core::Internal::FancyToolButton' text='Run' visible='1'}", 20000)) + waitFor("runControlFinished==True") + appOutput = str(waitForObject("{type='Core::OutputWindow' unnamed='1' visible='1'}", 20000).plainText) + verifyOutput(appOutput, outputStdOut, "std::cout", "Application Output") + verifyOutput(appOutput, outputStdErr, "std::cerr", "Application Output") + verifyOutput(appOutput, outputQDebug, "qDebug()", "Application Output") + clickButton(waitForObject(":Qt Creator_CloseButton")) + + test.log("Debugging application") + runControlFinished = False + invokeMenuItem("Debug", "Start Debugging", "Start Debugging") + if "Release" in config and platform.system() == "Linux": + snooze(1) # work around QTCREATORBUG-6853 + handleDebuggerWarnings(config) + waitFor("runControlFinished==True") + try: + debuggerLog = takeDebuggerLog() + if not "MSVC" in config: + # cout works with MSVC, too, but we don't check it since it's not supported + verifyOutput(debuggerLog, outputStdOut, "std::cout", "Debugger Log") + verifyOutput(debuggerLog, outputStdErr, "std::cerr", "Debugger Log") + verifyOutput(debuggerLog, outputQDebug, "qDebug()", "Debugger Log") + except LookupError: + # takeDebuggerLog() expects the debugger log to not be visible. + # If debugger log showed up automatically, previous call to takeDebuggerLog() has closed it. + debuggerLog = takeDebuggerLog() + if "lib\qtcreatorcdbext64\qtcreatorcdbext.dll cannot be found." in debuggerLog: + test.fatal("qtcreatorcdbext.dll is missing in lib\qtcreatorcdbext64") + else: + test.fatal("Debugger log did not behave as expected. Please check manually.") + switchViewTo(ViewConstants.EDIT) + appOutput = str(waitForObject("{type='Core::OutputWindow' unnamed='1' visible='1'}", 20000).plainText) + if not "MSVC" in config: + verifyOutput(appOutput, outputStdOut, "std::cout", "Application Output") + verifyOutput(appOutput, outputStdErr, "std::cerr", "Application Output") + verifyOutput(appOutput, outputQDebug, "qDebug()", "Application Output") + clickButton(waitForObject(":Qt Creator_CloseButton")) + + invokeMenuItem("File", "Exit") + waitForCleanShutdown() + +def init(): + cleanup() + +def cleanup(): + deleteDirIfExists(projectsPath + os.sep + project) + deleteDirIfExists(shadowBuildDir(projectsPath, project, defaultQtVersion, 1))