New flakiness dashboard should align results by revision numbers
[WebKit-https.git] / Websites / test-results / index.html
index 48e20a5..2dd0429 100644 (file)
@@ -111,7 +111,7 @@ TestResultsView._createResultCell = function (master, builder, result, previousR
     var build = result['buildNumber'];
     var actual = result['actual'];
     var expected = result['expected'];
-    var timeIfSlow = result.isSlow ? result.roundedTime : '-';
+    var timeIfSlow = result.isSlow ? result.roundedTime : '';
     var anchor = element('a', {'href': this._urlFromBuilder('result', master, builder, revision, build)}, [timeIfSlow]);
     anchor.onmouseenter = function () {
         var repositoryById = TestResultsView._repositories;
@@ -145,41 +145,71 @@ TestResultsView._createResultCell = function (master, builder, result, previousR
 
 TestResultsView._populateTestPane = function(testName, results, section) {
     var table = element('table', {'class': 'resultsTable'}, [element('caption', [testName])]);
+    table.appendChild(this._createTestResultHeader('Builder'));
+
     var resultsByBuilder = results['builders'];
+    var buildTimes = new Array();
     for (var builderId in resultsByBuilder) {
-        var resultsByTest = resultsByBuilder[builderId];
-        var results;
-        for (var testId in resultsByTest)
-            results = resultsByTest[testId];
-        if (!results)
-            continue;
+        var results = resultsByBuilder[builderId];
+        this._createBuildsAndComputeSlownessOfResults(results);
+        for (var i = 0; i < results.length; i++) {
+            var time = results[i].build.time();
+            if (buildTimes.indexOf(time) < 0)
+                buildTimes.push(time);
+        }
+    }
+    buildTimes.sort(function (a, b) { return b - a; });
 
+    for (var builderId in resultsByBuilder) {
         var builder = this._builders[builderId];
         // FIXME: Add a master name if there is more than one.
-        table.appendChild(this._createTestResultRow(builder.name, results, builder));
+        table.appendChild(this._createTestResultRow(builder.name, resultsByBuilder[builderId], builder, buildTimes));
     }
     section.appendChild(table);
 }
 
-TestResultsView._createTestResultRow = function (title, results, builder) {
-    var slowestTime = 0;
+TestResultsView._createTestResultHeader = function (labelForFirstColumn) {
+    return element('thead', [element('tr', [
+        element('th', [labelForFirstColumn]),
+        element('th', ['Bug']),
+        element('th', ['Expectations']),
+        element('th', ['Slowest'])])]);
+}
+
+TestResultsView._createBuildsAndComputeSlownessOfResults = function (results) {
     for (var i = 0; i < results.length; i++) {
         var result = results[i];
         result.build = new TestBuild(this._repositories, this._builders, result);
         result.roundedTime = result.time > 10000 ? Math.round(result.time / 1000) : Math.round(result.time / 100) / 10;
         result.isSlow = result.time > 1000;
-        if (result.isSlow)
-            slowestTime = Math.max(slowestTime, result.roundedTime);
     }
-    if (slowestTime)
-        slowestTime += 's';
-    else
-        slowestTime = '';
+}
 
+TestResultsView._createTestResultRow = function (title, results, builder, buildTimes) {
     var sortedResults = results.sort(function (result1, result2) { return result2.build.time() - result1.build.time(); });
-    var cells = new Array(sortedResults.length);
-    for (var i = 0; i < sortedResults.length; i++)
-        cells[i] = this._createResultCell(builder.master, builder.name, sortedResults[i], sortedResults[i - 1]);
+    var cells = new Array();
+
+    function addEmptyCell() { cells.push(element('span', {'class': 'resultCell'}, [element('a')])); }
+
+    var buildTimeIndex = 0;
+    for (var i = 0; i < sortedResults.length; i++) {
+        var result = sortedResults[i];
+        if (buildTimes) {
+            while (buildTimes[buildTimeIndex] > result.build.time()) {
+                addEmptyCell();
+                buildTimeIndex++;
+            }
+            if (buildTimes[buildTimeIndex] == result.build.time())
+                buildTimeIndex++;
+        }
+        cells.push(this._createResultCell(builder.master, builder.name, result, sortedResults[i - 1]));
+    }
+    if (buildTimes) {
+        while (buildTimeIndex < buildTimes.length) {
+            addEmptyCell();
+            buildTimeIndex++;
+        }
+    }
 
     var formattedModifiers = sortedResults[0].modifiers.split(' ').map(function (modifier) {
         if (modifier.indexOf('/') > 0)
@@ -187,6 +217,12 @@ TestResultsView._createTestResultRow = function (title, results, builder) {
         return modifier;
     });
 
+    var slowestTime = Math.max.apply(Math, results.map(function (result) { return result.roundedTime; }));
+    if (slowestTime >= 1)
+        slowestTime += 's';
+    else
+        slowestTime = '';
+
     return element('tr', [
         element('th', ['' + title]),
         element('td', {'class': 'modifiers'}, formattedModifiers),
@@ -287,11 +323,14 @@ TestResultsView._populateBuilderPane = function(builderName, failureType, result
     if (!resultsByTests)
         return;
 
+    table.appendChild(this._createTestResultHeader('Test'));
+
     var builder = this._builders[builderId];
     for (var testId in resultsByTests) {
         var results = resultsByTests[testId];
         if (!results.length || !this._matchesFailureType(results, failureType, this._availableTests[testId].name))
             continue;
+        this._createBuildsAndComputeSlownessOfResults(resultsByTests[testId]);
         table.appendChild(this._createTestResultRow(this._availableTests[testId].name, resultsByTests[testId], builder));
     }
     section.appendChild(table);