Commit b42f3a10 authored by ojan@chromium.org's avatar ojan@chromium.org

Delete garden-o-matic.

The port to polymer is (basically) complete. Sheriff-o-matic
is replacing garden-o-matic.

Only functional change in this patch is to sort the scripts
and imports in ct-sheriff-o-matic.html. The rest of the patch
is just deleting unused files.

There's more code to delete with unused functions in some of
the remaining files, but that can be done in a followup.

NOTRY=true

Review URL: https://codereview.chromium.org/405843002

git-svn-id: svn://svn.chromium.org/blink/trunk@178526 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent eb3be807
<!--
Copyright (C) 2011 Google Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
THE POSSIBILITY OF SUCH DAMAGE.
The favicons are from the awesome famfamfam.com, which is the website of Mark
James, a web developer from Birmingham, UK.
-->
<!DOCTYPE html>
<head>
<title>Garden-O-Matic</title>
<meta name="viewport" content="width=device-width, user-scalable=no">
<link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Open+Sans:400,700">
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.15/themes/base/jquery-ui.css">
<link rel="stylesheet" href="styles/common.css">
<link rel="stylesheet" href="styles/onebar.css">
<link rel="stylesheet" href="styles/failures.css">
<link rel="stylesheet" href="styles/results.css">
<link rel="stylesheet" href="styles/notifications.css">
<link rel="stylesheet" href="styles/pixelzoomer.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.15/jquery-ui.min.js"></script>
<script src="bower_components/sugar/release/sugar-full.development.js"></script>
<script src="scripts/base.js"></script>
<script src="scripts/config.js"></script>
<script src="scripts/net.js"></script>
<script src="scripts/rollbot.js"></script>
<script src="scripts/svn-log.js"></script>
<script src="scripts/treestatus.js"></script>
<script src="scripts/builders.js"></script>
<script src="scripts/results.js"></script>
<script src="scripts/ui.js"></script>
<script src="scripts/model.js"></script>
<script src="scripts/ui/actions.js"></script>
<script src="scripts/ui/failures.js"></script>
<script src="scripts/ui/notifications.js"></script>
<script src="scripts/ui/results.js"></script>
<script src="scripts/controllers.js"></script>
<script src="scripts/pixelzoomer.js"></script>
<script src="bower_components/platform/platform.js"></script>
<link rel="import" href="bower_components/polymer/polymer.html">
<link rel="import" href="polymer-load-warning.html">
<link rel="import" href="ui/ct-results-comparison.html">
<script src="scripts/garden-o-matic.js"></script>
</head>
...@@ -42,8 +42,6 @@ THE POSSIBILITY OF SUCH DAMAGE. ...@@ -42,8 +42,6 @@ THE POSSIBILITY OF SUCH DAMAGE.
<h2 id="qunit-userAgent"></h2> <h2 id="qunit-userAgent"></h2>
<ol id="qunit-tests"></ol> <ol id="qunit-tests"></ol>
<link rel="stylesheet" href="styles/results.css">
<script src="bower_components/sugar/release/sugar-full.development.js"></script> <script src="bower_components/sugar/release/sugar-full.development.js"></script>
<script src="scripts/base.js"></script> <script src="scripts/base.js"></script>
<script src="scripts/config.js"></script> <script src="scripts/config.js"></script>
...@@ -61,19 +59,9 @@ THE POSSIBILITY OF SUCH DAMAGE. ...@@ -61,19 +59,9 @@ THE POSSIBILITY OF SUCH DAMAGE.
<script src="scripts/results.js"></script> <script src="scripts/results.js"></script>
<script src="scripts/results_unittests.js"></script> <script src="scripts/results_unittests.js"></script>
<script src="scripts/ui.js"></script> <script src="scripts/ui.js"></script>
<script src="scripts/ui/actions.js"></script>
<script src="scripts/ui/actions_unittests.js"></script>
<script src="scripts/ui/failures.js"></script>
<script src="scripts/ui/failures_unittests.js"></script>
<script src="scripts/ui/results.js"></script>
<script src="scripts/controllers.js"></script> <!-- This script is slightly of order. -->
<script src="scripts/ui/results_unittests.js"></script>
<script src="scripts/ui_unittests.js"></script> <script src="scripts/ui_unittests.js"></script>
<script src="scripts/model.js"></script> <script src="scripts/model.js"></script>
<script src="scripts/model_unittests.js"></script> <script src="scripts/model_unittests.js"></script>
<script src="scripts/ui/notifications.js"></script>
<script src="scripts/ui/notifications_unittests.js"></script>
<script src="scripts/controllers_unittests.js"></script>
<script src="bower_components/platform/platform.js"></script> <script src="bower_components/platform/platform.js"></script>
<link rel="import" href="bower_components/polymer/polymer.html"> <link rel="import" href="bower_components/polymer/polymer.html">
......
/*
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
var controllers = controllers || {};
(function(){
controllers.ResultsDetails = base.extends(Object, {
init: function(view, resultsByTest)
{
this._view = view;
this._resultsByTest = resultsByTest;
this._view.setResultsByTest(resultsByTest);
this._view.firstResult();
$(this._view).bind('next', this.onNext.bind(this));
$(this._view).bind('previous', this.onPrevious.bind(this));
},
onNext: function()
{
this._view.nextResult();
},
onPrevious: function()
{
this._view.previousResult();
},
_failureInfoList: function()
{
var testName = this._view.currentTestName();
return Object.keys(this._resultsByTest[testName]).map(function(builderName) {
return results.failureInfoForTestAndBuilder(this._resultsByTest, testName, builderName);
}.bind(this));
},
});
var FailureStreamController = base.extends(Object, {
_resultsFilter: null,
_keyFor: function(failureAnalysis) { throw "Not implemented!"; },
_createFailureView: function(failureAnalysis) { throw "Not implemented!"; },
init: function(model, view, delegate)
{
this._model = model;
this._view = view;
this._delegate = delegate;
this._testFailures = new base.UpdateTracker();
},
update: function(failureAnalysis)
{
var key = this._keyFor(failureAnalysis);
var failure = this._testFailures.get(key);
if (!failure) {
failure = this._createFailureView(failureAnalysis);
this._view.add(failure);
$(failure).bind('examine', function() {
this.onExamine(failure);
}.bind(this));
}
failure.addFailureAnalysis(failureAnalysis);
this._testFailures.update(key, failure);
return failure;
},
purge: function() {
this._testFailures.purge(function(failure) {
failure.dismiss();
});
this._testFailures.forEach(function(failure) {
failure.purge();
});
},
onExamine: function(failures)
{
var resultsView = new ui.results.View({
fetchResultsURLs: results.fetchResultsURLs
});
var testNameList = failures.testNameList();
var failuresByTest = base.filterDictionary(
this._resultsFilter(this._model.resultsByBuilder),
function(key) {
return testNameList.indexOf(key) != -1;
});
var controller = new controllers.ResultsDetails(resultsView, failuresByTest);
this._delegate.showResults(resultsView);
},
_toFailureInfoList: function(failures)
{
return base.flattenArray(failures.testNameList().map(model.unexpectedFailureInfoForTestName));
},
});
controllers.UnexpectedFailures = base.extends(FailureStreamController, {
_resultsFilter: results.unexpectedFailuresByTest,
_impliedFirstFailingRevision: function(failureAnalysis)
{
return failureAnalysis.newestPassingRevision + 1;
},
_keyFor: function(failureAnalysis)
{
return failureAnalysis.newestPassingRevision + "+" + failureAnalysis.oldestFailingRevision;
},
_createFailureView: function(failureAnalysis)
{
var failure = new ui.notifications.FailingTestsSummary();
model.commitDataListForRevisionRange(this._impliedFirstFailingRevision(failureAnalysis), failureAnalysis.oldestFailingRevision).forEach(function(commitData) {
var suspiciousCommit = failure.addCommitData(commitData);
$(suspiciousCommit).bind('rollout', function() {
this.onRollout(commitData.revision, failure.testNameList());
}.bind(this));
}, this);
return failure;
},
update: function(failureAnalysis)
{
var failure = FailureStreamController.prototype.update.call(this, failureAnalysis);
failure.updateBuilderResults(model.buildersInFlightForRevision(this._impliedFirstFailingRevision(failureAnalysis)));
},
length: function()
{
return this._testFailures.length();
},
});
controllers.FailingBuilders = base.extends(Object, {
init: function(view, message)
{
this._view = view;
this._message = message;
this._notification = null;
},
hasFailures: function()
{
return !!this._notification;
},
update: function(failuresList)
{
if (Object.keys(failuresList).length == 0) {
if (this._notification) {
this._notification.dismiss();
this._notification = null;
}
return;
}
if (!this._notification) {
this._notification = new ui.notifications.BuildersFailing(this._message);
this._view.add(this._notification);
}
// FIXME: We should provide regression ranges for the failing builders.
// This doesn't seem to happen often enough to worry too much about that, however.
this._notification.setFailingBuilders(failuresList);
}
});
})();
/*
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
(function () {
var kExampleResultsByBuilder = {
"Mock Builder": unittest.kExampleResultsJSON,
};
module("controllers");
asyncTest("UnexpectedFailures", 3, function() {
var simulator = new NetworkSimulator();
simulator.probe = function() {
return Promise.resolve();
};
simulator.runTest(function() {
var mockView = {};
var mockState = {
resultsByBuilder: kExampleResultsByBuilder
};
var expectedResultsByTest = null;
var mockDelegate = {
showResults: function(resultsView)
{
deepEqual(resultsView._resultsByTest, expectedResultsByTest);
}
}
var controller = controllers.UnexpectedFailures(mockState, mockView, mockDelegate);
var testNameList = null;
var mockFailures = {
testNameList: function() { return testNameList; }
};
testNameList = ["scrollbars/custom-scrollbar-with-incomplete-style.html"];
expectedResultsByTest = {};
controller.onExamine(mockFailures);
testNameList = ["userscripts/another-test.html"];
expectedResultsByTest = {
"userscripts/another-test.html": {
"Mock Builder": {
"expected": "PASS",
"actual": "TEXT",
"is_unexpected": true,
}
}
};
controller.onExamine(mockFailures);
}).then(start);
});
test("controllers.FailingBuilders", 3, function() {
var MockView = base.extends('div', {
add: function(node) {
this.appendChild(node);
}
})
var view = new MockView();
var failingBuilders = new controllers.FailingBuilders(view, 'dummy message');
ok(!failingBuilders.hasFailures());
failingBuilders.update({'DummyBuilder': ['webkit_tests']});
ok(failingBuilders.hasFailures());
equal(view.outerHTML, '<div>' +
'<li>' +
'<div class="how"></div>' +
'<div class="what">' +
'<div class="problem">dummy message:' +
'<ul class="effects">' +
'<li class="builder"><a class="failing-builder" href="http://build.chromium.org/p/chromium.webkit/waterfall?builder=DummyBuilder">' +
'<span class="version">DummyBuilder</span><span class="failures"> webkit_tests</span></a>' +
'</li>' +
'</ul>' +
'</div>' +
'<ul class="causes"></ul>' +
'</div>' +
'</li>' +
'</div>')
});
})();
/*
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
(function() {
var g_info = null;
var g_revisionHint = null;
var g_updateTimerId = 0;
var g_unexpectedFailuresController = null;
var g_nonLayoutTestFailureBuilders = null;
var g_updating = false;
var g_updateButton = null;
function updatePartyTime()
{
if (!g_unexpectedFailuresController.length() && !g_nonLayoutTestFailureBuilders.hasFailures())
document.getElementById('onebar').classList.add('partytime');
else
document.getElementById('onebar').classList.remove('partytime');
}
function updateTreeStatus()
{
var oldTreeStatus = document.querySelector('.treestatus');
oldTreeStatus.remove();
var newTreeStatus = new ui.TreeStatus();
document.querySelector('.topbar').appendChild(newTreeStatus);
}
function update()
{
if (g_updating)
return;
g_updating = true;
if (g_updateButton)
g_updateButton.disabled = true;
if (g_revisionHint)
g_revisionHint.dismiss();
// FIXME: This should be a button with a progress element.
var numberOfTestsAnalyzed = 0;
var updating = new ui.notifications.Info('Loading commit data ...');
g_info.add(updating);
builders.buildersFailingNonLayoutTests().then(function(failuresList) {
g_nonLayoutTestFailureBuilders.update(failuresList);
updatePartyTime();
});
Promise.all([model.updateRecentCommits(), model.updateResultsByBuilder()]).then(function() {
updating.update('Analyzing test failures ...');
model.analyzeUnexpectedFailures(function(failureAnalysis, total) {
updating.update('Analyzing test failures ... ' + ++numberOfTestsAnalyzed + '/' + total + ' tests analyzed.');
g_unexpectedFailuresController.update(failureAnalysis);
}).then(function() {
updatePartyTime();
g_unexpectedFailuresController.purge();
Object.keys(config.builders).forEach(function(builderName) {
if (!model.state.resultsByBuilder[builderName])
g_info.add(new ui.notifications.Info('Could not find test results for ' + builderName + '.'));
});
updating.dismiss();
g_revisionHint = new ui.notifications.Info('');
g_revisionHint.updateWithNode(new ui.revisionDetails());
g_info.add(g_revisionHint);
g_updating = false;
if (g_updateButton)
g_updateButton.disabled = false;
});
});
}
window.addEventListener('DOMContentLoaded', function() {
g_updateTimerId = window.setInterval(update, config.kUpdateFrequency);
window.setInterval(updateTreeStatus, config.kTreeStatusUpdateFrequency);
pixelzoomer.installEventListeners();
onebar = new ui.onebar();
onebar.attach();
// FIXME: This doesn't belong here.
var onebarController = {
showResults: function(resultsView)
{
var resultsContainer = onebar.results();
resultsContainer.innerHTML = '';
resultsContainer.appendChild(resultsView)
onebar.select('results');
}
};
var unexpectedFailuresView = new ui.notifications.Stream();
g_unexpectedFailuresController = new controllers.UnexpectedFailures(model.state, unexpectedFailuresView, onebarController);
g_info = new ui.notifications.Stream();
g_nonLayoutTestFailureBuilders = new controllers.FailingBuilders(g_info);
var unexpected = onebar.unexpected();
var topBar = document.createElement('div');
topBar.className = 'topbar';
unexpected.appendChild(topBar);
// FIXME: This should be an Action object.
var updateButton = document.body.insertBefore(document.createElement('button'), document.body.firstChild);
updateButton.addEventListener("click", update);
updateButton.textContent = 'update';
topBar.appendChild(updateButton);
g_updateButton = updateButton;
var treeStatus = new ui.TreeStatus();
topBar.appendChild(treeStatus);
unexpected.appendChild(g_info);
unexpected.appendChild(unexpectedFailuresView);
update();
});
})();
/*
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
// pixelzoomer is shared with LayoutTests/fast/harness/results.html
// Unfortuantely, there's no good way to share code between these two uses.
var pixelzoomer = pixelzoomer || {};
(function() {
var kZoomFactor = 6;
var kDelayTimeoutMS = 400;
var kResultWidth = 800;
var kResultHeight = 600;
var kZoomedResultWidth = kResultWidth * kZoomFactor;
var kZoomedResultHeight = kResultHeight * kZoomFactor;
function matchesSelector(node, selector)
{
if (node.webkitMatchesSelector)
return node.webkitMatchesSelector(selector);
if (node.mozMatchesSelector)
return node.mozMatchesSelector(selector);
}
function parentOfType(node, selector)
{
while (node = node.parentNode) {
if (matchesSelector(node, selector))
return node;
}
return null;
}
function zoomImageContainer(url)
{
var container = document.createElement('div');
container.className = 'zoom-image-container';
var title = url.match(/\-([^\-]*)\.png/)[1];
var label = document.createElement('div');
label.className = 'label';
label.appendChild(document.createTextNode(title));
container.appendChild(label);
var imageContainer = document.createElement('div');
imageContainer.className = 'scaled-image-container';
var image = new Image();
image.src = url;
image.style.display = 'none';
var canvas = document.createElement('canvas');
imageContainer.appendChild(image);
imageContainer.appendChild(canvas);
container.appendChild(imageContainer);
return container;
}
function createContainer(e)
{
var tbody = parentOfType(e.target, 'tbody');
var row = tbody.querySelector('tr');
var images = row.querySelectorAll('img[src$=".png"]');
var container = document.createElement('div');
container.className = 'pixel-zoom-container';
for (var i = 0; i < images.length; i++)
container.appendChild(zoomImageContainer(images[i].src));
document.body.appendChild(container);
drawAll();
}
function draw(imageContainer)
{
var image = imageContainer.querySelector('img');
var canvas = imageContainer.querySelector('canvas');
if (!image.complete) {
image.onload = function() {
draw(imageContainer);
};
return;
}
canvas.width = imageContainer.clientWidth;
canvas.height = imageContainer.clientHeight;
var ctx = canvas.getContext('2d');
ctx.mozImageSmoothingEnabled = false;
ctx.imageSmoothingEnabled = false;
ctx.translate(imageContainer.clientWidth / 2, imageContainer.clientHeight / 2);
ctx.translate(-pixelzoomer._percentX * kZoomedResultWidth, -pixelzoomer._percentY * kZoomedResultHeight);
ctx.strokeRect(-1.5, -1.5, kZoomedResultWidth + 2, kZoomedResultHeight + 2);
ctx.scale(kZoomFactor, kZoomFactor);
ctx.drawImage(image, 0, 0);
}
function drawAll()
{
Array.prototype.forEach.call(document.querySelectorAll('.pixel-zoom-container .scaled-image-container'), draw);
}
function handleMouseOut(e)
{
if (e.relatedTarget && e.relatedTarget.tagName != 'IFRAME')
return;
// If e.relatedTarget is null, we've moused out of the document.
var container = document.querySelector('.pixel-zoom-container');
if (container)
container.remove();
}
function handleMouseMove(e)
{
if (pixelzoomer._mouseMoveTimeout)
clearTimeout(pixelzoomer._mouseMoveTimeout);
if (parentOfType(e.target, '.pixel-zoom-container'))
return;
var container = document.querySelector('.pixel-zoom-container');
var resultContainer = (e.target.className == 'result-container') ?
e.target : parentOfType(e.target, '.result-container');
if (!resultContainer || !resultContainer.querySelector('img')) {
if (container)
container.remove();
return;
}
var targetLocation = e.target.getBoundingClientRect();
pixelzoomer._percentX = (e.clientX - targetLocation.left) / targetLocation.width;
pixelzoomer._percentY = (e.clientY - targetLocation.top) / targetLocation.height;
if (!container) {
if (pixelzoomer.showOnDelay) {
pixelzoomer._mouseMoveTimeout = setTimeout(function() {
createContainer(e);
}, kDelayTimeoutMS);
return;
}
createContainer(e);
return;
}
drawAll();
}
pixelzoomer.showOnDelay = true;
pixelzoomer.installEventListeners = function()
{
document.addEventListener('mousemove', handleMouseMove, false);
document.addEventListener('mouseout', handleMouseOut, false);
};
})();
/*
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
(function() {
function minutesAgo(minutes)
{
var time = new Date();
time.setMinutes(time.getMinutes() - minutes);
return time;
}
function Cycler(items, repeat)
{
this._index = 0;
this._repeat = repeat || 1;
this._repeated = 0;
this._items = items;
}
Cycler.prototype = {
_updateRepeat: function()
{
if (++this._repeated >= this._repeat) {
this._repeated = this._repeat;
return false;
}
return true;
},
_updateIndex: function()
{
if (this._updateRepeat())
return;
if (++this._index >= this._items.length)
this._index = 0;
},
cycle: function()
{
var result = this._items[this._index];
this._updateIndex();
return result;
}
}
var people = new Cycler([
'Eustace Bagge',
'Dick Dastardly',
'Major Glory',
'Barney Rubble',
'Bunny Bravo',
'Race Bannon',
]);
var bugTitles = new Cycler([
'Unreviewed. Chromium rebaselines for r93794. * ...',
'Fix build when GCC 4.2 is not installed. * ... ',
'[Qt] Unreviewed gardening. * platform/qt/Skipped: Skip new tests until ...',
'garden-o-matic needs a way to report where and how tests are failing in ... ',
'REGRESSION(r90971): Fix an assertion failure with textarea placeholder. ...',
'Incorrect layout of :before and :after content, with display table, ...',
' JSHTMLImageElement (and associated Node) is abandoned when image load is ... '
]);
var testNames = new Cycler([
'fast/ruby/text-emphasis.html',
'plugins/destroy-during-npp-new.html',
'tables/mozilla/bugs/bug60749.html',
'tables/mozilla/bugs/bug51727.html',
'tables/mozilla/bugs/bug33855.html',
'tables/mozilla/bugs/bug52506.htm',
'tables/mozilla/bugs/bug18359.html',
'tables/mozilla/bugs/bug46368-1.html',
'tables/mozilla/bugs/bug46368-2.html',
'tables/mozilla/bugs/bug52505.html'
]);
var builders = new Cycler(Object.keys(config.builders), 3);
var expectations = new Cycler([
'TEXT',
'IMAGE+TEXT',
'TIMEOUT',
'CRASH'
], 4);
function createResultNodesByBuilder(builderFailureCount)
{
var result = {};
for(var i = 0; i < builderFailureCount; ++i)
result[builders.cycle()] = { actual: expectations.cycle() };
return result;
}
var currentRevision = 66666;
var currentMinutesAgo = 0;
function createFailingTestsSummary(commitDataCount, failureAnalysisCount, builderFailureCount)
{
var failingTestsSummary = new ui.notifications.FailingTestsSummary();
for (var i = 0; i < commitDataCount; ++i)
failingTestsSummary.addCommitData({
time: minutesAgo(currentMinutesAgo++),
revision: currentRevision++,
summary: bugTitles.cycle(),
author: people.cycle(),
reviewer: people.cycle()
});
for (var i = 0; i < failureAnalysisCount; ++i)
failingTestsSummary.addFailureAnalysis({
testName: testNames.cycle(),
resultNodesByBuilder: createResultNodesByBuilder(builderFailureCount)
});
return failingTestsSummary;
}
function createBuildersFailing(failingBuilderCount)
{
var buildersFailing = new ui.notifications.BuildersFailing();
builderNameList = [];
for (var i = 0; i < failingBuilderCount; ++i)
builderNameList.push(builders.cycle());
buildersFailing.setFailingBuilders(builderNameList);
return buildersFailing
}
window.addEventListener('DOMContentLoaded', function() {
var actions = new ui.notifications.Stream();
document.body.insertBefore(actions, document.body.firstChild);
// FIXME: This should be an Action object.
var button = document.body.insertBefore(document.createElement('button'), document.body.firstChild);
button.textContent = 'update';
actions.add(createFailingTestsSummary(3, 4, 1));
actions.add(createFailingTestsSummary(3, 1, 3));
actions.add(createFailingTestsSummary(1, 20, 1));
actions.add(createBuildersFailing(1));
actions.add(createBuildersFailing(8));
});
})();
/*
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
var ui = ui || {};
ui.actions = ui.actions || {};
(function() {
var Action = base.extends('button', {
init: function() {
this._eventName = null;
this.classList.add('action');
this.addEventListener('click', function(event) {
if (this._eventName) {
$(this).trigger(this._eventName);
event.stopPropagation();
}
}.bind(this));
},
makeDefault: function() {
this.classList.add('default');
return this;
}
});
ui.actions.Examine = base.extends(Action, {
init: function() {
this.textContent = 'Examine';
this._eventName = 'examine';
this.title = 'Examine these failures in detail.'
}
});
ui.actions.Next = base.extends(Action, {
init: function() {
this.innerHTML = '&#9654;';
this._eventName = 'next';
this.classList.add('next');
}
});
ui.actions.Previous = base.extends(Action, {
init: function() {
this.innerHTML = '&#9664;';
this._eventName = 'previous';
this.classList.add('previous');
}
});
ui.actions.List = base.extends('ul', {
init: function(actions) {
this.className = 'actions';
if (!actions)
return;
actions.forEach(this.add.bind(this));
},
add: function(action)
{
var item = document.createElement('li');
item.appendChild(action);
this.appendChild(item);
}
});
})();
/*
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
(function () {
module('ui.actions');
test('Buttons', 2, function() {
var buttonInfos = [{
view: new ui.actions.Examine(),
text: 'Examine',
event: 'examine'
}];
buttonInfos.forEach(function(buttonInfo) {
equal(buttonInfo.view.textContent, buttonInfo.text);
equal(buttonInfo.view._eventName, buttonInfo.event);
});
});
test('click', 1, function() {
var examine = new ui.actions.Examine();
$(examine).bind('examine', function() {
ok('Examine triggered.');
});
$(examine).trigger('click');
});
test('default', 2, function() {
var next = new ui.actions.Next();
equal(next.makeDefault(), next);
equal(next.className, 'action next default');
});
test('List', 1, function() {
var list = new ui.actions.List([
new ui.actions.Previous(),
new ui.actions.Next()
]);
equal(list.innerHTML,
'<li><button class="action previous">\u25C0</button></li>' +
'<li><button class="action next">\u25B6</button></li>');
});
}());
/*
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
var ui = ui || {};
ui.failures = ui.failures || {};
(function(){
var kBuildingResult = 'BUILDING';
ui.failures.Builder = base.extends('a', {
init: function(builderName, failures)
{
var configuration = config.builders[builderName];
if (configuration) {
if (configuration.version)
this._addSpan('version', configuration.version);
if (configuration.is64bit)
this._addSpan('architecture', '64-bit');
this._configuration = configuration;
} else
this._addSpan('version', builderName);
this.className = 'failing-builder';
this.href = ui.displayURLForBuilder(builderName);
ui.setTargetForLink(this);
if (failures)
this._addSpan('failures', ' ' + failures.join(', '));
},
_addSpan: function(className, text)
{
var span = this.appendChild(document.createElement('span'));
span.className = className;
span.textContent = text;
},
equals: function(configuration)
{
return this._configuration && this._configuration.is64bit == configuration.is64bit && this._configuration.version == configuration.version;
}
});
function cellContainsConfiguration(cell, configuration)
{
return Array.prototype.some.call(cell.children, function(configurationElement) {
return configurationElement.equals && configurationElement.equals(configuration);
});
}
function cellByBuildType(row, configuration)
{
return row.cells[configuration.debug ? 2 : 1];
}
ui.failures.FailureGrid = base.extends('table', {
init: function()
{
this.className = 'failures';
var titles = this.createTHead().insertRow();
titles.insertCell().textContent = 'type';
titles.insertCell().textContent = 'release';
titles.insertCell().textContent = 'debug';
this._body = this.appendChild(document.createElement('tbody'));
this._reset();
},
_rowByResult: function(result)
{
var row = this._resultRows[result];
if (row) {
row.style.display = '';
return row;
}
row = this._resultRows[result] = this._body.insertRow(0);
row.className = result;
var titleCell = row.insertCell();
titleCell.appendChild(document.createElement('span')).textContent = result;
row.insertCell();
row.insertCell();
return row;
},
update: function(resultsByBuilder)
{
if (this._pendingReset)
this._reset();
if (!resultsByBuilder)
return;
Object.keys(resultsByBuilder).forEach(function(builderName) {
var configuration = config.builders[builderName];
if (!configuration)
throw "Unknown builder name: " + builderName;
var row = this._rowByResult(resultsByBuilder[builderName].actual);
var cell = cellByBuildType(row, configuration);
if (cellContainsConfiguration(cell, configuration))
return;
cell.appendChild(new ui.failures.Builder(builderName));
}, this);
},
purge: function()
{
this._pendingReset = true;
},
_reset: function()
{
this._pendingReset = false;
this._resultRows = {};
this._body.innerHTML = '';
// Add the BUILDING row eagerly so that it appears last.
this._rowByResult(kBuildingResult).style.display = 'none';
}
});
})();
/*
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
(function () {
module('ui.failures');
test('Builder', 6, function() {
var configuration;
configuration = new ui.failures.Builder("WebKit Linux", ["update", "webkit_tests"]);
deepEqual(Object.getOwnPropertyNames(configuration.__proto__).sort(), [
'_addSpan',
'equals',
'init',
]);
equal(configuration.outerHTML, '<a class="failing-builder" href="http://build.chromium.org/p/chromium.webkit/waterfall?builder=WebKit+Linux"><span class="version">lucid</span><span class="architecture">64-bit</span><span class="failures"> update, webkit_tests</span></a>');
configuration = new ui.failures.Builder("WebKit XP");
equal(configuration.outerHTML, '<a class="failing-builder" href="http://build.chromium.org/p/chromium.webkit/waterfall?builder=WebKit+XP"><span class="version">xp</span></a>');
configuration._addSpan('foo', 'bar');
equal(configuration.outerHTML, '<a class="failing-builder" href="http://build.chromium.org/p/chromium.webkit/waterfall?builder=WebKit+XP"><span class="version">xp</span><span class="foo">bar</span></a>');
ok(configuration.equals({version: 'xp'}));
ok(!configuration.equals({version: 'lucid', is64bit: true}));
});
test('FailureGrid', 10, function() {
var grid = new ui.failures.FailureGrid();
deepEqual(Object.getOwnPropertyNames(grid.__proto__).sort(), [
"_reset",
"_rowByResult",
"init",
"purge",
"update"
]);
equal(grid.outerHTML, '<table class="failures">' +
'<thead><tr><td>type</td><td>release</td><td>debug</td></tr></thead>' +
'<tbody><tr class="BUILDING" style="display: none;"><td><span>BUILDING</span></td><td></td><td></td></tr></tbody>' +
'</table>');
var row = grid._rowByResult('TEXT');
equal(grid.outerHTML, '<table class="failures">' +
'<thead><tr><td>type</td><td>release</td><td>debug</td></tr></thead>' +
'<tbody>' +
'<tr class="TEXT">' +
'<td><span>TEXT</span></td><td></td><td></td>' +
'</tr>' +
'<tr class="BUILDING" style="display: none;"><td><span>BUILDING</span></td><td></td><td></td></tr>' +
'</tbody>' +
'</table>');
equal(row.outerHTML, '<tr class="TEXT"><td><span>TEXT</span></td><td></td><td></td></tr>');
grid.update({});
equal(grid.outerHTML, '<table class="failures">' +
'<thead><tr><td>type</td><td>release</td><td>debug</td></tr></thead>' +
'<tbody>' +
'<tr class="TEXT">' +
'<td><span>TEXT</span></td><td></td><td></td>' +
'</tr>' +
'<tr class="BUILDING" style="display: none;"><td><span>BUILDING</span></td><td></td><td></td></tr>' +
'</tbody>' +
'</table>');
raises(function() {
grid.update({'Atari': {}})
});
grid.update({'WebKit Linux (dbg)': { actual: 'TEXT'}});
equal(grid.outerHTML, '<table class="failures">' +
'<thead><tr><td>type</td><td>release</td><td>debug</td></tr></thead>' +
'<tbody>' +
'<tr class="TEXT">' +
'<td><span>TEXT</span></td>' +
'<td></td>' +
'<td><a class="failing-builder" href="http://build.chromium.org/p/chromium.webkit/waterfall?builder=WebKit+Linux+(dbg)"><span class="version">lucid</span><span class="architecture">64-bit</span></a></td>' +
'</tr>' +
'<tr class="BUILDING" style="display: none;"><td><span>BUILDING</span></td><td></td><td></td></tr>' +
'</tbody>' +
'</table>');
grid.update({'WebKit Mac10.6': { actual: 'IMAGE+TEXT'}});
equal(grid.outerHTML, '<table class="failures">' +
'<thead><tr><td>type</td><td>release</td><td>debug</td></tr></thead>' +
'<tbody>' +
'<tr class="IMAGE+TEXT">' +
'<td><span>IMAGE+TEXT</span></td>' +
'<td><a class="failing-builder" href="http://build.chromium.org/p/chromium.webkit/waterfall?builder=WebKit+Mac10.6"><span class="version">snowleopard</span></a></td>' +
'<td></td>' +
'</tr>' +
'<tr class="TEXT">' +
'<td><span>TEXT</span></td>' +
'<td></td>' +
'<td><a class="failing-builder" href="http://build.chromium.org/p/chromium.webkit/waterfall?builder=WebKit+Linux+(dbg)"><span class="version">lucid</span><span class="architecture">64-bit</span></a></td>' +
'</tr>' +
'<tr class="BUILDING" style="display: none;"><td><span>BUILDING</span></td><td></td><td></td></tr>' +
'</tbody>' +
'</table>');
grid.update({'WebKit Mac10.6': { actual: 'IMAGE+TEXT'}});
equal(grid.outerHTML, '<table class="failures">' +
'<thead><tr><td>type</td><td>release</td><td>debug</td></tr></thead>' +
'<tbody>' +
'<tr class="IMAGE+TEXT">' +
'<td><span>IMAGE+TEXT</span></td>' +
'<td><a class="failing-builder" href="http://build.chromium.org/p/chromium.webkit/waterfall?builder=WebKit+Mac10.6"><span class="version">snowleopard</span></a></td>' +
'<td></td>' +
'</tr>' +
'<tr class="TEXT">' +
'<td><span>TEXT</span></td>' +
'<td></td>' +
'<td><a class="failing-builder" href="http://build.chromium.org/p/chromium.webkit/waterfall?builder=WebKit+Linux+(dbg)"><span class="version">lucid</span><span class="architecture">64-bit</span></a></td>' +
'</tr>' +
'<tr class="BUILDING" style="display: none;"><td><span>BUILDING</span></td><td></td><td></td></tr>' +
'</tbody>' +
'</table>');
grid.purge();
grid.update({'WebKit Linux (dbg)': { actual: 'TEXT'}});
equal(grid.outerHTML, '<table class="failures">' +
'<thead><tr><td>type</td><td>release</td><td>debug</td></tr></thead>' +
'<tbody>' +
'<tr class="TEXT">' +
'<td><span>TEXT</span></td>' +
'<td></td>' +
'<td><a class="failing-builder" href="http://build.chromium.org/p/chromium.webkit/waterfall?builder=WebKit+Linux+(dbg)"><span class="version">lucid</span><span class="architecture">64-bit</span></a></td>' +
'</tr>' +
'<tr class="BUILDING" style="display: none;"><td><span>BUILDING</span></td><td></td><td></td></tr>' +
'</tbody>' +
'</table>');
});
}());
/*
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
var ui = ui || {};
ui.notifications = ui.notifications || {};
(function(){
var kMaxTestsPerGroup = 3;
ui.notifications.Stream = base.extends('ol', {
init: function()
{
this.className = 'notifications';
},
add: function(notification)
{
this.appendChild(notification);
return notification;
}
});
ui.notifications.Notification = base.extends('li', {
init: function()
{
this._how = this.appendChild(document.createElement('div'));
this._how.className = 'how';
this._what = this.appendChild(document.createElement('div'));
this._what.className = 'what';
this._index = 0;
// FIXME: Why is this requestAnimationFrame needed to make the
// animation happen?
requestAnimationFrame(function() {
this.animate([
{opacity: '0'},
{opacity: '1'},
], 200);
}.bind(this));
},
dismiss: function()
{
this.animate([
{opacity: '1'},
{opacity: '0'},
], 200).onfinish = this.remove.bind(this);
},
});
ui.notifications.Info = base.extends(ui.notifications.Notification, {
init: function(message)
{
this.update(message);
},
update: function(message)
{
this._what.textContent = message;
},
updateWithNode: function(node)
{
this._what.innerHTML = '';
this._what.appendChild(node);
}
});
ui.notifications.FailingTestGroup = base.extends('li', {
init: function(groupName, testNameList)
{
this.appendChild(ui.createLinkNode(ui.urlForFlakinessDashboard(testNameList), groupName));
}
});
var Cause = base.extends('li', {
init: function()
{
this._description = this.appendChild(document.createElement('div'));
this._description.className = 'description';
}
});
ui.notifications.SuspiciousCommit = base.extends(Cause, {
init: function(commitData)
{
this._revision = commitData.revision;
this._description.appendChild(ui.createLinkNode(trac.changesetURL(commitData.revision), commitData.revision));
this._details = this._description.appendChild(document.createElement('span'));
this._addDetail('title', commitData);
this._addDetail('author', commitData);
this._addDetail('reviewer', commitData);
this._addDetail('bugID', commitData,
ui.urlForCrbug,
function(value) {
return value.split(/\s*,\s*/);
}
);
},
hasRevision: function(revision)
{
return this._revision == revision;
},
_addDetail: function(part, commitData, linkFunction)
{
var content = commitData[part];
if (!content)
return;
var span = this._details.appendChild(document.createElement('span'));
span.className = part;
if (linkFunction) {
var parts = Array.isArray(content) ? content : [content];
parts.forEach(function(item, index) {
if (index > 0)
span.appendChild(document.createTextNode(', '));
var link = ui.createLinkNode(linkFunction(item), item);
link.className = part + '-item';
span.appendChild(link);
});
} else {
span.textContent = content;
}
}
});
ui.notifications.Failure = base.extends(ui.notifications.Notification, {
init: function()
{
this._problem = this._what.appendChild(document.createElement('div'));
this._problem.className = 'problem';
this._effects = this._problem.appendChild(document.createElement('ul'));
this._effects.className = 'effects';
this._causes = this._what.appendChild(document.createElement('ul'));
this._causes.className = 'causes';
},
});
ui.notifications.FailingTests = base.extends(ui.notifications.Failure, {
init: function() {
// FIXME: Convert actions to a link from test!
this._problem.appendChild(new ui.actions.List([
new ui.actions.Examine().makeDefault()
]));
this._testNameList = [];
},
testNameList: function()
{
return this._testNameList;
},
containsFailureAnalysis: function(failureAnalysis)
{
return this._testNameList.indexOf(failureAnalysis.testName) != -1;
},
addFailureAnalysis: function(failureAnalysis)
{
if (this.containsFailureAnalysis(failureAnalysis))
return false;
this._testNameList.push(failureAnalysis.testName);
this._effects.innerHTML = '';
this._forEachTestGroup(function(groupName, testNameList) {
this._effects.appendChild(new ui.notifications.FailingTestGroup(groupName, testNameList))
}.bind(this));
return true;
},
_forEachTestGroup: function(callback)
{
var individualTests = [];
base.forEachDirectory(this._testNameList, function(groupLabel, testsInDirectory) {
if (testsInDirectory.length <= kMaxTestsPerGroup) {
individualTests = individualTests.concat(testsInDirectory);
return;
}
callback(groupLabel, testsInDirectory);
});
individualTests.forEach(function(testName) {
callback(testName, [testName]);
});
}
});
ui.notifications.FailingTestsSummary = base.extends(ui.notifications.FailingTests, {
init: function() {
this._where = this._how.appendChild(new ui.failures.FailureGrid());
},
purge: function() {
this._where.purge();
},
updateBuilderResults: function(resultNodesByBuilder)
{
this._where.update(resultNodesByBuilder);
},
addFailureAnalysis: function(failureAnalysis)
{
this.updateBuilderResults(failureAnalysis.resultNodesByBuilder);
if (!ui.notifications.FailingTests.prototype.addFailureAnalysis.call(this, failureAnalysis))
return false;
},
addCommitData: function(commitData)
{
return this._causes.appendChild(new ui.notifications.SuspiciousCommit(commitData));
}
});
ui.notifications.BuildersFailing = base.extends(ui.notifications.Failure, {
init: function(message)
{
if (message)
this._problem.insertBefore(document.createTextNode(message + ':'), this._problem.firstChild);
},
setFailingBuilders: function(failuresList)
{
this._effects.innerHTML = '';
Object.keys(failuresList).map(function(builderName) {
var effect = document.createElement('li');
effect.className = 'builder';
effect.appendChild(new ui.failures.Builder(builderName, failuresList[builderName]));
this._effects.appendChild(effect);
}.bind(this));
}
});
})();
/*
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
(function () {
module('ui.results');
asyncTest('FlakinessData', 1, function() {
var dashboard = new ui.results.FlakinessData();
dashboard.addEventListener('load', function() {
// setTimeout to be after the FlakinessData's load handler.
setTimeout(function() {
window.postMessage({command: 'heightChanged', height: 15}, '*');
// setTimeout to be after the postMessage has been handled.
setTimeout(function() {
equals(dashboard.offsetHeight, 15);
dashboard.remove();
start();
}, 0);
}, 0);
});
document.body.appendChild(dashboard);
});
var kExampleResultsByTest = {
"scrollbars/custom-scrollbar-with-incomplete-style.html": {
"Mock Builder": {
"expected": "IMAGE",
"actual": "CRASH"
},
"Mock Linux": {
"expected": "TEXT",
"actual": "CRASH"
}
},
"userscripts/another-test.html": {
"Mock Builder": {
"expected": "PASS",
"actual": "TEXT"
}
}
};
var kExampleReftestResults = {
"reftest.html": {
"Mock Builder": {
"expected": "PASS",
"actual": "IMAGE",
"reftest_type": ["=="]
}
},
"mismatch-reftest.html": {
"Mock Builder": {
"expected": "PASS",
"actual": "IMAGE",
"reftest_type": ["!="]
}
}
};
var kExampleResultsWithTimeoutByTest = {
"fast/not-fast-test.html": {
"Mock Builder": {
"expected": "PASS",
"actual": "TIMEOUT"
}
}
};
var kExampleGreaterThanFourResultsByTest = {
"scrollbars/custom-scrollbar-with-incomplete-style.html": {
"Mock Linux": {
"expected": "TEXT",
"actual": "CRASH"
}
},
"scrollbars/1.html": {
"Mock Linux": {
"expected": "TEXT",
"actual": "CRASH"
}
},
"scrollbars/2.html": {
"Mock Linux": {
"expected": "TEXT",
"actual": "CRASH"
}
},
"scrollbars/3.html": {
"Mock Linux": {
"expected": "TEXT",
"actual": "CRASH"
}
},
"userscripts/another-test.html": {
"Mock Builder": {
"expected": "PASS",
"actual": "TEXT"
}
}
};
test('View', 18, function() {
var delegate = {
fetchResultsURLs: function(failureInfo) { return Promise.resolve(); }
};
var view = new ui.results.View(delegate);
view.setResultsByTest(kExampleResultsByTest);
view.firstResult();
var testSelector = view.querySelector('.test-selector');
var topPanel = testSelector.querySelector('.top-panel');
equals(topPanel.childNodes[0], topPanel.querySelector('.active'));;
equals($($('.builder-selector', view)[0]).tabs('option', 'selected'), 0);
view.nextResult();
equals(topPanel.childNodes[0], topPanel.querySelector('.active'));;
equals($($('.builder-selector', view)[0]).tabs('option', 'selected'), 1);
equals(view.currentTestName(), 'scrollbars/custom-scrollbar-with-incomplete-style.html');
view.nextResult();
equals(topPanel.childNodes[1], topPanel.querySelector('.active'));;
equals($($('.builder-selector', view)[0]).tabs('option', 'selected'), 0);
equals(view.currentTestName(), 'userscripts/another-test.html');
view.previousResult();
equals(topPanel.childNodes[0], topPanel.querySelector('.active'));;
equals($($('.builder-selector', view)[0]).tabs('option', 'selected'), 1);
view.nextTest();
equals(topPanel.childNodes[1], topPanel.querySelector('.active'));;
equals($($('.builder-selector', view)[0]).tabs('option', 'selected'), 0);
equals(view.currentTestName(), 'userscripts/another-test.html');
view.previousTest();
equals(topPanel.childNodes[0], topPanel.querySelector('.active'));;
equals($($('.builder-selector', view)[0]).tabs('option', 'selected'), 1);
equals(view.currentTestName(), 'scrollbars/custom-scrollbar-with-incomplete-style.html');
ok(!testSelector.querySelector('.resize-handle'));
equals(topPanel.style.minHeight, '');
});
test('View with more than four tests', 2, function() {
var delegate = {
fetchResultsURLs: function(failureInfo) { return Promise.resolve(); }
};
var view = new ui.results.View(delegate);
view.setResultsByTest(kExampleGreaterThanFourResultsByTest);
var testSelector = view.querySelector('.test-selector');
var topPanel = testSelector.querySelector('.top-panel');
ok(testSelector.querySelector('.resize-handle'));
equals(topPanel.style.minHeight, '100px');
});
test('View with reftests', 2, function() {
var delegate = {
fetchResultsURLs: function(failureInfo) { return Promise.resolve(); }
};
var view = new ui.results.View(delegate);
view.setResultsByTest(kExampleReftestResults);
view.firstResult();
equals(view.querySelectorAll('.non-action-button').length, 0);
equals(view.querySelectorAll('.action').length, 0);
});
asyncTest('View of timeouts', 1, function() {
var emptyPromise = Promise.resolve([]);
var delegate = {
fetchResultsURLs: function(failureInfo) { return emptyPromise; }
};
var view = new ui.results.View(delegate);
view.setResultsByTest(kExampleResultsWithTimeoutByTest);
view.firstResult();
emptyPromise.then(function() {
equals(view.querySelector('.results-grid').innerHTML, 'No results to display.');
start();
});
});
})();
/*
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
html {
overflow-y: scroll;
}
body {
font-family: 'Open Sans';
font-size: 14px;
margin: 0px;
}
a {
color: #333;
}
.ui-widget-content {
font-family: 'Open Sans';
}
.ui-widget button, button {
font-family: 'Open Sans';
border-radius: 2px;
background-image: linear-gradient(#f5f5f5, #f1f1f1);
border: 1px solid rgba(0, 0, 0, 0.1);
border-radius: 2px;
color: #666;
cursor: pointer;
font-size: 11px;
font-weight: bold;
height: 29px;
line-height: 27px;
min-width: 54px;
padding: 0 8px;
text-align: center
}
button.next {
margin-left: 0px;
}
button.previous {
margin-right: 0px;
}
button[disabled] {
visibility: hidden;
}
/* FIXME: This hover effect can't work on mobile. */
button:hover {
background-image: linear-gradient(#f8f8f8, #f1f1f1);
-webkit-box-shadow: 0 1px 1px rgba(0,0,0,0.1);
background-color: #f8f8f8;
background-image: linear-gradient(top,#f8f8f8,#f1f1f1);
border: 1px solid #c6c6c6;
box-shadow: 0 1px 1px rgba(0,0,0,0.1);
color: #333
}
button:focus {
border: 1px solid #4d90fe;
outline: none
}
button.default {
border: 1px solid #3079ED;
color: white;
background-image: linear-gradient(#4d90fe, #4787ed);
}
/* FIXME: This hover effect can't work on mobile. */
button.default:hover {
border: 1px solid #2f5bb7;
color: white;
background-color: #357ae8;
background-image: -webkit-gradient(linear,left top,left bottom,from(#4d90fe),to(#357ae8));
}
.clear {
clear: both;
}
/*** Visual escalation ***/
.warning {
color: white;
background-color: #ffc343;
font-weight: bold;
font-size: 2em;
}
.critical {
color: white;
background-color: #e98080;
font-weight: bold;
font-size: 3em;
}
/*
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
.failures .BUILDING {
opacity: 0.5;
}
a.failing-builder {
display: inline-block;
border: 1px solid Gray;
margin: 0 0 2px 0;
padding: 1px;
color: Black;
font-size: 11px;
text-decoration: none;
}
a.failing-builder > span.version {
text-transform: uppercase;
background-color: #555;
color: White;
padding: 0 2px;
}
a.failing-builder > span.architecture {
padding: 0 2px;
}
.effects a.failing-builder > span.architecture {
background-color: #555;
color: White;
}
a.failing-builder > span.graphics {
padding: 0 2px;
}
ul.failures {
padding: 0px;
}
ul.failures > li {
display: -webkit-box;
position: relative;
}
ul.failures > li label {
margin-left: 10px;
}
ul.failures > li ul.actions {
padding: 0px;
visibility: hidden;
}
/* FIXME: This hover effect can't work on mobile. */
ul.failures > li:hover ul.actions {
visibility: visible;
}
/*
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
body {
font-family: Tahoma, sans-serif;
font-size: 11px;
margin: 0;
padding: 0;
}
a {
color: Black;
}
table {
table-layout: fixed;
width: 100%;
border-collapse: collapse;
}
td, th {
overflow: hidden;
vertical-align: top;
/* border-right: 1px solid #c6c6c6; */
}
td:last-of-type, th:last-of-type {
/* border-right: 0px; */
}
th {
/* border-bottom: 1px solid #c6c6c6; */
}
button {
border-radius: 2px;
background-image: linear-gradient(#f5f5f5, #f1f1f1);
border: 1px solid rgba(0, 0, 0, 0.1);
border-radius: 2px;
color: #666;
cursor: pointer;
font-size: 11px;
font-weight: bold;
height: 29px;
line-height: 27px;
margin: 11px 6px;
min-width: 54px;
padding: 0 8px;
text-align: center
}
button.next {
margin-left: 0px;
}
button.previous {
margin-right: 0px;
}
button[disabled] {
visibility: hidden;
}
/* FIXME: This hover effect can't work on mobile. */
button:hover {
background-image: linear-gradient(#f8f8f8, #f1f1f1);
-webkit-box-shadow: 0 1px 1px rgba(0,0,0,0.1);
background-color: #f8f8f8;
background-image: linear-gradient(top,#f8f8f8,#f1f1f1);
border: 1px solid #c6c6c6;
box-shadow: 0 1px 1px rgba(0,0,0,0.1);
color: #333
}
button:focus {
border: 1px solid #4d90fe;
outline: none
}
button.default {
border: 1px solid #3079ED;
color: white;
background-image: linear-gradient(#4d90fe, #4787ed);
}
/* FIXME: This hover effect can't work on mobile. */
button.default:hover {
border: 1px solid #2f5bb7;
color: white;
background-color: #357ae8;
background-image: -webkit-gradient(linear,left top,left bottom,from(#4d90fe),to(#357ae8));
}
.clear {
clear: both;
}
/*** butterbar ***/
.butterbar {
background-color: #f5f5f5;
padding: 5px;
position: fixed;
top: 0px;
right: 0px;
}
.butterbar .hide {
margin-left: 20px;
}
/*** infobar ***/
.infobar {
display: none;
background-color: Cornsilk;
border: 5px solid Tomato;
padding: 10px;
margin: 5px auto;
font-size: 15px;
width: 100%;
text-align: center;
}
.infobar .status a {
font-weight: normal;
}
.infobar .status ul {
margin: 0;
padding: 0;
list-style: none;
display: inline-block;
padding: 0 0 0 10px;
}
.infobar .status li {
display: inline-block;
margin: 0px 5px;
}
/*** recent-history ***/
.recent-history {
}
.recent-history .builder {
width: 5px;
border-right: 1px solid #f5f5f5;
}
.recent-history .built {
background-color: #c6c6c6;
}
.recent-history td[data-failure-types] {
background-color: Black;
}
.changelog .result {
padding: 4px 0px;
border-top: 2px solid white;
border-bottom: 2px solid white;
}
.changelog .test {
padding-left: 3px;
}
.changelog .entry {
padding: 4px 0px 4px 3px;
}
.changelog .reverted {
text-decoration: line-through;
}
.changelog .possible-regression {
background-color: PapayaWhip;
}
.changelog .details, .changelog .details a {
color: #555;
}
.changelog .summary {
color: Black;
}
.changelog .author {
font-style: italic;
}
.test-name.IMAGE\+TEXT::after {
content: 'IMAGE+TEXT';
font-weight: normal;
text-decoration: none;
color: white;
background-color: Indigo;
font-size: 10px;
padding: 1px 2px;
margin: 0 0 0 3px;
border-radius: 4px;
}
.test-name.IMAGE::after {
content: 'IMAGE';
font-weight: normal;
text-decoration: none;
color: white;
background-color: MidnightBlue;
font-size: 10px;
padding: 1px 2px;
margin: 0 0 0 3px;
border-radius: 4px;
}
.test-name.TIMEOUT::after {
content: 'TIMEOUT';
font-weight: normal;
text-decoration: none;
color: white;
background-color: DarkGoldenRod;
font-size: 10px;
padding: 1px 2px;
margin: 0 0 0 3px;
border-radius: 4px;
}
.test-name.TEXT::after {
content: 'TEXT';
font-weight: normal;
text-decoration: none;
color: white;
background-color: DodgerBlue;
font-size: 10px;
padding: 1px 2px;
margin: 0 0 0 3px;
border-radius: 4px;
}
.test-name.CRASH::after {
content: 'CRASH';
font-weight: normal;
text-decoration: none;
color: white;
background-color: Tomato;
font-size: 10px;
padding: 1px 2px;
margin: 0 0 0 3px;
border-radius: 4px;
}
/*** results-view ***/
/* FIXME: Remove this once garden-o-matic switches to the new results view. */
.old-results-view {
display: none;
position: fixed;
left: 0px;
right: 0px;
top: 25%;
bottom: 0px;
}
.results-view {
background-color: #f5f5f5;
}
.results-view .toolbar {
border-top: 1px solid #c6c6c6;
border-bottom: 1px solid #c6c6c6;
}
.results-view .toolbar .selector {
font-size: 11px;
font-weight: bold;
height: 29px;
line-height: 27px;
margin: 11px 6px;
padding: 0 8px;
}
.results-view .test-selector {
width: 400px;
margin-right: 6px;
}
.results-view .toolbar .actions {
float: right;
}
.results-detail td {
background-color: white;
}
/*** partytime ***/
.partytime {
display: none;
text-align: center;
}
/*
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
/* FIXME: This should really be in actions.css. */
ul.actions > li {
display: inline-block;
}
ol.notifications {
list-style: none;
padding: 0;
margin: 0;
}
ol.notifications ul {
list-style: none;
padding: 0;
}
ol.notifications > li {
display: flex;
flex-wrap: wrap;
position: relative;
width: 100%;
padding: 10px;
box-sizing: border-box;
border-top: 1px solid Gray;
}
ol.notifications div.how {
width: 350px;
}
ol.notifications div.what {
display: -webkit-box;
-webkit-box-orient: vertical;
padding: 0 0 0 10px;
flex: 1;
}
ol.notifications > li div.what ul.effects > li.builder {
display: inline;
padding-right: 5px;
}
ol.notifications ul.causes > li, ol.notifications div.problem {
display: -webkit-box;
}
ol.notifications ul.causes div.description, ol.notifications div.problem ul.effects {
-webkit-box-flex: 1;
}
ol.notifications > li div.problem {
padding-bottom: 10px;
}
ol.notifications > li div.problem > ul.actions {
visibility: hidden;
}
ol.notifications > li:hover div.problem > ul.actions {
visibility: visible;
}
ol.notifications > li table.failures {
opacity: 0.2;
-webkit-transition: opacity 0.5s;
}
ol.notifications > li:hover table.failures {
opacity: 1;
}
ol.notifications > li ul.causes > li > ul.actions {
}
ol.notifications > li ul.causes > li > div.description {
padding: 0 10px 5px 0;
display: -webkit-box;
}
ol.notifications > li ul.causes > li > div.description > a {
padding: 5px 10px 5px 10px;
margin: -5px 10px -2px 0;
border-radius: 4px;
display: inline-block;
}
ol.notifications > li ul.causes > li:hover > div.description > a {
background-color: #555;
color: White;
}
ol.notifications > li ul.causes > li:hover > div.description > a::after {
content: '';
width: 0;
height: 0;
margin-top: 5px;
position: absolute;
margin-left: 10px;
border-top: 5px solid White;
border-left: 5px solid #555;
border-bottom: 5px solid White;
}
ol.notifications > li ul.causes > li > div.description > span {
padding: 0 10px 0 0;
display: block;
cursor: default;
pointer-events: none;
-webkit-box-flex: 1;
}
ol.notifications > li ul.causes > li > div.description > span > span.author {
padding: 0 0 0 5px;
font-style: italic;
}
ol.notifications > li ul.causes > li > div.description > span > span.reviewer {
color: Gray;
}
ol.notifications > li ul.causes > li > div.description > span > span.bugID::before {
content: '[bug ';
padding-left: 8px;
}
ol.notifications > li ul.causes > li > div.description > span > span.bugID::after {
content: ']';
}
ol.notifications > li ul.causes > li > div.description > span > span.bugID > a {
cursor: hand;
pointer-events: auto;
}
ol.notifications > li ul.causes > li > div.description > span > span.reviewer::before {
content: ' (';
}
ol.notifications > li ul.causes > li > div.description > span > span.reviewer::after {
content: ')';
}
ol.notifications > li ul.causes > li > ul.actions {
visibility: hidden;
}
ol.notifications > li ul.causes > li:hover > ul.actions {
visibility: visible;
}
ol.notifications > li ul.causes > li li {
padding: 10px 0 0 0;
display: inline;
}
ol.notifications table.failures {
border-collapse: collapse;
table-layout: fixed;
font-size: 11px;
width: 350px;
}
ol.notifications table.failures thead tr td:first-child {
visibility: hidden;
}
ol.notifications table.failures tbody tr {
border-top: 1px solid #eee;
}
ol.notifications table.failures tbody td:first-child {
width: 20%;
}
ol.notifications table.failures tbody td {
width: 40%;
padding: 2px;
}
ol.notifications table.failures tbody tr td:first-child {
vertical-align: top;
}
ol.notifications table.failures tbody tr td:first-child span {
padding: 0 2px;
}
ol.notifications table.failures tbody tr.TIMEOUT td:first-child span {
background-color: #fffc6c;
}
ol.notifications table.failures tbody tr.TEXT td:first-child span {
background-color: #e98080;
}
ol.notifications table.failures tbody tr.CRASH td:first-child span {
background-color: #ffc343;
}
ol.notifications table.failures tbody tr.AUDIO td:first-child span {
background-color: #bfdfff;
}
ol.notifications table.failures tbody tr.IMAGE td:first-child span {
background-color: #69f;
}
ol.notifications table.failures tbody tr.IMAGE\+TEXT td:first-child span {
background-color: #96f;
}
/*
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* We mostly use the styles from jQuery UI, but we clear some of them to
* make the UI slightly tighter.
*/
#onebar {
border: none;
padding: 0px;
margin-bottom: 100px;
}
#onebar .ui-widget-header {
border-top: none;
border-right: none;
border-left: none;
border-radius: 0px;
}
#onebar #platform-picker {
float: right;
margin-top: 8px;
margin-right: 8px;
font-size: larger;
}
#unexpected {
min-height: 550px;
padding: 0 8px;
}
#onebar.partytime #unexpected {
background: url(../images/partytime.gif) center center no-repeat;
}
#link-handling {
position: absolute;
top: 10px;
right: 0;
padding-right: 4px;
}
/* This checkbox just overlaps the main content on smalls screens and doesn't
make a lot of sense as currently designed.*/
@media only screen and (max-width: 400px) {
#link-handling { display: none; }
}
#new-window-for-links {
vertical-align: text-bottom;
}
#onebar details {
padding-left: 2px;
padding-right: 2px;
display: inline-block;
vertical-align: top;
}
#onebar details table, #revisionPopUp table {
font-size: 11px;
text-decoration: none;
border: 1px solid Gray;
padding: 2px 2px;
}
#revisionPopUp {
display: none;
}
#revisionPopUp.active {
background-color: white;
display: block;
box-shadow: 2px 2px #ccc;
z-index: 1;
}
.topbar {
display: flex;
align-items: center;
}
.treestatus {
display: inline-block;
margin: 4px;
font-size: 11px;
}
/*
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
.pixel-zoom-container {
position: fixed;
top: 0;
left: 0;
width: 96%;
margin: 10px;
padding: 10px;
display: -webkit-box;
display: -moz-box;
pointer-events: none;
background-color: silver;
border-radius: 20px;
border: 1px solid gray;
box-shadow: 0 0 5px rgba(0, 0, 0, 0.75);
}
.pixel-zoom-container > * {
-webkit-box-flex: 1;
-moz-box-flex: 1;
border: 1px solid black;
margin: 4px;
overflow: hidden;
background-color: white;
}
.pixel-zoom-container .scaled-image-container {
position: relative;
overflow: hidden;
width: 100%;
height: 400px;
}
.scaled-image-container > img {
position: absolute;
top: 0;
left: 0;
image-rendering: -webkit-optimize-contrast;
}
/*
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
.non-action-button, .results-view ul.actions, .ui-dialog ul.actions {
float: right;
margin: 0;
padding: 5px 0px;
list-style: none;
display: inline-block;
}
.non-action-button {
padding: 5px;
}
.results-view ul.actions li, .ui-dialog ul.actions li {
display: inline-block;
}
.results-view h3 ul.actions {
padding: 2px 0px;
}
.results-view h3 ul.actions {
visibility: hidden;
}
.results-view h3.ui-state-active ul.actions {
visibility: visible;
}
.ui-tabs .ui-tabs-panel.results-detail {
padding: 0px;
}
.results-grid table {
table-layout: fixed;
width: 100%;
border-collapse: collapse;
}
.results-grid table td, .results-view table th {
overflow: hidden;
vertical-align: top;
}
.results-grid table th {
padding: 3px;
border-top: 1px solid #DDD;
border-bottom: 1px solid #DDD;
}
.results-view .top-panel {
max-height: 20%;
overflow: auto;
position: relative;
border: 1px solid #EEE;
}
.results-view .resize-handle {
height: 5px;
text-align: center;
-webkit-user-select: none;
line-height: 5px;
cursor: ns-resize;
font-size: 5px;
font-weight: bold;
padding: 1px;
}
.results-view .resize-handle:before {
content: '|||';
}
.results-view .link-title,
.results-view .active .non-link-title {
display: none;
}
.results-view .non-link-title,
.results-view .active .link-title {
display: inline-block;
}
.results-view h3 {
font-size: 14px;
font-weight: normal;
border-top: 1px solid #DDD;
margin: 0;
cursor: pointer;
}
.results-view h3:not(.active):hover {
background-color: #EEE;
}
.results-view .active {
background-color: #CCC;
}
/* CSS percentages in standards-mode are dumb. You need to have a percentage or fixed height
all the way up the tree in order to have percentages resolve. */
html, body, #onebar, .results-view, .test-selector {
height: 100%;
}
#results {
/* FIXME: We really should use flexbox so we don't have to do this. But that requires restructuring the DOM a bit. */
height: -webkit-calc(100% - 39px);
box-sizing: border-box;
/* Position relative so that nested percentages size to this element. */
position: relative;
}
.flakiness-iframe, .flakiness-iframe-placeholder {
border: none;
height: 0;
width: 100%;
}
<!DOCTYPE html>
<!--
Copyright (C) 2011 Google Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
THE POSSIBILITY OF SUCH DAMAGE.
The favicons are from the awesome famfamfam.com, which is the website of Mark
James, a web developer from Birmingham, UK.
-->
<html>
<head>
<title>Mock Summary View</title>
<link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Open+Sans:400,700">
<link rel="stylesheet" href="styles/common.css">
<link rel="stylesheet" href="styles/results.css">
<link rel="stylesheet" href="styles/notifications.css">
</head>
<body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
<script src="scripts/config.js"></script>
<script src="scripts/base.js"></script>
<script src="scripts/net.js"></script>
<script src="scripts/svn-log.js"></script>
<script src="scripts/builders.js"></script>
<script src="scripts/results.js"></script>
<script src="scripts/ui.js"></script>
<script src="scripts/model.js"></script>
<script src="scripts/ui/actions.js"></script>
<script src="scripts/ui/failures.js"></script>
<script src="scripts/ui/notifications.js"></script>
<script src="scripts/ui/results.js"></script>
<script src="scripts/controllers.js"></script>
<script src="scripts/summary-mock.js"></script>
</body>
</html>
...@@ -6,22 +6,22 @@ found in the LICENSE file. ...@@ -6,22 +6,22 @@ found in the LICENSE file.
<script src="../bower_components/sugar/release/sugar-full.development.js"></script> <script src="../bower_components/sugar/release/sugar-full.development.js"></script>
<script src="../scripts/base.js"></script> <script src="../scripts/base.js"></script>
<script src="../scripts/builders.js"></script>
<script src="../scripts/config.js"></script> <script src="../scripts/config.js"></script>
<script src="../scripts/model.js"></script>
<script src="../scripts/net.js"></script> <script src="../scripts/net.js"></script>
<script src="../scripts/results.js"></script>
<script src="../scripts/rollbot.js"></script> <script src="../scripts/rollbot.js"></script>
<script src="../scripts/svn-log.js"></script> <script src="../scripts/svn-log.js"></script>
<script src="../scripts/treestatus.js"></script> <script src="../scripts/treestatus.js"></script>
<script src="../scripts/builders.js"></script>
<script src="../scripts/results.js"></script>
<script src="../scripts/ui.js"></script> <script src="../scripts/ui.js"></script>
<script src="../scripts/model.js"></script>
<link rel="import" href="../bower_components/core-animated-pages/core-animated-pages.html"> <link rel="import" href="../bower_components/core-animated-pages/core-animated-pages.html">
<link rel="import" href="../bower_components/core-animated-pages/transitions/slide-from-right.html"> <link rel="import" href="../bower_components/core-animated-pages/transitions/slide-from-right.html">
<link rel="import" href="../bower_components/paper-tabs/paper-tab.html"> <link rel="import" href="../bower_components/paper-tabs/paper-tab.html">
<link rel="import" href="../bower_components/paper-tabs/paper-tabs.html"> <link rel="import" href="../bower_components/paper-tabs/paper-tabs.html">
<link rel="import" href="ct-unexpected-failures.html">
<link rel="import" href="ct-results-panel.html"> <link rel="import" href="ct-results-panel.html">
<link rel="import" href="ct-unexpected-failures.html">
<polymer-element name="ct-sheriff-o-matic"> <polymer-element name="ct-sheriff-o-matic">
<template> <template>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment