index.html (12711B)
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8" /> 5 <title>Results - Web Platform Test</title> 6 <link rel="stylesheet" href="css/bulma.min.css" /> 7 <link rel="stylesheet" href="css/result.css" /> 8 <script src="lib/utils.js"></script> 9 <script src="lib/ui.js"></script> 10 <script src="results.json.js"></script> 11 <script src="details.json.js"></script> 12 </head> 13 <body> 14 <script> 15 window.onload = () => { 16 resultUi.render(); 17 resultUi.loadData(); 18 }; 19 20 const resultUi = { 21 state: { details: null, results: null }, 22 loadData: () => { 23 resultUi.loadSessionDetails(); 24 resultUi.loadSessionResults(); 25 }, 26 loadSessionDetails(callback = () => {}) { 27 resultUi.state.details = details; 28 resultUi.renderSessionDetails(); 29 callback(details); 30 }, 31 loadSessionResults(callback = () => {}) { 32 const { details } = resultUi.state; 33 Object.keys(details.test_files_count).forEach(api => 34 !results[api] ? (results[api] = {}) : null 35 ); 36 for (let api in results) { 37 let { pass, fail, timeout, not_run } = results[api]; 38 let complete = 0; 39 if (pass) complete += pass; 40 if (fail) complete += fail; 41 if (timeout) complete += timeout; 42 if (not_run) complete += not_run; 43 results[api].complete = complete; 44 const { test_files_count, test_files_completed } = details; 45 results[api].isDone = 46 test_files_count[api] === test_files_completed[api]; 47 results[api].testFilesCount = test_files_count[api]; 48 results[api].testFilesCompleted = test_files_completed[api]; 49 } 50 resultUi.state.results = results; 51 resultUi.renderApiResults(); 52 callback(results); 53 }, 54 render() { 55 const resultView = UI.createElement({ 56 className: "content", 57 style: "margin-bottom: 40px;", 58 children: [ 59 { 60 className: "header", 61 children: [ 62 { 63 children: [ 64 { 65 element: "img", 66 src: "res/wavelogo_2016.jpg", 67 className: "site-logo" 68 } 69 ] 70 } 71 ] 72 }, 73 { 74 id: "header", 75 children: [ 76 { className: "title", text: "Result" }, 77 { id: "controls" } 78 ] 79 }, 80 { id: "session-details" }, 81 { id: "api-results" }, 82 { id: "timeout-files" }, 83 { id: "export" } 84 ] 85 }); 86 const root = UI.getRoot(); 87 root.innerHTML = ""; 88 root.appendChild(resultView); 89 resultUi.renderSessionDetails(); 90 resultUi.renderApiResults(); 91 }, 92 renderSessionDetails() { 93 const { state } = resultUi; 94 const { details } = state; 95 if (!details) return; 96 const sessionDetailsView = UI.createElement({ 97 style: "margin-bottom: 20px" 98 }); 99 100 const heading = UI.createElement({ 101 text: "Session details", 102 className: "title is-4" 103 }); 104 sessionDetailsView.appendChild(heading); 105 106 const getTagStyle = status => { 107 switch (status) { 108 case "completed": 109 return "is-success"; 110 case "running": 111 return "is-info"; 112 case "aborted": 113 return "is-danger"; 114 case "paused": 115 return "is-warning"; 116 } 117 }; 118 119 const { test_files_count, token } = details; 120 const detailsTable = UI.createElement({ 121 element: "table", 122 children: { 123 element: "tbody", 124 children: [ 125 { 126 element: "tr", 127 children: [ 128 { element: "td", text: "Token:", style: "width: 140px;" }, 129 { 130 element: "td", 131 text: token, 132 className: "is-family-monospace" 133 } 134 ] 135 }, 136 { 137 element: "tr", 138 children: [ 139 { element: "td", text: "User Agent:" }, 140 { element: "td", text: details.user_agent || "" } 141 ] 142 }, 143 { 144 element: "tr", 145 children: [ 146 { element: "td", text: "Test Path:" }, 147 { element: "td", text: details.path || "" } 148 ] 149 }, 150 { 151 element: "tr", 152 children: [ 153 { element: "td", text: "Total Test Files:" }, 154 { 155 element: "td", 156 text: Object.keys(test_files_count).reduce( 157 (sum, api) => (sum += test_files_count[api]), 158 0 159 ) 160 } 161 ] 162 }, 163 { 164 element: "tr", 165 children: [ 166 { element: "td", text: "Test Timeout:" }, 167 { element: "td", text: details.test_timeout || "" } 168 ] 169 }, 170 { 171 element: "tr", 172 children: [ 173 { element: "td", text: "Started:" }, 174 { 175 element: "td", 176 text: new Date(details.date_started).toLocaleString() 177 } 178 ] 179 }, 180 details.date_finished 181 ? { 182 element: "tr", 183 children: [ 184 { element: "td", text: "Finished:" }, 185 { 186 element: "td", 187 text: new Date(details.date_finished).toLocaleString() 188 } 189 ] 190 } 191 : null, 192 193 details.date_finished 194 ? { 195 element: "tr", 196 children: [ 197 { element: "td", text: "Duration:" }, 198 { 199 element: "td", 200 id: "duration", 201 text: utils.millisToTimeString( 202 details.date_finished 203 ? parseInt(details.date_finished) - 204 parseInt(details.date_started) 205 : Date.now() - parseInt(details.date_started) 206 ) 207 } 208 ] 209 } 210 : null 211 ] 212 } 213 }); 214 sessionDetailsView.appendChild(detailsTable); 215 216 const sessionDetails = UI.getElement("session-details"); 217 sessionDetails.innerHTML = ""; 218 sessionDetails.appendChild(sessionDetailsView); 219 }, 220 renderApiResults() { 221 const { results } = resultUi.state; 222 if (!results) return; 223 224 const apiResultsView = UI.createElement({ 225 style: "margin-bottom: 20px" 226 }); 227 228 const heading = UI.createElement({ 229 text: "API Results", 230 className: "title is-4" 231 }); 232 apiResultsView.appendChild(heading); 233 234 const header = UI.createElement({ 235 element: "thead", 236 children: [ 237 { 238 element: "tr", 239 children: [ 240 { element: "th", text: "API" }, 241 { element: "th", text: "Pass" }, 242 { element: "th", text: "Fail" }, 243 { element: "th", text: "Timeout" }, 244 { element: "th", text: "Not Run" }, 245 { element: "th", text: "Test Files Run" } 246 ] 247 } 248 ] 249 }); 250 251 const apis = Object.keys(results).sort((apiA, apiB) => 252 apiA.toLowerCase() > apiB.toLowerCase() ? 1 : -1 253 ); 254 255 const rows = apis.map(api => { 256 const { 257 complete = 0, 258 pass = 0, 259 fail = 0, 260 timeout = 0, 261 timeoutfiles = [], 262 not_run: notRun = 0, 263 isDone = false, 264 testFilesCount, 265 testFilesCompleted = 0 266 } = results[api]; 267 return UI.createElement({ 268 element: "tr", 269 children: [ 270 { element: "td", text: api }, 271 { 272 element: "td", 273 style: "color: hsl(141, 71%, 38%)", 274 text: `${pass} (${utils.percent(pass, complete)}%)` 275 }, 276 { 277 element: "td", 278 className: "has-text-danger", 279 text: `${fail} (${utils.percent(fail, complete)}%)` 280 }, 281 { 282 element: "td", 283 style: "color: hsl(48, 100%, 40%)", 284 text: `${timeout} (${utils.percent(timeout, complete)}%)` 285 }, 286 { 287 element: "td", 288 className: "has-text-info", 289 text: `${notRun} (${utils.percent(notRun, complete)}%)` 290 }, 291 { 292 element: "td", 293 text: `${testFilesCompleted}/${testFilesCount} (${utils.percent( 294 testFilesCompleted, 295 testFilesCount 296 )}%)` 297 } 298 ] 299 }); 300 }); 301 302 const { pass, fail, timeout, not_run, complete } = apis.reduce( 303 (sum, api) => { 304 Object.keys(sum).forEach( 305 key => (sum[key] += results[api][key] ? results[api][key] : 0) 306 ); 307 return sum; 308 }, 309 { complete: 0, pass: 0, fail: 0, timeout: 0, not_run: 0 } 310 ); 311 const testFilesCount = Object.keys(results).reduce( 312 (sum, api) => (sum += results[api].testFilesCount), 313 0 314 ); 315 const testFilesCompleted = Object.keys(results).reduce( 316 (sum, api) => (sum += results[api].testFilesCompleted || 0), 317 0 318 ); 319 320 const footer = UI.createElement({ 321 element: "tfoot", 322 children: [ 323 { 324 element: "tr", 325 children: [ 326 { element: "th", text: "Total" }, 327 { 328 element: "th", 329 style: "color: hsl(141, 71%, 38%)", 330 text: `${pass} (${utils.percent(pass, complete)}%)` 331 }, 332 { 333 element: "th", 334 className: "has-text-danger", 335 text: `${fail} (${utils.percent(fail, complete)}%)` 336 }, 337 { 338 element: "th", 339 style: "color: hsl(48, 100%, 40%)", 340 text: `${timeout} (${utils.percent(timeout, complete)}%)` 341 }, 342 { 343 element: "th", 344 className: "has-text-info", 345 text: `${not_run} (${utils.percent(not_run, complete)}%)` 346 }, 347 { 348 element: "th", 349 text: `${testFilesCompleted}/${testFilesCount} (${utils.percent( 350 testFilesCompleted, 351 testFilesCount 352 )}%)` 353 } 354 ] 355 } 356 ] 357 }); 358 359 const resultsTable = UI.createElement({ 360 element: "table", 361 className: "table", 362 id: "results-table", 363 style: "border-radius: 3px; border: 2px solid hsl(0, 0%, 86%);", 364 children: [header, { element: "tbody", children: rows }, footer] 365 }); 366 apiResultsView.appendChild(resultsTable); 367 368 const apiResults = UI.getElement("api-results"); 369 apiResults.innerHTML = ""; 370 apiResults.appendChild(apiResultsView); 371 } 372 }; 373 </script> 374 </body> 375 </html>