Changeset 61217 in vbox for trunk/src/VBox/ValidationKit/testmanager/webui
- Timestamp:
- May 26, 2016 8:04:05 PM (9 years ago)
- svn:sync-xref-src-repo-rev:
- 107506
- Location:
- trunk/src/VBox/ValidationKit/testmanager/webui
- Files:
-
- 1 added
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/ValidationKit/testmanager/webui/wuiadmin.py
r56295 r61217 138 138 139 139 ksActionFailureReasonList = 'FailureReasonList' 140 ksActionFailureReasonDetails = 'FailureReasonDetails' 140 141 ksActionFailureReasonShowAdd = 'FailureReasonShowAdd' 141 142 ksActionFailureReasonShowEdit = 'FailureReasonShowEdit' … … 365 366 WuiAdminFailureReasonList) 366 367 367 d[self.ksActionFailureReason ShowAdd] = lambda: self._actionGenericFormAdd(368 FailureReasonData,369 WuiAdminFailureReason)370 368 d[self.ksActionFailureReasonDetails] = lambda: self._actionGenericFormDetails(FailureReasonData, 369 FailureReasonLogic, 370 WuiAdminFailureReason, 371 'idFailureReason'); 371 372 d[self.ksActionFailureReasonShowEdit] = lambda: self._actionGenericFormEditL( 372 373 FailureReasonLogic, -
trunk/src/VBox/ValidationKit/testmanager/webui/wuibase.py
r56295 r61217 74 74 ## The name of the effective date (timestamp) parameter. 75 75 ksParamEffectiveDate = 'EffectiveDate'; 76 77 ## The name of the redirect-to (test manager relative url) parameter. 78 ksParamRedirectTo = 'RedirectTo'; 76 79 77 80 ## The name of the list-action parameter (WuiListContentWithActionBase). … … 546 549 return str(oDate); 547 550 551 def getRedirectToParameter(self, sDefault = None): 552 """ 553 Gets the special redirect to parameter if it exists, will Return default 554 if not, with None being a valid default. 555 556 Makes sure the it doesn't got offsite. 557 Raises exception if invalid. 558 """ 559 if sDefault is not None or self.ksParamRedirectTo in self._dParams: 560 sValue = self.getStringParam(self.ksParamRedirectTo, sDefault = sDefault); 561 cch = sValue.find("?"); 562 if cch < 0: 563 cch = sValue.find("#"); 564 if cch < 0: 565 cch = len(sValue); 566 for ch in (':', '/', '\\', '..'): 567 if sValue.find(ch, 0, cch) >= 0: 568 raise WuiException('Invalid character (%c) in redirect-to url: %s' % (ch, sValue,)); 569 else: 570 sValue = None; 571 return sValue; 572 548 573 549 574 def _checkForUnknownParameters(self): … … 701 726 return True; 702 727 703 def _actionGenericFormAdd(self, oDataType, oFormType ):728 def _actionGenericFormAdd(self, oDataType, oFormType, sRedirectTo = None): 704 729 """ 705 730 Generic add something form display request handler. … … 709 734 """ 710 735 oData = oDataType().initFromParams(oDisp = self, fStrict = False); 736 sRedirectTo = self.getRedirectToParameter(sRedirectTo); 711 737 self._checkForUnknownParameters(); 712 738 713 739 oForm = oFormType(oData, oFormType.ksMode_Add, oDisp = self); 740 oForm.setRedirectTo(sRedirectTo); 714 741 (self._sPageTitle, self._sPageBody) = oForm.showForm(); 715 742 return True … … 757 784 758 785 759 def _actionGenericFormEdit(self, oDataType, oFormType, sIdParamName ):786 def _actionGenericFormEdit(self, oDataType, oFormType, sIdParamName, sRedirectTo = None): 760 787 """ 761 788 Generic edit something form display request handler. … … 766 793 """ 767 794 795 tsNow = self.getEffectiveDateParam(); 768 796 idObject = self.getIntParam(sIdParamName, 0, 0x7ffffffe); 797 sRedirectTo = self.getRedirectToParameter(sRedirectTo); 769 798 self._checkForUnknownParameters(); 770 oData = oDataType().initFromDbWithId(self._oDb, idObject );799 oData = oDataType().initFromDbWithId(self._oDb, idObject, tsNow = tsNow); 771 800 772 801 oContent = oFormType(oData, oFormType.ksMode_Edit, oDisp = self); 802 oContent.setRedirectTo(sRedirectTo); 773 803 (self._sPageTitle, self._sPageBody) = oContent.showForm(); 774 804 return True … … 850 880 # 851 881 oData = oDataType().initFromParams(oDisp = self, fStrict = fStrict); 882 sRedirectTo = self.getRedirectToParameter(sRedirectTo); 852 883 self._checkForUnknownParameters(); 853 884 self._assertPostRequest(); … … 864 895 self._oDb.rollback(); 865 896 oForm = oFormType(oData, sMode, oDisp = self); 897 oForm.setRedirectTo(sRedirectTo); 866 898 sErrorMsg = str(oXcpt) if not config.g_kfDebugDbXcpt else '\n'.join(utils.getXcptInfo(4)); 867 899 (self._sPageTitle, self._sPageBody) = oForm.showForm(sErrorMsg = sErrorMsg); … … 961 993 self._sAction = self.ksActionDefault; 962 994 963 if self._sAction not in self._dDispatch:995 if isinstance(self._sAction, list) or self._sAction not in self._dDispatch: 964 996 raise WuiException('Unknown action "%s" requested' % (self._sAction,)); 965 997 -
trunk/src/VBox/ValidationKit/testmanager/webui/wuicontentbase.py
r56807 r61217 190 190 191 191 ## The text/symbol for a very short edit link. 192 ksShortEditLink = u'\u270D' 192 ksShortEditLink = u'\u270D' 193 ## HTML hex entity string for ksShortDetailsLink. 194 ksShortEditLinkHtml = '✍' 193 195 ## The text/symbol for a very short details link. 194 ksShortDetailsLink = u'\u2318' 196 ksShortDetailsLink = u'\u2318' 197 ## HTML hex entity string for ksShortDetailsLink. 198 ksShortDetailsLinkHtml = '⌘' 195 199 196 200 … … 327 331 if sSubmitAction is None and sMode != self.ksMode_Show: 328 332 self._sSubmitAction = getattr(oDisp, self._sActionBase + self.kdSubmitActionMappings[sMode]); 333 self._sRedirectTo = None; 329 334 330 335 … … 469 474 '</div>\n'; 470 475 return sNavigation; 476 477 def setRedirectTo(self, sRedirectTo): 478 """ 479 For setting the hidden redirect-to field. 480 """ 481 self._sRedirectTo = sRedirectTo; 482 return True; 471 483 472 484 def showChangeLog(self, aoEntries, fMoreEntries, iPageNo, cEntriesPerPage, tsNow, fShowNavigation = True): … … 521 533 try: 522 534 self._populateForm(oForm, self._oData); 535 if self._sRedirectTo is not None: 536 oForm.addTextHidden(self._oDisp.ksParamRedirectTo, self._sRedirectTo); 523 537 except WuiException, oXcpt: 524 538 sContent = unicode(oXcpt) … … 558 572 dParams[WuiDispatcherBase.ksParamEffectiveDate] = self._oData.tsEffective; 559 573 dParams[getattr(self._oData, 'ksParam_' + self._oData.ksIdAttr)] = getattr(self._oData, self._oData.ksIdAttr); 560 dParams[WuiDispatcherBase.ksParamAction] = getattr(self._oDisp, self._sActionBase + ' Edit');574 dParams[WuiDispatcherBase.ksParamAction] = getattr(self._oDisp, self._sActionBase + 'Details'); 561 575 aoActions.append(WuiTmLink('Details', '', dParams)); 562 576 … … 629 643 assert len(aoValues) == len(self._asColumnHeaders), '%s vs %s' % (len(aoValues), len(self._asColumnHeaders)); 630 644 631 for i in range(len(aoValues)):645 for i, _ in enumerate(aoValues): 632 646 if i < len(self._asColumnAttribs) and len(self._asColumnAttribs[i]) > 0: 633 647 sRow += u' <td ' + self._asColumnAttribs[i] + '>'; -
trunk/src/VBox/ValidationKit/testmanager/webui/wuihlpform.py
r56295 r61217 48 48 ksItemsList = 'ksItemsList' 49 49 50 def __init__(self, sId, sAction, dErrors = None, fReadOnly = False): 50 ksOnSubmit_AddReturnToFieldWithCurrentUrl = '+AddReturnToFieldWithCurrentUrl+'; 51 52 def __init__(self, sId, sAction, dErrors = None, fReadOnly = False, sOnSubmit = None): 51 53 self._fFinalized = False; 52 54 self._fReadOnly = fReadOnly; 53 55 self._dErrors = dErrors if dErrors is not None else dict(); 56 57 if sOnSubmit == self.ksOnSubmit_AddReturnToFieldWithCurrentUrl: 58 sOnSubmit = 'return addRedirectToInputFieldWithCurrentUrl(this)'; 59 if sOnSubmit is None: sOnSubmit = u''; 60 else: sOnSubmit = u' onsubmit=\"%s\"' % (escapeAttr(sOnSubmit),); 61 54 62 self._sBody = u'\n' \ 55 63 u'<div id="%s" class="tmform">\n' \ 56 u' <form action="%s" method="post" >\n' \64 u' <form action="%s" method="post"%s>\n' \ 57 65 u' <ul>\n' \ 58 % (sId, sAction );66 % (sId, sAction, sOnSubmit); 59 67 60 68 def _add(self, sText): … … 70 78 if sText.find('<br>') >= 0: 71 79 asParts = sText.split('<br>'); 72 for i in range(len(asParts)):80 for i, _ in enumerate(asParts): 73 81 asParts[i] = escapeElem(asParts[i].strip()); 74 82 sText = '<br>\n'.join(asParts); … … 114 122 ' </li>\n' 115 123 % ( escapeAttr(sName), escapeAttr(sName), sExtraAttribs, escapeElem(str(sValue)) )); 124 # 125 # Non-input stuff. 126 # 127 def addNonText(self, sValue, sLabel, sPostHtml = ''): 128 """Adds a read-only text input.""" 129 self._addLabel('non-text', sLabel, 'string'); 130 if sValue is None: sValue = ''; 131 return self._add(' <p>%s</p>%s\n' 132 ' </div></div>\n' 133 ' </li>\n' 134 % (escapeElem(str(sValue)), sPostHtml )); 135 116 136 117 137 # … … 124 144 if sSubClass not in ('int', 'long', 'string', 'uuid', 'timestamp', 'wide'): raise Exception(sSubClass); 125 145 self._addLabel(sName, sLabel, sSubClass); 146 if sValue is None: sValue = ''; 126 147 return self._add(' <input name="%s" id="%s" type="text"%s value="%s">%s\n' 127 148 ' </div></div>\n' … … 133 154 if sSubClass not in ('int', 'long', 'string', 'uuid', 'timestamp', 'wide'): raise Exception(sSubClass); 134 155 self._addLabel(sName, sLabel, sSubClass); 156 if sValue is None: sValue = ''; 135 157 return self._add(' <input name="%s" id="%s" type="text" readonly%s value="%s" class="tmform-input-readonly">%s\n' 136 158 ' </div></div>\n' … … 153 175 if sSubClass not in ('int', 'long', 'string', 'uuid', 'timestamp'): raise Exception(sSubClass) 154 176 self._addLabel(sName, sLabel, sSubClass) 177 if sValue is None: sValue = ''; 155 178 sNewValue = str(sValue) if not isinstance(sValue, list) else '\n'.join(sValue) 156 179 return self._add(' <textarea name="%s" id="%s" %s>%s</textarea>\n' … … 163 186 if sSubClass not in ('int', 'long', 'string', 'uuid', 'timestamp'): raise Exception(sSubClass) 164 187 self._addLabel(sName, sLabel, sSubClass) 188 if sValue is None: sValue = ''; 165 189 sNewValue = str(sValue) if not isinstance(sValue, list) else '\n'.join(sValue) 166 190 return self._add(' <textarea name="%s" id="%s" readonly %s>%s</textarea>\n' … … 213 237 self._add(' <select name="%s" id="%s" class="tmform-combobox"%s>\n' 214 238 % (escapeAttr(sName), escapeAttr(sName), sExtraAttribs)); 239 sSelected = str(sSelected); 215 240 for iValue, sText, _ in aoOptions: 216 241 sValue = str(iValue); 217 242 self._add(' <option value="%s"%s>%s</option>\n' 218 % (escapeAttr(sValue), ' selected' if sValue == s tr(sSelected)else '',243 % (escapeAttr(sValue), ' selected' if sValue == sSelected else '', 219 244 escapeElem(sText))); 220 245 return self._add(' </select>\n' … … 229 254 self._add(' <select name="%s" id="%s" disabled class="tmform-combobox"%s>\n' 230 255 % (escapeAttr(sName), escapeAttr(sName), sExtraAttribs)); 256 sSelected = str(sSelected); 231 257 for iValue, sText, _ in aoOptions: 232 258 sValue = str(iValue); 233 259 self._add(' <option value="%s"%s>%s</option>\n' 234 % (escapeAttr(sValue), ' selected' if sValue == s tr(sSelected)else '',260 % (escapeAttr(sValue), ' selected' if sValue == sSelected else '', 235 261 escapeElem(sText))); 236 262 return self._add(' </select>\n' … … 526 552 dSubErrors = self._dErrors[sName]; 527 553 528 for iVar in range(len(aoVariations)):554 for iVar, _ in enumerate(aoVariations): 529 555 oVar = copy.copy(aoVariations[iVar]); 530 556 oVar.convertToParamNull(); … … 623 649 oDefMember = TestGroupMemberData(); 624 650 aoTestGroupMembers = list(aoTestGroupMembers); # Copy it so we can pop. 625 for iTestCase in range(len(aoAllTestCases)):651 for iTestCase, _ in enumerate(aoAllTestCases): 626 652 oTestCase = aoAllTestCases[iTestCase]; 627 653 628 654 # Is it a member? 629 655 oMember = None; 630 for i in range(len(aoTestGroupMembers)):656 for i, _ in enumerate(aoTestGroupMembers): 631 657 if aoTestGroupMembers[i].oTestCase.idTestCase == oTestCase.idTestCase: 632 658 oMember = aoTestGroupMembers.pop(i); … … 735 761 oDefMember = SchedGroupMemberData(); 736 762 aoSchedGroupMembers = list(aoSchedGroupMembers); # Copy it so we can pop. 737 for iTestGroup in range(len(aoAllTestGroups)):763 for iTestGroup, _ in enumerate(aoAllTestGroups): 738 764 oTestGroup = aoAllTestGroups[iTestGroup]; 739 765 740 766 # Is it a member? 741 767 oMember = None; 742 for i in range(len(aoSchedGroupMembers)):768 for i, _ in enumerate(aoSchedGroupMembers): 743 769 if aoSchedGroupMembers[i].oTestGroup.idTestGroup == oTestGroup.idTestGroup: 744 770 oMember = aoSchedGroupMembers.pop(i); -
trunk/src/VBox/ValidationKit/testmanager/webui/wuimain.py
r56809 r61217 69 69 ksActionResultsGroupedByTestCase = 'ResultsGroupedByTestCase' 70 70 ksActionTestResultDetails = 'TestResultDetails' 71 ksActionTestResultFailureDetails = 'TestResultFailureDetails' 72 ksActionTestResultFailureAdd = 'TestResultFailureAdd' 73 ksActionTestResultFailureAddPost = 'TestResultFailureAddPost' 74 ksActionTestResultFailureEdit = 'TestResultFailureEdit' 75 ksActionTestResultFailureEditPost = 'TestResultFailureEditPost' 71 76 ksActionViewLog = 'ViewLog' 72 77 ksActionGetFile = 'GetFile' … … 228 233 WuiGroupedResultList) 229 234 230 d[self.ksActionTestResultDetails] = self.actionTestResultDetails 235 d[self.ksActionTestResultDetails] = self._actionTestResultDetails; 236 237 d[self.ksActionTestResultFailureAdd] = self._actionTestResultFailureAdd; 238 d[self.ksActionTestResultFailureAddPost] = self._actionTestResultFailureAddPost; 239 d[self.ksActionTestResultFailureDetails] = self._actionTestResultFailureDetails; 240 d[self.ksActionTestResultFailureEdit] = self._actionTestResultFailureEdit; 241 d[self.ksActionTestResultFailureEditPost] = self._actionTestResultFailureEditPost; 231 242 232 243 d[self.ksActionViewLog] = self.actionViewLog; … … 813 824 return WuiDispatcherBase._generatePage(self) 814 825 815 def actionTestResultDetails(self):826 def _actionTestResultDetails(self): 816 827 """Show test case execution result details.""" 817 828 from testmanager.webui.wuitestresult import WuiTestResult; … … 849 860 return True 850 861 862 def _actionTestResultFailureAdd(self): 863 """ Pro forma. """ 864 from testmanager.core.testresults import TestResultFailureLogic, TestResultFailureData; 865 from testmanager.webui.wuitestresultfailure import WuiTestResultFailure; 866 return self._actionGenericFormAdd(TestResultFailureData, WuiTestResultFailure); 867 868 def _actionTestResultFailureAddPost(self): 869 """Add test result failure result""" 870 from testmanager.core.testresults import TestResultFailureLogic, TestResultFailureData; 871 from testmanager.webui.wuitestresultfailure import WuiTestResultFailure; 872 if self.ksParamRedirectTo not in self._dParams: 873 raise WuiException('Missing parameter ' + self.ksParamRedirectTo); 874 875 return self._actionGenericFormAddPost(TestResultFailureData, TestResultFailureLogic, 876 WuiTestResultFailure, self.ksActionResultsUnGrouped); 877 878 def _actionTestResultFailureDetails(self): 879 """ Pro forma. """ 880 from testmanager.core.testresults import TestResultFailureLogic, TestResultFailureData; 881 from testmanager.webui.wuitestresultfailure import WuiTestResultFailure; 882 return self._actionGenericFormDetails(TestResultFailureData, TestResultFailureLogic, 883 WuiTestResultFailure, 'idTestResult'); 884 885 def _actionTestResultFailureEdit(self): 886 """ Pro forma. """ 887 from testmanager.core.testresults import TestResultFailureData; 888 from testmanager.webui.wuitestresultfailure import WuiTestResultFailure; 889 return self._actionGenericFormEdit(TestResultFailureData, WuiTestResultFailure, 890 TestResultFailureData.ksParam_idTestResult); 891 892 def _actionTestResultFailureEditPost(self): 893 """Edit test result failure result""" 894 from testmanager.core.testresults import TestResultFailureLogic, TestResultFailureData; 895 from testmanager.webui.wuitestresultfailure import WuiTestResultFailure; 896 if self.ksParamRedirectTo not in self._dParams: 897 raise WuiException('Missing parameter ' + self.ksParamRedirectTo); 898 899 return self._actionGenericFormEditPost(TestResultFailureData, TestResultFailureLogic, 900 WuiTestResultFailure, self.ksActionResultsUnGrouped); 901 851 902 def actionViewLog(self): 852 903 """ -
trunk/src/VBox/ValidationKit/testmanager/webui/wuitestresult.py
r56806 r61217 35 35 WuiSvnLink, WuiSvnLinkWithTooltip, WuiBuildLogLink, WuiRawHtml; 36 36 from testmanager.webui.wuimain import WuiMain; 37 from testmanager.webui.wuihlpform import WuiHlpForm; 38 from testmanager.core.failurereason import FailureReasonData, FailureReasonLogic; 37 39 from testmanager.core.report import ReportGraphModel; 38 40 from testmanager.core.testbox import TestBoxData; … … 40 42 from testmanager.core.testset import TestSetData; 41 43 from testmanager.core.testgroup import TestGroupData; 44 from testmanager.core.testresults import TestResultFailureData; 42 45 from testmanager.core.build import BuildData; 43 46 from testmanager.core import db; … … 137 140 sErrCnt = ' (1 error)' if oTestResult.cErrors == 1 else ' (%d errors)' % oTestResult.cErrors; 138 141 142 # Format bits for adding or editing the failure reason. Level 0 is handled at the top of the page. 143 sChangeReason = ''; 144 if oTestResult.cErrors > 0 and iDepth > 0: 145 dTmp = { 146 self._oDisp.ksParamAction: self._oDisp.ksActionTestResultFailureAdd if oTestResult.oReason is None else 147 self._oDisp.ksActionTestResultFailureEdit, 148 TestResultFailureData.ksParam_idTestResult: oTestResult.idTestResult, 149 }; 150 sChangeReason = ' <a href="?%s" class="tmtbl-edit-reason" onclick="addRedirectToAnchorHref(this)">%s</a> ' \ 151 % ( webutils.encodeUrlParams(dTmp), WuiContentBase.ksShortEditLinkHtml ); 152 139 153 # Format the include in graph checkboxes. 140 154 sLineage += ':%u' % (oTestResult.idStrName,); … … 148 162 149 163 if len(oTestResult.aoChildren) == 0 \ 150 and len(oTestResult.aoValues) == 0 \ 151 and len(oTestResult.aoMsgs) == 0 \ 152 and len(oTestResult.aoFiles) == 0: 164 and len(oTestResult.aoValues) + len(oTestResult.aoMsgs) + len(oTestResult.aoFiles) == 0: 153 165 # Leaf - single row. 154 166 tsEvent = oTestResult.tsCreated; … … 160 172 ' <td>%s</td>\n' \ 161 173 ' <td>%s</td>\n' \ 162 ' <td colspan="2"%s>%s%s </td>\n' \174 ' <td colspan="2"%s>%s%s%s</td>\n' \ 163 175 ' <td>%s</td>\n' \ 164 176 ' </tr>\n' \ … … 170 182 sDisplayName, 171 183 ' id="failure-%u"' % (iFailure,) if oTestResult.isFailure() else '', 172 webutils.escapeElem(oTestResult.enmStatus), webutils.escapeElem(sErrCnt), 184 webutils.escapeElem(oTestResult.enmStatus), webutils.escapeElem(sErrCnt), sChangeReason, 173 185 sResultGraph ); 174 186 iRow += 1; … … 189 201 iRow += 1; 190 202 191 # Depth. 203 # Depth. Check if our error count is just reflecting the one of our children. 204 cErrorsBelow = 0; 192 205 for oChild in oTestResult.aoChildren: 193 206 (sChildHtml, iRow, iFailure) = self._recursivelyGenerateEvents(oChild, sName, sLineage, 194 207 iRow, iFailure, oTestSet, iDepth + 1); 195 208 sHtml += sChildHtml; 196 209 cErrorsBelow += oChild.cErrors; 210 211 if cErrorsBelow >= oTestResult.cErrors: 212 sChangeReason = ''; 197 213 198 214 # Messages. … … 263 279 264 280 sHtml += ' <tr class="%s tmtbl-events-file tmtbl-events-lvl%s">\n' \ 265 ' <td> </td>\n' \266 ' <td> %s</td>\n' \281 ' <td>%s</td>\n' \ 282 ' <td></td>\n' \ 267 283 ' <td></td>\n' \ 268 284 ' <td>%s</td>\n' \ … … 296 312 iRow += 1; 297 313 314 # Failure reason. 315 if oTestResult.oReason is not None: 316 sReasonText = '%s / %s' % ( oTestResult.oReason.oFailureReason.oCategory.sShort, 317 oTestResult.oReason.oFailureReason.sShort, ); 318 sCommentHtml = ''; 319 if oTestResult.oReason.sComment is not None and len(oTestResult.oReason.sComment.strip()) > 0: 320 sCommentHtml = '<br>' + webutils.escapeElem(oTestResult.oReason.sComment.strip()); 321 sCommentHtml = sCommentHtml.replace('\n', '<br>'); 322 323 sDetailedReason = ' <a href="?%s" class="tmtbl-show-reason">%s</a>' \ 324 % ( webutils.encodeUrlParams({ self._oDisp.ksParamAction: 325 self._oDisp.ksActionTestResultFailureDetails, 326 TestResultFailureData.ksParam_idTestResult: 327 oTestResult.idTestResult,}), 328 WuiContentBase.ksShortDetailsLinkHtml,); 329 330 331 sHtml += ' <tr class="%s tmtbl-events-reason tmtbl-events-lvl%s">\n' \ 332 ' <td>%s</td>\n' \ 333 ' <td colspan="2">%s</td>\n' \ 334 ' <td colspan="3">%s%s%s%s</td>\n' \ 335 ' <td>%s</td>\n' \ 336 ' </tr>\n' \ 337 % ( 'tmodd' if iRow & 1 else 'tmeven', iDepth, 338 webutils.escapeElem(self.formatTsShort(oTestResult.oReason.tsEffective)), 339 oTestResult.oReason.oAuthor.sUsername, 340 webutils.escapeElem(sReasonText), sDetailedReason, sChangeReason, 341 sCommentHtml, 342 'todo'); 343 iRow += 1; 344 298 345 if oTestResult.isFailure(): 299 346 iFailure += 1; 300 347 301 348 return (sHtml, iRow, iFailure); 349 350 351 def _generateMainReason(self, oTestResultTree, oTestSet): 352 """ 353 Generates the form for displaying and updating the main failure reason. 354 355 oTestResultTree is an instance TestResultDataEx. 356 oTestSet is an instance of TestSetData. 357 358 """ 359 _ = oTestSet; 360 sHtml = ' '; 361 362 if oTestResultTree.isFailure() or oTestResultTree.cErrors > 0: 363 sHtml += ' <h2>Failure Reason:</h2>\n'; 364 oData = oTestResultTree.oReason; 365 366 # We need the failure reasons for the combobox. 367 aoFailureReasons = FailureReasonLogic(self._oDisp.getDb()).fetchForCombo('Todo: Figure out why'); 368 assert len(aoFailureReasons) > 0; 369 370 # For now we'll use the standard form helper. 371 sFormActionUrl = '%s?%s=%s' % ( self._oDisp.ksScriptName, self._oDisp.ksParamAction, 372 WuiMain.ksActionTestResultFailureAddPost if oData is None else 373 WuiMain.ksActionTestResultFailureEditPost ) 374 oForm = WuiHlpForm('failure-reason', sFormActionUrl, 375 sOnSubmit = WuiHlpForm.ksOnSubmit_AddReturnToFieldWithCurrentUrl); 376 oForm.addTextHidden(TestResultFailureData.ksParam_idTestResult, oTestResultTree.idTestResult); 377 oForm.addComboBox(TestResultFailureData.ksParam_idFailureReason, oData.idFailureReason if oData is not None else -1, 378 'Reason', aoFailureReasons); 379 oForm.addMultilineText(TestResultFailureData.ksParam_sComment, 380 oData.sComment if oData is not None else '', 'Comment'); 381 if oData is not None: 382 oForm.addNonText('%s (%s)' % (oData.oAuthor.sUsername, oData.oAuthor.sUsername), 'Sheriff'); 383 oForm.addNonText(oData.tsEffective, 'When'); 384 oForm.addTextHidden(TestResultFailureData.ksParam_tsEffective, oData.tsEffective); 385 oForm.addTextHidden(TestResultFailureData.ksParam_tsExpire, oData.tsExpire); 386 oForm.addTextHidden(TestResultFailureData.ksParam_uidAuthor, oData.uidAuthor); 387 else: 388 oForm.addTextHidden(TestResultFailureData.ksParam_tsEffective, ''); 389 oForm.addTextHidden(TestResultFailureData.ksParam_tsExpire, ''); 390 oForm.addTextHidden(TestResultFailureData.ksParam_uidAuthor, ''); 391 392 oForm.addSubmit('Change Reason', ); 393 sHtml += oForm.finalize(); 394 return sHtml; 395 302 396 303 397 def showTestCaseResultDetails(self, # pylint: disable=R0914,R0915 … … 534 628 535 629 sHtml += ' <td valign="top" width="80%" style="padding-left:6px">\n'; 630 sHtml += self._generateMainReason(oTestResultTree, oTestSet); 631 536 632 sHtml += ' <h2>Events:</h2>\n'; 537 633 sHtml += ' <form action="#" method="get" id="graph-form">\n' \ … … 614 710 'Start', 615 711 'Product Build', 616 ' ValidationKit',617 ' TestBox OS',618 ' TestBox Name',712 'Kit', 713 'Box', 714 'OS.Arch', 619 715 'Test Case', 620 716 'Elapsed', 621 717 'Result', 718 'Reason', 622 719 ]; 623 720 self._asColumnAttribs = ['align="center"', 'align="center"', 'align="center"', 624 721 'align="center"', 'align="center"', 'align="center"', 625 722 'align="center"', 'align="center"', 'align="center"', 626 'align="center"', 'align="center"', 'align="center"' ] 723 'align="center"', 'align="center"', 'align="center"', 724 'align="center"', ]; 627 725 628 726 … … 650 748 oValidationKit = None; 651 749 if oEntry.idBuildTestSuite is not None: 652 oValidationKit = WuiTmLink(' #%d - r%s' % (oEntry.idBuildTestSuite, oEntry.iRevisionTestSuite),750 oValidationKit = WuiTmLink('r%s' % (oEntry.iRevisionTestSuite,), 653 751 WuiAdmin.ksScriptName, 654 752 { WuiAdmin.ksParamAction: WuiAdmin.ksActionBuildDetails, … … 656 754 fBracketed = False); 657 755 658 659 aoTestSetLinks = [WuiTmLink(oEntry.enmStatus,660 WuiMain.ksScriptName,661 { WuiMain.ksParamAction: WuiMain.ksActionTestResultDetails,662 TestSetData.ksParam_idTestSet: oEntry.idTestSet },663 fBracketed = False),];756 aoTestSetLinks = []; 757 aoTestSetLinks.append(WuiTmLink(oEntry.enmStatus, 758 WuiMain.ksScriptName, 759 { WuiMain.ksParamAction: WuiMain.ksActionTestResultDetails, 760 TestSetData.ksParam_idTestSet: oEntry.idTestSet }, 761 fBracketed = False)); 664 762 if oEntry.cErrors > 0: 665 aoTestSetLinks.append(WuiTmLink('- %d error(s)' % (oEntry.cErrors, ), 763 aoTestSetLinks.append(WuiRawHtml('-')); 764 aoTestSetLinks.append(WuiTmLink('%d error%s' % (oEntry.cErrors, '' if oEntry.cErrors == 1 else 's', ), 666 765 WuiMain.ksScriptName, 667 766 { WuiMain.ksParamAction: WuiMain.ksActionTestResultDetails, … … 688 787 sTestBoxTitle += u'CPU features:\t' + u', '.join(asFeatures); 689 788 789 # Reason: 790 oReason = None; 791 if oEntry.oFailureReason is not None: 792 sReasonTitle = 'Reason: \t%s\n' % ( oEntry.oFailureReason.sShort, ); 793 sReasonTitle += 'Category:\t%s\n' % ( oEntry.oFailureReason.oCategory.sShort, ); 794 sReasonTitle += 'Assigned:\t%s\n' % ( self.formatTsShort(oEntry.tsFailureReasonAssigned), ); 795 sReasonTitle += 'By User: \t%s\n' % ( oEntry.oFailureReasonAssigner.sUsername, ); 796 if oEntry.sFailureReasonComment is not None and len(oEntry.sFailureReasonComment) > 0: 797 sReasonTitle += 'Comment: \t%s\n' % ( self.formatTsShort(oEntry.sFailureReasonComment), ); 798 if oEntry.oFailureReason.iTicket is not None and oEntry.oFailureReason.iTicket > 0: 799 sReasonTitle += 'xTracker:\t#%s\n' % ( oEntry.oFailureReason.iTicket, ); 800 for i, sUrl in enumerate(oEntry.oFailureReason.asUrls): 801 sUrl = sUrl.strip(); 802 if len(sUrl) > 0: 803 sReasonTitle += 'URL#%u: \t%s\n' % ( i, sUrl, ); 804 oReason = WuiTmLink(oEntry.oFailureReason.sShort, WuiAdmin.ksScriptName, 805 { WuiAdmin.ksParamAction: WuiAdmin.ksActionFailureReasonDetails, 806 FailureReasonData.ksParam_idFailureReason: oEntry.oFailureReason.idFailureReason }, 807 sTitle = sReasonTitle); 808 690 809 return [ 691 810 oEntry.tsCreated, 692 [ WuiTmLink(' #%d - %s %s (%s)' % (oEntry.idBuild,oEntry.sProduct, oEntry.sVersion, oEntry.sType,),811 [ WuiTmLink('%s %s (%s)' % (oEntry.sProduct, oEntry.sVersion, oEntry.sType,), 693 812 WuiMain.ksScriptName, self._dRevLinkParams, sTitle = '%s' % (oEntry.sBranch,), fBracketed = False), 694 813 WuiSvnLinkWithTooltip(oEntry.iRevision, 'vbox'), ## @todo add sRepository TestResultListingData … … 699 818 ], 700 819 oValidationKit, 701 '%s.%s' % (oEntry.sOs, oEntry.sArch),702 820 [ WuiTmLink(oEntry.sTestBoxName, WuiMain.ksScriptName, self._dTestBoxLinkParams, fBracketed = False, 703 821 sTitle = sTestBoxTitle), … … 706 824 TestBoxData.ksParam_idTestBox: oEntry.idTestBox }, 707 825 fBracketed = False) ], 826 '%s.%s' % (oEntry.sOs, oEntry.sArch), 708 827 [ WuiTmLink(oEntry.sTestCaseName, WuiMain.ksScriptName, self._dTestCaseLinkParams, fBracketed = False, 709 828 sTitle = (oEntry.sBaseCmd + ' ' + oEntry.sArgs) if oEntry.sArgs else oEntry.sBaseCmd), … … 713 832 fBracketed = False), ], 714 833 oEntry.tsElapsed, 715 aoTestSetLinks 834 aoTestSetLinks, 835 oReason 716 836 ];
Note:
See TracChangeset
for help on using the changeset viewer.