Diff
Modified: trunk/Tools/ChangeLog (90821 => 90822)
--- trunk/Tools/ChangeLog 2011-07-12 16:28:01 UTC (rev 90821)
+++ trunk/Tools/ChangeLog 2011-07-12 17:46:16 UTC (rev 90822)
@@ -1,3 +1,25 @@
+2011-07-12 Adam Barth <[email protected]>
+
+ Re-work garden-o-matic UI to begin to look like the mocks
+ https://bugs.webkit.org/show_bug.cgi?id=64334
+
+ Reviewed by Dimitri Glazkov.
+
+ This patch changes how we display failures to be more like the mock the
+ dglazkov made. We now can display the same information much more
+ compactly.
+
+ * Scripts/webkitpy/tool/servers/data/gardeningserver/base.js:
+ * Scripts/webkitpy/tool/servers/data/gardeningserver/base_unittests.js:
+ * Scripts/webkitpy/tool/servers/data/gardeningserver/index.html:
+ * Scripts/webkitpy/tool/servers/data/gardeningserver/main.css: Added.
+ * Scripts/webkitpy/tool/servers/data/gardeningserver/main.js:
+ * Scripts/webkitpy/tool/servers/data/gardeningserver/results.js:
+ * Scripts/webkitpy/tool/servers/data/gardeningserver/results_unittests.js:
+ * Scripts/webkitpy/tool/servers/data/gardeningserver/ui.js:
+ * Scripts/webkitpy/tool/servers/data/gardeningserver/ui_unittests.js:
+ * Scripts/webkitpy/tool/servers/gardeningserver.py:
+
2011-07-11 Adam Roben <[email protected]>
Extract TestFailures's bug-filing code into two new classes
Modified: trunk/Tools/Scripts/webkitpy/tool/servers/data/gardeningserver/base.js (90821 => 90822)
--- trunk/Tools/Scripts/webkitpy/tool/servers/data/gardeningserver/base.js 2011-07-12 16:28:01 UTC (rev 90821)
+++ trunk/Tools/Scripts/webkitpy/tool/servers/data/gardeningserver/base.js 2011-07-12 17:46:16 UTC (rev 90822)
@@ -25,6 +25,19 @@
return url.substr(0, index);
}
+base.uniquifyArray = function(array)
+{
+ var seen = {};
+ var result = [];
+ $.each(array, function(index, value) {
+ if (seen[value])
+ return;
+ seen[value] = true;
+ result.push(value);
+ });
+ return result;
+};
+
base.filterTree = function(tree, isLeaf, predicate)
{
var filteredTree = {};
Modified: trunk/Tools/Scripts/webkitpy/tool/servers/data/gardeningserver/base_unittests.js (90821 => 90822)
--- trunk/Tools/Scripts/webkitpy/tool/servers/data/gardeningserver/base_unittests.js 2011-07-12 16:28:01 UTC (rev 90821)
+++ trunk/Tools/Scripts/webkitpy/tool/servers/data/gardeningserver/base_unittests.js 2011-07-12 17:46:16 UTC (rev 90822)
@@ -31,6 +31,14 @@
equals(value, "test.html");
});
+test("uniquifyArray", 5, function() {
+ deepEqual(base.uniquifyArray([]), []);
+ deepEqual(base.uniquifyArray(["a"]), ["a"]);
+ deepEqual(base.uniquifyArray(["a", "b"]), ["a", "b"]);
+ deepEqual(base.uniquifyArray(["a", "b", "b"]), ["a", "b"]);
+ deepEqual(base.uniquifyArray(["a", "b", "b", "a"]), ["a", "b"]);
+});
+
test("filterTree", 2, function() {
var tree = {
'path': {
Modified: trunk/Tools/Scripts/webkitpy/tool/servers/data/gardeningserver/index.html (90821 => 90822)
--- trunk/Tools/Scripts/webkitpy/tool/servers/data/gardeningserver/index.html 2011-07-12 16:28:01 UTC (rev 90821)
+++ trunk/Tools/Scripts/webkitpy/tool/servers/data/gardeningserver/index.html 2011-07-12 17:46:16 UTC (rev 90822)
@@ -6,58 +6,12 @@
<html>
<head>
<title>Garden-O-Matic</title>
-<style>
-body {
- margin: 0;
- padding: 0px;
-}
-h1 {
- margin: 0px;
- padding: 3px;
-}
-.butterbar {
- width: 500px;
- margin-left: -250px;
- position: fixed;
- border-radius: 5px;
- top: 1px;
- left: 50%;
- padding: 3px;
- background-color: #F5F6CE;
-}
-.butterbar .hide {
- float: right;
-}
-.toolbar {
- float: right;
-}
-.failures {
- padding: 3px;
-}
-.failures .test {
- margin: 6px 3px;
-}
-.failures .builders {
- color: #888;
-}
-.builder .builderName, .builder .actual {
- float: left;
- width: 200px;
-}
-.results iframe, .results img {
- width: 400px;
- height: 300px;
-}
-</style>
+<link rel="stylesheet" href=""
<link rel="icon" id="favicon" type="image/png" href=""
</head>
<body>
-<div class="butterbar"><span class="status">Loading...</span> <a class="hide" href=""
-<div class="toolbar">
- <button class="quit">Quit</button>
-</div>
-<h1>Garden-O-Matic</h1>
-<div class="failures"></div>
+<div class="butterbar"><span class="status">Loading...</span> <a class="dismiss" href=""
+<div class="results"></div>
<script src=""
<script src=""
<script src=""
Added: trunk/Tools/Scripts/webkitpy/tool/servers/data/gardeningserver/main.css (0 => 90822)
--- trunk/Tools/Scripts/webkitpy/tool/servers/data/gardeningserver/main.css (rev 0)
+++ trunk/Tools/Scripts/webkitpy/tool/servers/data/gardeningserver/main.css 2011-07-12 17:46:16 UTC (rev 90822)
@@ -0,0 +1,108 @@
+body {
+ font-family: Tahoma, sans-serif;
+ font-size: 11px;
+ margin: 0;
+ padding: 10px;
+}
+
+a {
+ color: Black;
+ font-weight: bold;
+}
+
+table {
+ table-layout: fixed;
+ width: 100%;
+ border-collapse: collapse;
+}
+
+td {
+ padding: 5px;
+ overflow: hidden;
+ vertical-align: top;
+ border-bottom: 1px solid LightGray;
+ border-top: 0;
+}
+
+tr:last-of-type td {
+ border-bottom: 0;
+}
+
+.butterbar {
+ background-color: #f3f3f3;
+ padding: 5px;
+ position: fixed;
+ top: 0px;
+ right: 0px;
+}
+
+.butterbar .hide {
+ margin-left: 20px;
+}
+
+.regression {
+ padding: 0 0 10px 0;
+}
+
+.regression .test {
+ margin: 10px 0px;
+}
+
+.regression ul {
+ margin: 0;
+ list-style: none;
+ padding: 0 0 0 10px;
+}
+
+.regression li {
+}
+
+.regression a {
+ text-decoration: none;
+ font-weight: normal;
+}
+
+.regression .what a[draggable].IMAGE\+TEXT::after {
+ content: 'IMAGE+TEXT';
+ color: white;
+ background-color: Indigo;
+ font-size: 10px;
+ padding: 1px 2px;
+ margin: 0 0 0 3px;
+ border-radius: 4px;
+}
+
+.regression .what a[draggable].IMAGE::after {
+ content: 'IMAGE';
+ color: white;
+ background-color: MidnightBlue;
+ font-size: 10px;
+ padding: 1px 2px;
+ margin: 0 0 0 3px;
+ border-radius: 4px;
+}
+
+.regression .what a[draggable].TEXT::after {
+ content: 'TEXT';
+ color: white;
+ background-color: DodgerBlue;
+ font-size: 10px;
+ padding: 1px 2px;
+ margin: 0 0 0 3px;
+ border-radius: 4px;
+}
+
+.regression .what a {
+ padding: 1px 2px;
+ border-radius: 4px;
+ color: black;
+ background-color: #f0f0f0;
+}
+
+.regression .where li {
+ margin: 3px;
+ display: inline-block;
+ padding: 1px 2px;
+ border-radius: 4px;
+ color: #555;
+}
Modified: trunk/Tools/Scripts/webkitpy/tool/servers/data/gardeningserver/main.js (90821 => 90822)
--- trunk/Tools/Scripts/webkitpy/tool/servers/data/gardeningserver/main.js 2011-07-12 16:28:01 UTC (rev 90821)
+++ trunk/Tools/Scripts/webkitpy/tool/servers/data/gardeningserver/main.js 2011-07-12 17:46:16 UTC (rev 90822)
@@ -1,18 +1,10 @@
(function() {
-function quit()
+function dismissButterbar()
{
- $.post('/quitquitquit', function(data){
- $('.butterbar .status').html(data)
- $('.butterbar').fadeIn();
- });
+ $('.butterbar').fadeOut();
}
-function hide()
-{
- $(this).parent().fadeOut();
-}
-
function setIconState(hasFailures)
{
var faviconURL = 'favicon-' + (hasFailures ? 'red' : 'green') + '.png';
@@ -22,46 +14,21 @@
function fetchResults(onsuccess)
{
results.fetchResultsByBuilder(config.builders, function(resultsByBuilder) {
- var unexpectedFailures = ui.summarizeResultsByTest(results.unexpectedFailuresByTest(resultsByBuilder));
- $('.failures').append(unexpectedFailures);
+ var unexpectedFailures = results.unexpectedFailuresByTest(resultsByBuilder);
+ var hasFailures = !$.isEmptyObject(unexpectedFailures)
+ if (!hasFailures) {
+ $('.results').text('No failures. Party time!');
+ } else {
+ var resultsSummary = ui.summarizeResultsByTest(unexpectedFailures);
+ $('.results').append($(resultsSummary).addClass('regression'));
+ }
+ setIconState(hasFailures);
onsuccess();
});
- setIconState($('.failures').length);
}
-function showResults()
-{
- // FIXME: This is fragile.
- var resultsSummary = $(this).parent().parent().parent();
- var testName = $('.testName', resultsSummary).text();
- $('.builderName', resultsSummary).each(function() {
- var builderName = $(this).text();
- results.fetchResultsURLs(builderName, testName, function(resultURLs) {
- resultsSummary.append(ui.results(resultURLs));
- });
- });
-}
+$('.butterbar .dismiss').live('click', dismissButterbar);
-function findRegressionRange()
-{
- // FIXME: This is fragile!
- var builderName = $('.builderName', $(this).parent()).text();
- var testName = $('.testName', $(this).parent().parent().parent()).text();
- results.regressionRangeForFailure(builderName, testName, function(oldestFailingRevision, newestPassingRevision) {
- var tracURLs = [];
- for (var i = newestPassingRevision + 1; i <= oldestFailingRevision; ++i) {
- tracURLs.push('<a href="" + i + '">' + i + '</a>');
- }
- $('.butterbar .status').html('Regression range: ' + tracURLs.join(' '));
- $('.butterbar').fadeIn();
- });
-}
-
-$('.hide').live('click', hide);
-$('.quit').live('click', quit);
-$('.show-results').live('click', showResults);
-$('.regression-range').live('click', findRegressionRange);
-
$(document).ready(function() {
fetchResults(function() {
$('.butterbar').fadeOut();
Modified: trunk/Tools/Scripts/webkitpy/tool/servers/data/gardeningserver/results.js (90821 => 90822)
--- trunk/Tools/Scripts/webkitpy/tool/servers/data/gardeningserver/results.js 2011-07-12 16:28:01 UTC (rev 90821)
+++ trunk/Tools/Scripts/webkitpy/tool/servers/data/gardeningserver/results.js 2011-07-12 17:46:16 UTC (rev 90822)
@@ -172,6 +172,16 @@
return unexpectedFailures;
};
+results.collectUnexpectedResults = function(dictionaryOfResultNodes)
+{
+ var collectedResults = {};
+ var results = [];
+ $.each(dictionaryOfResultNodes, function(key, resultNode) {
+ results = results.concat(unexpectedResults(resultNode));
+ });
+ return base.uniquifyArray(results);
+};
+
function TestHistoryWalker(builderName, testName)
{
this._builderName = builderName;
Modified: trunk/Tools/Scripts/webkitpy/tool/servers/data/gardeningserver/results_unittests.js (90821 => 90822)
--- trunk/Tools/Scripts/webkitpy/tool/servers/data/gardeningserver/results_unittests.js 2011-07-12 16:28:01 UTC (rev 90821)
+++ trunk/Tools/Scripts/webkitpy/tool/servers/data/gardeningserver/results_unittests.js 2011-07-12 17:46:16 UTC (rev 90822)
@@ -7,7 +7,7 @@
"expected": "IMAGE",
"actual": "IMAGE"
},
- "flaky-scrollbarhtml": {
+ "flaky-scrollbar.html": {
"expected": "PASS",
"actual": "PASS TEXT"
}
@@ -35,7 +35,7 @@
"uses_expectations_file": true,
"has_wdiff": true,
"revision": "90430"
-}
+};
test("BuilderResults.unexpectedFailures", 1, function() {
var builderResults = new results.BuilderResults(kExampleResultsJSON);
@@ -218,6 +218,34 @@
});
});
+test("collectUnexpectedResults", 1, function() {
+ var dictionaryOfResultNodes = {
+ "foo": {
+ "expected": "IMAGE",
+ "actual": "IMAGE"
+ },
+ "bar": {
+ "expected": "PASS",
+ "actual": "PASS TEXT"
+ },
+ "baz": {
+ "expected": "TEXT",
+ "actual": "IMAGE"
+ },
+ "qux": {
+ "expected": "PASS",
+ "actual": "TEXT"
+ },
+ "taco": {
+ "expected": "PASS",
+ "actual": "TEXT"
+ },
+ };
+
+ var collectedResults = results.collectUnexpectedResults(dictionaryOfResultNodes);
+ deepEqual(collectedResults, ["TEXT", "IMAGE"]);
+});
+
test("fetchResultsURLs", 3, function() {
var simulator = new NetworkSimulator();
Modified: trunk/Tools/Scripts/webkitpy/tool/servers/data/gardeningserver/ui.js (90821 => 90822)
--- trunk/Tools/Scripts/webkitpy/tool/servers/data/gardeningserver/ui.js 2011-07-12 16:28:01 UTC (rev 90821)
+++ trunk/Tools/Scripts/webkitpy/tool/servers/data/gardeningserver/ui.js 2011-07-12 17:46:16 UTC (rev 90822)
@@ -2,22 +2,41 @@
(function () {
+function displayNameForBuilder(builderName)
+{
+ return builderName.replace(/Webkit /, '');
+}
+
+ui.urlForTest = function(testName)
+{
+ return 'http://trac.webkit.org/browser/trunk/LayoutTests/' + testName;
+}
+
+ui.summarizeTest = function(testName, resultNodesByBuilder)
+{
+ var unexpectedResults = results.collectUnexpectedResults(resultNodesByBuilder);
+ var block = $(
+ '<div class="test">' +
+ '<span class="what"><a draggable></a></span>' +
+ '<span>fails on</span>' +
+ '<ul class="where"></ul>' +
+ '</div>');
+ $('.what a', block).text(testName).attr('href', ui.urlForTest(testName)).attr('class', unexpectedResults.join(' '));
+
+ var where = $('.where', block);
+ $.each(resultNodesByBuilder, function(builderName, resultNode) {
+ where.append($('<li></li>').text(displayNameForBuilder(builderName)));
+ });
+
+ return block;
+};
+
ui.summarizeResultsByTest = function(resultsByTest)
{
var block = $('<div class="results-summary"></div>');
$.each(resultsByTest, function(testName, resultNodesByBuilder) {
- var testBlock = $('<div class="test"><div class="testName"></div><div class="builders"></div></div>');
- block.append(testBlock);
- $('.testName', testBlock).text(testName);
- $.each(resultNodesByBuilder, function(builderName, resultNode) {
- var builderBlock = $('<div class="builder"><div class="builderName"></div><div class="actual"></div><div class="expected"></div><button class="show-results">Show Results</button><button class="regression-range">Regression Range</button></div>');
- $('.builders', testBlock).append(builderBlock);
- $('.builderName', builderBlock).text(builderName);
- $('.actual', builderBlock).text(resultNode.actual);
- $('.expected', builderBlock).text(resultNode.expected);
- });
+ block.append(ui.summarizeTest(testName, resultNodesByBuilder));
});
-
return block;
};
Modified: trunk/Tools/Scripts/webkitpy/tool/servers/data/gardeningserver/ui_unittests.js (90821 => 90822)
--- trunk/Tools/Scripts/webkitpy/tool/servers/data/gardeningserver/ui_unittests.js 2011-07-12 16:28:01 UTC (rev 90821)
+++ trunk/Tools/Scripts/webkitpy/tool/servers/data/gardeningserver/ui_unittests.js 2011-07-12 17:46:16 UTC (rev 90822)
@@ -19,25 +19,12 @@
}
}
-test("summarizeResultsByTest", 1, function() {
+test("summarizeResultsByTest", 3, function() {
var resultsSummary = ui.summarizeResultsByTest(kExampleResultsByTest);
- equal(resultsSummary.html(),
- '<div class="test">' +
- '<div class="testName">scrollbars/custom-scrollbar-with-incomplete-style.html</div>' +
- '<div class="builders">' +
- '<div class="builder"><div class="builderName">Mock Builder</div><div class="actual">CRASH</div><div class="expected">IMAGE</div>' +
- '<button class="show-results">Show Results</button><button class="regression-range">Regression Range</button></div>' +
- '<div class="builder"><div class="builderName">Mock Linux</div><div class="actual">CRASH</div><div class="expected">TEXT</div>' +
- '<button class="show-results">Show Results</button><button class="regression-range">Regression Range</button></div>' +
- '</div>' +
- '</div>' +
- '<div class="test">' +
- '<div class="testName">userscripts/another-test.html</div>' +
- '<div class="builders">' +
- '<div class="builder"><div class="builderName">Mock Builder</div><div class="actual">TEXT</div><div class="expected">PASS</div>' +
- '<button class="show-results">Show Results</button><button class="regression-range">Regression Range</button></div>' +
- '</div>' +
- '</div>');
+ var resultsSummaryHTML = resultsSummary.html();
+ ok(resultsSummaryHTML.indexOf('scrollbars/custom-scrollbar-with-incomplete-style.html') != -1);
+ ok(resultsSummaryHTML.indexOf('userscripts/another-test.html') != -1);
+ ok(resultsSummaryHTML.indexOf('Mock Builder') != -1);
});
test("results", 1, function() {
Modified: trunk/Tools/Scripts/webkitpy/tool/servers/gardeningserver.py (90821 => 90822)
--- trunk/Tools/Scripts/webkitpy/tool/servers/gardeningserver.py 2011-07-12 16:28:01 UTC (rev 90821)
+++ trunk/Tools/Scripts/webkitpy/tool/servers/gardeningserver.py 2011-07-12 17:46:16 UTC (rev 90822)
@@ -38,6 +38,7 @@
class GardeningHTTPRequestHandler(ReflectionHandler):
STATIC_FILE_NAMES = frozenset([
"index.html",
+ "main.css",
"base.js",
"config.js",
"main.js",