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 53 function gotoStep(stepId) { 54 let element = document.getElementById(stepId); 55 if (element != null) { 56 let distance = element.offsetTop - 50; 57 document.documentElement.scrollTo(0, distance); 58 } 59 } 60 </script> 61 <style> 62 body { 63 font-size: 0.875em; 64 margin-right: 50px; 65 margin-left: 50px; 66 } 67 68 a:link { 69 text-decoration: none; 70 } 71 72 #logs div { 73 white-space: pre-wrap; 74 } 75 76 .aw { 77 font-weight: bold; 78 color: #1E90FF; 79 } 80 81 .aw1 { 82 color: #008B45; 83 } 84 85 .aw2 { 86 color: #00CD00; 87 } 88 89 .error, 90 .fail, 91 .failed, 92 .investigated, 93 .unavailable { 94 color: red; 95 } 96 97 .pass, 98 .passed { 99 color: green; 100 } 101 102 .warn, 103 .warning { 104 color: #FFCC00; 105 } 106 107 .operations { 108 background-color: white; 109 position: sticky; 110 top: 0; 111 } 112 113 table.steps { 114 border-collapse: collapse; 115 border: 1px solid #ddd; 116 } 117 118 table.steps thead, 119 table.steps tbody tr { 120 display: table; 121 width: 100%; 122 table-layout: fixed; 123 } 124 125 table.steps tbody { 126 display: block; 127 max-height: 360px; 128 overflow-x: hidden; 129 overflow-y: auto; 130 } 131 132 table.steps tbody::-webkit-scrollbar { 133 width: 0; 134 } 135 136 table.steps th, 137 table.steps td { 138 padding: 1px 5px; 139 border-right: 1px solid #ddd; 140 border-bottom: 1px solid #ddd; 141 } 142 143 table.steps th { 144 background: #C6C6C6; 145 text-align: left; 146 } 147 148 table.steps td { 149 word-break: break-all; 150 } 151 152 .col_no { 153 width: 3em; 154 } 155 156 .col_time { 157 width: 7em; 158 } 159 160 .col_shot { 161 display: none; 162 } 163 </style> 164 <title>{{ case.name }}</title> 165</head> 166 167<body> 168 <h1>{{ case.name }}</h1> 169 <h2>Summary</h2> 170 <table class="summary"> 171 <tbody> 172 <tr> 173 <td>Begin/End/Elapsed:</td> 174 <td>{{ case.begin }}/{{ case.end }}/{{ case.elapsed }}</td> 175 </tr> 176 <tr> 177 <td>Result:</td> 178 <td class="{{ case.result | lower }}">{{ case.result | replace("\n", "<br>") }}</td> 179 </tr> 180 {% if case.error %} 181 <tr> 182 <td>Error:</td> 183 <td class="col_error error">{{ case.error }}</td> 184 </tr> 185 {% endif %} 186 </tbody> 187 </table> 188 {% if case.steps %} 189 <table class="steps"> 190 <thead> 191 <tr> 192 <th class="col_no">No.</th> 193 <th>Step</th> 194 <th>Result</th> 195 <th class="col_time">Time(s)</th> 196 <th class="col_shot">Screenshot</th> 197 {% for head in case.extra_head %} 198 <th>{{ head | capitalize }}</th> 199 {% endfor %} 200 </tr> 201 </thead> 202 <tbody> 203 {% for step in case.steps %} 204 <tr> 205 <td class="col_no">{{ loop.index }}</td> 206 <td> 207 <a href="javascript:" onclick="gotoStep('{{ loop.index0 }}')">{{ step.name }}</a> 208 </td> 209 {% if step.result == "pass" %} 210 <td class="pass">{{ step.result }}</td> 211 {% else %} 212 <td class="fail">{{ step.result | replace("\n", "<br>") }}</td> 213 {% endif %} 214 <td class="col_time">{{ step.cost }}</td> 215 <td class="col_shot">{{ step.screenshot | join("<br>") }}</td> 216 {% for head in case.extra_head %} 217 {% if head == "video" and step.video %} 218 <td> 219 <a href="{{ step.video }}">view video</a> 220 </td> 221 {% else %} 222 <td>{{ step[head] }}</td> 223 {% endif %} 224 {% endfor %} 225 </tr> 226 {% endfor %} 227 </tbody> 228 </table> 229 {% endif %} 230 231 <h2>Execution Log</h2> 232 <div class="operations"> 233 <a href="javascript:" onclick="displayMedia()">display media</a> | 234 <a href="javascript:" onclick="hideMedia()">hide media</a> | 235 <a href="javascript:" onclick="gotoTrace()">goto trace</a> 236 </div> 237 <div id="logs"> 238 {% for log in case.logs %} 239 <div>{{ log | replace("\n", "<br>") }}</div> 240 {% endfor %} 241 </div> 242</body> 243 244</html>