Commit aa3a2dc9 authored by Christian Stenger's avatar Christian Stenger
Browse files

Squish: Added debug test case



This is intended to be a starting point.

Change-Id: I0941ed16876810832aa6088287f8062bba6a273e
Reviewed-by: default avatarRobert Löhning <robert.loehning@nokia.com>
parent 29062c64
:*Qt Creator.Build Project_Core::Internal::FancyToolButton {text='Build Project' type='Core::Internal::FancyToolButton' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
:*Qt Creator.Continue_Core::Internal::FancyToolButton {text='Continue' type='Core::Internal::FancyToolButton' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
:*Qt Creator.Interrupt_Core::Internal::FancyToolButton {text='Interrupt' type='Core::Internal::FancyToolButton' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
:*Qt Creator.Run_Core::Internal::FancyToolButton {text='Run' type='Core::Internal::FancyToolButton' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
:*Qt Creator.Start Debugging_Core::Internal::FancyToolButton {text='Start Debugging' type='Core::Internal::FancyToolButton' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
:*Qt Creator.findEdit_Utils::FilterLineEdit {name='findEdit' type='Utils::FilterLineEdit' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
:*Qt Creator.qt_tabwidget_stackedwidget_QStackedWidget {name='qt_tabwidget_stackedwidget' type='QStackedWidget' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
:*Qt Creator_Core::Internal::FancyToolButton {occurrence='3' type='Core::Internal::FancyToolButton' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
......@@ -12,6 +15,12 @@
: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'}
:DebugModeWidget.Debugger Toolbar_QDockWidget {container=':Qt Creator.DebugModeWidget_QSplitter' name='Debugger Toolbar' type='QDockWidget' visible='1' windowTitle='Debugger Toolbar'}
:DebugModeWidget.OK_QPushButton {container=':Qt Creator.DebugModeWidget_QSplitter' text='OK' type='QPushButton' unnamed='1' visible='1'}
: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='Exit Debugger' type='QToolButton' unnamed='1' visible='1'}
:Debugger Toolbar.StatusText_Utils::StatusLabel {container=':DebugModeWidget.Debugger Toolbar_QDockWidget' type='Utils::StatusLabel' unnamed='1'}
: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'}
:New.templateCategoryView_QTreeView {name='templateCategoryView' type='QTreeView' visible='1' window=':New_Core::Internal::NewDialog'}
......@@ -57,6 +66,7 @@
: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.Details_Utils::DetailsButton {container=':Qt Creator.scrollArea_QScrollArea' text='Details' type='Utils::DetailsButton' 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'}
:scrollArea.Edit build configuration:_QLabel {container=':Qt Creator.scrollArea_QScrollArea' text='Edit build configuration:' type='QLabel' unnamed='1' visible='1'}
:scrollArea.Qt 4 for Desktop - (Qt SDK) debug_QCheckBox {container=':Qt Gui Application.scrollArea_QScrollArea' text?='*Qt 4.* for *(Qt SDK) debug' type='QCheckBox' unnamed='1' visible='1'}
......
......@@ -163,3 +163,25 @@ def selectBuildConfig(targetCount, currentTarget, configName):
waitForSignal("{type='CppTools::Internal::CppModelManager' unnamed='1'}",
"sourceFilesRefreshed(QStringList)")
switchViewTo(ViewConstants.EDIT)
def verifyBuildConfig(targetCount, currentTarget, shouldBeDebug=False, enableShadowBuild=False):
switchViewTo(ViewConstants.PROJECTS)
switchToBuildOrRunSettingsFor(targetCount, currentTarget, ProjectSettings.BUILD)
detailsButton = waitForObject(":scrollArea.Details_Utils::DetailsButton")
ensureChecked(detailsButton)
ensureChecked("{name='shadowBuildCheckBox' type='QCheckBox' visible='1'}", enableShadowBuild)
buildCfCombo = waitForObject("{type='QComboBox' name='buildConfigurationComboBox' visible='1' "
"container=':Qt Creator.scrollArea_QScrollArea'}")
if shouldBeDebug:
test.compare(buildCfCombo.currentText, 'Debug', "Verifying whether it's a debug build")
else:
test.compare(buildCfCombo.currentText, 'Release', "Verifying whether it's a release build")
try:
problemFound = waitForObject("{container=':Qt Creator.scrollArea_QScrollArea' type='QLabel' "
"name='problemLabel' visible='1'}", 1000)
if problemFound:
test.warning('%s' % problemFound.text)
except:
pass
clickButton(detailsButton)
switchViewTo(ViewConstants.EDIT)
import re
def handleDebuggerWarnings(config):
if "MSVC" in config:
try:
......@@ -31,3 +33,187 @@ def takeDebuggerLog():
waitFor("str(debuggerLogWindow.plainText)==''", 5000)
invokeMenuItem("Window", "Views", "Debugger Log")
return debuggerLog
# function to set breakpoints for the current project
# on the given file,line pairs inside the given dict
# the lines are treated as regular expression
def setBreakpointsForCurrentProject(filesAndLines):
# internal helper for setBreakpointsForCurrentProject
# double clicks the treeElement inside the given navTree
# TODO: merge with doubleClickFile() from tst_qml_editor & move to utils(?)
def __doubleClickFile__(navTree, treeElement):
waitForObjectItem(navTree, treeElement)
fileNamePattern = re.compile(".*\.(?P<file>(.*\\\..*)?)$")
fileName = fileNamePattern.search(treeElement).group("file").replace("\\.", ".")
doubleClickItem(navTree, treeElement, 5, 5, 0, Qt.LeftButton)
mainWindow = waitForObject(":Qt Creator_Core::Internal::MainWindow")
waitFor('fileName in str(mainWindow.windowTitle)', 5000)
return fileName
switchViewTo(ViewConstants.DEBUG)
removeOldBreakpoints()
if not filesAndLines or not isinstance(filesAndLines, dict):
test.fatal("This function only takes a non-empty dict.")
return False
navTree = waitForObject("{type='Utils::NavigationTreeView' unnamed='1' visible='1' "
"window=':Qt Creator_Core::Internal::MainWindow'}", 20000)
for curFile,curLine in filesAndLines.iteritems():
fName = __doubleClickFile__(navTree, curFile)
editor = getEditorForFileSuffix(curFile)
if not placeCursorToLine(editor, curLine, True):
return False
invokeMenuItem("Debug", "Toggle Breakpoint")
test.log('Set breakpoint in %s' % fName, curLine)
breakPointTreeView = waitForObject("{type='Debugger::Internal::BreakWindow' visible='1' "
"windowTitle='Breakpoints' name='Debugger.Docks.Break'}")
waitFor("breakPointTreeView.model().rowCount() == len(filesAndLines)", 2000)
test.compare(breakPointTreeView.model().rowCount(), len(filesAndLines),
'Expected %d set break points, found %d listed' %
(len(filesAndLines), breakPointTreeView.model().rowCount()))
return True
# helper that removes all breakpoints - assumes that it's getting called
# being already on Debug view and Breakpoints widget is not disabled
def removeOldBreakpoints():
test.log("Removing old breakpoints if there are any")
try:
breakPointTreeView = waitForObject("{type='Debugger::Internal::BreakWindow' visible='1' "
"windowTitle='Breakpoints' name='Debugger.Docks.Break'}")
model = breakPointTreeView.model()
if model.rowCount()==0:
test.log("No breakpoints found...")
else:
test.log("Found %d breakpoints - removing them" % model.rowCount())
for row in range(model.rowCount()):
currentIndex = model.index(row,0)
rect = breakPointTreeView.visualRect(currentIndex)
mouseClick(breakPointTreeView, rect.x+5, rect.y+5, 0, Qt.LeftButton)
type(breakPointTreeView, "<Delete>")
except LookupError:
pass
return test.compare(model.rowCount(), 0, "Check if all breakpoints have been removed.")
# function to do simple debugging of the current (configured) project
# param pressContinueCount defines how often it is expected to press
# the 'Continue' button while debugging
# param expectedBPOrder holds a list of dicts where the dicts contain always
# only 1 key:value pair - the key is the name of the file, the value is
# line number where the debugger should stop
def doSimpleDebugging(currentConfigName, pressContinueCount=1, expectedBPOrder=[]):
expectedLabelTexts = ['Stopped\.', 'Stopped at breakpoint \d+ \(\d+\) in thread \d+\.']
if len(expectedBPOrder) == 0:
expectedLabelTexts.append("Running\.")
if not __startDebugger__(currentConfigName):
return False
statusLabel = findObject(":Debugger Toolbar.StatusText_Utils::StatusLabel")
test.log("Continuing debugging %d times..." % pressContinueCount)
for i in range(pressContinueCount):
if waitFor("regexVerify(str(statusLabel.text), expectedLabelTexts)", 20000):
verifyBreakPoint(expectedBPOrder[i])
else:
test.fail('%s' % str(statusLabel.text))
contDbg = waitForObject(":*Qt Creator.Continue_Core::Internal::FancyToolButton", 3000)
test.log("Continuing...")
clickButton(contDbg)
waitFor("str(statusLabel.text) == 'Running.'", 5000)
timedOut = not waitFor("str(statusLabel.text) in ['Running.', 'Debugger finished.']", 30000)
if timedOut:
test.log("Waiting for 'Running.' / 'Debugger finished.' timed out.",
"Debugger is in state: '%s'..." % statusLabel.text)
if str(statusLabel.text) == 'Running.':
test.log("Debugger is still running... Will be stopped.")
return __stopDebugger__()
elif str(statusLabel.text) == 'Debugger finished.':
test.log("Debugger has finished.")
return __logDebugResult__()
else:
test.log("Trying to stop debugger...")
try:
return __stopDebugger__()
except:
# if stopping failed - debugger had already stopped
return True
def __startDebugger__(config):
clickButton(waitForObject(":*Qt Creator.Start Debugging_Core::Internal::FancyToolButton"))
handleDebuggerWarnings(config)
hasNotTimedOut = waitFor("object.exists(':Debugger Toolbar.Continue_QToolButton')", 20000)
try:
mBox = findObject(":Failed to start application_QMessageBox")
mBoxText = mBox.text
mBoxIText = mBox.informativeText
clickButton(":DebugModeWidget.OK_QPushButton")
test.fail("Debugger hasn't started... QMessageBox appeared!")
test.log("QMessageBox content: '%s'" % mBoxText,
"'%s'" % mBoxIText)
return False
except:
pass
if hasNotTimedOut:
test.passes("Debugger started...")
else:
test.fail("Debugger seems to have not started...")
if "MSVC" in config:
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.")
logApplicationOutput()
return False
try:
waitForObject(":*Qt Creator.Interrupt_Core::Internal::FancyToolButton", 3000)
test.passes("'Interrupt' (debugger) button visible.")
except:
try:
waitForObject(":*Qt Creator.Continue_Core::Internal::FancyToolButton", 3000)
test.passes("'Continue' (debugger) button visible.")
except:
test.fatal("Neither 'Interrupt' nor 'Continue' button visible (Debugger).")
return True
def __stopDebugger__():
clickButton(waitForObject(":Debugger Toolbar.Exit Debugger_QToolButton"))
ensureChecked("{type='Core::Internal::OutputPaneToggleButton' unnamed='1' visible='1' "
"window=':Qt Creator_Core::Internal::MainWindow' occurrence='3'}")
output = waitForObject("{type='Core::OutputWindow' visible='1' windowTitle='Application Output Window'}", 20000)
waitFor("'Debugging has finished' in str(output.plainText)", 20000)
return __logDebugResult__()
def __logDebugResult__():
try:
result = waitForObject(":*Qt Creator.Start Debugging_Core::Internal::FancyToolButton")
test.passes("'Start Debugging' button visible.")
except:
test.fail("'Start Debugging' button is not visible.")
result = None
if result:
test.passes("Debugger stopped.. Qt Creator is back at normal state.")
else:
test.fail("Debugger seems to have not stopped...")
logApplicationOutput()
return result
def verifyBreakPoint(bpToVerify):
if isinstance(bpToVerify, dict):
fileName = bpToVerify.keys()[0]
editor = getEditorForFileSuffix(fileName)
if editor == None:
return False
textPos = editor.textCursor().position()
line = str(editor.plainText)[:textPos].count("\n") + 1
windowTitle = str(waitForObject(":Qt Creator_Core::Internal::MainWindow").windowTitle)
if fileName in windowTitle:
test.passes("Creator's window title changed according to current file")
else:
test.fail("Creator's window title did not change according to current file")
if line == bpToVerify.values()[0]:
test.passes("Breakpoint at expected line (%d) inside expected file (%s)"
% (line, fileName))
return True
else:
test.fail("Breakpoint did not match expected line/file",
"Found: %d in %s" % (line, fileName))
else:
test.fatal("Expected a dict for bpToVerify - got '%s'" % className(bpToVerify))
return False
source("../../shared/qtcreator.py")
workingDir = None
def main():
global workingDir
startApplication("qtcreator" + SettingsPath)
if not checkDebuggingLibrary("4.8.0", [QtQuickConstants.Targets.DESKTOP]):
test.fatal("Error while checking debugging libraries - leaving this test.")
invokeMenuItem("File", "Exit")
return
# using a temporary directory won't mess up a potentially existing
workingDir = tempDir()
projectName = createNewQtQuickApplication(workingDir, targets = QtQuickConstants.Targets.DESKTOP)
# wait for parsing to complete
waitForSignal("{type='CppTools::Internal::CppModelManager' unnamed='1'}",
"sourceFilesRefreshed(QStringList)")
editor = waitForObject("{type='QmlJSEditor::QmlJSTextEditorWidget' unnamed='1' "
"visible='1' window=':Qt Creator_Core::Internal::MainWindow'}")
if placeCursorToLine(editor, "MouseArea.*", True):
type(editor, '<Up>')
type(editor, '<Return>')
type(editor, 'Component.onCompleted: console.log("Break here")')
invokeMenuItem("File", "Save All")
filesAndLines = {
"%s.QML.qml/%s.main\\.qml" % (projectName,projectName) : 'Component.onCompleted.*',
"%s.Sources.main\\.cpp" % projectName : "viewer.setOrientation\\(.+\\);"
}
test.log("Setting breakpoints")
result = setBreakpointsForCurrentProject(filesAndLines)
if result:
expectedBreakpointsOrder = [{"main.cpp":9}, {"main.qml":11}]
availableConfigs = iterateBuildConfigs(1, 0, ".*4\.8(\.\d+)?.*$(?<![Rr]elease)")
if not availableConfigs:
test.fatal("Haven't found a suitable Qt version (need Qt >= 4.8) - leaving without debugging.")
for config in availableConfigs:
test.log("Selecting '%s' as build config" % config)
selectBuildConfig(1, 0, config)
verifyBuildConfig(1, 0, True)
# explicitly build before start debugging for adding the executable as allowed program to WinFW
invokeMenuItem("Build", "Rebuild All")
waitForSignal("{type='ProjectExplorer::BuildManager' unnamed='1'}",
"buildQueueFinished(bool)", 300000)
if not checkCompile():
test.fatal("Compile had errors... Skipping current build config")
continue
allowAppThroughWinFW(workingDir, projectName, False)
if not doSimpleDebugging(config, 2, expectedBreakpointsOrder):
try:
stopB = findObject(':Qt Creator.Stop_QToolButton')
if stopB.enabled:
clickButton(stopB)
except:
pass
deleteAppFromWinFW(workingDir, projectName, False)
# close application output window of current run to avoid mixing older output on the next run
ensureChecked(":Qt Creator_AppOutput_Core::Internal::OutputPaneToggleButton")
clickButton(waitForObject("{type='CloseButton' unnamed='1' visible='1' "
"window=':Qt Creator_Core::Internal::MainWindow'}"))
else:
test.fatal("Setting breakpoints failed - leaving without testing.")
invokeMenuItem("File", "Exit")
Markdown is supported
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