UNPKG

aft-mocha-reporter

Version:

Automated Functional Testing (AFT) Reporter for use with Mocha Test Framework

365 lines (339 loc) 21 kB
<!DOCTYPE html> <html lang="en" xmlns="http://www.w3.org/1999/xhtml"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Test Results</title> <script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/css/bootstrap.min.css" integrity="sha384-B0vP5xmATw1+K9KRQjQERJvTumQW0nPEzvF6L/Z6nronJ3oUOFUFpCjEUQouq2+l" crossorigin="anonymous"> <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/js/bootstrap.min.js" integrity="sha384-+YQ4JLhjyBLPDQt//I+STsc9iw4uQqACwlvpslubQzn4u2UU2UFM80nGisd026JF" crossorigin="anonymous"></script> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.4.1/font/bootstrap-icons.css"> <script type="text/javascript" src="https://www.google.com/jsapi"></script> <script type="text/javascript"> var notRun = 'notrun'; var failing = 'failing'; var passing = 'passing'; function showAll() { var rows = document.querySelectorAll('tr'); toggleDisplayOfElements(rows, true); updateUrlParameter(''); } function showOnlyPassing() { var passingRows = getPassingRows('html'); var failingRows = getFailingRows('html'); var notRunRows = getNotRunRows('html'); toggleDisplayOfElements(passingRows, true); toggleDisplayOfElements(failingRows, false); toggleDisplayOfElements(notRunRows, false); updateUrlParameter(passing); } function showOnlyFailing() { var passingRows = getPassingRows('html'); var failingRows = getFailingRows('html'); var notRunRows = getNotRunRows('html'); toggleDisplayOfElements(passingRows, false); toggleDisplayOfElements(failingRows, true); toggleDisplayOfElements(notRunRows, false); updateUrlParameter(failing); } function showOnlyNotRun() { var passingRows = getPassingRows('html'); var failingRows = getFailingRows('html'); var notRunRows = getNotRunRows('html'); toggleDisplayOfElements(passingRows, false); toggleDisplayOfElements(failingRows, false); toggleDisplayOfElements(notRunRows, true); updateUrlParameter(notRun); } function toggleAllPanels(enable) { var panels = document.querySelectorAll('.card'); for (var i=0; i<panels.length; i++) { var name = panels[i].getAttribute('name'); toggleCard(name, enable); } } function toggleCard(name, enable) { if (name) { var panelHeader = document.querySelector("[name='" + name + "']"); var panelBody = document.querySelector("[name='body-" + name + "']"); if (panelBody) { var glyph = panelHeader.querySelector('.bi'); if (enable == undefined) { // detect current state and toggle enable = false; if (glyph && glyph.classList.contains('bi-plus')) { // display enable = true; glyph.classList.remove('bi-plus'); glyph.classList.add('bi-dash'); } else { // hide enable = false; glyph.classList.remove('bi-dash'); glyph.classList.add('bi-plus'); } } else { // use passed in state no matter current state glyph.classList.remove('bi-plus'); glyph.classList.remove('bi-dash'); if (enable) { glyph.classList.add('bi-dash'); } else { glyph.classList.add('bi-plus'); } } toggleDisplayOfElements([panelBody], enable); } } } function toggleDisplayOfElements(elementArray, enable) { var re = new RegExp(/d-none/g); for (var i=0; i<elementArray.length; i++) { var row = elementArray[i]; var classes = row.className; if (enable) { row.className = classes.replace(re, ''); } else { row.className += " d-none"; } } } function updateUrlParameter(param) { var url = window.location.href; if (url.indexOf('#') !== -1) { // remove existing param url = url.substring(0, url.indexOf('#')); } url += '#' + param; window.location.href = url; } function getUrlParameter() { var param = ''; var url = window.location.href; if (url.indexOf('#') !== -1) { // remove existing param param = url.substring(url.indexOf('#') + 1, url.length); } return param; } function getPassingRows(selectorScope) { var passingRows = document.querySelectorAll(selectorScope + ' tr.passing'); return passingRows; } function getFailingRows(selectorScope) { var failingRows = document.querySelectorAll(selectorScope + ' tr.failing'); return failingRows; } function getNotRunRows(selectorScope) { var notRunRows = document.querySelectorAll(selectorScope + ' tr.notrun'); return notRunRows; } function updateCounts(resultsScope, totalsScope) { var passing = getPassingRows(resultsScope).length; var failing = getFailingRows(resultsScope).length; var notRun = getNotRunRows(resultsScope).length; var pSpan = document.querySelector(totalsScope).querySelector('span.totalTestsPassing'); var fSpan = document.querySelector(totalsScope).querySelector('span.totalTestsFailing'); var nSpan = document.querySelector(totalsScope).querySelector('span.totalTestsNotRun'); var tSpan = document.querySelector(totalsScope).querySelector('span.totalTests'); pSpan.innerText = passing; fSpan.innerText = failing; nSpan.innerText = notRun; tSpan.innerText = passing + failing + notRun; } function parseUrlForDisplay() { var param = getUrlParameter(); switch(param) { case notRun: showOnlyNotRun(); break; case passing: showOnlyPassing(); break; case failing: showOnlyFailing(); break; default: showAll(); } } function initialise(results) { if (results?.length) { for (var j=0; j<results.length; j++) { var result = results[j]; addResult(result); } } updateCounts('html', '#summaryContainer'); parseUrlForDisplay(); } function addResult(result) { var passing = getTestsWithStatus(/(passed)/gi, result).length; var failing = getTestsWithStatus(/(failed|retest)/gi, result).length; var notRun = getTestsWithStatus(/(untested|blocked|skipped)/gi, result).length; var container = document.querySelector('#resultsContainer'); var section = ` <div class="card card-info" name="${result.description}-ps-results"> <div class="card-header p-0 bg-secondary d-flex justify-content-between flex-row text-light" onclick="toggleCard('${result.description}-ps-results');"> <div class="p-1"><i class="bi bi-dash" aria-hidden="true"></i></div> <div class="p-1 flex-grow-1 breakWrap"><span class="badge badge-default">Description:</span> ${result.description}</div> <div class="p-1 noWrap"><span class="badge rounded-pill bg-primary totalTests">${passing + failing + notRun}</span> <span class="badge bg-success totalTestsPassing">${passing}</span> <span class="badge bg-danger totalTestsFailing">${failing}</span> <span class="badge bg-warning totalTestsNotRun">${notRun}</span></div> </div> <div class="card-body p-0" name="body-${result.description}-ps-results"></div> </div> `; container.innerHTML += section; var testContainer = document.querySelector(`[name='body-${result.description}-ps-results']`); if (result.tests?.length) { addTests(testContainer, result.tests); } } function getTestsWithStatus(statusRegex, result) { var statusTests = []; if (result?.tests?.length) { for (var i=0; i<result.tests.length; i++) { var t = result.tests[i]; if (t.status.match(statusRegex)?.length) { statusTests.push(t); } } } return statusTests; } function addTests(container, tests) { var startSection = ` <table class="table table-striped table-hover"> <thead> <tr><th>Timestamp</th><th>Test ID</th><th>Status</th><th>Logs</th></tr> </thead> <tbody> `; var testResultSection = ''; for (var i=0; i<tests.length; i++) { var result = tests[i]; var statusClass, trClass; switch (result.status) { case "passed": statusClass = "success"; trClass = "passing"; break; case "failed": case "retest": statusClass = "danger"; trClass = "failing"; break; default: statusClass = "warning"; trClass = "notrun"; break; } testResultSection += ` <tr class="${trClass}" name="${result.testId}-pstt-results"> <td class="created"> ${new Date(result.created)} </td> <td class="id"> ${result.testId || 'n/a'} </td> <td class="status"> <span class="badge badge-${statusClass}">${result.status}</span> </td> <td class="logs breakWrap"> ${result.logs.join('<br />')} </td> </tr> `; } var endSection = ` </tbody> </table> `; container.innerHTML += startSection + testResultSection + endSection; } function drawChart() { var data = google.visualization.arrayToDataTable([ ['Test Status', 'Count'], ['Pass', getPassingRows('html').length], ['Fail', getFailingRows('html').length], ['NotRun', getNotRunRows('html').length] ]); var options = { title: 'Test Summary', colors: ['#96d86d','#f48592','#f0ad4e'] }; var chart = new google.visualization.PieChart(document.getElementById('piechart')); chart.draw(data, options); } </script> <style> tbody tr td.ellide { max-width: 200px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } div.vertical-align { display: flex; align-items: center; } .thumbnail img { height:50px; } .breakWrap { max-width: 100dvw; overflow-wrap: break-word; -ms-word-break: break-all; /* Be VERY careful with this, breaks normal words wh_erever */ word-break: break-all; /* Non standard for webkit */ /* ReSharper disable once InvalidValue */ word-break: break-word; -webkit-hyphens: auto; -moz-hyphens: auto; hyphens: auto; } .noWrap { max-width: 100dvw; white-space: nowrap; } </style> </head> <body class="w-100"> <div id="summaryContainer" class="container-fluid"> <div class="row vertical-align"> <div id="chartContainer" class="col-xs-8"> <div id="piechart" style="width: 600px; height: 250px;"></div> </div> <div id="buttonContainer" class="col-xs-4"> <div class="btn-group-vertical" role="group"> <button onclick="showOnlyPassing();" class="btn btn-success" type="button" title="click to show only passing tests"> PASSING <span class="badge totalTestsPassing">0</span> </button> <button onclick="showOnlyFailing();" class="btn btn-danger" type="button" title="click to show only failing tests"> FAILING <span class="badge totalTestsFailing">0</span> </button> <button onclick="showOnlyNotRun();" class="btn btn-warning" type="button" title="click to show only not run tests"> NOT RUN <span class="badge totalTestsNotRun">0</span> </button> <button onclick="showAll();" class="btn btn-primary" type="button" title="click to show all tests"> TOTAL <span class="badge totalTests">0</span> </button> </div> </div> </div> </div> <div id="groupContainer" class="container-fluid"> <div class="row"> <button type="button" class="btn btn-info mx-1" onclick="toggleAllPanels(true);">Expand All <i class="bi-plus" aria-hidden="true"></i></button><button type="button" class="btn btn-info mx-1" onclick="toggleAllPanels(false);">Collapse All <i class="bi-dash" aria-hidden="true"></i></button> </div> <div class="row"> <div class="m-1 w-100" id="resultsContainer"></div> </div> </div> </body> <script type="text/javascript"> google.load("visualization", "1", {packages:["corechart"]}); google.setOnLoadCallback(drawChart); initialise([{"description":"AftMochaReporter_C1234_provides_a_AftMochaTest_instance_for_use_in_test_control","tests":[{"testName":"AftMochaReporter [C1234] provides a AftMochaTest instance for use in test control","created":1716474325906,"resultId":"a76bdd3c-143c-4388-8a17-ea3750c8e459","status":"passed","metadata":{"durationMs":20,"buildName":"RUNNER_FVAZ566100","buildNumber":"20240523"},"logs":["pass - "]},{"testName":"AftMochaReporter [C1234] provides a AftMochaTest instance for use in test control","created":1716474325922,"resultId":"6f16f0d6-ac5a-42dd-a9de-23a83632ad6e","resultMessage":"expected to parse test ID from description","status":"passed","metadata":{"durationMs":36,"buildName":"RUNNER_FVAZ566100","buildNumber":"20240523"},"logs":["pass - expected to parse test ID from description"]},{"testName":"AftMochaReporter [C1234] provides a AftMochaTest instance for use in test control","testId":"C1234","created":1716474325937,"resultId":"dfb5b242-5099-4a3e-b309-a8c7b4c2639a","status":"passed","metadata":{"durationMs":47,"buildName":"RUNNER_FVAZ566100","buildNumber":"20240523"},"logs":["pass - C1234"]}]},{"description":"AftMochaReporter_C9999_allows_retry_to_be_wrapped_around_the_aftMochaTest","tests":[{"testName":"AftMochaReporter [C9999] allows retry to be wrapped around the aftMochaTest","testId":"C9999","created":1716474325957,"resultId":"14b4c7c1-bae2-49ca-b8ea-ddb66089eb99","resultMessage":"Error: [C9999] - expected '2' to equal '0'\n at AftMochaTest.<anonymous> (/home/runner/work/automated-functional-testing/automated-functional-testing/packages/aft-core/dist/src/verification/aft-test.js:250:27)\n at Generator.next (<anonymous>)\n at /home/runner/work/automated-functional-testing/automated-functional-testing/packages/aft-core/dist/src/verification/aft-test.js:8:71\n at new Promise (<anonymous>)\n at __awaiter (/home/runner/work/automated-functional-testing/automated-functional-testing/packages/aft-core/dist/src/verification/aft-test.js:4:12)\n at AftMochaTest.verify (/home/runner/work/automated-functional-testing/automated-functional-testing/packages/aft-core/dist/src/verification/aft-test.js:216:16)\n at Context.<anonymous> (/home/runner/work/automated-functional-testing/automated-functional-testing/packages/aft-mocha-reporter/dist/test/aft-mocha-reporter.spec.js:65:25)\n at Generator.next (<anonymous>)\n at /home/runner/work/automated-functional-testing/automated-functional-testing/packages/aft-mocha-reporter/dist/test/aft-mocha-reporter.spec.js:8:71\n at new Promise (<anonymous>)","status":"failed","metadata":{"attempt":1,"durationMs":7,"buildName":"RUNNER_FVAZ566100","buildNumber":"20240523"},"logs":["fail - C9999 - Error: [C9999] - expected '2' to equal '0'\n at AftMochaTest.<anonymous> (/home/runner/work/automated-functional-testing/automated-functional-testing/packages/aft-core/dist/src/verification/aft-test.js:250:27)\n at Generator.next (<anonymous>)\n at /home/runner/work/automated-functional-testing/automated-functional-testing/packages/aft-core/dist/src/verification/aft-test.js:8:71\n at new Promise (<anonymous>)\n at __awaiter (/home/runner/work/automated-functional-testing/automated-functional-testing/packages/aft-core/dist/src/verification/aft-test.js:4:12)\n at AftMochaTest.verify (/home/runner/work/automated-functional-testing/automated-functional-testing/packages/aft-core/dist/src/verification/aft-test.js:216:16)\n at Context.<anonymous> (/home/runner/work/automated-functional-testing/automated-functional-testing/packages/aft-mocha-reporter/dist/test/aft-mocha-reporter.spec.js:65:25)\n at Generator.next (<anonymous>)\n at /home/runner/work/automated-functional-testing/automated-functional-testing/packages/aft-mocha-reporter/dist/test/aft-mocha-reporter.spec.js:8:71\n at new Promise (<anonymous>)"]},{"testName":"AftMochaReporter [C9999] allows retry to be wrapped around the aftMochaTest","testId":"C9999","created":1716474325990,"resultId":"5db97a12-1cb6-4ca9-b1c1-4ddb35e45ecf","resultMessage":"Error: [C9999] - expected '2' to equal '1'\n at AftMochaTest.<anonymous> (/home/runner/work/automated-functional-testing/automated-functional-testing/packages/aft-core/dist/src/verification/aft-test.js:250:27)\n at Generator.next (<anonymous>)\n at /home/runner/work/automated-functional-testing/automated-functional-testing/packages/aft-core/dist/src/verification/aft-test.js:8:71\n at new Promise (<anonymous>)\n at __awaiter (/home/runner/work/automated-functional-testing/automated-functional-testing/packages/aft-core/dist/src/verification/aft-test.js:4:12)\n at AftMochaTest.verify (/home/runner/work/automated-functional-testing/automated-functional-testing/packages/aft-core/dist/src/verification/aft-test.js:216:16)\n at Context.<anonymous> (/home/runner/work/automated-functional-testing/automated-functional-testing/packages/aft-mocha-reporter/dist/test/aft-mocha-reporter.spec.js:65:25)\n at Generator.next (<anonymous>)\n at /home/runner/work/automated-functional-testing/automated-functional-testing/packages/aft-mocha-reporter/dist/test/aft-mocha-reporter.spec.js:8:71\n at new Promise (<anonymous>)","status":"failed","metadata":{"attempt":2,"durationMs":8,"buildName":"RUNNER_FVAZ566100","buildNumber":"20240523"},"logs":["fail - C9999 - Error: [C9999] - expected '2' to equal '1'\n at AftMochaTest.<anonymous> (/home/runner/work/automated-functional-testing/automated-functional-testing/packages/aft-core/dist/src/verification/aft-test.js:250:27)\n at Generator.next (<anonymous>)\n at /home/runner/work/automated-functional-testing/automated-functional-testing/packages/aft-core/dist/src/verification/aft-test.js:8:71\n at new Promise (<anonymous>)\n at __awaiter (/home/runner/work/automated-functional-testing/automated-functional-testing/packages/aft-core/dist/src/verification/aft-test.js:4:12)\n at AftMochaTest.verify (/home/runner/work/automated-functional-testing/automated-functional-testing/packages/aft-core/dist/src/verification/aft-test.js:216:16)\n at Context.<anonymous> (/home/runner/work/automated-functional-testing/automated-functional-testing/packages/aft-mocha-reporter/dist/test/aft-mocha-reporter.spec.js:65:25)\n at Generator.next (<anonymous>)\n at /home/runner/work/automated-functional-testing/automated-functional-testing/packages/aft-mocha-reporter/dist/test/aft-mocha-reporter.spec.js:8:71\n at new Promise (<anonymous>)"]},{"testName":"AftMochaReporter [C9999] allows retry to be wrapped around the aftMochaTest","testId":"C9999","created":1716474326028,"resultId":"794fb61f-1cb1-49e5-9894-6863e689cf54","resultMessage":"[C9999]","status":"passed","metadata":{"attempt":3,"durationMs":4,"buildName":"RUNNER_FVAZ566100","buildNumber":"20240523"},"logs":["pass - C9999 - [C9999]"]}]},{"description":"AftMochaReporter_passes_a_Mocha_Test_to_the_test_that_can_be_used_by_AftMochaTest","tests":[{"testName":"AftMochaReporter passes a Mocha Test to the test that can be used by AftMochaTest","created":1716474326156,"resultId":"2a87d9e2-01c4-4838-8415-34e5096aad7c","status":"passed","metadata":{"durationMs":0,"buildName":"RUNNER_FVAZ566100","buildNumber":"20240523"},"logs":["pass - "]}]},{"description":"AftMochaReporter_can_skip_a_test_during_execution","tests":[{"testName":"AftMochaReporter can skip a test during execution","created":1716474326157,"resultId":"e6c26303-881a-4570-94aa-7d373bf7c625","resultMessage":"test skipped","status":"skipped","metadata":{"durationMs":0,"buildName":"RUNNER_FVAZ566100","buildNumber":"20240523"},"logs":["warn - test skipped"]}]},{"description":"AftMochaReporter_still_works_if_using_an_arrow_function","tests":[{"testName":"AftMochaReporter still works if using an arrow function","created":1716474326157,"resultId":"83995dfb-456b-491b-9d37-699971f9fc37","status":"passed","metadata":{"durationMs":0,"buildName":"RUNNER_FVAZ566100","buildNumber":"20240523"},"logs":["pass - "]}]}]); </script> </html>