UNPKG

aft-jest-reporter

Version:

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

365 lines (339 loc) 24 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":"AftJestReporter_can_create_an_AftJestTest_instance","tests":[{"testName":"AftJestReporter can create an AftJestTest instance","created":1716474310697,"resultId":"5cdf7753-cacf-42ae-aa56-949713e84e4c","status":"passed","metadata":{"durationMs":0,"buildName":"RUNNER_FVAZ566100","buildNumber":"20240523"},"logs":["pass - "]}]},{"description":"AftJestReporter_can_check_if_test_should_be_run_C1234","tests":[{"testName":"AftJestReporter can check if test should be run [C1234]","testId":"C1234","created":1716474310718,"resultId":"ed5fcd55-2800-4da1-bd1c-7d69d7cd2968","status":"passed","metadata":{"durationMs":0,"buildName":"RUNNER_FVAZ566100","buildNumber":"20240523"},"logs":["pass - C1234"]}]},{"description":"AftJestReporter_can_skip_test_C4567_if_should_not_be_run","tests":[{"testName":"AftJestReporter can skip test [C4567] if should not be run","testId":"C4567","created":1716474310738,"resultId":"4345f8bf-820b-4ea0-94a1-9ef93111c758","resultMessage":"fake","status":"skipped","metadata":{"durationMs":0,"buildName":"RUNNER_FVAZ566100","buildNumber":"20240523"},"logs":["warn - C4567 - fake"]}]},{"description":"AftJestReporter_C1234_provides_a_AftJestTest_instance_for_use_in_test_control","tests":[{"testName":"AftJestReporter [C1234] provides a AftJestTest instance for use in test control","created":1716474310793,"resultId":"d1148e5f-cb04-45eb-a177-bb88e4450bae","status":"passed","metadata":{"durationMs":17,"buildName":"RUNNER_FVAZ566100","buildNumber":"20240523"},"logs":["pass - "]},{"testName":"AftJestReporter [C1234] provides a AftJestTest instance for use in test control","created":1716474310827,"resultId":"b3795968-5a5d-401b-9bb7-c467aeb3bbd7","resultMessage":"expected to parse test ID from description","status":"passed","metadata":{"durationMs":51,"buildName":"RUNNER_FVAZ566100","buildNumber":"20240523"},"logs":["pass - expected to parse test ID from description"]},{"testName":"AftJestReporter [C1234] provides a AftJestTest instance for use in test control","testId":"C1234","created":1716474310850,"resultId":"471d6710-503a-4c53-b06f-643948fc7d76","status":"passed","metadata":{"durationMs":66,"buildName":"RUNNER_FVAZ566100","buildNumber":"20240523"},"logs":["pass - C1234"]}]},{"description":"AftJestReporter_C9999_allows_retry_to_be_wrapped_around_the_aftJestTest","tests":[{"testName":"AftJestReporter [C9999] allows retry to be wrapped around the aftJestTest","testId":"C9999","created":1716474310880,"resultId":"9cefb3e0-96ad-4e27-bd00-1154c29d39ca","resultMessage":"Error: [C9999] - expected '2' to equal '0'\n at AftJestTest.<anonymous> (/home/runner/work/automated-functional-testing/automated-functional-testing/packages/aft-core/src/verification/aft-test.ts:314:23)\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:27:67\n at new Promise (<anonymous>)\n at Object.<anonymous>.__awaiter (/home/runner/work/automated-functional-testing/automated-functional-testing/packages/aft-core/dist/src/verification/aft-test.js:9:10)\n at AftJestTest.verify (/home/runner/work/automated-functional-testing/automated-functional-testing/packages/aft-core/dist/src/verification/aft-test.js:237:12)\n at verify (/home/runner/work/automated-functional-testing/automated-functional-testing/packages/aft-jest-reporter/test/aft-jest-reporter.spec.ts:45:21)\n at Generator.next (<anonymous>)\n at /home/runner/work/automated-functional-testing/automated-functional-testing/packages/aft-jest-reporter/dist/test/aft-jest-reporter.spec.js:27:67\n at new Promise (<anonymous>)\n at Object.<anonymous>.__awaiter (/home/runner/work/automated-functional-testing/automated-functional-testing/packages/aft-jest-reporter/dist/test/aft-jest-reporter.spec.js:9:10)\n at AftJestTest.__awaiter [as _testFunction] (/home/runner/work/automated-functional-testing/automated-functional-testing/packages/aft-jest-reporter/test/aft-jest-reporter.spec.ts:44:93)\n at AftJestTest._testFunction (/home/runner/work/automated-functional-testing/automated-functional-testing/packages/aft-core/src/verification/aft-test.ts:385:28)\n at Generator.next (<anonymous>)\n at fulfilled (/home/runner/work/automated-functional-testing/automated-functional-testing/packages/aft-core/dist/src/verification/aft-test.js:12:24)\n at processTicksAndRejections (node:internal/process/task_queues:95:5)","status":"failed","metadata":{"attempt":1,"durationMs":12,"buildName":"RUNNER_FVAZ566100","buildNumber":"20240523"},"logs":["fail - C9999 - Error: [C9999] - expected '2' to equal '0'\n at AftJestTest.<anonymous> (/home/runner/work/automated-functional-testing/automated-functional-testing/packages/aft-core/src/verification/aft-test.ts:314:23)\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:27:67\n at new Promise (<anonymous>)\n at Object.<anonymous>.__awaiter (/home/runner/work/automated-functional-testing/automated-functional-testing/packages/aft-core/dist/src/verification/aft-test.js:9:10)\n at AftJestTest.verify (/home/runner/work/automated-functional-testing/automated-functional-testing/packages/aft-core/dist/src/verification/aft-test.js:237:12)\n at verify (/home/runner/work/automated-functional-testing/automated-functional-testing/packages/aft-jest-reporter/test/aft-jest-reporter.spec.ts:45:21)\n at Generator.next (<anonymous>)\n at /home/runner/work/automated-functional-testing/automated-functional-testing/packages/aft-jest-reporter/dist/test/aft-jest-reporter.spec.js:27:67\n at new Promise (<anonymous>)\n at Object.<anonymous>.__awaiter (/home/runner/work/automated-functional-testing/automated-functional-testing/packages/aft-jest-reporter/dist/test/aft-jest-reporter.spec.js:9:10)\n at AftJestTest.__awaiter [as _testFunction] (/home/runner/work/automated-functional-testing/automated-functional-testing/packages/aft-jest-reporter/test/aft-jest-reporter.spec.ts:44:93)\n at AftJestTest._testFunction (/home/runner/work/automated-functional-testing/automated-functional-testing/packages/aft-core/src/verification/aft-test.ts:385:28)\n at Generator.next (<anonymous>)\n at fulfilled (/home/runner/work/automated-functional-testing/automated-functional-testing/packages/aft-core/dist/src/verification/aft-test.js:12:24)\n at processTicksAndRejections (node:internal/process/task_queues:95:5)"]},{"testName":"AftJestReporter [C9999] allows retry to be wrapped around the aftJestTest","testId":"C9999","created":1716474310935,"resultId":"441c12f9-d5c9-4f94-a0ea-a133e196b280","resultMessage":"Error: [C9999] - expected '2' to equal '1'\n at AftJestTest.<anonymous> (/home/runner/work/automated-functional-testing/automated-functional-testing/packages/aft-core/src/verification/aft-test.ts:314:23)\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:27:67\n at new Promise (<anonymous>)\n at Object.<anonymous>.__awaiter (/home/runner/work/automated-functional-testing/automated-functional-testing/packages/aft-core/dist/src/verification/aft-test.js:9:10)\n at AftJestTest.verify (/home/runner/work/automated-functional-testing/automated-functional-testing/packages/aft-core/dist/src/verification/aft-test.js:237:12)\n at verify (/home/runner/work/automated-functional-testing/automated-functional-testing/packages/aft-jest-reporter/test/aft-jest-reporter.spec.ts:45:21)\n at Generator.next (<anonymous>)\n at /home/runner/work/automated-functional-testing/automated-functional-testing/packages/aft-jest-reporter/dist/test/aft-jest-reporter.spec.js:27:67\n at new Promise (<anonymous>)\n at Object.<anonymous>.__awaiter (/home/runner/work/automated-functional-testing/automated-functional-testing/packages/aft-jest-reporter/dist/test/aft-jest-reporter.spec.js:9:10)\n at AftJestTest.__awaiter [as _testFunction] (/home/runner/work/automated-functional-testing/automated-functional-testing/packages/aft-jest-reporter/test/aft-jest-reporter.spec.ts:44:93)\n at AftJestTest._testFunction (/home/runner/work/automated-functional-testing/automated-functional-testing/packages/aft-core/src/verification/aft-test.ts:385:28)\n at Generator.next (<anonymous>)\n at fulfilled (/home/runner/work/automated-functional-testing/automated-functional-testing/packages/aft-core/dist/src/verification/aft-test.js:12:24)","status":"failed","metadata":{"attempt":2,"durationMs":24,"buildName":"RUNNER_FVAZ566100","buildNumber":"20240523"},"logs":["fail - C9999 - Error: [C9999] - expected '2' to equal '1'\n at AftJestTest.<anonymous> (/home/runner/work/automated-functional-testing/automated-functional-testing/packages/aft-core/src/verification/aft-test.ts:314:23)\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:27:67\n at new Promise (<anonymous>)\n at Object.<anonymous>.__awaiter (/home/runner/work/automated-functional-testing/automated-functional-testing/packages/aft-core/dist/src/verification/aft-test.js:9:10)\n at AftJestTest.verify (/home/runner/work/automated-functional-testing/automated-functional-testing/packages/aft-core/dist/src/verification/aft-test.js:237:12)\n at verify (/home/runner/work/automated-functional-testing/automated-functional-testing/packages/aft-jest-reporter/test/aft-jest-reporter.spec.ts:45:21)\n at Generator.next (<anonymous>)\n at /home/runner/work/automated-functional-testing/automated-functional-testing/packages/aft-jest-reporter/dist/test/aft-jest-reporter.spec.js:27:67\n at new Promise (<anonymous>)\n at Object.<anonymous>.__awaiter (/home/runner/work/automated-functional-testing/automated-functional-testing/packages/aft-jest-reporter/dist/test/aft-jest-reporter.spec.js:9:10)\n at AftJestTest.__awaiter [as _testFunction] (/home/runner/work/automated-functional-testing/automated-functional-testing/packages/aft-jest-reporter/test/aft-jest-reporter.spec.ts:44:93)\n at AftJestTest._testFunction (/home/runner/work/automated-functional-testing/automated-functional-testing/packages/aft-core/src/verification/aft-test.ts:385:28)\n at Generator.next (<anonymous>)\n at fulfilled (/home/runner/work/automated-functional-testing/automated-functional-testing/packages/aft-core/dist/src/verification/aft-test.js:12:24)"]},{"testName":"AftJestReporter [C9999] allows retry to be wrapped around the aftJestTest","testId":"C9999","created":1716474310978,"resultId":"cfc28eb5-b543-4683-a7ce-1a9f0ce43892","resultMessage":"[C9999]","status":"passed","metadata":{"attempt":3,"durationMs":6,"buildName":"RUNNER_FVAZ566100","buildNumber":"20240523"},"logs":["pass - C9999 - [C9999]"]}]}]); </script> </html>