Home | History | Annotate | Download | only in rebaselineserver
      1 /*
      2  * Copyright (c) 2010 Google Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions are
      6  * met:
      7  *
      8  *     * Redistributions of source code must retain the above copyright
      9  * notice, this list of conditions and the following disclaimer.
     10  *     * Redistributions in binary form must reproduce the above
     11  * copyright notice, this list of conditions and the following disclaimer
     12  * in the documentation and/or other materials provided with the
     13  * distribution.
     14  *     * Neither the name of Google Inc. nor the names of its
     15  * contributors may be used to endorse or promote products derived from
     16  * this software without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29  */
     30 
     31 function RebaselineQueue()
     32 {
     33     this._selectNode = $('queue-select');
     34     this._rebaselineButtonNode = $('rebaseline-queue');
     35     this._toggleNode = $('toggle-queue');
     36     this._removeSelectionButtonNode = $('remove-queue-selection');
     37 
     38     this._inProgressRebaselineCount = 0;
     39 
     40     var self = this;
     41     $('add-to-rebaseline-queue').addEventListener(
     42         'click', function() { self.addCurrentTest(); });
     43     this._selectNode.addEventListener('change', updateState);
     44     this._removeSelectionButtonNode.addEventListener(
     45         'click', function() { self._removeSelection(); });
     46     this._rebaselineButtonNode.addEventListener(
     47         'click', function() { self.rebaseline(); });
     48     this._toggleNode.addEventListener(
     49         'click', function() { toggle('queue'); });
     50 }
     51 
     52 RebaselineQueue.prototype.updateState = function()
     53 {
     54     var testName = getSelectedTest();
     55 
     56     var state = results.tests[testName].state;
     57     $('add-to-rebaseline-queue').disabled = state != STATE_NEEDS_REBASELINE;
     58 
     59     var queueLength = this._selectNode.options.length;
     60     if (this._inProgressRebaselineCount > 0) {
     61       this._rebaselineButtonNode.disabled = true;
     62       this._rebaselineButtonNode.textContent =
     63           'Rebaseline in progress (' + this._inProgressRebaselineCount +
     64           ' tests left)';
     65     } else if (queueLength == 0) {
     66       this._rebaselineButtonNode.disabled = true;
     67       this._rebaselineButtonNode.textContent = 'Rebaseline queue';
     68       this._toggleNode.textContent = 'Queue';
     69     } else {
     70       this._rebaselineButtonNode.disabled = false;
     71       this._rebaselineButtonNode.textContent =
     72           'Rebaseline queue (' + queueLength + ' tests)';
     73       this._toggleNode.textContent = 'Queue (' + queueLength + ' tests)';
     74     }
     75     this._removeSelectionButtonNode.disabled =
     76         this._selectNode.selectedIndex == -1;
     77 };
     78 
     79 RebaselineQueue.prototype.addCurrentTest = function()
     80 {
     81     var testName = getSelectedTest();
     82     var test = results.tests[testName];
     83 
     84     if (test.state != STATE_NEEDS_REBASELINE) {
     85         log('Cannot add test with state "' + test.state + '" to queue.',
     86             log.WARNING);
     87         return;
     88     }
     89 
     90     var queueOption = document.createElement('option');
     91     queueOption.value = testName;
     92     queueOption.textContent = testName;
     93     this._selectNode.appendChild(queueOption);
     94     test.state = STATE_IN_QUEUE;
     95     updateState();
     96 };
     97 
     98 RebaselineQueue.prototype.removeCurrentTest = function()
     99 {
    100     this._removeTest(getSelectedTest());
    101 };
    102 
    103 RebaselineQueue.prototype._removeSelection = function()
    104 {
    105     if (this._selectNode.selectedIndex == -1)
    106         return;
    107 
    108     this._removeTest(
    109         this._selectNode.options[this._selectNode.selectedIndex].value);
    110 };
    111 
    112 RebaselineQueue.prototype._removeTest = function(testName)
    113 {
    114     var queueOption = this._selectNode.firstChild;
    115 
    116     while (queueOption && queueOption.value != testName) {
    117         queueOption = queueOption.nextSibling;
    118     }
    119 
    120     if (!queueOption)
    121         return;
    122 
    123     this._selectNode.removeChild(queueOption);
    124     var test = results.tests[testName];
    125     test.state = STATE_NEEDS_REBASELINE;
    126     updateState();
    127 };
    128 
    129 RebaselineQueue.prototype.rebaseline = function()
    130 {
    131     var testNames = [];
    132     for (var queueOption = this._selectNode.firstChild;
    133          queueOption;
    134          queueOption = queueOption.nextSibling) {
    135         testNames.push(queueOption.value);
    136     }
    137 
    138     this._inProgressRebaselineCount = testNames.length;
    139     updateState();
    140 
    141     testNames.forEach(this._rebaselineTest, this);
    142 };
    143 
    144 RebaselineQueue.prototype._rebaselineTest = function(testName)
    145 {
    146     var baselineTarget = getSelectValue('baseline-target');
    147     var baselineMoveTo = getSelectValue('baseline-move-to');
    148 
    149     var xhr = new XMLHttpRequest();
    150     xhr.open('POST',
    151         '/rebaseline?test=' + encodeURIComponent(testName) +
    152         '&baseline-target=' + encodeURIComponent(baselineTarget) +
    153         '&baseline-move-to=' + encodeURIComponent(baselineMoveTo));
    154 
    155     var self = this;
    156     function handleResponse(logType, newState) {
    157         log(xhr.responseText, logType);
    158         self._removeTest(testName);
    159         self._inProgressRebaselineCount--;
    160         results.tests[testName].state = newState;
    161         updateState();
    162         // If we're done with a set of rebaselines, regenerate the test menu
    163         // (which is grouped by state) since test states have changed.
    164         if (self._inProgressRebaselineCount == 0) {
    165             selectDirectory();
    166         }
    167     }
    168 
    169     function handleSuccess() {
    170         handleResponse(log.SUCCESS, STATE_REBASELINE_SUCCEEDED);
    171     }
    172     function handleFailure() {
    173         handleResponse(log.ERROR, STATE_REBASELINE_FAILED);
    174     }
    175 
    176     xhr.addEventListener('load', function() {
    177       if (xhr.status < 400) {
    178           handleSuccess();
    179       } else {
    180           handleFailure();
    181       }
    182     });
    183     xhr.addEventListener('error', handleFailure);
    184 
    185     xhr.send();
    186 };
    187