Commit 89d65473 authored by leviw@chromium.org's avatar leviw@chromium.org

[Sheriff-o-matic] Refactor cards and get rid of ct-failure-cards

Directly embed the failure cards into the failure stream, and abstract
the button UI out into ct-failure-card-buttons.

NOTRY=true
R=ojan@chromium.org

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

git-svn-id: svn://svn.chromium.org/blink/trunk@181864 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 4234fdbd
......@@ -4,12 +4,15 @@ Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->
<link rel="import" href="ct-builder-list.html">
<script>
function CTBuilderFailureGroupData(failure, bot, url) {
this.bot = bot;
this.failure = failure;
this.category = 'builder';
this.url = url;
this.builderList = new CTBuilderList(failure);
this.category = 'builder';
};
CTBuilderFailureGroupData.prototype.getAnnotations = function() {
......
......@@ -4,12 +4,14 @@ Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->
<link rel="import" href="ct-builder-list.html">
<link rel="import" href="ct-commit-list.html">
<script>
function CTSheriffFailureGroupData(failures, commitList) {
this.failures = failures;
this.commitList = commitList;
this.builderList = new CTBuilderList(failures);
this.category = 'sheriff';
};
......@@ -40,5 +42,5 @@ CTSheriffFailureGroupData.prototype.failedOnce = function() {
}
}
return totalFailures == 1;
}
};
</script>
......@@ -18,12 +18,13 @@ found in the LICENSE file.
<link rel="import" href="../model/test/ct-failure-tests.html">
<link rel="import" href="../model/test/tree-status-tests.html">
<link rel="import" href="../scripts/test/results-tests.html">
<link rel="import" href="../ui/test/ct-bot-failure-card-tests.html">
<link rel="import" href="../ui/test/ct-builder-grid-tests.html">
<link rel="import" href="../ui/test/ct-builder-tests.html">
<link rel="import" href="../ui/test/ct-commit-list-tests.html">
<link rel="import" href="../ui/test/ct-commit-tests.html">
<link rel="import" href="../ui/test/ct-embedded-flakiness-dashboard-tests.html">
<link rel="import" href="../ui/test/ct-failure-card-tests.html">
<link rel="import" href="../ui/test/ct-failure-card-button-tests.html">
<link rel="import" href="../ui/test/ct-failure-stream-tests.html">
<link rel="import" href="../ui/test/ct-last-updated-tests.html">
<link rel="import" href="../ui/test/ct-party-time-tests.html">
......
......@@ -8,9 +8,13 @@ found in the LICENSE file.
<link rel="import" href="ct-commit-list.html">
<link rel="import" href="ct-test-list.html">
<polymer-element name="ct-bot-failure-card" attributes="group builderList" noscript>
<polymer-element name="ct-bot-failure-card" attributes="group commitLog" noscript>
<template>
<style>
:host {
display: flex;
}
ct-builder-grid {
margin-right: 10px;
width: 250px;
......@@ -24,12 +28,29 @@ found in the LICENSE file.
flex: 1;
}
</style>
<ct-builder-grid builderList="{{ builderList }}"></ct-builder-grid>
<ct-builder-grid builderList="{{ group.builderList }}"></ct-builder-grid>
<div id="failure">
<ct-test-list tests="{{ group.failures }}" tree="{{ tree }}"></ct-test-list>
<ct-commit-list commitList="{{ group.commitList }}"></ct-commit-list>
</div>
</template>
<script>
Polymer({
group: null,
commitLog: null,
_builderList: null,
observe: {
group: '_updateCommitList',
commitLog: '_updateCommitList',
},
_updateCommitList: function() {
if (this.group && this.group.commitList && this.commitLog)
this.group.commitList.update(this.commitLog);
},
});
</script>
</polymer-element>
......@@ -8,9 +8,13 @@ found in the LICENSE file.
<link rel="import" href="ct-commit-list.html">
<link rel="import" href="ct-test-list.html">
<polymer-element name="ct-builder-failure-card" attributes="group builderList" noscript>
<polymer-element name="ct-builder-failure-card" attributes="group" noscript>
<template>
<style>
:host {
display: flex;
}
ct-builder-grid {
margin-right: 10px;
width: 250px;
......@@ -20,7 +24,7 @@ found in the LICENSE file.
flex: 1;
}
</style>
<ct-builder-grid builderList="{{ builderList }}"></ct-builder-grid>
<ct-builder-grid builderList="{{ group.builderList }}"></ct-builder-grid>
<div id="failure">
<template if="{{ group.failure.step == 'building' }}">
Running
......
......@@ -5,22 +5,16 @@ found in the LICENSE file.
-->
<link rel="import" href="../model/ct-builder-list.html">
<link rel="import" href="ct-bot-failure-card.html">
<link rel="import" href="ct-builder-failure-card.html">
<link rel="import" href="ct-trooper-card.html">
<link rel="import" href="../bower_components/paper-dialog/paper-dialog.html">
<link rel="import" href="../bower_components/paper-dialog/paper-dialog-transition.html">
<link rel="import" href="../bower_components/paper-input/paper-input.html">
<polymer-element name="ct-failure-card" attributes="group commitLog tree bug">
<polymer-element name="ct-failure-card-buttons" attributes="group bug">
<template>
<style>
:host {
display: block;
}
#container {
display: flex;
flex-direction: column;
}
/* FIXME: All this paper-button styling should go in a cr-button component so that
......@@ -51,71 +45,31 @@ found in the LICENSE file.
box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.1);
color: #222;
}
#buttons {
display: flex;
flex-direction: column;
}
.card {
display: flex;
flex: 1;
}
.snoozed {
opacity: 0.5;
}
</style>
<div id="container">
<div class="card {{ { snoozed: group.isSnoozed } | tokenList }}">
<!-- FIXME: Refactor the buttons into their own widget so we don't need cards within cards -->
<template if="{{ group.data.category == 'sheriff' }}">
<ct-bot-failure-card class='card' group="{{ group.data }}" builderList="{{ _builderList }}"></ct-bot-failure-card>
</template>
<template if="{{ group.data.category == 'builder' }}">
<ct-builder-failure-card class='card' group="{{ group.data }}" builderList="{{ _builderList }}"></ct-builder-failure-card>
</template>
<template if="{{ group.data.category == 'trooper' }}">
<ct-trooper-card class='card' group="{{ group.data }}"></ct-trooper-card>
</template>
</div>
<div id="buttons">
<paper-button id="examine" on-tap="{{ examine }}" label="Examine"></paper-button>
<template if="{{ !group.isSnoozed }}">
<paper-button id="snooze" on-tap="{{ snooze }}" label="Snooze"></paper-button>
</template>
<template if="{{ group.isSnoozed }}">
<paper-button id="snooze" on-tap="{{ unsnooze }}" label="Unsnooze"></paper-button>
</template>
<paper-button id="link-bug" on-tap="{{ linkBug }}" label="Link Bug"></paper-button>
<template if="{{ group.bug !== undefined }}">
<div>
<a href="{{ group.bug }}">
{{ group.bugLabel }}</a>
</div>
</template>
<paper-button id="examine" on-tap="{{ examine }}" label="Examine"></paper-button>
<template if="{{ !group.isSnoozed }}">
<paper-button id="snooze" on-tap="{{ snooze }}" label="Snooze"></paper-button>
</template>
<template if="{{ group.isSnoozed }}">
<paper-button id="snooze" on-tap="{{ unsnooze }}" label="Unsnooze"></paper-button>
</template>
<paper-button id="link-bug" on-tap="{{ linkBug }}" label="Link Bug"></paper-button>
<template if="{{ group.bug !== undefined }}">
<div>
<a href="{{ group.bug }}">
{{ group.bugLabel }}</a>
</div>
</template>
<paper-dialog heading="Enter bug number" transition="paper-transition-center" id="bugDialog">
<paper-input label="Bug# or URL" floatingLabel autofocus id="bug"></paper-input>
<paper-button label="Remove bug link" on-tap="{{ removeBug }}" dismissive id="dialogRemoveBug"></paper-button>
<paper-button label="OK" on-tap="{{ saveBug }}" affirmative id="dialogOk"></paper-button>
</paper-dialog>
</div>
<paper-dialog heading="Enter bug number" transition="paper-transition-center" id="bugDialog">
<paper-input label="Bug# or URL" floatingLabel autofocus id="bug"></paper-input>
<paper-button label="Remove bug link" on-tap="{{ removeBug }}" dismissive id="dialogRemoveBug"></paper-button>
<paper-button label="OK" on-tap="{{ saveBug }}" affirmative id="dialogOk"></paper-button>
</paper-dialog>
</template>
<script>
Polymer({
group: null,
commitLog: null,
_builderList: null,
tree: '',
observe: {
group: '_updateCommitList',
commitLog: '_updateCommitList',
'group.data.failures': '_updateBuilderList',
'group.data.failure': '_updateBuilderList',
},
examine: function() {
this.fire('ct-examine-failures', this.group);
......@@ -129,18 +83,6 @@ found in the LICENSE file.
this.group.unsnooze();
},
_updateCommitList: function() {
if (this.group && this.group.commitList && this.commitLog)
this.group.commitList.update(this.commitLog);
},
_updateBuilderList: function() {
if (this.group.data.category == 'sheriff')
this._builderList = new CTBuilderList(this.group.data.failures);
else if (this.group.data.category == 'builder')
this._builderList = new CTBuilderList(this.group.data.failure);
},
linkBug: function() {
this.$.bug.value = this.group.bug;
this.$.bugDialog.toggle();
......
......@@ -4,7 +4,9 @@ Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->
<link rel="import" href="ct-failure-card.html">
<link rel="import" href="ct-bot-failure-card.html">
<link rel="import" href="ct-builder-failure-card.html">
<link rel="import" href="ct-trooper-card.html">
<polymer-element name="ct-failure-stream" attributes="groups commitLog tree category title" noscript>
<template>
......@@ -13,13 +15,18 @@ found in the LICENSE file.
display: block;
}
ct-failure-card {
.card {
padding: 15px 5px;
border-bottom: 1px solid lightgrey;
display: flex;
}
.card > * {
flex: 1;
}
/* FIXME: Don't use before hax to add labels */
ct-failure-card:first-of-type::before {
:host > div:first-of-type::before {
content: "{{ title }}:";
display: block;
font-weight: bold;
......@@ -28,10 +35,27 @@ found in the LICENSE file.
background-color: #f5f5f5;
margin-bottom: 5px;
}
.snoozed {
opacity: 0.5;
}
</style>
<template repeat="{{ group in groups }}">
<template if="{{ group.category == category }}">
<ct-failure-card group="{{ group }}" commitLog="{{ commitLog }}" tree="{{ tree }}"></ct-failure-card>
<div> <!-- FIXME: Remove when we have a better title solution. -->
<div class="card">
<template if="{{ group.data.category == 'sheriff' }}">
<ct-bot-failure-card class='{{ { snoozed: group.isSnoozed } | tokenList }}' group="{{ group.data }}" commitLog="{{ commitLog }}"></ct-bot-failure-card>
</template>
<template if="{{ group.data.category == 'builder' }}">
<ct-builder-failure-card class='{{ { snoozed: group.isSnoozed } | tokenList }}' group="{{ group.data }}"></ct-builder-failure-card>
</template>
<template if="{{ group.data.category == 'trooper' }}">
<ct-trooper-card class='{{ { snoozed: group.isSnoozed } | tokenList }}' group="{{ group.data }}"></ct-trooper-card>
</template>
<ct-failure-card-buttons group="{{ group }}" bug="{{ bug }}"></ct-failure-card-buttons>
</div>
</div>
</template>
</template>
</template>
......
......@@ -9,6 +9,10 @@ found in the LICENSE file.
<polymer-element name="ct-trooper-card" attributes="group">
<template>
<style>
:host {
display: flex;
}
#failure {
flex: 1;
margin-left: 10px;
......
<!--
Copyright 2014 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->
<link rel="import" href="../ct-bot-failure-card.html">
<link rel="import" href="../../model/ct-commit-list-mock.html">
<link rel="import" href="../../model/ct-commit-log-mock.html">
<link rel="import" href="../../model/ct-failure-group.html">
<script>
(function () {
var assert = chai.assert;
describe('ct-bot-failure-card', function() {
var group;
var card;
var failures;
beforeEach(function(done) {
card = document.createElement('ct-bot-failure-card');
var cl = new CTCommitListMock();
group = new CTFailureGroup('', new CTSheriffFailureGroupData([
new CTFailure('autobot', 'unknown', {someBuilder: {key: 'a'}}, {'blink':158547},
{'blink':158544})], cl));
card.group = group.data;
card.commitLog = new CTCommitLogMock();
setTimeout(done);
});
describe('failure card UI', function() {
it('should have commit summaries', function(done) {
// Expand the first repository so that the <ct-commit>'s are generated.
card.group.commitList.repositories[0].expanded = true;
setTimeout(function() {
var list = card.shadowRoot.querySelector('ct-commit-list');
var commits = list.shadowRoot.querySelectorAll('ct-commit');
assert(commits[1].data);
assert(commits[1].data.summary);
done();
});
});
it('removing a commit summary', function(done) {
card.commitLog.commits['blink']['158545'].summary = undefined;
card.group.commitList.repositories[0].expanded = true;
setTimeout(function() {
var list = card.shadowRoot.querySelector('ct-commit-list');
var commits = list.shadowRoot.querySelectorAll('ct-commit');
assert.notOk(commits[0].data.summary);
done();
});
});
});
});
})()
</script>
......@@ -4,7 +4,8 @@ Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->
<link rel="import" href="../ct-failure-card.html">
<link rel="import" href="../ct-bot-failure-card.html">
<link rel="import" href="../ct-failure-card-buttons.html">
<link rel="import" href="../../model/ct-commit-list-mock.html">
<link rel="import" href="../../model/ct-commit-log-mock.html">
......@@ -15,71 +16,22 @@ found in the LICENSE file.
var assert = chai.assert;
describe('ct-failure-card', function() {
describe('ct-failure-card-buttons', function() {
var group;
var card;
var failures;
beforeEach(function(done) {
card = document.createElement('ct-failure-card');
card = document.createElement('ct-failure-card-buttons');
var cl = new CTCommitListMock();
group = new CTFailureGroup('', new CTSheriffFailureGroupData([
new CTFailure('autobot', 'unknown', {someBuilder: {key: 'a'}}, {'blink':158547},
{'blink':158544})], cl));
card.group = group;
card.commitLog = new CTCommitLogMock();
setTimeout(done);
});
describe('failure card UI', function() {
it('should select the correct card type', function(done) {
assert(card.shadowRoot.querySelector('ct-bot-failure-card') != null,
'missing sheriff card');
card.group = new CTFailureGroup('', new CTTrooperFailureGroupData(
'details', 'url', {percent_over_median_slo: '6%',
percent_over_max_slo: '7%'}, 'cq_latency', ''));
setTimeout(function() {
assert(card.shadowRoot.querySelector('ct-trooper-card') != null,
'missing cq-latency card');
card.group.data.type = 'tree_status';
setTimeout(function() {
assert(card.shadowRoot.querySelector('ct-trooper-card') !=
null, 'missing tree-status card');
card.group.data.type = 'cycle_time';
setTimeout(function() {
assert(card.shadowRoot.querySelector('ct-trooper-card') !=
null, 'missing cycle-time card');
done();
});
});
});
});
it('should have commit summaries', function(done) {
// Expand the first repository so that the <ct-commit>'s are generated.
card.group.data.commitList.repositories[0].expanded = true;
setTimeout(function() {
var list = card.shadowRoot.querySelector('::shadow ct-commit-list');
var commits = list.shadowRoot.querySelectorAll('ct-commit');
assert(commits[1].data);
assert(commits[1].data.summary);
done();
});
});
it('removing a commit summary', function(done) {
card.commitLog.commits['blink']['158545'].summary = undefined;
card.group.data.commitList.repositories[0].expanded = true;
setTimeout(function() {
var list = card.shadowRoot.querySelector('::shadow ct-commit-list');
var commits = list.shadowRoot.querySelectorAll('ct-commit');
assert.notOk(commits[0].data.summary);
done();
});
});
describe('failure card buttons', function() {
it('examine should dispatch event', function(done) {
card.addEventListener('ct-examine-failures', function(event) {
......
......@@ -30,7 +30,7 @@ describe('ct-failure-stream', function() {
new CTFailureGroup('', new CTSheriffFailureGroupData([]))];
stream.category = 'default';
setTimeout(function() {
var cards = stream.shadowRoot.querySelectorAll('ct-failure-card');
var cards = stream.shadowRoot.querySelectorAll('ct-bot-failure-card');
assert.equal(cards.length, 2);
done();
});
......@@ -38,18 +38,49 @@ describe('ct-failure-stream', function() {
});
describe('category', function() {
it('should only show failure groups for the specified category', function(done) {
var failures = [new CTFailure('step', 'reason', [{key: 'a', annotation: {snoozeTime: Date.now() + 1000 * 1000}}])];
var snoozed = new CTFailureGroup('', new CTSheriffFailureGroupData(failures));
stream.groups = [new CTFailureGroup('', new CTSheriffFailureGroupData([])), snoozed];
stream.category = 'snoozed';
setTimeout(function() {
var cards = stream.shadowRoot.querySelectorAll('ct-failure-card');
var cards = stream.shadowRoot.querySelectorAll('ct-bot-failure-card');
assert.equal(cards.length, 1);
assert.equal(cards[0].group, snoozed);
assert.equal(cards[0].group, snoozed.data);
done();
});
});
it('should select the correct card type', function(done) {
var failures = [new CTFailure('step', 'reason', [{key: 'a', annotation: {}}])];
var failureGroup = new CTFailureGroup('', new CTSheriffFailureGroupData(failures));
stream.groups = [new CTFailureGroup('', new CTSheriffFailureGroupData([])), failureGroup];
stream.category = 'default';
setTimeout(function() {
assert(stream.shadowRoot.querySelector('ct-bot-failure-card') != null,
'missing sheriff card');
stream.groups = [new CTFailureGroup('', new CTTrooperFailureGroupData(
'details', 'url', {percent_over_median_slo: '6%',
percent_over_max_slo: '7%'}, 'cq_latency', ''))];
setTimeout(function() {
assert(stream.shadowRoot.querySelector('ct-trooper-card') != null,
'missing cq-latency card');
stream.groups[0].data.type = 'tree_status';
setTimeout(function() {
assert(stream.shadowRoot.querySelector('ct-trooper-card') !=
null, 'missing tree-status card');
stream.groups[0].data.type = 'cycle_time';
setTimeout(function() {
assert(stream.shadowRoot.querySelector('ct-trooper-card') !=
null, 'missing cycle-time card');
done();
});
});
});
});
});
});
});
......
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