| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8" /> |
| <title>Compare Results - Web Platform Test</title> |
| <link rel="stylesheet" href="css/bulma-0.7.5/bulma.min.css" /> |
| <link rel="stylesheet" href="css/fontawesome-5.7.2.min.css" /> |
| <script src="lib/utils.js"></script> |
| <script src="lib/wave-service.js"></script> |
| <script src="lib/ui.js"></script> |
| <style> |
| body { |
| margin: 0; |
| padding: 0; |
| width: 100vw; |
| height: 100vh; |
| display: flex; |
| justify-content: center; |
| font-family: "Noto Sans", sans-serif; |
| overflow-y: auto; |
| overflow-x: hidden; |
| background-color: white; |
| color: #000; |
| } |
| |
| .site-logo { |
| max-width: 300px; |
| margin-left: -15px; |
| } |
| |
| .content { |
| width: 1000px; |
| } |
| |
| .header { |
| display: flex; |
| margin: 50px 0 30px 0; |
| } |
| |
| .header :first-child { |
| flex: 1; |
| } |
| |
| .session-header { |
| display: flex; |
| justify-content: center; |
| align-items: center; |
| cursor: pointer; |
| } |
| |
| .session-header div { |
| padding: 5px; |
| font-weight: bold; |
| } |
| |
| .session-header:hover div { |
| text-decoration: underline; |
| } |
| </style> |
| </head> |
| <body> |
| <script> |
| window.onload = () => { |
| let { tokens, reftokens } = utils.parseQuery(location.search); |
| tokens = tokens ? tokens.split(",") : []; |
| const refTokens = reftokens ? reftokens.split(",") : []; |
| if (tokens) { |
| WaveService.readStatus(function(config) { |
| comparisonUi.state.reportsEnabled = config.reportsEnabled; |
| comparisonUi.render(); |
| }); |
| WaveService.addRecentSessions(tokens); |
| WaveService.addRecentSessions(refTokens); |
| comparisonUi.state.tokens = tokens; |
| comparisonUi.state.refTokens = refTokens; |
| comparisonUi.render(); |
| comparisonUi.refreshData(); |
| } |
| }; |
| |
| const comparisonUi = { |
| state: { |
| tokens: [], |
| refTokens: [], |
| sessions: {} |
| }, |
| refreshData: () => { |
| const { tokens, refTokens } = comparisonUi.state; |
| const allTokens = tokens.slice(); |
| refTokens |
| .filter(token => allTokens.indexOf(token) === -1) |
| .forEach(token => allTokens.push(token)); |
| |
| WaveService.readMultipleSessions(allTokens, configurations => { |
| const sessions = {}; |
| configurations.forEach( |
| details => (sessions[details.token] = details) |
| ); |
| comparisonUi.state.sessions = sessions; |
| |
| WaveService.readResultComparison(tokens, results => { |
| comparisonUi.state.results = results; |
| comparisonUi.renderApiResults(); |
| }); |
| |
| const sessionsReferenceTokens = []; |
| configurations.forEach(({ referenceTokens }) => |
| referenceTokens |
| .filter(token => refTokens.indexOf(token) === -1) |
| .filter(token => sessionsReferenceTokens.indexOf(token) === -1) |
| .forEach(token => sessionsReferenceTokens.push(token)) |
| ); |
| |
| sessionsReferenceTokens.forEach(token => |
| comparisonUi.state.refTokens.push(token) |
| ); |
| |
| WaveService.readMultipleSessions( |
| sessionsReferenceTokens, |
| configurations => { |
| const { sessions } = comparisonUi.state; |
| configurations.forEach( |
| details => (sessions[details.token] = details) |
| ); |
| comparisonUi.renderDetails(); |
| } |
| ); |
| }); |
| }, |
| openResultsOverview() { |
| location.href = WEB_ROOT + "overview.html"; |
| }, |
| render() { |
| const comparisonView = UI.createElement({ |
| className: "content", |
| style: "margin-bottom: 40px;", |
| children: [ |
| { |
| className: "header", |
| children: [ |
| { |
| children: [ |
| { |
| element: "img", |
| src: "res/wavelogo_2016.jpg", |
| className: "site-logo" |
| } |
| ] |
| }, |
| { |
| className: "button is-dark is-outlined", |
| onClick: comparisonUi.openResultsOverview, |
| children: [ |
| { |
| element: "span", |
| className: "icon", |
| children: [ |
| { |
| element: "i", |
| className: "fas fa-arrow-left" |
| } |
| ] |
| }, |
| { |
| text: "Results Overview", |
| element: "span" |
| } |
| ] |
| } |
| ] |
| }, |
| { |
| id: "header", |
| children: [ |
| { className: "title", text: "Comparison" }, |
| { id: "controls" } |
| ] |
| }, |
| { id: "details" }, |
| { id: "api-results" } |
| ] |
| }); |
| |
| const root = UI.getRoot(); |
| root.innerHTML = ""; |
| root.appendChild(comparisonView); |
| comparisonUi.renderDetails(); |
| comparisonUi.renderApiResults(); |
| }, |
| renderDetails() { |
| const detailsView = UI.createElement({ |
| style: "margin-bottom: 20px" |
| }); |
| |
| const { refTokens } = comparisonUi.state; |
| const detailsTable = UI.createElement({ |
| element: "table", |
| children: { |
| element: "tbody", |
| children: [ |
| { |
| element: "tr", |
| id: "reference-sessions" |
| } |
| ] |
| } |
| }); |
| detailsView.appendChild(detailsTable); |
| |
| const details = UI.getElement("details"); |
| details.innerHTML = ""; |
| details.appendChild(detailsView); |
| comparisonUi.renderReferenceSessions(); |
| }, |
| renderReferenceSessions() { |
| const { sessions, refTokens } = comparisonUi.state; |
| if (!refTokens || refTokens.length === 0) return; |
| if (!Object.keys(sessions) || Object.keys(sessions).length === 0) |
| return; |
| const referenceSessions = refTokens.map(token => sessions[token]); |
| const referenceSessionsTarget = UI.getElement("reference-sessions"); |
| referenceSessionsTarget.innerHTML = ""; |
| |
| const referenceSessionsLabel = UI.createElement({ |
| element: "td", |
| text: "Reference Sessions:", |
| style: "width: 175px" |
| }); |
| referenceSessionsTarget.appendChild(referenceSessionsLabel); |
| |
| const referenceSessionsList = UI.createElement({ element: "td" }); |
| referenceSessions.forEach(session => { |
| const { token, browser } = session; |
| const referenceSessionItem = UI.createElement({ |
| style: "margin-right: 10px", |
| className: "button is-dark is-small is-rounded is-outlined", |
| onClick: () => WaveService.openSession(token), |
| children: [ |
| { |
| element: "span", |
| className: "icon", |
| children: { |
| element: "i", |
| className: utils.getBrowserIcon(browser.name) |
| } |
| }, |
| { |
| element: "span", |
| className: "is-family-monospace", |
| text: token.split("-").shift() |
| } |
| ] |
| }); |
| referenceSessionsList.appendChild(referenceSessionItem); |
| }); |
| referenceSessionsTarget.appendChild(referenceSessionsList); |
| }, |
| renderApiResults() { |
| const apiResultsView = UI.createElement({ |
| style: "margin-bottom: 20px" |
| }); |
| |
| const heading = UI.createElement({ |
| className: "title is-4", |
| text: "Results" |
| }); |
| apiResultsView.appendChild(heading); |
| |
| const { results, tokens, sessions } = comparisonUi.state; |
| |
| if (!results) { |
| const loadingIndicator = UI.createElement({ |
| className: "level", |
| children: { |
| element: "span", |
| className: "level-item icon", |
| children: [ |
| { |
| element: "i", |
| className: "fas fa-spinner fa-pulse" |
| }, |
| { |
| style: "margin-left: 0.4em;", |
| text: "Loading comparison ..." |
| } |
| ] |
| } |
| }); |
| apiResultsView.appendChild(loadingIndicator); |
| |
| const apiResults = UI.getElement("api-results"); |
| apiResults.innerHTML = ""; |
| apiResults.appendChild(apiResultsView); |
| return; |
| } |
| |
| const resultsTable = UI.createElement({ |
| element: "table" |
| }); |
| apiResultsView.appendChild(resultsTable); |
| |
| const getColor = percent => { |
| const tRed = 28; |
| const tGreen = 166; |
| const tBlue = 76; |
| const mRed = 204; |
| const mGreen = 163; |
| const mBlue = 0; |
| const bRed = 255; |
| const bGreen = 56; |
| const bBlue = 96; |
| if (percent > 50) { |
| const red = mRed + ((percent - 50) / 50) * (tRed - mRed); |
| const green = mGreen + ((percent - 50) / 50) * (tGreen - mGreen); |
| const blue = mBlue + ((percent - 50) / 50) * (tBlue - mBlue); |
| return `rgb(${red}, ${green}, ${blue})`; |
| } else { |
| const red = bRed + (percent / 50) * (mRed - bRed); |
| const green = bGreen + (percent / 50) * (mGreen - bGreen); |
| const blue = bBlue + (percent / 50) * (mBlue - bBlue); |
| return `rgb(${red}, ${green}, ${blue})`; |
| } |
| }; |
| |
| const resultsTableHeader = UI.createElement({ |
| element: "thead", |
| children: { |
| element: "tr", |
| children: [ |
| { |
| element: "td", |
| text: "API", |
| style: "vertical-align: bottom; width: 200px" |
| } |
| ] |
| .concat( |
| tokens.map(token => ({ |
| element: "td", |
| children: { |
| onClick: () => WaveService.openSession(token), |
| className: "session-header", |
| children: [ |
| { |
| element: "i", |
| style: "font-size: 1.5em; margin-right: 0.1em", |
| className: utils.getBrowserIcon( |
| sessions[token].browser.name |
| ) |
| }, |
| { |
| children: [ |
| { |
| style: "margin: 0; padding: 0;", |
| className: "is-family-monospace", |
| text: `${token.split("-").shift()}` |
| }, |
| { |
| style: "margin: 0; padding: 0;", |
| text: `${sessions[token].browser.name} ${ |
| sessions[token].browser.version |
| }` |
| } |
| ] |
| } |
| ] |
| } |
| })) |
| ) |
| .concat([{ element: "td", style: "width: 80px" }]) |
| } |
| }); |
| resultsTable.appendChild(resultsTableHeader); |
| |
| let apis = []; |
| tokens.forEach(token => |
| Object.keys(results[token]) |
| .filter(api => apis.indexOf(api) === -1) |
| .forEach(api => apis.push(api)) |
| ); |
| apis = apis.sort((apiA, apiB) => |
| apiA.toLowerCase() > apiB.toLowerCase() ? 1 : -1 |
| ); |
| |
| const resultsTableBody = UI.createElement({ |
| element: "tbody", |
| children: apis.map(api => ({ |
| element: "tr", |
| children: [{ element: "td", text: api }] |
| .concat( |
| tokens.map(token => |
| results[token][api] |
| ? { |
| element: "td", |
| style: |
| "text-align: center; font-weight: bold;" + |
| `color: ${getColor( |
| utils.percent( |
| results[token][api], |
| results["total"][api] |
| ) |
| )}`, |
| text: `${utils.percent( |
| results[token][api], |
| results["total"][api] |
| )}%` |
| } |
| : { |
| element: "td", |
| text: "Not Tested", |
| style: "text-align: center;" |
| } |
| ) |
| ) |
| .concat([ |
| comparisonUi.state.reportsEnabled ? |
| { |
| element: "td", |
| children: { |
| className: |
| "html-report button is-dark is-outlined is-small", |
| onclick: () => |
| WaveService.readMultiReportUri( |
| comparisonUi.state.tokens, |
| api, |
| function(uri) { |
| window.open(uri, "_blank"); |
| } |
| ), |
| text: "report" |
| } |
| } : null |
| ]) |
| })) |
| }); |
| resultsTable.appendChild(resultsTableBody); |
| |
| const apiResults = UI.getElement("api-results"); |
| apiResults.innerHTML = ""; |
| apiResults.appendChild(apiResultsView); |
| } |
| }; |
| </script> |
| </body> |
| </html> |