Web Inspector: AXI: expose selectedChildNodeIds of list boxes, tree controls, etc...
[WebKit-https.git] / Websites / test-results / public / index.html
index 6972ba5..0c0236b 100644 (file)
@@ -19,9 +19,7 @@
 </ul>
 </header>
 
-<form onsubmit="TestResultsView.fetchTest(this['testName'].value);
-    TestResultsView.updateLocationHash();
-    return false;">
+<form>
 <input id="testName" type="text" size="150" onpaste="pasteHelper(this, event)"
     placeholder="Type in a test name, or copy and paste test names on results.html or NRWT stdout (including junks)"></form>
 <div id="testView"></div>
@@ -65,6 +63,7 @@ var TestResultsView = new (function () {
     this._slaves = {};
     this._repositories = {};
     this._testCategories = {};
+    this._newBugLinks = [];
 });
 
 TestResultsView.setAvailableTests = function (availableTests) {
@@ -91,6 +90,10 @@ TestResultsView.setTestCategories = function (testCategories) {
     this._testCategories = testCategories;
 }
 
+TestResultsView.setNewBugLinks = function (newBugLinks) {
+    this._newBugLinks = newBugLinks;
+}
+
 TestResultsView.showTooltip = function (anchor, contentElement) {
     var tooltipContainer = this._tooltipContainer;
     tooltipContainer.style.display = null;
@@ -184,16 +187,30 @@ TestResultsView._populateTestPane = function(testName, results, section) {
     table.appendChild(this._createTestResultHeader('Builder', repositories));
 
     var tbody = element('tbody');
-    for (var builderId in resultsByBuilder) {
-        var builder = this._builders[builderId];
-        // FIXME: Add a master name if there is more than one.
-        tbody.appendChild(this._createTestResultRow(builder.name, resultsByBuilder[builderId], builder, buildTimes, repositories));
-    }
+    var builders = [];
+    for (var builderId in resultsByBuilder)
+        builders.push(this._builders[builderId]);
+
+    var self = this;
+    this._sortObjectsByName(builders).forEach(function (builder) {
+        tbody.appendChild(self._createTestResultRow(builder.name, resultsByBuilder[builder.id], test, builder, buildTimes, repositories));        
+    })
+
     table.appendChild(tbody);
     section.appendChild(table);
     $(table).tablesorter();
 }
 
+TestResultsView._sortObjectsByName = function (list) {
+    return list.sort(function (a, b) {
+        if (a.name < b.name)
+            return -1;
+        if (a.name > b.name)
+            return 1;
+        return 0;
+    });
+}
+
 TestResultsView._urlFromTest = function (test) {
     var category = this._testCategories[test.category];
     if (!category)
@@ -207,13 +224,19 @@ TestResultsView._linkifiedTestName = function (test) {
 }
 
 TestResultsView._createTestResultHeader = function (labelForFirstColumn, repositories) {
+    var latestResultsLabel = '';
+    if (repositories) {
+        latestResultsLabel = ['Latest results', element('br'),
+            repositories.map(function (repository) { return repository.name; }).join(' / ')];
+    }
+        
     return element('thead', [element('tr', [
         element('th', [labelForFirstColumn]),
         element('th', ['Bug']),
         element('th', ['Expectations']),
-        element('th', ['Slowest'])]
-        .concat(repositories ? repositories.map(function (repository) { return element('th', [repository.name]); }) : [])
-        .concat([element('th')]))]);
+        element('th', ['Slowest']),
+        element('th', latestResultsLabel),
+        element('th')])]);
 }
 
 TestResultsView._createBuildsAndComputeSlownessOfResults = function (builderId, results) {
@@ -226,7 +249,7 @@ TestResultsView._createBuildsAndComputeSlownessOfResults = function (builderId,
     }
 }
 
-TestResultsView._createTestResultRow = function (title, results, builder, buildTimes, repositories) {
+TestResultsView._createTestResultRow = function (title, results, test, builder, buildTimes, repositories) {
     var sortedResults = results.sort(function (result1, result2) { return result2.build.time() - result1.build.time(); });
     var cells = new Array();
 
@@ -263,9 +286,12 @@ TestResultsView._createTestResultRow = function (title, results, builder, buildT
 
     if (!seenBugLink) {
         // FIXME: Make bug tracker configurable.
-        formattedModifiers.push(element('a',
-            {'href': 'https://bugs.webkit.org/enter_bug.cgi?product=WebKit&component=Tools%20/%20Tests&form_name=enter_bug&keywords=LayoutTestFailure'},
-            ['File a bug']));
+        for (var i = 0; i < this._newBugLinks.length; i++) {
+            if (i)
+                formattedModifiers.push(' / ');
+            var link = this._newBugLinks[i];
+            formattedModifiers.push(element('a', {'href': link.url.replace(/\$testName/g, test.name)}, link.label));
+        }
     }
 
     var slowestTime = Math.max.apply(Math, results.map(function (result) { return result.roundedTime; }));
@@ -274,15 +300,19 @@ TestResultsView._createTestResultRow = function (title, results, builder, buildT
     else
         slowestTime = '';
 
-    var formattedRevisionCells = [];
+    var latestRevisions = [];
     if (repositories) {
         var build = sortedResults[0].build;
         for (var i = 0; i < repositories.length; i++) {
+            if (!build.revision(repositories[i].id))
+                continue;
             var revisionInfo = build.formattedRevision(repositories[i].id);
+            if (latestRevisions.length)
+                latestRevisions.push(' / ');
             if (revisionInfo.url)
-                formattedRevisionCells.push(element('a', {'href': revisionInfo.url}, [revisionInfo.label]));
+                latestRevisions.push(element('a', {'href': revisionInfo.url}, [revisionInfo.label]));
             else
-                formattedRevisionCells.push(revisionInfo.label);
+                latestRevisions.push(revisionInfo.label);
         }
     }
 
@@ -291,7 +321,7 @@ TestResultsView._createTestResultRow = function (title, results, builder, buildT
         element('td', {'class': 'modifiers'}, formattedModifiers),
         element('td', {'class': 'expected'}, [sortedResults[0].expected]),
         element('td', {'class': 'slowestTime'}, [slowestTime])]
-        .concat(formattedRevisionCells)
+        .concat(element('td', latestRevisions))
         .concat([element('td', cells)]));
 }
 
@@ -358,24 +388,30 @@ TestResultsView._populateBuilderPane = function(builderName, failureType, result
 
     table.appendChild(this._createTestResultHeader('Test'));
 
+    var tests = [];
+    for (var testId in resultsByTests)
+        tests.push(this._availableTests[testId]);
+
     var tbody = element('tbody');
     var builder = this._builders[builderId];
     var self = this;
-    for (var testId in resultsByTests) {
-        var results = resultsByTests[testId];
-        if (!results.length)
-            continue;
-        this._createBuildsAndComputeSlownessOfResults(builderId, resultsByTests[testId]);
-        var test = this._availableTests[testId];
-        var externalTestLink = element('a', {'class': 'externalTestLink', 'href': this._urlFromTest(test)});
-        var testName = element('a', {'href':'#'}, [test.name]);
+    this._sortObjectsByName(tests).forEach(function (test) {
+        var results = resultsByTests[test.id];
+        if (!results.length || (failureType == 'failing' && results[0].actual == 'PASS'))
+            return;
+        self._createBuildsAndComputeSlownessOfResults(builderId, results);
+        var externalTestLink = element('a', {'class': 'externalTestLink',
+            'href': self._urlFromTest(test),
+            'title': 'View the source code of ' + test.name});
+        var testName = element('a', {'href':'#',
+            'title': 'Show results of ' + test.name + ' on all platforms'}, [test.name]);
         testName.onclick = function (event) {
             self.fetchTests([this.textContent]);
             event.preventDefault();
             return false;
         }
-        tbody.appendChild(this._createTestResultRow(element('span', [testName, externalTestLink]), resultsByTests[testId], builder));
-    }
+        tbody.appendChild(self._createTestResultRow(element('span', [testName, externalTestLink]), results, test, builder));
+    });
 
     table.appendChild(tbody);
     section.appendChild(table);
@@ -393,7 +429,7 @@ TestResultsView.fetchFailingTestsForBuilder = function (builderName, numberOfDay
     var self = this;
     var xhr = new XMLHttpRequest();
     var builderId = this._builderByName[builderName].id;
-    xhr.open('GET', 'data/' + builderId + '-' + failureType + '.json', true);  
+    xhr.open('GET', 'data/' + builderId + '-' + (failureType == 'failing' ? 'wrongexpectations' : failureType) + '.json', true);  
     xhr.onload = function(event) {
         if (xhr.status != 200) {
             section.appendChild(text('Failed to load results for ' + builderName + ': ' + xhr.status));
@@ -490,9 +526,27 @@ fetchManifest(function (response) {
     var input = document.getElementById('testName');
     input.autocompleter = new Autocompleter(input, testNames);
 
+    input.form.onsubmit = function (event) {
+        addTests(input.value);
+        event.preventDefault();
+        return false;
+    }
+
+    function addTests(filter) {
+        var candidates = input.autocompleter.filterCandidates(filter);
+        if (candidates.length > 15) {
+            if (!confirm('Are you sure you want to add ' + candidates.length + ' tests that match this substring?'))
+                return;
+        }
+        for (var i = 0; i < candidates.length; i++)
+            TestResultsView.fetchTest(candidates[i]);
+        TestResultsView.updateLocationHash();
+    }
+
     var builderListView = document.getElementById('builderListView');
-    for (var builderId in response['builders'])
-        builderListView.appendChild(element('option', [text(response['builders'][builderId].name)]));
+    TestResultsView._sortObjectsByName(response['builders']).forEach(function (builder) {
+        builderListView.appendChild(element('option', [builder.name]));
+    });
 
     var builderDaysView = document.getElementById('builderDaysView');
     var builderFailureTypeView = document.getElementById('builderFailureTypeView');
@@ -518,6 +572,7 @@ fetchManifest(function (response) {
     TestResultsView.setSlaves(mapById(response['slaves']));
     TestResultsView.setRepositories(mapById(response['repositories']));
     TestResultsView.setTestCategories(response['testCategories']);
+    TestResultsView.setNewBugLinks(response['newBugLinks']);
     // FIXME: Updating location.href shouldn't be TestResultsView's responsibility.
     var parsedStates = TestResultsView.loadTestsFromLocationHash();
     if (parsedStates['builder']) {
@@ -547,4 +602,4 @@ function pasteHelper(input, event) {
 
 </script>
 </body>
-</html>
\ No newline at end of file
+</html>