VirtualBox

Changeset 64986 in vbox


Ignore:
Timestamp:
Dec 21, 2016 2:36:33 PM (8 years ago)
Author:
vboxsync
Message:

testmanager/webui: started on test result filtering.

Location:
trunk/src/VBox/ValidationKit/testmanager
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/ValidationKit/testmanager/htdocs/css/common.css

    r61255 r64986  
    138138#side-menu {
    139139    position:       fixed;
    140     width:          110px;
     140    width:          116px;
    141141    height:         auto;
    142142    top:            92px;
     
    152152    max-height:     28px;
    153153    top:            92px;
    154     left:           118px;
     154    left:           0px;
    155155    right:          0;
    156156    bottom:         auto;
     
    161161    width:          auto;
    162162    height:         auto;
    163     top:            118px;  /**< header + top-menu + padding. */
     163    top:            124px;  /**< header + top-menu + padding. */
    164164    right:          0;
    165165    bottom:         0;
    166     left:           118px;
     166    left:           124px;
    167167    overflow:       auto;
    168168    padding-top:    16px;
     
    217217
    218218#side-menu {
    219     padding-top:    36px;
     219    padding-top:    28px; /**< #top-menu.max-height */
    220220    margin-right:   3px;
    221221    margin-left:    3px;
     
    235235
    236236#side-menu li {
    237     padding-bottom: 0.8em;
    238     line-height:    1.2em;
    239     text-align:     center;
    240 }
     237    padding-top:    0.3em;
     238    padding-bottom: 0.3em;
     239    line-height:    1.0em;
     240    text-align:     left;
     241}
     242
     243#side-menu .subheader_item {
     244    font-style:     italic;
     245    font-size:      1.1em;
     246    text-decoration: underline;
     247}
     248
     249.subheader_item:not(:first-child) {
     250    margin-top:     0.5em;
     251}
     252
     253
     254#side-filters p:first-child {
     255    margin-top:     0.5em;
     256    font-style:     italic;
     257    font-size:      1.1em;
     258    text-decoration: underline;
     259}
     260
     261#side-filters dd.sf-collapsable {
     262    display:        block;
     263}
     264
     265#side-filters dd.sf-expandable {
     266    display:        none;
     267}
     268
     269#side-filters a {
     270    text-decoration: none;
     271    color:          #000000;
     272}
     273
    241274
    242275#side-footer {
  • trunk/src/VBox/ValidationKit/testmanager/htdocs/js/common.js

    r61217 r64986  
    352352}
    353353
     354
     355/** @name Collapsable / Expandable items
     356 * @{
     357 */
     358
     359
     360/**
     361 * Toggles the collapsable / expandable state of a parent DD and DT unclke.
     362 *
     363 * @returns true
     364 * @param   oAnchor             The anchor object.
     365 */
     366function toggleCollapsableDtDd(oAnchor)
     367{
     368    var oParent = oAnchor.parentElement;
     369    var sClass  = oParent.className;
     370    var oUncle  = oParent.nextSibling;
     371    var sNewClass;
     372    var sNewChar;
     373
     374    /* Determin the new class and arrow char. */
     375    if (sClass.endsWith('collapsable'))
     376    {
     377        sNewClass = sClass.substr(0, sClass.length - 11) + 'expandable';
     378        sNewChar  = '\u25B6'; /* black right-pointing triangle */
     379    }
     380    else if (sClass.endsWith('expandable'))
     381    {
     382        sNewClass = sClass.substr(0, sClass.length - 10) + 'collapsable';
     383        sNewChar  = '\u25BC'; /* black down-pointing triangle */
     384    }
     385    else
     386    {
     387        console.log('toggleCollapsableParent: Invalid class: ' + sClass);
     388        return true;
     389    }
     390
     391    /* Update the parent (DT) class and anchor text. */
     392    oParent.className   = sNewClass;
     393    oAnchor.firstChild.textContent = sNewChar + oAnchor.firstChild.textContent.substr(1);
     394
     395    /* Update the uncle (DD) class.*/
     396    if (oUncle)
     397        oUncle.className = sNewClass;
     398    return true;
     399}
     400
     401/** @} */
    354402
    355403
  • trunk/src/VBox/ValidationKit/testmanager/webui/template.html

    r64951 r64986  
    2929
    3030<div id="side-menu">
    31     <ul>
    32         @@SIDE_MENU_ITEMS@@
    33     </ul>
     31    <form id="side-menu-form">
     32        <ul>
     33            @@SIDE_MENU_ITEMS@@
     34        </ul>
     35        @@SIDE_FILTER_CONTROL@@
     36    </form>
    3437    <div id="side-footer">
    3538        <p>
  • trunk/src/VBox/ValidationKit/testmanager/webui/wuiadmin.py

    r62484 r64986  
    315315                    [ 'Builds',                 self._sActionUrlBase + self.ksActionBuildList ],
    316316                    [ 'Blacklist',              self._sActionUrlBase + self.ksActionBuildBlacklist ],
    317                     [ 'Build Sources',          self._sActionUrlBase + self.ksActionBuildSrcList ],
    318                     [ 'Build Categories',       self._sActionUrlBase + self.ksActionBuildCategoryList ],
    319                     [ 'New Build',              self._sActionUrlBase + self.ksActionBuildAdd ],
    320                     [ 'New Blacklisting',       self._sActionUrlBase + self.ksActionBuildBlacklistAdd ],
    321                     [ 'New Build Source',       self._sActionUrlBase + self.ksActionBuildSrcAdd],
    322                     [ 'New Build Category',     self._sActionUrlBase + self.ksActionBuildCategoryAdd ],
     317                    [ 'Build sources',          self._sActionUrlBase + self.ksActionBuildSrcList ],
     318                    [ 'Build categories',       self._sActionUrlBase + self.ksActionBuildCategoryList ],
     319                    [ 'New build',              self._sActionUrlBase + self.ksActionBuildAdd ],
     320                    [ 'New blacklisting',       self._sActionUrlBase + self.ksActionBuildBlacklistAdd ],
     321                    [ 'New build source',       self._sActionUrlBase + self.ksActionBuildSrcAdd],
     322                    [ 'New build category',     self._sActionUrlBase + self.ksActionBuildCategoryAdd ],
    323323                ]
    324324            ],
     
    326326                'Failure Reasons',       self._sActionUrlBase + self.ksActionFailureReasonList,
    327327                [
    328                     [ 'Failure Categories',     self._sActionUrlBase + self.ksActionFailureCategoryList ],
    329                     [ 'Failure Reasons',        self._sActionUrlBase + self.ksActionFailureReasonList ],
    330                     [ 'New Failure Category',   self._sActionUrlBase + self.ksActionFailureCategoryAdd ],
    331                     [ 'New Failure Reason',     self._sActionUrlBase + self.ksActionFailureReasonAdd ],
     328                    [ 'Failure categories',     self._sActionUrlBase + self.ksActionFailureCategoryList ],
     329                    [ 'Failure reasons',        self._sActionUrlBase + self.ksActionFailureReasonList ],
     330                    [ 'New failure category',   self._sActionUrlBase + self.ksActionFailureCategoryAdd ],
     331                    [ 'New failure reason',     self._sActionUrlBase + self.ksActionFailureReasonAdd ],
    332332                ]
    333333            ],
     
    335335                'System',      self._sActionUrlBase + self.ksActionSystemLogList,
    336336                [
    337                     [ 'System Log',             self._sActionUrlBase + self.ksActionSystemLogList ],
    338                     [ 'User Accounts',          self._sActionUrlBase + self.ksActionUserList ],
    339                     [ 'New User',               self._sActionUrlBase + self.ksActionUserAdd ],
     337                    [ 'System log',             self._sActionUrlBase + self.ksActionSystemLogList ],
     338                    [ 'User accounts',          self._sActionUrlBase + self.ksActionUserList ],
     339                    [ 'New user',               self._sActionUrlBase + self.ksActionUserAdd ],
    340340                ]
    341341            ],
    342342            [
    343                 'TestBoxes',   self._sActionUrlBase + self.ksActionTestBoxList,
     343                'Testboxes',   self._sActionUrlBase + self.ksActionTestBoxList,
    344344                [
    345                     [ 'TestBoxes',              self._sActionUrlBase + self.ksActionTestBoxList ],
    346                     [ 'Scheduling Groups',      self._sActionUrlBase + self.ksActionSchedGroupList ],
    347                     [ 'New TestBox',            self._sActionUrlBase + self.ksActionTestBoxAdd ],
    348                     [ 'New Scheduling Group',   self._sActionUrlBase + self.ksActionSchedGroupAdd ],
    349                     [ 'Regenerate All Scheduling Queues', self._sActionUrlBase + self.ksActionTestBoxesRegenQueues ],
     345                    [ 'Testboxes',              self._sActionUrlBase + self.ksActionTestBoxList ],
     346                    [ 'Scheduling groups',      self._sActionUrlBase + self.ksActionSchedGroupList ],
     347                    [ 'New testbox',            self._sActionUrlBase + self.ksActionTestBoxAdd ],
     348                    [ 'New scheduling group',   self._sActionUrlBase + self.ksActionSchedGroupAdd ],
     349                    [ 'Regenerate all scheduling queues', self._sActionUrlBase + self.ksActionTestBoxesRegenQueues ],
    350350                ]
    351351            ],
     
    353353                'Test Config', self._sActionUrlBase + self.ksActionTestGroupList,
    354354                [
    355                     [ 'Test Cases',             self._sActionUrlBase + self.ksActionTestCaseList ],
    356                     [ 'Test Groups',            self._sActionUrlBase + self.ksActionTestGroupList ],
    357                     [ 'Global Resources',       self._sActionUrlBase + self.ksActionGlobalRsrcShowAll ],
    358                     [ 'New Test Case',          self._sActionUrlBase + self.ksActionTestCaseAdd ],
    359                     [ 'New Test Group',         self._sActionUrlBase + self.ksActionTestGroupAdd ],
    360                     [ 'New Global Resource',    self._sActionUrlBase + self.ksActionGlobalRsrcShowAdd ],
    361                     [ 'Regenerate All Scheduling Queues', self._sActionUrlBase + self.ksActionTestCfgRegenQueues ],
     355                    [ 'Test cases',             self._sActionUrlBase + self.ksActionTestCaseList ],
     356                    [ 'Test groups',            self._sActionUrlBase + self.ksActionTestGroupList ],
     357                    [ 'Global resources',       self._sActionUrlBase + self.ksActionGlobalRsrcShowAll ],
     358                    [ 'New test case',          self._sActionUrlBase + self.ksActionTestCaseAdd ],
     359                    [ 'New test group',         self._sActionUrlBase + self.ksActionTestGroupAdd ],
     360                    [ 'New global resource',    self._sActionUrlBase + self.ksActionGlobalRsrcShowAdd ],
     361                    [ 'Regenerate all scheduling queues', self._sActionUrlBase + self.ksActionTestCfgRegenQueues ],
    362362                ]
    363363            ],
  • trunk/src/VBox/ValidationKit/testmanager/webui/wuiadmintestbox.py

    r64719 r64986  
    205205            cDead   = 0;
    206206            for oTestBox in self._aoEntries:
    207                 oDelta = oTestBox.tsCurrent - oTestBox.oStatus.tsUpdated;
    208                 if oDelta.days <= 0 and oDelta.seconds <= self.kcSecMaxStatusDeltaAlive:
    209                     if oTestBox.fEnabled:
    210                         cActive += 1;
     207                if oTestBox.oStatus is not None:
     208                    oDelta = oTestBox.tsCurrent - oTestBox.oStatus.tsUpdated;
     209                    if oDelta.days <= 0 and oDelta.seconds <= self.kcSecMaxStatusDeltaAlive:
     210                        if oTestBox.fEnabled:
     211                            cActive += 1;
     212                    else:
     213                        cDead += 1;
    211214                else:
    212215                    cDead += 1;
  • trunk/src/VBox/ValidationKit/testmanager/webui/wuibase.py

    r62484 r64986  
    3333import os;
    3434import sys;
     35import string;
    3536
    3637# Validation Kit imports.
     
    115116        self._sPageTitle        = '$$TODO$$';   # The page title.
    116117        self._aaoMenus          = [];           # List of [sName, sLink, [ [sSideName, sLink], .. ] tuples.
     118        self._sPageFilter       = '';           # The filter controls (optional).
    117119        self._sPageBody         = '$$TODO$$';   # The body text.
    118120        self._sRedirectTo       = None;
     
    154156    def _isMenuMatch(self, sMenuUrl, sActionParam):
    155157        """ Overridable menu matcher. """
    156         return sMenuUrl.find(sActionParam) > 0;
     158        return sMenuUrl is not None and sMenuUrl.find(sActionParam) > 0;
    157159
    158160    def _isSideMenuMatch(self, sSideMenuUrl, sActionParam):
    159161        """ Overridable side menu matcher. """
    160         return sSideMenuUrl.find(sActionParam) > 0;
     162        return sSideMenuUrl is not None and sSideMenuUrl.find(sActionParam) > 0;
    161163
    162164    def _generateMenus(self):
     
    200202        if aasSideMenu is not None:
    201203            for asSubItem in aasSideMenu:
    202                 if self._isSideMenuMatch(asSubItem[1], sActionParam):
    203                     sSideMenuItems += '<li class="current_page_item">';
     204                if asSubItem[1] is not None:
     205                    if self._isSideMenuMatch(asSubItem[1], sActionParam):
     206                        sSideMenuItems += '<li class="current_page_item">';
     207                    else:
     208                        sSideMenuItems += '<li>';
     209                    sSideMenuItems += '<a href="' + webutils.escapeAttr(asSubItem[1]) + '">' \
     210                                    + webutils.escapeElem(asSubItem[0]) + '</a></li>\n';
    204211                else:
    205                     sSideMenuItems += '<li>';
    206                 sSideMenuItems += '<a href="' + webutils.escapeAttr(asSubItem[1]) + '">' \
    207                                 + webutils.escapeElem(asSubItem[0]) + '</a></li>\n';
    208 
     212                    sSideMenuItems += '<li class="subheader_item">' + webutils.escapeElem(asSubItem[0]) + '</a></li>';
    209213        return (sTopMenuItems, sSideMenuItems);
    210214
    211 
    212215    def _generatePage(self):
    213216        """
     
    216219        assert self._sRedirectTo is None;
    217220
    218         # Load the template.
    219         oFile = open(os.path.join(self._oSrvGlue.pathTmWebUI(), self._sTemplate));
    220         sTmpl = oFile.read();
    221         oFile.close();
    222 
    223         # Do replacements.
    224         sTmpl = sTmpl.replace('@@PAGE_TITLE@@', self._sPageTitle);
    225         sTmpl = sTmpl.replace('@@PAGE_BODY@@', self._sPageBody);
    226         if self._oCurUser is not None:
    227             sTmpl = sTmpl.replace('@@USER_NAME@@', self._oCurUser.sUsername);
    228         else:
    229             sTmpl = sTmpl.replace('@@USER_NAME@@', 'unauthorized user "' + self._oSrvGlue.getLoginName() + '"');
    230         sTmpl = sTmpl.replace('@@TESTMANAGER_VERSION@@', config.g_ksVersion);
    231         sTmpl = sTmpl.replace('@@TESTMANAGER_REVISION@@', config.g_ksRevision);
    232         sTmpl = sTmpl.replace('@@BASE_URL@@', self._oSrvGlue.getBaseUrl());
    233 
    234         (sTopMenuItems, sSideMenuItems) = self._generateMenus();
    235         sTmpl = sTmpl.replace('@@TOP_MENU_ITEMS@@', sTopMenuItems);
    236         sTmpl = sTmpl.replace('@@SIDE_MENU_ITEMS@@', sSideMenuItems);
     221        #
     222        # Build the replacement string dictionary.
     223        #
    237224
    238225        # Provide basic auth log out for browsers that supports it.
     
    265252        else:
    266253            sLogOut = ''
    267         sTmpl = sTmpl.replace('@@LOG_OUT@@', sLogOut)
    268 
    269         # Debug section.
     254
     255        # Prep Menus.
     256        (sTopMenuItems, sSideMenuItems) = self._generateMenus();
     257
     258        # The dictionary (max variable length is 28 chars (see further down)).
     259        dReplacements = {
     260            '@@PAGE_TITLE@@':           self._sPageTitle,
     261            '@@LOG_OUT@@':              sLogOut,
     262            '@@TESTMANAGER_VERSION@@':  config.g_ksVersion,
     263            '@@TESTMANAGER_REVISION@@': config.g_ksRevision,
     264            '@@BASE_URL@@':             self._oSrvGlue.getBaseUrl(),
     265            '@@TOP_MENU_ITEMS@@':       sTopMenuItems,
     266            '@@SIDE_MENU_ITEMS@@':      sSideMenuItems,
     267            '@@SIDE_FILTER_CONTROL@@':  self._sPageFilter,
     268            '@@PAGE_BODY@@':            self._sPageBody,
     269            '@@DEBUG@@':                '',
     270        };
     271
     272        # Special current user handling.
     273        if self._oCurUser is not None:
     274            dReplacements['@@USER_NAME@@'] = self._oCurUser.sUsername;
     275        else:
     276            dReplacements['@@USER_NAME@@'] = 'unauthorized user "' + self._oSrvGlue.getLoginName() + '"';
     277
     278        # Prep debug section.
    270279        if self._sDebug == '':
    271280            if config.g_kfWebUiSqlTrace or self._fDbgSqlTrace or self._fDbgSqlExplain:
     
    278287            if config.g_kfWebUiDebugPanel:
    279288                self._sDebug += self._debugRenderPanel();
    280 
    281289        if self._sDebug != '':
    282             sTmpl = sTmpl.replace('@@DEBUG@@', '<div id="debug"><br><br><hr/>' + \
    283                 unicode(self._sDebug, errors='ignore') if isinstance(self._sDebug, str) else self._sDebug + '</div>');
    284         else:
    285             sTmpl = sTmpl.replace('@@DEBUG@@', '');
    286 
    287         # Output the result.
    288         self._oSrvGlue.write(sTmpl);
     290            dReplacements['@@DEBUG@@'] = '<div id="debug"><br><br><hr/>' + \
     291                unicode(self._sDebug, errors='ignore') if isinstance(self._sDebug, str) else self._sDebug + '</div>';
     292
     293        #
     294        # Load the template.
     295        #
     296        oFile = open(os.path.join(self._oSrvGlue.pathTmWebUI(), self._sTemplate));
     297        sTmpl = oFile.read();
     298        oFile.close();
     299
     300        #
     301        # Process the template, outputting each part we process.
     302        #
     303        offStart = 0;
     304        offCur   = 0;
     305        while offCur < len(sTmpl):
     306            # Look for a replacement variable.
     307            offAtAt = sTmpl.find('@@', offCur);
     308            if offAtAt < 0:
     309                break;
     310            offCur = offAtAt + 2;
     311            if sTmpl[offCur] not in string.ascii_uppercase:
     312                continue;
     313            offEnd = sTmpl.find('@@', offCur, offCur+28);
     314            if offEnd <= 0:
     315                continue;
     316            offCur = offEnd;
     317            sReplacement = sTmpl[offAtAt:offEnd+2];
     318            if sReplacement in dReplacements:
     319                # Got a match! Write out the previous chunk followed by the replacement text.
     320                if offStart < offAtAt:
     321                    self._oSrvGlue.write(sTmpl[offStart:offAtAt]);
     322                self._oSrvGlue.write(dReplacements[sReplacement]);
     323                # Advance past the replacement point in the template.
     324                offCur += 2;
     325                offStart = offCur;
     326            else:
     327                assert False, 'Unknown replacement "%s" at offset %s in %s' % (sReplacement, offAtAt, self._sTemplate );
     328
     329        # The final chunk.
     330        if offStart < offCur:
     331            self._oSrvGlue.write(sTmpl[offStart:]);
     332
    289333        return True;
    290334
  • trunk/src/VBox/ValidationKit/testmanager/webui/wuimain.py

    r64951 r64986  
    263263                'Sheriff',     sActUrlBase + self.ksActionResultsUnGrouped + sSheriff,
    264264                [
    265                     [ 'Ungrouped results',           sActUrlBase + self.ksActionResultsUnGrouped           + sSheriff ],
    266                     [ 'Grouped by Scheduling Group', sActUrlBase + self.ksActionResultsGroupedBySchedGroup + sSheriff ],
    267                     [ 'Grouped by Test Group',       sActUrlBase + self.ksActionResultsGroupedByTestGroup  + sSheriff ],
    268                     [ 'Grouped by TestBox',          sActUrlBase + self.ksActionResultsGroupedByTestBox    + sSheriff ],
    269                     [ 'Grouped by Test Case',        sActUrlBase + self.ksActionResultsGroupedByTestCase   + sSheriff ],
    270                     [ 'Grouped by OS',               sActUrlBase + self.ksActionResultsGroupedByOS         + sSheriff ],
    271                     [ 'Grouped by Architecture',     sActUrlBase + self.ksActionResultsGroupedByArch       + sSheriff ],
    272                     [ 'Grouped by Revision',         sActUrlBase + self.ksActionResultsGroupedByBuildRev   + sSheriff ],
    273                     [ 'Grouped by Build Category',   sActUrlBase + self.ksActionResultsGroupedByBuildCat   + sSheriff ],
     265                    [ 'Grouped by',        None ],
     266                    [ 'Ungrouped',          sActUrlBase + self.ksActionResultsUnGrouped           + sSheriff ],
     267                    [ 'Sched group',        sActUrlBase + self.ksActionResultsGroupedBySchedGroup + sSheriff ],
     268                    [ 'Test group',         sActUrlBase + self.ksActionResultsGroupedByTestGroup  + sSheriff ],
     269                    [ 'Test case',          sActUrlBase + self.ksActionResultsGroupedByTestCase   + sSheriff ],
     270                    [ 'Testbox',            sActUrlBase + self.ksActionResultsGroupedByTestBox    + sSheriff ],
     271                    [ 'OS',                 sActUrlBase + self.ksActionResultsGroupedByOS         + sSheriff ],
     272                    [ 'Architecture',       sActUrlBase + self.ksActionResultsGroupedByArch       + sSheriff ],
     273                    [ 'Revision',           sActUrlBase + self.ksActionResultsGroupedByBuildRev   + sSheriff ],
     274                    [ 'Build category',     sActUrlBase + self.ksActionResultsGroupedByBuildCat   + sSheriff ],
    274275                ]
    275276            ],
     
    278279                [
    279280                    [ 'Summary',                  sActUrlBase + self.ksActionReportSummary                 + sExtraReports ],
    280                     [ 'Success Rate',             sActUrlBase + self.ksActionReportRate                    + sExtraReports ],
    281                     [ 'Test Case Failures',       sActUrlBase + self.ksActionReportTestCaseFailures        + sExtraReports ],
    282                     [ 'TestBox Failures',         sActUrlBase + self.ksActionReportTestBoxFailures         + sExtraReports ],
    283                     [ 'Failure Reasons',          sActUrlBase + self.ksActionReportFailureReasons          + sExtraReports ],
     281                    [ 'Success rate',             sActUrlBase + self.ksActionReportRate                    + sExtraReports ],
     282                    [ 'Test case failures',       sActUrlBase + self.ksActionReportTestCaseFailures        + sExtraReports ],
     283                    [ 'Testbox failures',         sActUrlBase + self.ksActionReportTestBoxFailures         + sExtraReports ],
     284                    [ 'Failure reasons',          sActUrlBase + self.ksActionReportFailureReasons          + sExtraReports ],
    284285                ]
    285286            ],
     
    287288                'Test Results',     sActUrlBase + self.ksActionResultsUnGrouped + sExtraTimeNav,
    288289                [
    289                     [ 'Ungrouped results',           sActUrlBase + self.ksActionResultsUnGrouped           + sExtraTimeNav ],
    290                     [ 'Grouped by Scheduling Group', sActUrlBase + self.ksActionResultsGroupedBySchedGroup + sExtraTimeNav ],
    291                     [ 'Grouped by Test Group',       sActUrlBase + self.ksActionResultsGroupedByTestGroup  + sExtraTimeNav ],
    292                     [ 'Grouped by TestBox',          sActUrlBase + self.ksActionResultsGroupedByTestBox    + sExtraTimeNav ],
    293                     [ 'Grouped by Test Case',        sActUrlBase + self.ksActionResultsGroupedByTestCase   + sExtraTimeNav ],
    294                     [ 'Grouped by OS',               sActUrlBase + self.ksActionResultsGroupedByOS         + sExtraTimeNav ],
    295                     [ 'Grouped by Architecture',     sActUrlBase + self.ksActionResultsGroupedByArch       + sExtraTimeNav ],
    296                     [ 'Grouped by Revision',         sActUrlBase + self.ksActionResultsGroupedByBuildRev   + sExtraTimeNav ],
    297                     [ 'Grouped by Build Category',   sActUrlBase + self.ksActionResultsGroupedByBuildCat   + sExtraTimeNav ],
     290                    [ 'Grouped by',        None ],
     291                    [ 'Ungrouped',          sActUrlBase + self.ksActionResultsUnGrouped           + sExtraTimeNav ],
     292                    [ 'Sched group',        sActUrlBase + self.ksActionResultsGroupedBySchedGroup + sExtraTimeNav ],
     293                    [ 'Test group',         sActUrlBase + self.ksActionResultsGroupedByTestGroup  + sExtraTimeNav ],
     294                    [ 'Test case',          sActUrlBase + self.ksActionResultsGroupedByTestCase   + sExtraTimeNav ],
     295                    [ 'Testbox',            sActUrlBase + self.ksActionResultsGroupedByTestBox    + sExtraTimeNav ],
     296                    [ 'OS',                 sActUrlBase + self.ksActionResultsGroupedByOS         + sExtraTimeNav ],
     297                    [ 'Architecture',       sActUrlBase + self.ksActionResultsGroupedByArch       + sExtraTimeNav ],
     298                    [ 'Revision',           sActUrlBase + self.ksActionResultsGroupedByBuildRev   + sExtraTimeNav ],
     299                    [ 'Build category',     sActUrlBase + self.ksActionResultsGroupedByBuildCat   + sExtraTimeNav ],
    298300                ]
    299301            ],
     
    301303                'Test Failures',     sActUrlBase + self.ksActionResultsUnGrouped + sOnlyFailures,
    302304                [
    303                     [ 'Ungrouped results',           sActUrlBase + self.ksActionResultsUnGrouped           + sOnlyFailures ],
    304                     [ 'Grouped by Scheduling Group', sActUrlBase + self.ksActionResultsGroupedBySchedGroup + sOnlyFailures ],
    305                     [ 'Grouped by Test Group',       sActUrlBase + self.ksActionResultsGroupedByTestGroup  + sOnlyFailures ],
    306                     [ 'Grouped by TestBox',          sActUrlBase + self.ksActionResultsGroupedByTestBox    + sOnlyFailures ],
    307                     [ 'Grouped by Test Case',        sActUrlBase + self.ksActionResultsGroupedByTestCase   + sOnlyFailures ],
    308                     [ 'Grouped by OS',               sActUrlBase + self.ksActionResultsGroupedByOS         + sOnlyFailures ],
    309                     [ 'Grouped by Architecture',     sActUrlBase + self.ksActionResultsGroupedByArch       + sOnlyFailures ],
    310                     [ 'Grouped by Revision',         sActUrlBase + self.ksActionResultsGroupedByBuildRev   + sOnlyFailures ],
    311                     [ 'Grouped by Build Category',   sActUrlBase + self.ksActionResultsGroupedByBuildCat   + sOnlyFailures ],
     305                    [ 'Grouped by',        None ],
     306                    [ 'Ungrouped',          sActUrlBase + self.ksActionResultsUnGrouped           + sOnlyFailures ],
     307                    [ 'Sched group',        sActUrlBase + self.ksActionResultsGroupedBySchedGroup + sOnlyFailures ],
     308                    [ 'Test group',         sActUrlBase + self.ksActionResultsGroupedByTestGroup  + sOnlyFailures ],
     309                    [ 'Test case',          sActUrlBase + self.ksActionResultsGroupedByTestCase   + sOnlyFailures ],
     310                    [ 'Testbox',            sActUrlBase + self.ksActionResultsGroupedByTestBox    + sOnlyFailures ],
     311                    [ 'OS',                 sActUrlBase + self.ksActionResultsGroupedByOS         + sOnlyFailures ],
     312                    [ 'Architecture',       sActUrlBase + self.ksActionResultsGroupedByArch       + sOnlyFailures ],
     313                    [ 'Revision',           sActUrlBase + self.ksActionResultsGroupedByBuildRev   + sOnlyFailures ],
     314                    [ 'Build category',     sActUrlBase + self.ksActionResultsGroupedByBuildCat   + sOnlyFailures ],
    312315                ]
    313316            ],
     
    812815            raise TMExceptionBase('Unknown grouping type')
    813816
    814         _sPageBody  = ''
    815         oContent    = None
    816         cEntriesMax = 0
    817         _dParams    = self.getParameters()
     817        _sPageBody   = ''
     818        oContent     = None
     819        cEntriesMax  = 0
     820        _dParams     = self.getParameters()
     821        oResultLogic = oResultsLogicType(self._oDb);
    818822        for idMember, sMemberName in aoGroupMembers:
    819823            #
     
    827831                continue
    828832
    829             oResultLogic = oResultsLogicType(self._oDb);
    830833            cEntries = oResultLogic.getEntriesCount(tsNow = tsEffective,
    831834                                                    sInterval = sCurPeriod,
     
    883886        else:
    884887            self._sPageBody = sHtmlNavigation + '<p align="center"><i>No data to display</i></p>\n';
     888
     889        #
     890        # Now, generate a filter control panel for the side bar.
     891        #
     892        self._sPageFilter = self._generateResultFilter(oResultLogic,
     893                                                       tsNow = tsEffective,
     894                                                       sInterval = sCurPeriod,
     895                                                       enmResultsGroupingType = enmResultsGroupingType,
     896                                                       aoGroupMembers = aoGroupMembers,
     897                                                       fOnlyFailures = fOnlyFailures,
     898                                                       fOnlyNeedingReason = fOnlyNeedingReason);
    885899        return True;
    886900
     901    def _generateResultFilter(self, oResultLogic, tsNow, sInterval, enmResultsGroupingType, aoGroupMembers,
     902                              fOnlyFailures, fOnlyNeedingReason):
     903        """
     904        Generates the result filter for the left hand side.
     905        """
     906        sHtml  = u'<div id="side-filters">\n' \
     907                 u' <p>Filters</p>\n' \
     908                 u' <dl>\n';
     909
     910        sHtml += u'  <dt class="sf-collapsable"><a href="javascript:void(0)" onclick="toggleCollapsableDtDd(this);">&#9660; Test filter 1</a></dd>\n';
     911        sHtml += u'  <dd class="sf-collapsable"><ul><li>stuff 1</li><li>stuff 2</li><ul></dd>\n'
     912
     913        sHtml += u'  <dt class="sf-expandable"><a href="javascript:void(0)" onclick="toggleCollapsableDtDd(this);">&#9654; Test filter 2</a></dd>\n';
     914        sHtml += u'  <dd class="sf-expandable"><ul><li>stuff 3</li><li>stuff 4</li><ul></dd>\n'
     915
     916
     917        sHtml += u' </dl>\n' \
     918                 u'</div>\n';
     919        return sHtml;
    887920
    888921    def _actionResultsUnGrouped(self):
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette