1<%-- 2 ~ Copyright (c) 2018 Google Inc. All Rights Reserved. 3 ~ 4 ~ Licensed under the Apache License, Version 2.0 (the "License"); you 5 ~ may not use this file except in compliance with the License. You may 6 ~ obtain a copy of the License at 7 ~ 8 ~ http://www.apache.org/licenses/LICENSE-2.0 9 ~ 10 ~ Unless required by applicable law or agreed to in writing, software 11 ~ distributed under the License is distributed on an "AS IS" BASIS, 12 ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 13 ~ implied. See the License for the specific language governing 14 ~ permissions and limitations under the License. 15 --%> 16<%@ page contentType='text/html;charset=UTF-8' language='java' %> 17<%@ taglib prefix='fn' uri='http://java.sun.com/jsp/jstl/functions' %> 18<%@ taglib prefix='c' uri='http://java.sun.com/jsp/jstl/core'%> 19<%@ taglib prefix='fmt' uri='http://java.sun.com/jsp/jstl/fmt'%> 20<jsp:useBean id="startDateObject" class="java.util.Date"/> 21<jsp:useBean id="endDateObject" class="java.util.Date"/> 22<c:set var="timeZone" value="America/Los_Angeles"/> 23 24<html> 25 <%@ include file='header.jsp' %> 26 <link type='text/css' href='/css/show_test_runs_common.css' rel='stylesheet'> 27 <link type='text/css' href='/css/test_results.css' rel='stylesheet'> 28 <link rel='stylesheet' href='/css/search_header.css'> 29 <script type='text/javascript'> 30 $(document).ready(function() { 31 32 $.deparam = $.deparam || function(uri){ 33 if(uri === undefined){ 34 uri = window.location.search; 35 } 36 var queryString = {}; 37 uri.replace( 38 new RegExp( 39 "([^?=&]+)(=([^&#]*))?", "g"), 40 function($0, $1, $2, $3) { queryString[$1] = $3; } 41 ); 42 return queryString; 43 }; 44 45 $("li.tab").each(function( index ) { 46 $(this).click(function() { 47 window.open($(this).children().attr("href"), '_self'); 48 }); 49 }); 50 51 $(".search-icon-wrapper").click(function() { 52 $(".search-wrapper").slideToggle("fast", function() { 53 // Animation complete. 54 }); 55 }); 56 57 <c:if test="${not empty branch or not empty hostName or not empty buildId or not empty deviceName}"> 58 $(".search-wrapper").slideToggle("fast"); 59 </c:if> 60 61 $("#searchBtn").click(function(event) { 62 event.preventDefault(); 63 64 var url = '<c:out value="${requestScope['javax.servlet.forward.servlet_path']}" escapeXml="false"></c:out>'; 65 var params = $.deparam('<c:out value="${requestScope['javax.servlet.forward.query_string']}" escapeXml="false"></c:out>'); 66 67 var branch = $("#deviceBranch").val().trim(); 68 if ( branch.length > 0 ) { 69 params['branch'] = branch; 70 } else { 71 delete params['branch']; 72 } 73 var host = $("#host").val().trim(); 74 if ( host.length > 0 ) { 75 params['hostName'] = host; 76 } else { 77 delete params['hostName']; 78 } 79 var buildId = $("#deviceBuildId").val().trim(); 80 if ( buildId.length > 0 ) { 81 params['buildId'] = buildId; 82 } else { 83 delete params['buildId']; 84 } 85 var deviceName = $("#deviceName").val().trim(); 86 if ( deviceName.length > 0 ) { 87 params['deviceName'] = deviceName; 88 } else { 89 delete params['deviceName']; 90 } 91 92 $(location).prop('href', url + "?" + decodeURIComponent($.param(params))); 93 $(this).prop('href', url); 94 }); 95 96 $("#deviceBranch").autocomplete({ 97 source: [ "c++", "java", "php", "coldfusion", "javascript", "asp", "ruby" ], 98 open: function( event, ui ) { 99 alert("open") 100 }, 101 close: function( event, ui ) { 102 alert("close") 103 } 104 }); 105 106 $( "div.test-case-container > div.input-field > a.btn" ).each(function() { 107 $( this ).click(function() { 108 $(this).parent().prev().children().select(); 109 document.execCommand('copy'); 110 alert("Reproduce Command copied to clipboard."); 111 }); 112 }); 113 }); 114 </script> 115 <body> 116 <div class='wide container'> 117 118 <div class="row card search-bar expanded"> 119 <div class="header-wrapper"> 120 <h5 class="section-header"> 121 <b>Plan: </b><span><c:out value="${plan}"></c:out></span> 122 </h5> 123 <div class="search-icon-wrapper"> 124 <i class="material-icons">search</i> 125 </div> 126 </div> 127 <div class="search-wrapper" style="display: none"> 128 <div class="col s12"> 129 <div class="input-field col s4"> 130 <input id="deviceBranch" type="text" value="<c:out value="${branch}"></c:out>" autocomplete="off" /> 131 <label>Device Branch</label> 132 </div> 133 <div class="input-field col s4"> 134 <input id="host" type="text" value="<c:out value="${hostName}"></c:out>" autocomplete="off" /> 135 <label>Host</label> 136 </div> 137 <div class="input-field col s4"> 138 <input id="deviceBuildId" type="text" value="<c:out value="${buildId}"></c:out>" autocomplete="off" /> 139 <label>Device Build ID</label> 140 </div> 141 </div> 142 <div class="col s12"> 143 <div class="input-field col s4"> 144 <input id="deviceName" type="text" value="<c:out value="${deviceName}"></c:out>" autocomplete="off" /> 145 <label>Device Name</label> 146 </div> 147 <div class="input-field col s4"> 148 149 </div> 150 <div class="run-type-wrapper col s4 right-align"> 151 <a class="waves-effect waves-light btn" id="searchBtn"> 152 <i class="material-icons left">search</i>Apply 153 </a> 154 </div> 155 </div> 156 </div> 157 </div> 158 159 <div class='row'> 160 <div class='col s12'> 161 162 <ul class="tabs z-depth-1"> 163 <li class="tab col s4" id="totTabLink"> 164 <a class="<c:out value="${testCategoryType == '1' ? 'active' : 'inactive'}"></c:out>" href="${requestScope['javax.servlet.forward.servlet_path']}?plan=${plan}&type=${testType}&testCategoryType=1">TOT</a> 165 </li> 166 <li class="tab col s4" id="signedTabLink"> 167 <a class="<c:out value="${testCategoryType == '4' ? 'active' : 'inactive'}"></c:out>" href="${requestScope['javax.servlet.forward.servlet_path']}?plan=${plan}&type=${testType}&testCategoryType=4">SIGNED</a> 168 </li> 169 <li class="tab col s4" id="otaTabLink"> 170 <a class="<c:out value="${testCategoryType == '2' ? 'active' : 'inactive'}"></c:out>" href="${requestScope['javax.servlet.forward.servlet_path']}?plan=${plan}&type=${testType}&testCategoryType=2">OTA</a> 171 </li> 172 </ul> 173 174 </div> 175 </div> 176 177 <div class='row' id='test-suite-green-release-container'> 178 <div class="col s12"> 179 180 <ul class="collapsible popout test-runs"> 181 <c:forEach var="testSuiteResultEntity" items="${testSuiteResultEntityPagination.list}"> 182 <li class="test-run-container"> 183 <div class="collapsible-header test-run"> 184 <div class="row" style="margin-bottom: 0px; line-height: 30px;"> 185 <div class="col s9"> 186 <b><c:out value="${testSuiteResultEntity.branch}"></c:out>/<c:out value="${testSuiteResultEntity.target}"></c:out> (<c:out value="${testSuiteResultEntity.buildId}"></c:out>)</b> 187 </div> 188 <div class="col s3"> 189 <span class="indicator right center 190 <c:choose> 191 <c:when test="${testSuiteResultEntity.passedTestCaseCount eq 0 and testSuiteResultEntity.failedTestCaseCount eq 0}"> 192 black 193 </c:when> 194 <c:otherwise> 195 green 196 </c:otherwise> 197 </c:choose> 198 "> 199 <c:out value="${testSuiteResultEntity.passedTestCaseCount}"></c:out>/<c:out value="${testSuiteResultEntity.passedTestCaseCount + testSuiteResultEntity.failedTestCaseCount}"></c:out> 200 ( 201 <c:set var="integerVal" value="${fn:substringBefore(testSuiteResultEntity.passedTestCaseRatio, '.')}" /> 202 <c:choose> 203 <c:when test="${integerVal eq '100'}"> 204 100% 205 </c:when> 206 <c:otherwise> 207 <c:set var="decimalVal" value="${fn:substring(fn:substringAfter(testSuiteResultEntity.passedTestCaseRatio, '.'), 0, 2)}" /> 208 <c:choose> 209 <c:when test="${decimalVal eq '00'}"> 210 <c:out value="${integerVal}"></c:out>% 211 </c:when> 212 <c:otherwise> 213 <c:out value="${integerVal}"></c:out>.<c:out value="${decimalVal}"></c:out>% 214 </c:otherwise> 215 </c:choose> 216 </c:otherwise> 217 </c:choose> 218 ) 219 </span> 220 <c:if test="${!testSuiteResultEntity.bootSuccess}"> 221 <span class="indicator right center" style="min-width: 0px; padding: 0 2px;"></span> 222 <span class="indicator right center red">Boot Error</span> 223 </c:if> 224 </div> 225 <div class="col s5"> 226 <span class="suite-test-run-metadata"> 227 <b>Suite Build Number: </b><c:out value="${testSuiteResultEntity.suiteBuildNumber}"></c:out><br> 228 <b>Device Name: </b><c:out value="${testSuiteResultEntity.deviceName}"></c:out><br> 229 </span> 230 </div> 231 <div class="col s5"> 232 <span class="suite-test-run-metadata"> 233 <b>Host: </b><c:out value="${testSuiteResultEntity.hostName}"></c:out><br> 234 <b>Modules: </b><c:out value="${testSuiteResultEntity.modulesDone}"></c:out>/<c:out value="${testSuiteResultEntity.modulesTotal}"></c:out><br> 235 </span> 236 </div> 237 <div class="col s2" style="padding: 5px 12px;"> 238 <a href="<c:out value="${testSuiteResultEntity.buganizerLink}"></c:out>" class="waves-effect waves-light btn right blue-grey" style="padding: 0 15px;" target="_blank"> 239 Buganizer 240 </a> 241 </div> 242 <div class="col s12"> 243 <span class="suite-test-run-metadata"> 244 <b>Result Log Path: </b> 245 <a href="show_gcs_log?path=${testSuiteResultEntity.screenResultLogPath}"> 246 <c:out value="${testSuiteResultEntity.screenResultLogPath}"></c:out> 247 </a> 248 <br> 249 <b>Infra Log Path: </b> 250 <a href="show_gcs_log/download?file=${testSuiteResultEntity.screenInfraLogPath}"> 251 <c:out value="${testSuiteResultEntity.screenInfraLogPath}"></c:out> 252 </a> 253 <br> 254 </span> 255 </div> 256 <div class="col s10"> 257 <span style="font-size: 13px;"> 258 <jsp:setProperty name="startDateObject" property="time" value="${testSuiteResultEntity.startTime}"/> 259 <jsp:setProperty name="endDateObject" property="time" value="${testSuiteResultEntity.endTime}"/> 260 <fmt:formatDate value="${startDateObject}" pattern="yyyy-MM-dd HH:mm:ss" timeZone="${timeZone}" /> - <fmt:formatDate value="${endDateObject}" pattern="yyyy-MM-dd HH:mm:ss z" timeZone="${timeZone}" /> 261 <c:set var="executionTime" scope="page" value="${(testSuiteResultEntity.endTime - testSuiteResultEntity.startTime) / 1000}"/> 262 (<c:out value="${executionTime}"></c:out>s) 263 </span> 264 </div> 265 <div class="col s2"> 266 <i class="material-icons expand-arrow">expand_more</i> 267 </div> 268 </div> 269 </div> 270 <div class="collapsible-body test-results row" style="display: none;"> 271 <div class="col test-col grey lighten-5 s12 left-most right-most"> 272 <h5 class="test-result-label white" style="text-transform: capitalize;"> 273 Vendor Fingerprint 274 </h5> 275 <div class="test-case-container"> 276 <c:out value="${testSuiteResultEntity.buildVendorFingerprint}"></c:out> 277 </div> 278 </div> 279 <div class="col test-col grey lighten-5 s12 left-most right-most"> 280 <h5 class="test-result-label white" style="text-transform: capitalize;"> 281 System Fingerprint 282 </h5> 283 <div class="test-case-container"> 284 <c:out value="${testSuiteResultEntity.buildSystemFingerprint}"></c:out> 285 </div> 286 </div> 287 <div class="col test-col grey lighten-5 s12 left-most right-most"> 288 <h5 class="test-result-label white" style="text-transform: capitalize;"> 289 Reproduce Command 290 </h5> 291 <div class="row test-case-container"> 292 <div class="input-field col s9"> 293 <input type="text" class="validate" readonly="true" onclick="this.select()" value="reproduce --report_path=gs://vts-report/<c:out value="${testSuiteResultEntity.getTestSuiteFileEntityKey().getName()}"></c:out> --suite=<c:out value="${fn:toLowerCase(testSuiteResultEntity.getSuiteName())}"></c:out>" /> 294 </div> 295 <div class="input-field col s3"> 296 <a class="waves-effect waves-light btn right"><i class="material-icons left">content_copy</i>Copy</a> 297 </div> 298 </div> 299 </div> 300 </div> 301 </li> 302 </c:forEach> 303 </ul> 304 305 </div> 306 </div> 307 308 <div class="row"> 309 <c:set var="searchQueryString" value="" /> 310 <c:if test="${not empty branch}"> 311 <c:set var="searchQueryString" value="${searchQueryString}&branch=${branch}" /> 312 </c:if> 313 <c:if test="${not empty hostName}"> 314 <c:set var="searchQueryString" value="${searchQueryString}&hostName=${hostName}" /> 315 </c:if> 316 <c:if test="${not empty buildId}"> 317 <c:set var="searchQueryString" value="${searchQueryString}&buildId=${buildId}" /> 318 </c:if> 319 <c:if test="${not empty deviceName}"> 320 <c:set var="searchQueryString" value="${searchQueryString}&deviceName=${deviceName}" /> 321 </c:if> 322 <div class="col s12 center-align"> 323 <ul class="pagination"> 324 <c:choose> 325 <c:when test="${testSuiteResultEntityPagination.minPageRange gt testSuiteResultEntityPagination.pageSize}"> 326 <li class="waves-effect"> 327 <a href="${requestScope['javax.servlet.forward.servlet_path']}?plan=${plan}&type=${testType}&testCategoryType=${testCategoryType}&page=${testSuiteResultEntityPagination.minPageRange - 1}&nextPageToken=${testSuiteResultEntityPagination.previousPageCountToken}${searchQueryString}"> 328 <i class="material-icons">chevron_left</i> 329 </a> 330 </li> 331 </c:when> 332 <c:otherwise> 333 334 </c:otherwise> 335 </c:choose> 336 <c:forEach var="pageLoop" begin="${testSuiteResultEntityPagination.minPageRange}" end="${testSuiteResultEntityPagination.maxPageRange}"> 337 <li class="waves-effect<c:if test="${pageLoop eq page}"> active</c:if>"> 338 <a href="${requestScope['javax.servlet.forward.servlet_path']}?plan=${plan}&type=${testType}&testCategoryType=${testCategoryType}&page=${pageLoop}<c:if test="${testSuiteResultEntityPagination.currentPageCountToken ne ''}">&nextPageToken=${testSuiteResultEntityPagination.currentPageCountToken}</c:if>${searchQueryString}"> 339 <c:out value="${pageLoop}" /> 340 </a> 341 </li> 342 </c:forEach> 343 <c:choose> 344 <c:when test="${testSuiteResultEntityPagination.maxPages gt testSuiteResultEntityPagination.pageSize}"> 345 <li class="waves-effect"> 346 <a href="${requestScope['javax.servlet.forward.servlet_path']}?plan=${plan}&type=${testType}&testCategoryType=${testCategoryType}&page=${testSuiteResultEntityPagination.maxPageRange + 1}&nextPageToken=${testSuiteResultEntityPagination.nextPageCountToken}${searchQueryString}"> 347 <i class="material-icons">chevron_right</i> 348 </a> 349 </li> 350 </c:when> 351 <c:otherwise> 352 353 </c:otherwise> 354 </c:choose> 355 </ul> 356 </div> 357 </div> 358 359 </div> 360 <%@ include file='footer.jsp' %> 361 </body> 362</html> 363