| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8" /> |
| <title>Results - Web Platform Test</title> |
| <link rel="stylesheet" href="css/bulma.min.css" /> |
| <link rel="stylesheet" href="css/result.css" /> |
| <script src="lib/utils.js"></script> |
| <script src="lib/ui.js"></script> |
| <script src="results.json.js"></script> |
| <script src="details.json.js"></script> |
| </head> |
| <body> |
| <script> |
| window.onload = () => { |
| resultUi.render(); |
| resultUi.loadData(); |
| }; |
| |
| const resultUi = { |
| state: { details: null, results: null }, |
| loadData: () => { |
| resultUi.loadSessionDetails(); |
| resultUi.loadSessionResults(); |
| }, |
| loadSessionDetails(callback = () => {}) { |
| resultUi.state.details = details; |
| resultUi.renderSessionDetails(); |
| callback(details); |
| }, |
| loadSessionResults(callback = () => {}) { |
| const { details } = resultUi.state; |
| Object.keys(details.test_files_count).forEach(api => |
| !results[api] ? (results[api] = {}) : null |
| ); |
| for (let api in results) { |
| let { pass, fail, timeout, not_run } = results[api]; |
| let complete = 0; |
| if (pass) complete += pass; |
| if (fail) complete += fail; |
| if (timeout) complete += timeout; |
| if (not_run) complete += not_run; |
| results[api].complete = complete; |
| const { test_files_count, test_files_completed } = details; |
| results[api].isDone = |
| test_files_count[api] === test_files_completed[api]; |
| results[api].testFilesCount = test_files_count[api]; |
| results[api].testFilesCompleted = test_files_completed[api]; |
| } |
| resultUi.state.results = results; |
| resultUi.renderApiResults(); |
| callback(results); |
| }, |
| render() { |
| const resultView = UI.createElement({ |
| className: "content", |
| style: "margin-bottom: 40px;", |
| children: [ |
| { |
| className: "header", |
| children: [ |
| { |
| children: [ |
| { |
| element: "img", |
| src: "res/wavelogo_2016.jpg", |
| className: "site-logo" |
| } |
| ] |
| } |
| ] |
| }, |
| { |
| id: "header", |
| children: [ |
| { className: "title", text: "Result" }, |
| { id: "controls" } |
| ] |
| }, |
| { id: "session-details" }, |
| { id: "api-results" }, |
| { id: "timeout-files" }, |
| { id: "export" } |
| ] |
| }); |
| const root = UI.getRoot(); |
| root.innerHTML = ""; |
| root.appendChild(resultView); |
| resultUi.renderSessionDetails(); |
| resultUi.renderApiResults(); |
| }, |
| renderSessionDetails() { |
| const { state } = resultUi; |
| const { details } = state; |
| if (!details) return; |
| const sessionDetailsView = UI.createElement({ |
| style: "margin-bottom: 20px" |
| }); |
| |
| const heading = UI.createElement({ |
| text: "Session details", |
| className: "title is-4" |
| }); |
| sessionDetailsView.appendChild(heading); |
| |
| const getTagStyle = status => { |
| switch (status) { |
| case "completed": |
| return "is-success"; |
| case "running": |
| return "is-info"; |
| case "aborted": |
| return "is-danger"; |
| case "paused": |
| return "is-warning"; |
| } |
| }; |
| |
| const { test_files_count, token } = details; |
| const detailsTable = UI.createElement({ |
| element: "table", |
| children: { |
| element: "tbody", |
| children: [ |
| { |
| element: "tr", |
| children: [ |
| { element: "td", text: "Token:", style: "width: 140px;" }, |
| { |
| element: "td", |
| text: token, |
| className: "is-family-monospace" |
| } |
| ] |
| }, |
| { |
| element: "tr", |
| children: [ |
| { element: "td", text: "User Agent:" }, |
| { element: "td", text: details.user_agent || "" } |
| ] |
| }, |
| { |
| element: "tr", |
| children: [ |
| { element: "td", text: "Test Path:" }, |
| { element: "td", text: details.path || "" } |
| ] |
| }, |
| { |
| element: "tr", |
| children: [ |
| { element: "td", text: "Total Test Files:" }, |
| { |
| element: "td", |
| text: Object.keys(test_files_count).reduce( |
| (sum, api) => (sum += test_files_count[api]), |
| 0 |
| ) |
| } |
| ] |
| }, |
| { |
| element: "tr", |
| children: [ |
| { element: "td", text: "Test Timeout:" }, |
| { element: "td", text: details.test_timeout || "" } |
| ] |
| }, |
| { |
| element: "tr", |
| children: [ |
| { element: "td", text: "Started:" }, |
| { |
| element: "td", |
| text: new Date(details.date_started).toLocaleString() |
| } |
| ] |
| }, |
| details.date_finished |
| ? { |
| element: "tr", |
| children: [ |
| { element: "td", text: "Finished:" }, |
| { |
| element: "td", |
| text: new Date(details.date_finished).toLocaleString() |
| } |
| ] |
| } |
| : null, |
| |
| details.date_finished |
| ? { |
| element: "tr", |
| children: [ |
| { element: "td", text: "Duration:" }, |
| { |
| element: "td", |
| id: "duration", |
| text: utils.millisToTimeString( |
| details.date_finished |
| ? parseInt(details.date_finished) - |
| parseInt(details.date_started) |
| : Date.now() - parseInt(details.date_started) |
| ) |
| } |
| ] |
| } |
| : null |
| ] |
| } |
| }); |
| sessionDetailsView.appendChild(detailsTable); |
| |
| const sessionDetails = UI.getElement("session-details"); |
| sessionDetails.innerHTML = ""; |
| sessionDetails.appendChild(sessionDetailsView); |
| }, |
| renderApiResults() { |
| const { results } = resultUi.state; |
| if (!results) return; |
| |
| const apiResultsView = UI.createElement({ |
| style: "margin-bottom: 20px" |
| }); |
| |
| const heading = UI.createElement({ |
| text: "API Results", |
| className: "title is-4" |
| }); |
| apiResultsView.appendChild(heading); |
| |
| const header = UI.createElement({ |
| element: "thead", |
| children: [ |
| { |
| element: "tr", |
| children: [ |
| { element: "th", text: "API" }, |
| { element: "th", text: "Pass" }, |
| { element: "th", text: "Fail" }, |
| { element: "th", text: "Timeout" }, |
| { element: "th", text: "Not Run" }, |
| { element: "th", text: "Test Files Run" } |
| ] |
| } |
| ] |
| }); |
| |
| const apis = Object.keys(results).sort((apiA, apiB) => |
| apiA.toLowerCase() > apiB.toLowerCase() ? 1 : -1 |
| ); |
| |
| const rows = apis.map(api => { |
| const { |
| complete = 0, |
| pass = 0, |
| fail = 0, |
| timeout = 0, |
| timeoutfiles = [], |
| not_run: notRun = 0, |
| isDone = false, |
| testFilesCount, |
| testFilesCompleted = 0 |
| } = results[api]; |
| return UI.createElement({ |
| element: "tr", |
| children: [ |
| { element: "td", text: api }, |
| { |
| element: "td", |
| style: "color: hsl(141, 71%, 38%)", |
| text: `${pass} (${utils.percent(pass, complete)}%)` |
| }, |
| { |
| element: "td", |
| className: "has-text-danger", |
| text: `${fail} (${utils.percent(fail, complete)}%)` |
| }, |
| { |
| element: "td", |
| style: "color: hsl(48, 100%, 40%)", |
| text: `${timeout} (${utils.percent(timeout, complete)}%)` |
| }, |
| { |
| element: "td", |
| className: "has-text-info", |
| text: `${notRun} (${utils.percent(notRun, complete)}%)` |
| }, |
| { |
| element: "td", |
| text: `${testFilesCompleted}/${testFilesCount} (${utils.percent( |
| testFilesCompleted, |
| testFilesCount |
| )}%)` |
| } |
| ] |
| }); |
| }); |
| |
| const { pass, fail, timeout, not_run, complete } = apis.reduce( |
| (sum, api) => { |
| Object.keys(sum).forEach( |
| key => (sum[key] += results[api][key] ? results[api][key] : 0) |
| ); |
| return sum; |
| }, |
| { complete: 0, pass: 0, fail: 0, timeout: 0, not_run: 0 } |
| ); |
| const testFilesCount = Object.keys(results).reduce( |
| (sum, api) => (sum += results[api].testFilesCount), |
| 0 |
| ); |
| const testFilesCompleted = Object.keys(results).reduce( |
| (sum, api) => (sum += results[api].testFilesCompleted || 0), |
| 0 |
| ); |
| |
| const footer = UI.createElement({ |
| element: "tfoot", |
| children: [ |
| { |
| element: "tr", |
| children: [ |
| { element: "th", text: "Total" }, |
| { |
| element: "th", |
| style: "color: hsl(141, 71%, 38%)", |
| text: `${pass} (${utils.percent(pass, complete)}%)` |
| }, |
| { |
| element: "th", |
| className: "has-text-danger", |
| text: `${fail} (${utils.percent(fail, complete)}%)` |
| }, |
| { |
| element: "th", |
| style: "color: hsl(48, 100%, 40%)", |
| text: `${timeout} (${utils.percent(timeout, complete)}%)` |
| }, |
| { |
| element: "th", |
| className: "has-text-info", |
| text: `${not_run} (${utils.percent(not_run, complete)}%)` |
| }, |
| { |
| element: "th", |
| text: `${testFilesCompleted}/${testFilesCount} (${utils.percent( |
| testFilesCompleted, |
| testFilesCount |
| )}%)` |
| } |
| ] |
| } |
| ] |
| }); |
| |
| const resultsTable = UI.createElement({ |
| element: "table", |
| className: "table", |
| id: "results-table", |
| style: "border-radius: 3px; border: 2px solid hsl(0, 0%, 86%);", |
| children: [header, { element: "tbody", children: rows }, footer] |
| }); |
| apiResultsView.appendChild(resultsTable); |
| |
| const apiResults = UI.getElement("api-results"); |
| apiResults.innerHTML = ""; |
| apiResults.appendChild(apiResultsView); |
| } |
| }; |
| </script> |
| </body> |
| </html> |