Changeset 61272 in vbox for trunk/src/VBox/ValidationKit/testmanager/webui
- Timestamp:
- May 29, 2016 6:54:05 AM (9 years ago)
- svn:sync-xref-src-repo-rev:
- 107564
- Location:
- trunk/src/VBox/ValidationKit/testmanager/webui
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/ValidationKit/testmanager/webui/wuiadmintestcase.py
r61255 r61272 32 32 # Validation Kit imports. 33 33 from common import utils, webutils; 34 from testmanager.webui.wuicontentbase import WuiFormContentBase, WuiListContentBase, Wui TmLink, WuiRawHtml;34 from testmanager.webui.wuicontentbase import WuiFormContentBase, WuiListContentBase, WuiContentBase, WuiTmLink, WuiRawHtml; 35 35 from testmanager.core.db import isDbTimestampInfinity; 36 36 from testmanager.core.testcase import TestCaseDataEx, TestCaseData, TestCaseDependencyLogic; 37 37 from testmanager.core.globalresource import GlobalResourceData, GlobalResourceLogic; 38 39 40 41 class WuiTestCaseDetailsLink(WuiTmLink): 42 """ Test case details link by ID. """ 43 44 def __init__(self, idTestCase, sName = WuiContentBase.ksShortDetailsLink, fBracketed = False, tsNow = None): 45 from testmanager.webui.wuiadmin import WuiAdmin; 46 dParams = { 47 WuiAdmin.ksParamAction: WuiAdmin.ksActionTestCaseDetails, 48 TestCaseData.ksParam_idTestCase: idTestCase, 49 }; 50 if tsNow is not None: 51 dParams[WuiAdmin.ksParamEffectiveDate] = tsNow; ## ?? 52 WuiTmLink.__init__(self, sName, WuiAdmin.ksScriptName, dParams, fBracketed = fBracketed); 53 self.idTestCase = idTestCase; 54 38 55 39 56 class WuiTestCaseList(WuiListContentBase): -
trunk/src/VBox/ValidationKit/testmanager/webui/wuicontentbase.py
r61253 r61272 173 173 def toHtml(self): 174 174 return self.sHtml; 175 176 class WuiHtmlKeeper(WuiHtmlBase): # pylint: disable=R0903 177 """ 178 For keeping a list of elements, concatenating their toHtml output together. 179 """ 180 def __init__(self, aoInitial = None, sSep = ' '): 181 WuiHtmlBase.__init__(self); 182 self.sSep = sSep; 183 self.aoKept = []; 184 if aoInitial is not None: 185 if isinstance(aoInitial, WuiHtmlBase): 186 self.aoKept.append(aoInitial); 187 else: 188 self.aoKept.extend(aoInitial); 189 190 def append(self, oObject): 191 """ Appends one objects. """ 192 self.aoKept.append(oObject); 193 194 def extend(self, aoObjects): 195 """ Appends a list of objects. """ 196 self.aoKept.extend(aoObjects); 197 198 def toHtml(self): 199 return self.sSep.join(oObj.toHtml() for oObj in self.aoKept); 175 200 176 201 class WuiSpanText(WuiRawHtml): # pylint: disable=R0903 … … 205 230 ## HTML hex entity string for ksShortDetailsLink. 206 231 ksShortChangeLogLinkHtml = '⎗' 232 ## The text/symbol for a very short reports link. 233 ksShortReportLink = u'\u2397' 234 ## HTML hex entity string for ksShortReportLink. 235 ksShortReportLinkHtml = '⎗' 207 236 208 237 … … 225 254 sTs = oTsZulu.strftime('%Y-%m-%d %H:%M:%SZ'); 226 255 return unicode(sTs).replace('-', u'\u2011').replace(' ', u'\u00a0'); 256 257 def getNowTs(self): 258 """ Gets a database compatible current timestamp from python. See db.dbTimestampPythonNow(). """ 259 return db.dbTimestampPythonNow(); 227 260 228 261 def formatIntervalShort(self, oInterval): -
trunk/src/VBox/ValidationKit/testmanager/webui/wuireport.py
r61271 r61272 32 32 # Validation Kit imports. 33 33 from common import webutils; 34 from testmanager.webui.wuicontentbase import WuiContentBase, Wui SvnLinkWithTooltip;34 from testmanager.webui.wuicontentbase import WuiContentBase, WuiTmLink, WuiSvnLinkWithTooltip; 35 35 from testmanager.webui.wuihlpgraph import WuiHlpGraphDataTable, WuiHlpBarGraph; 36 from testmanager.webui.wuitestresult import WuiTestSetLink; 37 from testmanager.webui.wuiadmintestcase import WuiTestCaseDetailsLink; 36 38 from testmanager.core.report import ReportModelBase; 39 40 41 class WuiReportSummaryLink(WuiTmLink): 42 """ Generic report summary link. """ 43 44 def __init__(self, sSubject, aIdSubjects, sName = WuiContentBase.ksShortReportLink, 45 tsNow = None, cPeriods = None, cHoursPerPeriod = None, fBracketed = False): 46 from testmanager.webui.wuimain import WuiMain; 47 dParams = { 48 WuiMain.ksParamAction: WuiMain.ksActionReportSummary, 49 WuiMain.ksParamReportSubject: sSubject, 50 WuiMain.ksParamReportSubjectIds: aIdSubjects, 51 }; 52 if tsNow is not None: 53 dParams[WuiMain.ksParamEffectiveDate] = tsNow; 54 if cPeriods is not None: 55 dParams[WuiMain.ksParamReportPeriods] = cPeriods; 56 if cPeriods is not None: 57 dParams[WuiMain.ksParamReportPeriodInHours] = cHoursPerPeriod; 58 WuiTmLink.__init__(self, sName, WuiMain.ksScriptName, dParams, fBracketed = fBracketed); 37 59 38 60 … … 77 99 sTitle = self._oModel.sSubject + ' - ' + sTitle; ## @todo add subject to title in a proper way! 78 100 101 sReport += '\n\n<!-- HEYYOU: sSubject=%s aidSubjects=%s -->\n\n' % (self._oModel.sSubject, self._oModel.aidSubjects); 79 102 return (sTitle, sReport); 80 103 … … 133 156 """ 134 157 158 def _splitSeriesIntoMultipleGraphs(self, aidSorted, cMaxSeriesPerGraph = 8): 159 """ 160 Splits the ID array into one or more arrays, making sure we don't 161 have too many series per graph. 162 Returns array of ID arrays. 163 """ 164 if len(aidSorted) <= cMaxSeriesPerGraph + 2: 165 return [aidSorted,]; 166 cGraphs = len(aidSorted) / cMaxSeriesPerGraph + (len(aidSorted) % cMaxSeriesPerGraph != 0); 167 cPerGraph = len(aidSorted) / cGraphs + (len(aidSorted) % cGraphs != 0); 168 169 aaoRet = []; 170 cLeft = len(aidSorted); 171 iSrc = 0; 172 while cLeft > 0: 173 cThis = cPerGraph; 174 if cLeft <= cPerGraph + 2: 175 cThis = cLeft; 176 elif cLeft <= cPerGraph * 2 + 4: 177 cThis = cLeft / 2; 178 aaoRet.append(aidSorted[iSrc : iSrc + cThis]); 179 iSrc += cThis; 180 cLeft -= cThis; 181 return aaoRet; 182 135 183 def _formatEdgeOccurenceSubject(self, oTransient): 136 184 """ … … 151 199 else: sHtml += 'Until '; 152 200 sHtml += WuiSvnLinkWithTooltip(oTransient.iRevision, oTransient.sRepository, fBracketed = 'False').toHtml(); 153 sHtml += u', %s: ' % (self.formatTsShort(oTransient.tsDone),); 201 sHtml += u', %s: ' % (WuiTestSetLink(oTransient.idTestSet, self.formatTsShort(oTransient.tsDone), 202 fBracketed = False).toHtml(), ) 154 203 sHtml += self._formatEdgeOccurenceSubject(oTransient); 155 204 sHtml += u'</li>\n'; … … 160 209 Generates the enter and leave lists. 161 210 """ 211 # Skip this if we're looking at builds. 212 if self._oModel.sSubject in [self._oModel.ksSubBuild,] and len(self._oModel.aidSubjects) in [1, 2]: 213 return u''; 214 162 215 sHtml = u'<h4>Movements:</h4>\n' \ 163 216 u'<ul>\n'; … … 174 227 175 228 229 def _formatSeriesNameForTable(self, oSet, idKey): 230 """ Formats the series name for the HTML table. """ 231 _ = oSet; 232 return '<td>%d</td>' % (idKey,); 233 234 def _formatRowValueForTable(self, oRow, oPeriod, cColsPerSeries): 235 """ Formats a row value for the HTML table. """ 236 _ = oPeriod; 237 if oRow is None: 238 return u'<td colspan="%d"> </td>' % (cColsPerSeries,); 239 if cColsPerSeries == 2: 240 return u'<td align="right">%u%%</td><td align="center">%u / %u</td>' \ 241 % (oRow.cHits * 100 / oRow.cTotal, oRow.cHits, oRow.cTotal); 242 return u'<td align="center">%u</td>' % (oRow.cHits,); 243 244 def _formatSeriesTotalForTable(self, oSet, idKey, cColsPerSeries): 245 """ Formats the totals cell for a data series in the HTML table. """ 246 dcTotalPerId = getattr(oSet, 'dcTotalPerId', None); 247 if cColsPerSeries == 2: 248 return u'<td align="right">%u%%</td><td align="center">%u/%u</td>' \ 249 % (oSet.dcHitsPerId[idKey] * 100 / dcTotalPerId[idKey], oSet.dcHitsPerId[idKey], dcTotalPerId[idKey]); 250 return u'<td align="center">%u</td>' % (oSet.dcHitsPerId[idKey],); 251 252 def _generateTableForSet(self, oSet, sColumnName, aidSorted = None, fWithTotals = True, cColsPerSeries = None): 253 """ 254 Turns the set into a table. 255 256 Returns raw html. 257 """ 258 sHtml = u'<table class="tmtbl-report-set" width="100%%">\n'; 259 if cColsPerSeries is None: 260 cColsPerSeries = 2 if hasattr(oSet, 'dcTotalPerId') else 1; 261 262 # Header row. 263 sHtml += u' <tr><thead><th></th><th>%s</th>' % (webutils.escapeElem(sColumnName),) 264 for oPeriod in reversed(oSet.aoPeriods): 265 sHtml += u'<th colspan="%d">%s</th>' % (cColsPerSeries, webutils.escapeElem(oPeriod.sDesc),); 266 if fWithTotals: 267 sHtml += u'<th colspan="%d">Total</th>' % (cColsPerSeries,); 268 sHtml += u'</thead></td>\n'; 269 270 # Each data series. 271 if aidSorted is None: 272 aidSorted = oSet.dSubjects.keys(); 273 sHtml += u' <tbody>\n'; 274 for iRow, idKey in enumerate(aidSorted): 275 sHtml += u' <tr class="%s">' % ('tmodd' if iRow & 1 else 'tmeven',); 276 sHtml += u'<td align="left">#%u</td>' % (iRow + 1,); 277 sHtml += self._formatSeriesNameForTable(oSet, idKey); 278 for oPeriod in reversed(oSet.aoPeriods): 279 oRow = oPeriod.dRowsById.get(idKey, None); 280 sHtml += self._formatRowValueForTable(oRow, oPeriod, cColsPerSeries); 281 if fWithTotals: 282 sHtml += self._formatSeriesTotalForTable(oSet, idKey, cColsPerSeries); 283 sHtml += u' </tr>\n'; 284 sHtml += u' </tbody>\n'; 285 sHtml += u'</table>\n'; 286 return sHtml; 287 288 289 176 290 177 291 class WuiReportFailureReasons(WuiReportFailuresBase): … … 184 298 webutils.escapeElem(oTransient.oReason.sShort),); 185 299 300 def _formatSeriesNameForTable(self, oSet, idKey): 301 oReason = oSet.dSubjects[idKey]; 302 sHtml = '<td>' 303 sHtml += u'%s / %s' % ( webutils.escapeElem(oReason.oCategory.sShort), webutils.escapeElem(oReason.sShort),); 304 sHtml += '</td>' 305 return sHtml; 306 186 307 187 308 def generateReportBody(self): … … 189 310 190 311 # 191 # Get the data and generate transition list.312 # Get the data and sort the data series in descending order of badness. 192 313 # 193 314 oSet = self._oModel.getFailureReasons(); 194 sHtml = self._generateTransitionList(oSet); 315 aidSorted = sorted(oSet.dSubjects, key = lambda idReason: oSet.dcHitsPerId[idReason], reverse = True); 316 317 # 318 # Generate table and transition list. These are the most useful ones with the current graph machinery. 319 # 320 sHtml = self._generateTableForSet(oSet, 'Test Cases', aidSorted); 321 sHtml += self._generateTransitionList(oSet); 195 322 196 323 # … … 208 335 # Generate the graph. 209 336 # 210 aidSorted = sorted(oSet.dSubjects, key = lambda idReason: oSet.dcHitsPerId[idReason], reverse = True); 211 212 asNames = []; 213 for idReason in aidSorted: 214 oReason = oSet.dSubjects[idReason]; 215 asNames.append('%s / %s' % (oReason.oCategory.sShort, oReason.sShort,) ) 216 if fIncludeWithoutReason: 217 asNames.append('No reason'); 218 219 oTable = WuiHlpGraphDataTable('Period', asNames); 220 221 cMax = oSet.cMaxHits; 222 for _, oPeriod in enumerate(reversed(oSet.aoPeriods)): 223 aiValues = []; 224 337 fGenerateGraph = True; 338 if fGenerateGraph: 339 asNames = []; 225 340 for idReason in aidSorted: 226 oRow = oPeriod.dRowsById.get(idReason, None); 227 iValue = oRow.cHits if oRow is not None else 0; 228 aiValues.append(iValue); 229 341 oReason = oSet.dSubjects[idReason]; 342 asNames.append('%s / %s' % (oReason.oCategory.sShort, oReason.sShort,) ) 230 343 if fIncludeWithoutReason: 231 aiValues.append(oPeriod.cWithoutReason); 232 if oPeriod.cWithoutReason > cMax: 233 cMax = oPeriod.cWithoutReason; 234 235 oTable.addRow(oPeriod.sDesc, aiValues); 236 237 oGraph = WuiHlpBarGraph('failure-reason', oTable, self._oDisp); 238 oGraph.setRangeMax(max(cMax + 1, 3)); 239 sHtml += oGraph.renderGraph(); 240 241 # 242 # Table form necessary? 243 # 244 #sHtml += u'<p>TODO: Show graph content in table form.</p>'; 245 344 asNames.append('No reason'); 345 346 oTable = WuiHlpGraphDataTable('Period', asNames); 347 348 cMax = oSet.cMaxHits; 349 for _, oPeriod in enumerate(reversed(oSet.aoPeriods)): 350 aiValues = []; 351 352 for idReason in aidSorted: 353 oRow = oPeriod.dRowsById.get(idReason, None); 354 iValue = oRow.cHits if oRow is not None else 0; 355 aiValues.append(iValue); 356 357 if fIncludeWithoutReason: 358 aiValues.append(oPeriod.cWithoutReason); 359 if oPeriod.cWithoutReason > cMax: 360 cMax = oPeriod.cWithoutReason; 361 362 oTable.addRow(oPeriod.sDesc, aiValues); 363 364 oGraph = WuiHlpBarGraph('failure-reason', oTable, self._oDisp); 365 oGraph.setRangeMax(max(cMax + 1, 3)); 366 sHtml += oGraph.renderGraph(); 246 367 return sHtml; 247 368 … … 253 374 254 375 def _formatEdgeOccurenceSubject(self, oTransient): 255 return u'%s (#%u)' % ( webutils.escapeElem(oTransient.oTestCase.sName), oTransient.oTestCase.idTestCase,); 256 376 sHtml = u'%s ' % ( webutils.escapeElem(oTransient.oTestCase.sName),); 377 sHtml += WuiTestCaseDetailsLink(oTransient.oTestCase.idTestCase, fBracketed = False).toHtml(); 378 return sHtml; 379 380 def _formatSeriesNameForTable(self, oSet, idKey): 381 oTestCase = oSet.dSubjects[idKey]; 382 sHtml = '<td>' 383 sHtml += WuiReportSummaryLink(ReportModelBase.ksSubTestCase, oTestCase.idTestCase, sName = oTestCase.sName).toHtml(); 384 sHtml += u' '; 385 sHtml += WuiTestCaseDetailsLink(oTestCase.idTestCase).toHtml(); 386 sHtml += '</td>' 387 return sHtml; 257 388 258 389 def generateReportBody(self): 259 390 self._sTitle = 'Test Case Failures'; 260 391 261 # 262 # Get the data and generate transition list. 392 393 # 394 # Get the data and sort the data series in descending order of badness. 263 395 # 264 396 oSet = self._oModel.getTestCaseFailures(); 265 sHtml = self._generateTransitionList(oSet); 397 if self._oModel.tsNow is not None and False: 398 # Sort the total. 399 aidSortedRaw = sorted(oSet.dSubjects, 400 key = lambda idKey: oSet.dcHitsPerId[idKey] * 10000 / oSet.dcTotalPerId[idKey], 401 reverse = True); 402 else: 403 # Sort by NOW column. 404 dTmp = {}; 405 for idKey in oSet.dSubjects: 406 oRow = oSet.aoPeriods[-1].dRowsById.get(idKey, None); 407 if oRow is None: dTmp[idKey] = 0; 408 else: dTmp[idKey] = oRow.cHits * 10000 / max(1, oRow.cTotal); 409 aidSortedRaw = sorted(dTmp, key = lambda idKey: dTmp[idKey], reverse = True); 410 411 # 412 # Generate table and transition list. These are the most useful ones with the current graph machinery. 413 # 414 sHtml = self._generateTableForSet(oSet, 'Test Cases', aidSortedRaw); 415 sHtml += self._generateTransitionList(oSet); 266 416 267 417 # 268 418 # Generate the graph. 269 419 # 270 aidSorted = sorted(oSet.dSubjects, 271 key = lambda idKey: oSet.dcHitsPerId[idKey] * 10000 / oSet.dcTotalPerId[idKey], 272 reverse = True); 273 274 asNames = []; 275 for idKey in aidSorted: 276 oSubject = oSet.dSubjects[idKey]; 277 asNames.append(oSubject.sName); 278 279 oTable = WuiHlpGraphDataTable('Period', asNames); 280 281 uPctMax = 10; 282 for _, oPeriod in enumerate(reversed(oSet.aoPeriods)): 283 aiValues = []; 284 asValues = []; 285 286 for idKey in aidSorted: 287 oRow = oPeriod.dRowsById.get(idKey, None); 288 if oRow is not None: 289 uPct = oRow.cHits * 100 / oRow.cTotal; 290 uPctMax = max(uPctMax, uPct); 291 aiValues.append(uPct); 292 asValues.append('%u%% (%u/%u)' % (uPct, oRow.cHits, oRow.cTotal)); 293 else: 294 aiValues.append(0); 295 asValues.append('0'); 296 297 oTable.addRow(oPeriod.sDesc, aiValues, asValues); 298 299 if True: # pylint: disable=W0125 300 aiValues = []; 301 asValues = []; 302 for idKey in aidSorted: 303 uPct = oSet.dcHitsPerId[idKey] * 100 / oSet.dcTotalPerId[idKey]; 304 uPctMax = max(uPctMax, uPct); 305 aiValues.append(uPct); 306 asValues.append('%u%% (%u/%u)' % (uPct, oSet.dcHitsPerId[idKey], oSet.dcTotalPerId[idKey])); 307 oTable.addRow('Totals', aiValues, asValues); 308 309 oGraph = WuiHlpBarGraph('testcase-failures', oTable, self._oDisp); 310 oGraph.setRangeMax(uPct + 2); 311 sHtml += oGraph.renderGraph(); 420 fGenerateGraph = len(aidSortedRaw) <= 6; ## Make this configurable. 421 if fGenerateGraph: 422 # Figure the graph width for all of them. 423 uPctMax = max(oSet.uMaxPct, oSet.cMaxHits * 100 / oSet.cMaxTotal); 424 uPctMax = max(uPctMax + 2, 10); 425 426 for _, aidSorted in enumerate(self._splitSeriesIntoMultipleGraphs(aidSortedRaw, 8)): 427 asNames = []; 428 for idKey in aidSorted: 429 oSubject = oSet.dSubjects[idKey]; 430 asNames.append(oSubject.sName); 431 432 oTable = WuiHlpGraphDataTable('Period', asNames); 433 434 for _, oPeriod in enumerate(reversed(oSet.aoPeriods)): 435 aiValues = []; 436 asValues = []; 437 438 for idKey in aidSorted: 439 oRow = oPeriod.dRowsById.get(idKey, None); 440 if oRow is not None: 441 uPct = oRow.cHits * 100 / oRow.cTotal; 442 aiValues.append(uPct); 443 asValues.append('%u%% (%u/%u)' % (uPct, oRow.cHits, oRow.cTotal)); 444 else: 445 aiValues.append(0); 446 asValues.append('0'); 447 448 oTable.addRow(oPeriod.sDesc, aiValues, asValues); 449 450 if True: # pylint: disable=W0125 451 aiValues = []; 452 asValues = []; 453 for idKey in aidSorted: 454 uPct = oSet.dcHitsPerId[idKey] * 100 / oSet.dcTotalPerId[idKey]; 455 aiValues.append(uPct); 456 asValues.append('%u%% (%u/%u)' % (uPct, oSet.dcHitsPerId[idKey], oSet.dcTotalPerId[idKey])); 457 oTable.addRow('Totals', aiValues, asValues); 458 459 oGraph = WuiHlpBarGraph('testcase-failures', oTable, self._oDisp); 460 oGraph.setRangeMax(uPctMax); 461 sHtml += '<br>\n'; 462 sHtml += oGraph.renderGraph(); 312 463 313 464 return sHtml; -
trunk/src/VBox/ValidationKit/testmanager/webui/wuitestresult.py
r61267 r61272 30 30 31 31 # Python imports. 32 import datetime; 32 33 33 34 # Validation Kit imports. 34 35 from testmanager.webui.wuicontentbase import WuiContentBase, WuiListContentBase, WuiHtmlBase, WuiTmLink, WuiLinkBase, \ 35 WuiSvnLink, WuiSvnLinkWithTooltip, WuiBuildLogLink, WuiRawHtml; 36 WuiSvnLink, WuiSvnLinkWithTooltip, WuiBuildLogLink, WuiRawHtml, \ 37 WuiHtmlKeeper; 36 38 from testmanager.webui.wuimain import WuiMain; 37 39 from testmanager.webui.wuihlpform import WuiHlpForm; … … 39 41 from testmanager.webui.wuitestresultfailure import WuiTestResultFailureDetailsLink; 40 42 from testmanager.core.failurereason import FailureReasonData, FailureReasonLogic; 41 from testmanager.core.report import ReportGraphModel ;43 from testmanager.core.report import ReportGraphModel, ReportModelBase; 42 44 from testmanager.core.testbox import TestBoxData; 43 45 from testmanager.core.testcase import TestCaseData; … … 49 51 from testmanager import config; 50 52 from common import webutils, utils; 53 54 55 class WuiTestSetLink(WuiTmLink): 56 """ Test set link. """ 57 58 def __init__(self, idTestSet, sName = WuiContentBase.ksShortDetailsLink, fBracketed = False): 59 WuiTmLink.__init__(self, sName, WuiMain.ksScriptName, 60 { WuiMain.ksParamAction: WuiMain.ksActionTestResultDetails, 61 TestSetData.ksParam_idTestSet: idTestSet, }, fBracketed = fBracketed); 62 self.idTestSet = idTestSet; 51 63 52 64 … … 442 454 asHtml = [] 443 455 456 from testmanager.webui.wuireport import WuiReportSummaryLink; 457 tsReportEffectiveDate = None; 458 if oTestSet.tsDone is not None: 459 tsReportEffectiveDate = oTestSet.tsDone + datetime.timedelta(days = 4); 460 if tsReportEffectiveDate >= self.getNowTs(): 461 tsReportEffectiveDate = None; 462 444 463 # Test result + test set details. 445 464 aoResultRows = [ 446 WuiTmLink(oTestCaseEx.sName, self.oWuiAdmin.ksScriptName, 447 { self.oWuiAdmin.ksParamAction: self.oWuiAdmin.ksActionTestCaseDetails, 448 TestCaseData.ksParam_idTestCase: oTestCaseEx.idTestCase, 449 self.oWuiAdmin.ksParamEffectiveDate: oTestSet.tsConfig, }, 450 fBracketed = False), 465 WuiHtmlKeeper([ WuiTmLink(oTestCaseEx.sName, self.oWuiAdmin.ksScriptName, 466 { self.oWuiAdmin.ksParamAction: self.oWuiAdmin.ksActionTestCaseDetails, 467 TestCaseData.ksParam_idTestCase: oTestCaseEx.idTestCase, 468 self.oWuiAdmin.ksParamEffectiveDate: oTestSet.tsConfig, }, 469 fBracketed = False), 470 WuiReportSummaryLink(ReportModelBase.ksSubTestCase, oTestCaseEx.idTestCase, 471 tsNow = tsReportEffectiveDate, fBracketed = False), 472 ]), 451 473 ]; 452 474 if oTestCaseEx.sDescription is not None and len(oTestCaseEx.sDescription) > 0: … … 483 505 484 506 aoResultRows += [ 485 ( 'Test Group:', WuiTmLink(oTestGroup.sName, self.oWuiAdmin.ksScriptName, 486 { self.oWuiAdmin.ksParamAction: self.oWuiAdmin.ksActionTestGroupDetails, 487 TestGroupData.ksParam_idTestGroup: oTestGroup.idTestGroup, 488 self.oWuiAdmin.ksParamEffectiveDate: oTestSet.tsConfig, }, 489 fBracketed = False) ), 507 ( 'Test Group:', 508 WuiHtmlKeeper([ WuiTmLink(oTestGroup.sName, self.oWuiAdmin.ksScriptName, 509 { self.oWuiAdmin.ksParamAction: self.oWuiAdmin.ksActionTestGroupDetails, 510 TestGroupData.ksParam_idTestGroup: oTestGroup.idTestGroup, 511 self.oWuiAdmin.ksParamEffectiveDate: oTestSet.tsConfig, }, 512 fBracketed = False), 513 WuiReportSummaryLink(ReportModelBase.ksSubTestGroup, oTestGroup.idTestGroup, 514 tsNow = tsReportEffectiveDate, fBracketed = False), 515 ]), ), 490 516 ]; 491 517 if oTestVarEx.sTestBoxReqExpr is not None: … … 508 534 if oBuildEx is not None: 509 535 aoBuildRows += [ 510 WuiTmLink('Build', self.oWuiAdmin.ksScriptName, 511 { self.oWuiAdmin.ksParamAction: self.oWuiAdmin.ksActionBuildDetails, 512 BuildData.ksParam_idBuild: oBuildEx.idBuild, 513 self.oWuiAdmin.ksParamEffectiveDate: oTestSet.tsCreated, }, 514 fBracketed = False), 536 WuiHtmlKeeper([ WuiTmLink('Build', self.oWuiAdmin.ksScriptName, 537 { self.oWuiAdmin.ksParamAction: self.oWuiAdmin.ksActionBuildDetails, 538 BuildData.ksParam_idBuild: oBuildEx.idBuild, 539 self.oWuiAdmin.ksParamEffectiveDate: oTestSet.tsCreated, }, 540 fBracketed = False), 541 WuiReportSummaryLink(ReportModelBase.ksSubBuild, oBuildEx.idBuild, 542 tsNow = tsReportEffectiveDate, fBracketed = False), ]), 515 543 ]; 516 544 self._anchorAndAppendBinaries(oBuildEx.sBinaries, aoBuildRows); … … 558 586 # TestBox. 559 587 aoTestBoxRows = [ 560 WuiTmLink(oTestBox.sName, self.oWuiAdmin.ksScriptName, 561 { self.oWuiAdmin.ksParamAction: self.oWuiAdmin.ksActionTestBoxDetails, 562 TestBoxData.ksParam_idGenTestBox: oTestSet.idGenTestBox, }, 563 fBracketed = False), 588 WuiHtmlKeeper([ WuiTmLink(oTestBox.sName, self.oWuiAdmin.ksScriptName, 589 { self.oWuiAdmin.ksParamAction: self.oWuiAdmin.ksActionTestBoxDetails, 590 TestBoxData.ksParam_idGenTestBox: oTestSet.idGenTestBox, }, 591 fBracketed = False), 592 WuiReportSummaryLink(ReportModelBase.ksSubTestBox, oTestSet.idTestBox, 593 tsNow = tsReportEffectiveDate, fBracketed = False), ]), 564 594 ]; 565 595 if oTestBox.sDescription is not None and len(oTestBox.sDescription) > 0: … … 756 786 757 787 from testmanager.webui.wuiadmin import WuiAdmin; 758 788 from testmanager.webui.wuireport import WuiReportSummaryLink; 759 789 760 790 oValidationKit = None; … … 842 872 { WuiAdmin.ksParamAction: WuiAdmin.ksActionTestBoxDetails, 843 873 TestBoxData.ksParam_idTestBox: oEntry.idTestBox }, 844 fBracketed = False) ], 874 fBracketed = False), 875 WuiReportSummaryLink(ReportModelBase.ksSubTestBox, oEntry.idTestBox, fBracketed = False), ], 845 876 '%s.%s' % (oEntry.sOs, oEntry.sArch), 846 877 [ WuiTmLink(sTestCaseName, WuiMain.ksScriptName, self._dTestCaseLinkParams, fBracketed = False, … … 849 880 { WuiAdmin.ksParamAction: WuiAdmin.ksActionTestCaseDetails, 850 881 TestCaseData.ksParam_idTestCase: oEntry.idTestCase }, 851 fBracketed = False), ], 882 fBracketed = False), 883 WuiReportSummaryLink(ReportModelBase.ksSubTestCase, oEntry.idTestCase, fBracketed = False), ], 852 884 oEntry.tsElapsed, 853 885 aoTestSetLinks,
Note:
See TracChangeset
for help on using the changeset viewer.