| 
									
										
										
										
											2012-01-17 13:47:47 +01:00
										 |  |  | import re; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-01 14:09:25 +02:00
										 |  |  | # dictionary to hold a list of all installed handler functions for all object-signalSignature pairs | 
					
						
							|  |  |  | installedSignalHandlers = {} | 
					
						
							|  |  |  | # flag to indicate whether overrideInstallLazySignalHandler() has been called already | 
					
						
							|  |  |  | overridenInstallLazySignalHandlers = False | 
					
						
							|  |  |  | # flag to indicate whether a tasks file should be created when building ends with errors | 
					
						
							|  |  |  | createTasksFileOnError = True | 
					
						
							|  |  |  | # currently used directory for tasks files | 
					
						
							|  |  |  | tasksFileDir = None | 
					
						
							|  |  |  | # counter for written tasks files | 
					
						
							|  |  |  | tasksFileCount = 0 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # call this function to override installLazySignalHandler() | 
					
						
							|  |  |  | def overrideInstallLazySignalHandler(): | 
					
						
							|  |  |  |     global overridenInstallLazySignalHandlers | 
					
						
							|  |  |  |     if overridenInstallLazySignalHandlers: | 
					
						
							|  |  |  |         return | 
					
						
							|  |  |  |     overridenInstallLazySignalHandlers = True | 
					
						
							|  |  |  |     global installLazySignalHandler | 
					
						
							| 
									
										
										
										
											2011-09-21 17:29:18 +02:00
										 |  |  |     installLazySignalHandler = __addSignalHandlerDict__(installLazySignalHandler) | 
					
						
							| 
									
										
										
										
											2011-09-01 14:09:25 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | # avoids adding a handler to a signal twice or more often | 
					
						
							|  |  |  | # do not call this function directly - use overrideInstallLazySignalHandler() instead | 
					
						
							| 
									
										
										
										
											2011-09-21 17:29:18 +02:00
										 |  |  | def __addSignalHandlerDict__(lazySignalHandlerFunction): | 
					
						
							| 
									
										
										
										
											2011-09-01 14:09:25 +02:00
										 |  |  |     global installedSignalHandlers | 
					
						
							|  |  |  |     def wrappedFunction(name, signalSignature, handlerFunctionName): | 
					
						
							|  |  |  |         handlers = installedSignalHandlers.get("%s____%s" % (name,signalSignature)) | 
					
						
							|  |  |  |         if handlers == None: | 
					
						
							|  |  |  |             lazySignalHandlerFunction(name, signalSignature, handlerFunctionName) | 
					
						
							|  |  |  |             installedSignalHandlers.setdefault("%s____%s" % (name,signalSignature), [handlerFunctionName]) | 
					
						
							|  |  |  |         else: | 
					
						
							| 
									
										
										
										
											2012-02-22 15:43:05 +01:00
										 |  |  |             if not handlerFunctionName in handlers: | 
					
						
							| 
									
										
										
										
											2011-09-01 14:09:25 +02:00
										 |  |  |                 lazySignalHandlerFunction(name, signalSignature, handlerFunctionName) | 
					
						
							|  |  |  |                 handlers.append(handlerFunctionName) | 
					
						
							|  |  |  |                 installedSignalHandlers.setdefault("%s____%s" % (name,signalSignature), handlers) | 
					
						
							|  |  |  |     return wrappedFunction | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # returns the currently assigned handler functions for a given object and signal | 
					
						
							|  |  |  | def getInstalledSignalHandlers(name, signalSignature): | 
					
						
							|  |  |  |     return installedSignalHandlers.get("%s____%s" % (name,signalSignature)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # this method checks the last build (if there's one) and logs the number of errors, warnings and | 
					
						
							| 
									
										
										
										
											2011-10-06 13:55:05 +02:00
										 |  |  | # lines within the Issues output | 
					
						
							| 
									
										
										
										
											2011-09-01 14:09:25 +02:00
										 |  |  | # optional parameter can be used to tell this function if the build was expected to fail or not | 
					
						
							|  |  |  | def checkLastBuild(expectedToFail=False): | 
					
						
							|  |  |  |     try: | 
					
						
							|  |  |  |         # can't use waitForObject() 'cause visible is always 0 | 
					
						
							|  |  |  |         buildProg = findObject("{type='ProjectExplorer::Internal::BuildProgress' unnamed='1' }") | 
					
						
							|  |  |  |     except LookupError: | 
					
						
							|  |  |  |         test.log("checkLastBuild called without a build") | 
					
						
							|  |  |  |         return | 
					
						
							|  |  |  |     # get labels for errors and warnings | 
					
						
							|  |  |  |     children = object.children(buildProg) | 
					
						
							|  |  |  |     if len(children)<4: | 
					
						
							|  |  |  |         test.fatal("Leaving checkLastBuild()", "Referred code seems to have changed - method has to get adjusted") | 
					
						
							|  |  |  |         return | 
					
						
							|  |  |  |     errors = children[2].text | 
					
						
							|  |  |  |     if errors == "": | 
					
						
							|  |  |  |         errors = "none" | 
					
						
							|  |  |  |     warnings = children[4].text | 
					
						
							|  |  |  |     if warnings == "": | 
					
						
							|  |  |  |         warnings = "none" | 
					
						
							|  |  |  |     gotErrors = errors != "none" and errors != "0" | 
					
						
							| 
									
										
										
										
											2011-09-26 15:24:49 +02:00
										 |  |  |     if not (gotErrors ^ expectedToFail): | 
					
						
							|  |  |  |         test.passes("Errors: %s | Warnings: %s" % (errors, warnings)) | 
					
						
							| 
									
										
										
										
											2011-09-01 14:09:25 +02:00
										 |  |  |     else: | 
					
						
							| 
									
										
										
										
											2011-09-26 15:24:49 +02:00
										 |  |  |         test.fail("Errors: %s | Warnings: %s" % (errors, warnings)) | 
					
						
							| 
									
										
										
										
											2011-09-01 14:09:25 +02:00
										 |  |  |     # additional stuff - could be removed... or improved :) | 
					
						
							| 
									
										
										
										
											2012-09-05 16:49:35 +02:00
										 |  |  |     ensureChecked(":Qt Creator_Issues_Core::Internal::OutputPaneToggleButton") | 
					
						
							| 
									
										
										
										
											2012-11-02 19:34:38 +01:00
										 |  |  |     list=waitForObject(":Qt Creator.Issues_QListView") | 
					
						
							| 
									
										
										
										
											2011-09-01 14:09:25 +02:00
										 |  |  |     model = list.model() | 
					
						
							| 
									
										
										
										
											2011-10-06 13:55:05 +02:00
										 |  |  |     test.log("Rows inside issues: %d" % model.rowCount()) | 
					
						
							| 
									
										
										
										
											2011-09-01 14:09:25 +02:00
										 |  |  |     if gotErrors and createTasksFileOnError: | 
					
						
							|  |  |  |         createTasksFile(list) | 
					
						
							|  |  |  |     return not gotErrors | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-05 11:00:32 +02:00
										 |  |  | # helper function to check the compilation when build wasn't successful | 
					
						
							|  |  |  | def checkCompile(): | 
					
						
							| 
									
										
										
										
											2012-09-05 16:49:35 +02:00
										 |  |  |     ensureChecked(":Qt Creator_CompileOutput_Core::Internal::OutputPaneToggleButton") | 
					
						
							| 
									
										
										
										
											2012-11-02 19:34:38 +01:00
										 |  |  |     output = waitForObject(":Qt Creator.Compile Output_Core::OutputWindow") | 
					
						
							| 
									
										
										
										
											2011-09-05 11:00:32 +02:00
										 |  |  |     waitFor("len(str(output.plainText))>0",5000) | 
					
						
							| 
									
										
										
										
											2013-02-04 11:08:38 +01:00
										 |  |  |     if compileSucceeded(output.plainText): | 
					
						
							| 
									
										
										
										
											2012-01-10 16:55:57 +01:00
										 |  |  |         if os.getenv("SYSTEST_DEBUG") == "1": | 
					
						
							|  |  |  |             test.log("Compile Output:\n%s" % output.plainText) | 
					
						
							| 
									
										
										
										
											2013-02-04 11:08:38 +01:00
										 |  |  |         test.passes("Compile successful") | 
					
						
							|  |  |  |         return True | 
					
						
							| 
									
										
										
										
											2011-09-05 11:00:32 +02:00
										 |  |  |     else: | 
					
						
							| 
									
										
										
										
											2011-10-06 16:46:03 +02:00
										 |  |  |         test.fail("Compile Output:\n%s" % output.plainText) | 
					
						
							| 
									
										
										
										
											2013-02-04 11:08:38 +01:00
										 |  |  |         return False | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def compileSucceeded(compileOutput): | 
					
						
							|  |  |  |     return None != re.match(".*exited normally\.\n\d\d:\d\d:\d\d: Elapsed time: " | 
					
						
							|  |  |  |                             "(\d:)?\d{2}:\d\d\.$", str(compileOutput), re.S) | 
					
						
							| 
									
										
										
										
											2011-09-01 14:09:25 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-06 13:55:05 +02:00
										 |  |  | # helper method that parses the Issues output and writes a tasks file | 
					
						
							| 
									
										
										
										
											2011-09-01 14:09:25 +02:00
										 |  |  | def createTasksFile(list): | 
					
						
							|  |  |  |     global tasksFileDir, tasksFileCount | 
					
						
							|  |  |  |     model = list.model() | 
					
						
							|  |  |  |     if tasksFileDir == None: | 
					
						
							| 
									
										
										
										
											2011-09-05 15:00:01 +02:00
										 |  |  |             tasksFileDir = os.getcwd() + "/tasks" | 
					
						
							|  |  |  |             tasksFileDir = os.path.abspath(tasksFileDir) | 
					
						
							|  |  |  |     if not os.path.exists(tasksFileDir): | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             os.makedirs(tasksFileDir) | 
					
						
							|  |  |  |         except OSError: | 
					
						
							|  |  |  |             test.log("Could not create %s - falling back to a temporary directory" % tasksFileDir) | 
					
						
							|  |  |  |             tasksFileDir = tempDir() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-01 14:09:25 +02:00
										 |  |  |     tasksFileCount += 1 | 
					
						
							|  |  |  |     outfile = os.path.join(tasksFileDir, os.path.basename(squishinfo.testCase)+"_%d.tasks" % tasksFileCount) | 
					
						
							|  |  |  |     file = codecs.open(outfile, "w", "utf-8") | 
					
						
							|  |  |  |     test.log("Writing tasks file - can take some time (according to number of issues)") | 
					
						
							| 
									
										
										
										
											2012-02-03 14:19:01 +01:00
										 |  |  |     rows = model.rowCount() | 
					
						
							|  |  |  |     if os.environ.get("SYSTEST_DEBUG") == "1": | 
					
						
							|  |  |  |         firstrow = 0 | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         firstrow = max(0, rows - 100) | 
					
						
							|  |  |  |     for row in range(firstrow, rows): | 
					
						
							| 
									
										
										
										
											2011-09-01 14:09:25 +02:00
										 |  |  |         index = model.index(row,0) | 
					
						
							|  |  |  |         # the following is currently a bad work-around | 
					
						
							|  |  |  |         fData = index.data(Qt.UserRole).toString() # file | 
					
						
							|  |  |  |         lData = index.data(Qt.UserRole + 1).toString() # line -> linenumber or empty | 
					
						
							| 
									
										
										
										
											2012-03-23 16:46:38 +01:00
										 |  |  |         tData = index.data(Qt.UserRole + 5).toString() # type -> 1==error 2==warning | 
					
						
							|  |  |  |         dData = index.data(Qt.UserRole + 3).toString() # description | 
					
						
							| 
									
										
										
										
											2011-09-01 14:09:25 +02:00
										 |  |  |         if lData == "": | 
					
						
							|  |  |  |             lData = "-1" | 
					
						
							|  |  |  |         if tData == "1": | 
					
						
							|  |  |  |             tData = "error" | 
					
						
							|  |  |  |         elif tData == "2": | 
					
						
							|  |  |  |             tData = "warning" | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             tData = "unknown" | 
					
						
							|  |  |  |         file.write("%s\t%s\t%s\t%s\n" % (fData, lData, tData, dData)) | 
					
						
							|  |  |  |     file.close() | 
					
						
							|  |  |  |     test.log("Written tasks file %s" % outfile) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-29 19:22:43 +01:00
										 |  |  | # returns a list of pairs each containing the zero based number of a kit | 
					
						
							|  |  |  | # and the name of the matching build configuration | 
					
						
							|  |  |  | # param kitCount specifies the number of kits currently defined (must be correct!) | 
					
						
							| 
									
										
										
										
											2012-01-17 13:47:47 +01:00
										 |  |  | # param filter is a regular expression to filter the configuration by their name | 
					
						
							| 
									
										
										
										
											2012-10-29 19:22:43 +01:00
										 |  |  | def iterateBuildConfigs(kitCount, filter = ""): | 
					
						
							| 
									
										
										
										
											2012-01-17 13:47:47 +01:00
										 |  |  |     switchViewTo(ViewConstants.PROJECTS) | 
					
						
							| 
									
										
										
										
											2012-10-29 19:22:43 +01:00
										 |  |  |     configs = [] | 
					
						
							|  |  |  |     for currentKit in range(kitCount): | 
					
						
							|  |  |  |         switchToBuildOrRunSettingsFor(kitCount, currentKit, ProjectSettings.BUILD) | 
					
						
							| 
									
										
										
										
											2012-11-02 19:34:38 +01:00
										 |  |  |         model = waitForObject(":scrollArea.Edit build configuration:_QComboBox").model() | 
					
						
							| 
									
										
										
										
											2012-10-29 19:22:43 +01:00
										 |  |  |         prog = re.compile(filter) | 
					
						
							|  |  |  |         # for each row in the model, write its data to a list | 
					
						
							|  |  |  |         configNames = dumpItems(model) | 
					
						
							|  |  |  |         # pick only those configuration names which pass the filter | 
					
						
							|  |  |  |         configs += zip([currentKit] * len(configNames), | 
					
						
							|  |  |  |                        [config for config in configNames if prog.match(config)]) | 
					
						
							| 
									
										
										
										
											2012-01-17 13:47:47 +01:00
										 |  |  |     switchViewTo(ViewConstants.EDIT) | 
					
						
							|  |  |  |     return configs | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # selects a build configuration for building the current project | 
					
						
							|  |  |  | # param targetCount specifies the number of targets currently defined (must be correct!) | 
					
						
							|  |  |  | # param currentTarget specifies the target for which to switch into the specified settings (zero based index) | 
					
						
							|  |  |  | # param configName is the name of the configuration that should be selected | 
					
						
							| 
									
										
										
										
											2013-04-03 13:57:02 +02:00
										 |  |  | # returns information about the selected kit, see getQtInformationForBuildSettings | 
					
						
							| 
									
										
										
										
											2012-01-17 13:47:47 +01:00
										 |  |  | def selectBuildConfig(targetCount, currentTarget, configName): | 
					
						
							|  |  |  |     switchViewTo(ViewConstants.PROJECTS) | 
					
						
							|  |  |  |     switchToBuildOrRunSettingsFor(targetCount, currentTarget, ProjectSettings.BUILD) | 
					
						
							|  |  |  |     if selectFromCombo(":scrollArea.Edit build configuration:_QComboBox", configName): | 
					
						
							| 
									
										
										
										
											2013-04-25 19:08:55 +02:00
										 |  |  |         progressBarWait(30000) | 
					
						
							| 
									
										
										
										
											2013-04-03 13:57:02 +02:00
										 |  |  |     return getQtInformationForBuildSettings(targetCount, True, ViewConstants.EDIT) | 
					
						
							| 
									
										
										
										
											2012-03-26 14:13:39 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-11 17:38:58 +02:00
										 |  |  | # This will not trigger a rebuild. If needed, caller has to do this. | 
					
						
							|  |  |  | def verifyBuildConfig(targetCount, currentTarget, shouldBeDebug=False, enableShadowBuild=False, enableQmlDebug=False): | 
					
						
							| 
									
										
										
										
											2012-03-26 14:13:39 +02:00
										 |  |  |     switchViewTo(ViewConstants.PROJECTS) | 
					
						
							|  |  |  |     switchToBuildOrRunSettingsFor(targetCount, currentTarget, ProjectSettings.BUILD) | 
					
						
							| 
									
										
										
										
											2012-08-01 11:30:31 +02:00
										 |  |  |     ensureChecked(waitForObject(":scrollArea.Details_Utils::DetailsButton")) | 
					
						
							| 
									
										
										
										
											2012-03-26 14:13:39 +02:00
										 |  |  |     ensureChecked("{name='shadowBuildCheckBox' type='QCheckBox' visible='1'}", enableShadowBuild) | 
					
						
							|  |  |  |     buildCfCombo = waitForObject("{type='QComboBox' name='buildConfigurationComboBox' visible='1' " | 
					
						
							| 
									
										
										
										
											2012-08-01 11:30:31 +02:00
										 |  |  |                                  "window=':Qt Creator_Core::Internal::MainWindow'}") | 
					
						
							| 
									
										
										
										
											2012-03-26 14:13:39 +02:00
										 |  |  |     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") | 
					
						
							| 
									
										
										
										
											2012-05-11 17:38:58 +02:00
										 |  |  |     try: | 
					
						
							|  |  |  |         libLabel = waitForObject(":scrollArea.Library not available_QLabel", 2000) | 
					
						
							| 
									
										
										
										
											2012-08-01 11:30:31 +02:00
										 |  |  |         mouseClick(libLabel, libLabel.width - 10, libLabel.height / 2, 0, Qt.LeftButton) | 
					
						
							| 
									
										
										
										
											2012-05-11 17:38:58 +02:00
										 |  |  |     except: | 
					
						
							|  |  |  |         pass | 
					
						
							|  |  |  |     # Since waitForObject waits for the object to be enabled, | 
					
						
							|  |  |  |     # it will wait here until compilation of the debug libraries has finished. | 
					
						
							|  |  |  |     qmlDebugCheckbox = waitForObject(":scrollArea.qmlDebuggingLibraryCheckBox_QCheckBox", 150000) | 
					
						
							|  |  |  |     if qmlDebugCheckbox.checked != enableQmlDebug: | 
					
						
							|  |  |  |         clickButton(qmlDebugCheckbox) | 
					
						
							|  |  |  |         # Don't rebuild now | 
					
						
							|  |  |  |         clickButton(waitForObject(":QML Debugging.No_QPushButton", 5000)) | 
					
						
							| 
									
										
										
										
											2012-03-26 14:13:39 +02:00
										 |  |  |     try: | 
					
						
							| 
									
										
										
										
											2012-08-01 11:30:31 +02:00
										 |  |  |         problemFound = waitForObject("{window=':Qt Creator_Core::Internal::MainWindow' " | 
					
						
							|  |  |  |                                      "type='QLabel' name='problemLabel' visible='1'}", 1000) | 
					
						
							| 
									
										
										
										
											2012-03-26 14:13:39 +02:00
										 |  |  |         if problemFound: | 
					
						
							|  |  |  |             test.warning('%s' % problemFound.text) | 
					
						
							|  |  |  |     except: | 
					
						
							|  |  |  |         pass | 
					
						
							| 
									
										
										
										
											2012-08-01 11:30:31 +02:00
										 |  |  |     clickButton(waitForObject(":scrollArea.Details_Utils::DetailsButton")) | 
					
						
							| 
									
										
										
										
											2012-03-26 14:13:39 +02:00
										 |  |  |     switchViewTo(ViewConstants.EDIT) |