1<!DOCTYPE html> 2<html lang="en"> 3 4<head> 5 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 6 <script type="text/javascript"> 7 function displayMedia() { 8 let video_elements = document.getElementById("logs").getElementsByTagName("video"); 9 for (let i = 0; i < video_elements.length; i++) { 10 let a_element = video_elements[i].parentNode; 11 let img_element = video_elements[i]; 12 img_element.src = a_element.href; 13 img_element.style.display = "block"; 14 } 15 let img_elements = document.getElementById("logs").getElementsByTagName("img"); 16 for (let i = 0; i < img_elements.length; i++) { 17 let a_element = img_elements[i].parentNode; 18 let img_element = img_elements[i]; 19 img_element.src = a_element.href; 20 img_element.style.display = "block"; 21 } 22 } 23 24 function hideMedia() { 25 let video_elements = document.getElementById("logs").getElementsByTagName("video"); 26 for (let i = 0; i < video_elements.length; i++) { 27 let a_element = video_elements[i].parentNode; 28 let img_element = video_elements[i]; 29 img_element.src = a_element.href; 30 img_element.style.display = "none"; 31 } 32 let img_elements = document.getElementById("logs").getElementsByTagName("img"); 33 for (let i = 0; i < img_elements.length; i++) { 34 let a_element = img_elements[i].parentNode; 35 let img_element = img_elements[i]; 36 img_element.src = a_element.href; 37 img_element.style.display = "none"; 38 } 39 } 40 41 function gotoTrace() { 42 let errorMsg = document.getElementsByClassName('col_error')[0].innerHTML; 43 let elements = document.getElementById('logs').getElementsByClassName('error'); 44 for (let i = 0; i < elements.length; i++) { 45 let element = elements[i]; 46 if (element.innerHTML.indexOf(errorMsg) >= 0) { 47 document.documentElement.scrollTop = element.offsetTop; 48 break; 49 } 50 } 51 } 52 </script> 53 <style> 54 body { 55 font-size: 0.875em; 56 margin-right: 50px; 57 margin-left: 50px; 58 } 59 60 a:link { 61 text-decoration: none; 62 } 63 64 #logs div { 65 white-space: pre-wrap; 66 } 67 68 .aw { 69 font-weight: bold; 70 color: #1E90FF; 71 } 72 73 .aw1 { 74 color: #008B45; 75 } 76 77 .aw2 { 78 color: #00CD00; 79 } 80 81 .error, 82 .fail, 83 .failed, 84 .investigated, 85 .unavailable { 86 color: red; 87 } 88 89 .pass, 90 .passed { 91 color: green; 92 } 93 94 .warn, 95 .warning { 96 color: #FFCC00; 97 } 98 99 .operations { 100 background-color: white; 101 position: sticky; 102 top: 0; 103 } 104 105 table.case_result { 106 border-collapse: collapse; 107 border: 1px solid #ddd; 108 } 109 110 table.case_result thead, 111 table.case_result tbody tr { 112 display: table; 113 width: 100%; 114 table-layout: fixed; 115 } 116 117 table.case_result tbody { 118 display: block; 119 max-height: 360px; 120 overflow-x: hidden; 121 overflow-y: auto; 122 } 123 124 table.case_result tbody::-webkit-scrollbar { 125 width: 0; 126 } 127 128 table.case_result th, 129 table.case_result td { 130 padding: 1px 5px; 131 text-align: left; 132 border-right: 1px solid #ddd; 133 border-bottom: 1px solid #ddd; 134 } 135 136 table.case_result th { 137 background: #C6C6C6; 138 } 139 140 table.case_result td { 141 word-break: break-all; 142 } 143 144 .col_name { 145 width: 25em; 146 font-weight: bold; 147 } 148 149 .col_result { 150 width: 6em; 151 } 152 153 .col_begin { 154 width: 10em; 155 } 156 157 .col_elapsed { 158 width: 10em; 159 } 160 </style> 161 <title>{{ suite.name }}</title> 162</head> 163 164<body> 165 <h1>{{ suite.name }}</h1> 166 <h2>Summary</h2> 167 <table> 168 <tbody> 169 <tr> 170 <td>Begin/End/Elapsed:</td> 171 <td>{{ suite.begin }}/{{ suite.end }}/{{ suite.elapsed }}</td> 172 </tr> 173 {% if suite.result %} 174 <tr> 175 <td>Result:</td> 176 <td>{{ suite.result }}</td> 177 </tr> 178 {% endif %} 179 {% if suite.error %} 180 <tr> 181 <td>Error:</td> 182 <td>{{ suite.error | replace('\n', '<br>') }}</td> 183 </tr> 184 {% endif %} 185 </tbody> 186 </table> 187 188 <table id='cases' class='case_result'> 189 <thead> 190 <tr> 191 <th class='col_name'>Name</th> 192 <th class='col_result'>Result</th> 193 <th class='col_error'>Error</th> 194 <th class='col_begin'>Begin</th> 195 <th class='col_elapsed'>Elapsed</th> 196 </tr> 197 </thead> 198 <tbody> 199 {% for case in suite.cases %} 200 <tr> 201 <td class='col_name'> 202 <a href='{{ case.report }}'>{{ case.name }}</a> 203 </td> 204 <td class='col_result {{ case.result | lower }}'>{{ case.result }}</td> 205 <td class='col_error error'>{{ case.error | replace('\n', '<br>') }}</td> 206 <td class='col_begin'>{{ case.begin }}</td> 207 <td class='col_elapsed'>{{ case.elapsed }}</td> 208 </tr> 209 {% endfor %} 210 </tbody> 211 </table> 212 213 <h2>Execution Log</h2> 214 <div id='opts' class='operations'> 215 <a href="javascript:" onclick="displayMedia()">display media</a> | 216 <a href="javascript:" onclick="hideMedia()">hide media</a> | 217 <a href='javascript:' onclick='gotoTrace()'>goto trace</a> 218 </div> 219 <div id='logs'> 220 {% for log in suite.logs %} 221 <div>{{ log | replace('\n', '<br>') }}</div> 222 {% endfor %} 223 </div> 224</body> 225 226</html>