diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/main/webapp/WEB-INF/jsp/show_coverage.jsp | 2 | ||||
-rw-r--r-- | src/main/webapp/WEB-INF/jsp/show_coverage_overview.jsp | 123 | ||||
-rw-r--r-- | src/main/webapp/js/common.js | 120 | ||||
-rw-r--r-- | src/main/webapp/js/test_results.js | 565 |
4 files changed, 520 insertions, 290 deletions
diff --git a/src/main/webapp/WEB-INF/jsp/show_coverage.jsp b/src/main/webapp/WEB-INF/jsp/show_coverage.jsp index 0d1e5ce..ee68588 100644 --- a/src/main/webapp/WEB-INF/jsp/show_coverage.jsp +++ b/src/main/webapp/WEB-INF/jsp/show_coverage.jsp @@ -177,7 +177,7 @@ <div class="right total-count">${coverageEntity.coveredCount}/${coverageEntity.totalCount}</div> <div class="indicator ${coverageEntity.percentage >= 70 ? "green" : "red"}">${coverageEntity.percentage}%</div> <c:if test="${isModerator}"> - <span data-id="${coverageEntity.ID}" class="indicator waves-effect blue lighten-1" style="margin-left: 5px;"><c:out value='${coverageEntity.isIgnored ? "enable" : "disable"}'/></span> + <span data-id="${coverageEntity.id}" class="indicator waves-effect blue lighten-1" style="margin-left: 5px;"><c:out value='${coverageEntity.isIgnored ? "enable" : "disable"}'/></span> </c:if> </div> <div class="collapsible-body row"> diff --git a/src/main/webapp/WEB-INF/jsp/show_coverage_overview.jsp b/src/main/webapp/WEB-INF/jsp/show_coverage_overview.jsp index 9c85618..7d4e32a 100644 --- a/src/main/webapp/WEB-INF/jsp/show_coverage_overview.jsp +++ b/src/main/webapp/WEB-INF/jsp/show_coverage_overview.jsp @@ -15,7 +15,8 @@ --%> <%@ page contentType='text/html;charset=UTF-8' language='java' %> <%@ taglib prefix='fn' uri='http://java.sun.com/jsp/jstl/functions' %> -<%@ taglib prefix='c' uri='http://java.sun.com/jsp/jstl/core'%> +<%@ taglib prefix='c' uri='http://java.sun.com/jsp/jstl/core' %> +<%@ taglib prefix='fmt' uri='http://java.sun.com/jsp/jstl/fmt' %> <html> <!-- <link rel='stylesheet' href='/css/dashboard_main.css'> --> @@ -26,7 +27,7 @@ <script type='text/javascript' src='https://www.gstatic.com/charts/loader.js'></script> <script src='https://www.gstatic.com/external_hosted/moment/min/moment-with-locales.min.js'></script> <script src='js/time.js'></script> - <script src='js/test_results.js'></script> + <script src='js/common.js'></script> <script src='js/search_header.js'></script> <script type='text/javascript'> google.charts.load('current', {'packages':['table', 'corechart']}); @@ -36,7 +37,7 @@ var search; $(document).ready(function() { - $('#test-results-container').showTests(${testRuns}, true); + // $('#test-results-container').showTests(${testRuns}, true); search = $('#filter-bar').createSearchHeader('Code Coverage', '', refresh); search.addFilter('Branch', 'branch', { corpus: ${branches} @@ -189,6 +190,56 @@ var tableChart = new google.visualization.Table(document.getElementById('coverage_table_chart_div')); tableChart.draw(data, tableOptions); } + + $('.collapsible').collapsible({ + accordion: false, + onOpen: function(el) { + var header = $( el[0].children[0] ); + var body = $( el[0].children[1] ); + var icon = header.children('.material-icons.expand-arrow'); + var testName = header.data('test'); + var timestamp = header.data('time'); + var url = '/api/test_run?test=' + testName + '×tamp=' + timestamp; + $.get(url).done(function(data) { + displayTestDetails(body, data, 16); + }).fail(function() { + icon.removeClass('rotate'); + }).always(function() { + header.removeClass('disabled'); + }); + }, // Callback for Collapsible open + onClose: function(el) { + console.log(el); + var body = $( el[0].children[1] ); + body.empty(); + } // Callback for Collapsible close + }); + + $( "span.indicator.badge:contains('Coverage')" ).click(function (evt) { + var header = $(evt.currentTarget.parentElement); + var testName = header.data('test'); + var startTime = header.data('time'); + var url = '/show_coverage?testName=' + testName + '&startTime=' + startTime; + window.location.href = url; + return false; + }); + + $( "span.indicator.badge:contains('Links')" ).click(function (evt) { + var header = $(evt.currentTarget.parentElement); + var logLinks = header.data('links'); + showLinks($('body'), logLinks); + return false; + }); + + $( "span.indicator.badge:contains('Graph')" ).click(function (evt) { + var header = $(evt.currentTarget.parentElement); + var testname = header.data('test'); + $('#coverageModalGraph').data("testname", testname); + $('#coverageModalGraph').modal('open'); + $(evt.target).removeClass("grey"); + $(evt.target).addClass("blue"); + return false; + }); }); // draw test statistics chart @@ -244,7 +295,6 @@ var data = google.visualization.arrayToDataTable(rows); - var optionsRaw = { is3D: false, colors: colors, @@ -327,10 +377,60 @@ </div> </div> </div> - <div class='col s12' id='test-results-container'></div> + <div class='col s12' id='test-results-container'> + <ul class="collapsible popout test-runs" data-collapsible="expandable"> + <c:forEach var="testRunEntity" items="${testRunEntityList}" varStatus="loop"> + <li class="test-run-container"> + <div data-test="<c:out value="${testRunEntity.testName}" />" data-time="<c:out value="${testRunEntity.startTimestamp}" />" data-links='${testRunEntity.jsonLogLinks}' class="collapsible-header test-run"> + <span class="test-run-metadata"> + <span class="test-run-label"> + <c:out value="${testRunEntity.testName}" /> + </span> + <br /> + <b>VTS Build: </b><c:out value="${testRunEntity.testBuildId}" /> + <br /> + <b>Host: </b><c:out value="${testRunEntity.hostName}" /> + <br /> + <c:out value="${testRunEntity.startDateTime}" /> - <c:out value="${testRunEntity.endDateTime}" />+0900 (<c:out value="${(testRunEntity.endTimestamp - testRunEntity.startTimestamp) / 1000}" />s) + </span> + <span class="indicator badge green" style="color: white;"> + <c:out value="${testRunEntity.passCount}" />/<c:out value="${testRunEntity.passCount + testRunEntity.passCount}" /> + </span> + + <c:set var="coveredLineCnt" value="${codeCoverageEntityMap[testRunEntity.id].coveredLineCount}" /> + <c:set var="totalLineCnt" value="${codeCoverageEntityMap[testRunEntity.id].totalLineCount}" /> + <c:set var="covPct" + value="${(coveredLineCnt / totalLineCnt * 1000) / 10}"/> + + <c:choose> + <c:when test = "${covPct <= 20}"> + <c:set var="badgeColor" value="green" /> + </c:when> + <c:when test = "${covPct >= 70}"> + <c:set var="badgeColor" value="yellow" /> + </c:when> + <c:otherwise> + <c:set var="badgeColor" value="orange" /> + </c:otherwise> + </c:choose> + + <span class="indicator badge padded hoverable waves-effect <c:out value="${badgeColor}" />" style="color: white; margin-left: 1px;"> + Coverage: <c:out value="${coveredLineCnt}" />/<c:out value="${totalLineCnt}" /> + (<fmt:formatNumber value="${(coveredLineCnt / totalLineCnt * 1000) / 10}" type="number" pattern="#.##"/>%) + </span> + <span class="indicator badge padded hoverable waves-effect grey lighten-1" style="color: white; margin-left: 1px;">Links</span> + <span class="indicator badge padded hoverable waves-effect grey lighten-1" style="color: white; margin-left: 1px;">Graph</span> + <i class="material-icons expand-arrow">expand_more</i> + </div> + <div class="collapsible-body test-results row"></div> + </li> + </c:forEach> + </ul> + + </div> </div> - <!-- Modal Structure --> + <!-- Coverage Graph Modal Structure --> <div id="coverageModalGraph" class="modal modal-fixed-footer" style="width: 75%;"> <div class="modal-content"> <h4 id="coverageModalTitle">Code Coverage Chart</h4> @@ -360,6 +460,17 @@ </div> </div> + <!-- Link Modal Structure --> + <div id="info-modal" class="modal modal-fixed-footer"> + <div class="modal-content"> + <h4>Links</h4> + <div class="info-container"></div> + </div> + <div class="modal-footer"> + <a class="btn-flat modal-close">Close</a> + </div> + </div> + <%@ include file="footer.jsp" %> </body> </html> diff --git a/src/main/webapp/js/common.js b/src/main/webapp/js/common.js new file mode 100644 index 0000000..a815868 --- /dev/null +++ b/src/main/webapp/js/common.js @@ -0,0 +1,120 @@ +/** + * Copyright (c) 2018 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may + * obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +/** + * Display the log links in a modal window. + * @param linkList A list of [name, url] tuples representing log links. + */ +function showLinks(container, linkList) { + if (!linkList || linkList.length == 0) return; + + var logCollection = $('<ul class="collection"></ul>'); + var entries = linkList.reduce(function(acc, entry) { + if (!entry || entry.length == 0) return acc; + var link = '<a href="' + entry[1] + '"'; + link += 'class="collection-item">' + entry[0] + '</li>'; + return acc + link; + }, ''); + logCollection.html(entries); + + if (container.find('#info-modal').length == 0) { + var modal = + $('<div id="info-modal" class="modal modal-fixed-footer"></div>'); + var content = $('<div class="modal-content"></div>'); + content.append('<h4>Links</h4>'); + content.append('<div class="info-container"></div>'); + content.appendTo(modal); + var footer = $('<div class="modal-footer"></div>'); + footer.append('<a class="btn-flat modal-close">Close</a></div>'); + footer.appendTo(modal); + modal.appendTo(container); + } + var infoContainer = $('#info-modal>.modal-content>.info-container'); + infoContainer.empty(); + logCollection.appendTo(infoContainer); + $('#info-modal').modal({dismissible: true}); + $('#info-modal').modal('open'); +} + +/** + * Get the nickname for a test case result. + * + * Removes the result prefix and suffix, extracting only the result name. + * + * @param testCaseResult The string name of a VtsReportMessage.TestCaseResult. + * @returns the string nickname of the result. + */ +function getNickname(testCaseResult) { + return testCaseResult.replace('TEST_CASE_RESULT_', '') + .replace('_RESULT', '') + .trim() + .toLowerCase(); +} + +/** + * Display test data in the body beneath a test run's metadata. + * @param container The jquery object in which to insert the test metadata. + * @param data The json object containing the columns to display. + * @param lineHeight The height of each list element. + */ +function displayTestDetails(container, data, lineHeight) { + var nCol = data.length; + var width = 's' + (12 / nCol); + test = container; + var maxLines = 0; + data.forEach(function(column, index) { + if (column.data == undefined || column.name == undefined) { + return; + } + var classes = 'col test-col grey lighten-5 ' + width; + if (index != nCol - 1) { + classes += ' bordered'; + } + if (index == 0) { + classes += ' left-most'; + } + if (index == nCol - 1) { + classes += ' right-most'; + } + var colContainer = $('<div class="' + classes + '"></div>'); + var col = $('<div class="test-case-container"></div>'); + colContainer.appendTo(container); + var count = column.data.length; + var head = $('<h5 class="test-result-label white"></h5>') + .text(getNickname(column.name)) + .appendTo(colContainer) + .css('text-transform', 'capitalize'); + $('<div class="indicator right center"></div>') + .text(count) + .addClass(column.name) + .appendTo(head); + col.appendTo(colContainer); + var list = $('<ul></ul>').appendTo(col); + column.data.forEach(function(testCase) { + $('<li></li>') + .text(testCase) + .addClass('test-case') + .css('font-size', lineHeight - 2) + .css('line-height', lineHeight + 'px') + .appendTo(list); + }); + if (count > maxLines) { + maxLines = count; + } + }); + var containers = container.find('.test-case-container'); + containers.height(maxLines * lineHeight); +} diff --git a/src/main/webapp/js/test_results.js b/src/main/webapp/js/test_results.js index 45c1de4..2811b0f 100644 --- a/src/main/webapp/js/test_results.js +++ b/src/main/webapp/js/test_results.js @@ -14,314 +14,313 @@ * permissions and limitations under the License. */ -(function ($, moment) { +(function($, moment) { - /** - * Display the log links in a modal window. - * @param linkList A list of [name, url] tuples representing log links. - */ - function showLinks(container, linkList) { - if (!linkList || linkList.length == 0) return; +/** + * Display the log links in a modal window. + * @param linkList A list of [name, url] tuples representing log links. + */ +function showLinks(container, linkList) { + if (!linkList || linkList.length == 0) return; - var logCollection = $('<ul class="collection"></ul>'); - var entries = linkList.reduce(function(acc, entry) { - if (!entry || entry.length == 0) return acc; - var link = '<a href="' + entry[1] + '"'; - link += 'class="collection-item">' + entry[0] + '</li>'; - return acc + link; - }, ''); - logCollection.html(entries); + var logCollection = $('<ul class="collection"></ul>'); + var entries = linkList.reduce(function(acc, entry) { + if (!entry || entry.length == 0) return acc; + var link = '<a href="' + entry[1] + '"'; + link += 'class="collection-item">' + entry[0] + '</li>'; + return acc + link; + }, ''); + logCollection.html(entries); - if (container.find('#info-modal').length == 0) { - var modal = $('<div id="info-modal" class="modal modal-fixed-footer"></div>'); - var content = $('<div class="modal-content"></div>'); - content.append('<h4>Links</h4>'); - content.append('<div class="info-container"></div>'); - content.appendTo(modal); - var footer = $('<div class="modal-footer"></div>'); - footer.append('<a class="btn-flat modal-close">Close</a></div>'); - footer.appendTo(modal); - modal.appendTo(container); - } - var infoContainer = $('#info-modal>.modal-content>.info-container'); - infoContainer.empty(); - logCollection.appendTo(infoContainer); - $('#info-modal').modal({ - dismissible: true - }); - $('#info-modal').modal('open'); + if (container.find('#info-modal').length == 0) { + var modal = + $('<div id="info-modal" class="modal modal-fixed-footer"></div>'); + var content = $('<div class="modal-content"></div>'); + content.append('<h4>Links</h4>'); + content.append('<div class="info-container"></div>'); + content.appendTo(modal); + var footer = $('<div class="modal-footer"></div>'); + footer.append('<a class="btn-flat modal-close">Close</a></div>'); + footer.appendTo(modal); + modal.appendTo(container); } + var infoContainer = $('#info-modal>.modal-content>.info-container'); + infoContainer.empty(); + logCollection.appendTo(infoContainer); + $('#info-modal').modal({dismissible: true}); + $('#info-modal').modal('open'); +} - /** - * Get the nickname for a test case result. - * - * Removes the result prefix and suffix, extracting only the result name. - * - * @param testCaseResult The string name of a VtsReportMessage.TestCaseResult. - * @returns the string nickname of the result. - */ - function getNickname(testCaseResult) { - return testCaseResult - .replace('TEST_CASE_RESULT_', '') +/** + * Get the nickname for a test case result. + * + * Removes the result prefix and suffix, extracting only the result name. + * + * @param testCaseResult The string name of a VtsReportMessage.TestCaseResult. + * @returns the string nickname of the result. + */ +function getNickname(testCaseResult) { + return testCaseResult.replace('TEST_CASE_RESULT_', '') .replace('_RESULT', '') - .trim().toLowerCase(); - } + .trim() + .toLowerCase(); +} - /** - * Display test data in the body beneath a test run's metadata. - * @param container The jquery object in which to insert the test metadata. - * @param data The json object containing the columns to display. - * @param lineHeight The height of each list element. - */ - function displayTestDetails(container, data, lineHeight) { - var nCol = data.length; - var width = 's' + (12 / nCol); - test = container; - var maxLines = 0; - data.forEach(function (column, index) { - if (column.data == undefined || column.name == undefined) { - return; - } - var classes = 'col test-col grey lighten-5 ' + width; - if (index != nCol -1) { - classes += ' bordered'; - } - if (index == 0) { - classes += ' left-most'; - } - if (index == nCol - 1) { - classes += ' right-most'; - } - var colContainer = $('<div class="' + classes + '"></div>'); - var col = $('<div class="test-case-container"></div>'); - colContainer.appendTo(container); - var count = column.data.length; - var head = $('<h5 class="test-result-label white"></h5>') - .text(getNickname(column.name)) - .appendTo(colContainer) - .css('text-transform', 'capitalize'); - $('<div class="indicator right center"></div>') +/** + * Display test data in the body beneath a test run's metadata. + * @param container The jquery object in which to insert the test metadata. + * @param data The json object containing the columns to display. + * @param lineHeight The height of each list element. + */ +function displayTestDetails(container, data, lineHeight) { + var nCol = data.length; + var width = 's' + (12 / nCol); + test = container; + var maxLines = 0; + data.forEach(function(column, index) { + if (column.data == undefined || column.name == undefined) { + return; + } + var classes = 'col test-col grey lighten-5 ' + width; + if (index != nCol - 1) { + classes += ' bordered'; + } + if (index == 0) { + classes += ' left-most'; + } + if (index == nCol - 1) { + classes += ' right-most'; + } + var colContainer = $('<div class="' + classes + '"></div>'); + var col = $('<div class="test-case-container"></div>'); + colContainer.appendTo(container); + var count = column.data.length; + var head = $('<h5 class="test-result-label white"></h5>') + .text(getNickname(column.name)) + .appendTo(colContainer) + .css('text-transform', 'capitalize'); + $('<div class="indicator right center"></div>') .text(count) .addClass(column.name) .appendTo(head); - col.appendTo(colContainer); - var list = $('<ul></ul>').appendTo(col); - column.data.forEach(function (testCase) { - $('<li></li>') + col.appendTo(colContainer); + var list = $('<ul></ul>').appendTo(col); + column.data.forEach(function(testCase) { + $('<li></li>') .text(testCase) .addClass('test-case') .css('font-size', lineHeight - 2) .css('line-height', lineHeight + 'px') .appendTo(list); - }); - if (count > maxLines) { - maxLines = count; - } }); - var containers = container.find('.test-case-container'); - containers.height(maxLines * lineHeight); - } + if (count > maxLines) { + maxLines = count; + } + }); + var containers = container.find('.test-case-container'); + containers.height(maxLines * lineHeight); +} - /** - * Click handler for displaying test run details. - * @param e The click event. - */ - function testRunClick(e) { - var header = $(this); - var icon = header.find('.material-icons.expand-arrow'); - var container = header.parent().find('.test-results'); - var test = header.attr('test'); - var time = header.attr('time'); - var url = '/api/test_run?test=' + test + '×tamp=' + time; - if (header.parent().hasClass('active')) { - header.parent().removeClass('active'); - header.removeClass('active'); - icon.removeClass('rotate'); - header.siblings('.collapsible-body').stop(true, false).slideUp({ - duration: 100, - easing: "easeOutQuart", - queue: false, - complete: function() { header.css('height', ''); } - }); - } else { - container.empty(); - header.parent().addClass('active'); - header.addClass('active'); - header.addClass('disabled'); - icon.addClass('rotate'); - $.get(url).done(function(data) { - displayTestDetails(container, data, 16); - header.siblings('.collapsible-body').stop(true, false).slideDown({ - duration: 100, - easing: "easeOutQuart", - queue: false, - complete: function() { header.css('height', ''); } +/** + * Click handler for displaying test run details. + * @param e The click event. + */ +function testRunClick(e) { + var header = $(this); + var icon = header.find('.material-icons.expand-arrow'); + var container = header.parent().find('.test-results'); + var test = header.attr('test'); + var time = header.attr('time'); + var url = '/api/test_run?test=' + test + '×tamp=' + time; + if (header.parent().hasClass('active')) { + header.parent().removeClass('active'); + header.removeClass('active'); + icon.removeClass('rotate'); + header.siblings('.collapsible-body').stop(true, false).slideUp({ + duration: 100, + easing: 'easeOutQuart', + queue: false, + complete: function() { + header.css('height', ''); + } + }); + } else { + container.empty(); + header.parent().addClass('active'); + header.addClass('active'); + header.addClass('disabled'); + icon.addClass('rotate'); + $.get(url) + .done(function(data) { + displayTestDetails(container, data, 16); + header.siblings('.collapsible-body').stop(true, false).slideDown({ + duration: 100, + easing: 'easeOutQuart', + queue: false, + complete: function() { + header.css('height', ''); + } + }); + }) + .fail(function() { + icon.removeClass('rotate'); + }) + .always(function() { + header.removeClass('disabled'); }); - }).fail(function() { - icon.removeClass('rotate'); - }).always(function() { - header.removeClass('disabled'); - }); - } } +} - /** - * Append a clickable indicator link to the container. - * @param container The jquery object to append the indicator to. - * @param content The text to display in the indicator. - * @param classes Additional space-delimited classes to add to the indicator. - * @param click The click handler to assign to the indicator. - * @returns The jquery object for the indicator. - */ - function createClickableIndicator(container, content, classes, click) { - var link = $('<span></span>'); - link.addClass('indicator badge padded hoverable waves-effect'); - link.addClass(classes); - link.css("color", "white"); - link.css("margin-left", "1px"); - link.append(content); - link.appendTo(container); - link.click(click); - return link; - } +/** + * Append a clickable indicator link to the container. + * @param container The jquery object to append the indicator to. + * @param content The text to display in the indicator. + * @param classes Additional space-delimited classes to add to the indicator. + * @param click The click handler to assign to the indicator. + * @returns The jquery object for the indicator. + */ +function createClickableIndicator(container, content, classes, click) { + var link = $('<span></span>'); + link.addClass('indicator badge padded hoverable waves-effect'); + link.addClass(classes); + link.css('color', 'white'); + link.css('margin-left', '1px'); + link.append(content); + link.appendTo(container); + link.click(click); + return link; +} - function displayTestMetadata(container, metadataList, showTestNames=false) { - var popout = $('<ul></ul>'); - popout.attr('data-collapsible', 'expandable'); - popout.addClass('collapsible popout test-runs'); - popout.appendTo(container); - popout.unbind(); - metadataList.forEach(function (metadata) { - var li = $('<li class="test-run-container"></li>'); - li.appendTo(popout); - var div = $('<div></div>'); - var test = metadata.testRun.testName; - var startTime = metadata.testRun.startTimestamp; - var endTime = metadata.testRun.endTimestamp; - div.attr('test', test); - div.attr('time', startTime); - div.addClass('collapsible-header test-run'); - div.appendTo(li); - div.unbind().click(testRunClick); - var span = $('<span></span>'); - span.addClass('test-run-metadata'); - span.appendTo(div); - span.click(function() { return false; }); - if (showTestNames) { - $('<span class="test-run-label"></span>').text(test).appendTo(span); - span.append('<br>'); - } - if (metadata.deviceInfo) { - $('<b></b>').text(metadata.deviceInfo).appendTo(span); - span.append('<br>'); - } - if (metadata.abiInfo) { - $('<b></b>').text('ABI: ') - .appendTo(span) - span.append(metadata.abiInfo).append('<br>'); - } - $('<b></b>').text('VTS Build: ') - .appendTo(span) - span.append(metadata.testRun.testBuildId).append('<br>'); - $('<b></b>').text('Host: ') - .appendTo(span) - span.append(metadata.testRun.hostName).append('<br>'); - var timeString = ( - moment().renderTime(startTime, false) + ' - ' + - moment().renderTime(endTime, true) + ' (' + - moment().renderDuration(endTime - startTime) + ')'); - span.append(timeString); - var indicator = $('<span></span>'); - var color = metadata.testRun.failCount > 0 ? 'red' : 'green'; - indicator.addClass('indicator badge ' + color); - indicator.css("color", "white"); - indicator.append( +function displayTestMetadata(container, metadataList, showTestNames = false) { + var popout = $('<ul></ul>'); + popout.attr('data-collapsible', 'expandable'); + popout.addClass('collapsible popout test-runs'); + popout.appendTo(container); + popout.unbind(); + metadataList.forEach(function(metadata) { + var li = $('<li class="test-run-container"></li>'); + li.appendTo(popout); + var div = $('<div></div>'); + var test = metadata.testRun.testName; + var startTime = metadata.testRun.startTimestamp; + var endTime = metadata.testRun.endTimestamp; + div.attr('test', test); + div.attr('time', startTime); + div.addClass('collapsible-header test-run'); + div.appendTo(li); + div.unbind().click(testRunClick); + var span = $('<span></span>'); + span.addClass('test-run-metadata'); + span.appendTo(div); + span.click(function() { + return false; + }); + if (showTestNames) { + $('<span class="test-run-label"></span>').text(test).appendTo(span); + span.append('<br>'); + } + if (metadata.deviceInfo) { + $('<b></b>').text(metadata.deviceInfo).appendTo(span); + span.append('<br>'); + } + if (metadata.abiInfo) { + $('<b></b>').text('ABI: ').appendTo(span) + span.append(metadata.abiInfo).append('<br>'); + } + $('<b></b>').text('VTS Build: ').appendTo(span) + span.append(metadata.testRun.testBuildId).append('<br>'); + $('<b></b>').text('Host: ').appendTo(span) + span.append(metadata.testRun.hostName).append('<br>'); + var timeString = + (moment().renderTime(startTime, false) + ' - ' + + moment().renderTime(endTime, true) + ' (' + + moment().renderDuration(endTime - startTime) + ')'); + span.append(timeString); + var indicator = $('<span></span>'); + var color = metadata.testRun.failCount > 0 ? 'red' : 'green'; + indicator.addClass('indicator badge ' + color); + indicator.css('color', 'white'); + indicator.append( metadata.testRun.passCount + '/' + (metadata.testRun.passCount + metadata.testRun.failCount)); - indicator.appendTo(div); - if (metadata.testRun.coveredLineCount != undefined && + indicator.appendTo(div); + if (metadata.testRun.coveredLineCount != undefined && metadata.testRun.totalLineCount != undefined) { - var url = ( - '/show_coverage?testName=' + test + '&startTime=' + startTime); - var covered = metadata.testRun.coveredLineCount; - var total = metadata.testRun.totalLineCount; - var covPct = Math.round(covered / total * 1000) / 10; - var color = 'red'; - if (covPct > 20 && covPct < 70) { - color = 'orange'; - } else if (covPct >= 70) { - color = 'green'; - } - var coverage = ( - 'Coverage: ' + covered + '/' + total + ' (' + covPct + '%)'); - createClickableIndicator( - div, coverage, color, - function () { window.location.href = url; return false; }); - } - if (metadata.testRun.coveredApiCount != undefined && - metadata.testRun.totalApiCount != undefined) { - var covered = metadata.testRun.coveredApiCount; - var total = metadata.testRun.totalApiCount; - var apiCoverage = ('API Coverage: ' + covered + '/' + total); - createClickableIndicator( - div, apiCoverage, 'orange', - function (evt) { - $('#apiCoverageModal').data("urlSafeKeyList", metadata.testRun.apiCoverageKeyList); - $('#apiCoverageModal').modal('open'); - return false; - } - ); - } - if (metadata.testRun.logLinks != undefined) { - createClickableIndicator( - div, 'Links', 'grey lighten-1', - function () { - showLinks(popout, metadata.testRun.logLinks); - return false; - }); - } - if ($('#coverageModalGraph').length) { - createClickableIndicator( - div, 'Graph', 'grey lighten-1', - function(evt) { - $('#coverageModalGraph').data("testname", test); - $('#coverageModalGraph').modal('open'); - $(evt.target).removeClass("grey"); - $(evt.target).addClass("blue"); - return false; - } - ); - } - - var expand = $('<i></i>'); - expand.addClass('material-icons expand-arrow') - expand.text('expand_more'); - expand.appendTo(div); - var body = $('<div></div>') - .addClass('collapsible-body test-results row') - .appendTo(li); - if (metadata.testDetails != undefined) { - expand.addClass('rotate'); - li.addClass('active'); - div.addClass('active'); - displayTestDetails(body, metadata.testDetails, 16); - div.siblings('.collapsible-body').stop(true, false).slideDown({ - duration: 0, - queue: false, - complete: function() { div.css('height', ''); } - }); + var url = ('/show_coverage?testName=' + test + '&startTime=' + startTime); + var covered = metadata.testRun.coveredLineCount; + var total = metadata.testRun.totalLineCount; + var covPct = Math.round(covered / total * 1000) / 10; + var color = 'red'; + if (covPct > 20 && covPct < 70) { + color = 'orange'; + } else if (covPct >= 70) { + color = 'green'; } - }); - } + var coverage = + ('Coverage: ' + covered + '/' + total + ' (' + covPct + '%)'); + createClickableIndicator(div, coverage, color, function() { + window.location.href = url; + return false; + }); + } + if (metadata.testRun.coveredApiCount != undefined && + metadata.testRun.totalApiCount != undefined) { + var covered = metadata.testRun.coveredApiCount; + var total = metadata.testRun.totalApiCount; + var apiCoverage = ('API Coverage: ' + covered + '/' + total); + createClickableIndicator(div, apiCoverage, 'orange', function(evt) { + $('#apiCoverageModal') + .data('urlSafeKeyList', metadata.testRun.apiCoverageKeyList); + $('#apiCoverageModal').modal('open'); + return false; + }); + } + if (metadata.testRun.logLinks != undefined) { + createClickableIndicator(div, 'Links', 'grey lighten-1', function() { + showLinks(popout, metadata.testRun.logLinks); + return false; + }); + } + if ($('#coverageModalGraph').length) { + createClickableIndicator(div, 'Graph', 'grey lighten-1', function(evt) { + $('#coverageModalGraph').data('testname', test); + $('#coverageModalGraph').modal('open'); + $(evt.target).removeClass('grey'); + $(evt.target).addClass('blue'); + return false; + }); + } - /** - * Display test metadata in a vertical popout. - * @param container The jquery object in which to insert the test metadata. - * @param metadataList The list of metadata objects to render on the display. - * @param showTestNames True to label each entry with the test module name. - */ - $.fn.showTests = function(metadataList, showTestNames=false) { - displayTestMetadata($(this), metadataList, showTestNames); - } + var expand = $('<i></i>'); + expand.addClass('material-icons expand-arrow') + expand.text('expand_more'); + expand.appendTo(div); + var body = $('<div></div>') + .addClass('collapsible-body test-results row') + .appendTo(li); + if (metadata.testDetails != undefined) { + expand.addClass('rotate'); + li.addClass('active'); + div.addClass('active'); + displayTestDetails(body, metadata.testDetails, 16); + div.siblings('.collapsible-body').stop(true, false).slideDown({ + duration: 0, + queue: false, + complete: function() { + div.css('height', ''); + } + }); + } + }); +} +/** + * Display test metadata in a vertical popout. + * @param container The jquery object in which to insert the test metadata. + * @param metadataList The list of metadata objects to render on the display. + * @param showTestNames True to label each entry with the test module name. + */ +$.fn.showTests = function(metadataList, showTestNames = false) { + displayTestMetadata($(this), metadataList, showTestNames); +} })(jQuery, moment); |