UNPKG

protractor-html-reporter-extended

Version:

Generates HTML report with pie charts based on a xml file

274 lines (250 loc) 12.1 kB
const xmlDocument = require('xmldoc'); const fileSystem = require('fs'); const filePath = require('path'); const fsextra = require('fs-extra'); var _ = require('lodash'); let csvRecords = []; let timeStampArr = []; let csvRecordsPass = []; let csvRecordsFail = []; let csvRecordsSkipped = []; let tcPassed = 0; let tcFailed = 0; let tcSkipped = 0; let stepsPassed = 0; let stepsFailed = 0; let stepsSkipped = 0; function readFile(filename) { return fileSystem.readFileSync(filename, 'utf-8'); } function getPath(filename, dir) { if (dir) { fsextra.ensureDirSync(dir); return filePath.join(dir, filename); } return filePath.join(__dirname, filename); } function getTime(time) { const toMMSSss = (secs) => { var secN = parseInt(secs, 10); var minutes = Math.floor(secN / 60) % 60; var seconds = secN % 60; if (minutes < 10) { minutes = '0' + minutes; } if (seconds < 10) { seconds = '0' + seconds; } return minutes + ' mins ' + seconds + ' secs'; }; return toMMSSss(time); } function calculateRunTime(timeArr) { var min = timeArr.sort((a, b) => a - b)[0], max = timeArr.slice(-1)[0]; var elapsedTime = max - min; elapsedTime /= 1000; var elapsedTimeSeconds = Number(elapsedTime); var h = Math.floor(elapsedTimeSeconds / 3600); var m = Math.floor(elapsedTimeSeconds % 3600 / 60); var s = Math.floor(elapsedTimeSeconds % 3600 % 60); var hDisplay = h > 0 ? h + (h == 1 ? " hr, " : " hrs") : ""; var mDisplay = m > 0 ? m + (m == 1 ? " min, " : " mins, ") : ""; var sDisplay = s > 0 ? s + (s == 1 ? " sec" : " secs") : ""; return hDisplay + mDisplay + sDisplay; } var HTMLReport = function () { this.from = function (xmlfile, testConfig) { try { let xmlData = fileSystem.readFileSync(xmlfile, 'utf8'); let testResultXml = new xmlDocument.XmlDocument(xmlData); let testSuites = testResultXml.childrenNamed('testsuite'); let fTestSuites = testSuites.filter(function (el) { return el.children.length > 0; }); let fDisabledSuites = fTestSuites.filter(function (el) { return el.attr.tests === el.attr.disabled; }); let fFailedSuites = fTestSuites.filter(function (el) { return el.attr.failures > 0 || el.attr.errors > 0; }); let fPassedSuites = fTestSuites.filter(x => fDisabledSuites.indexOf(x) < 0).filter(y => fFailedSuites.indexOf(y) < 0); // Display Over all summary in Console console.log('********************** Test Results Summary ************************'); console.log(' Total Passed: ' + fPassedSuites.length); console.log(' Total Failed: ' + fFailedSuites.length); console.log(' Total Skipped: ' + fDisabledSuites.length); console.log('********************************************************************'); // Parse the details test case and test step wise and assign necessary status and color for (let i = 0; i < fTestSuites.length; i++) { let className = fTestSuites[i].attr.name.replace(/\n/g, ';'); let moduleName = className.split(',')[0].split('.')[0].replace(/\d+/g, '') .replace(/_/g, ' ').replace('MBIL-', '').replace('@', '').replace(':', '').trim(); let testResult; let styleColor; let cssStyle; let timeStamp = fTestSuites[i].attr.timestamp; timeStampArr.push(new Date(timeStamp)); let time = fTestSuites[i].attr.time; if (fTestSuites[i].attr.tests === fTestSuites[i].attr.disabled) { testResult = 'Skipped'; styleColor = 'grey'; } else if (fTestSuites[i].attr.failures > 0 || fTestSuites[i].attr.errors > 0) { testResult = 'Failed'; styleColor = 'red'; } else { testResult = 'Passed'; styleColor = 'green'; } let stepDetails = ''; let stepsCnt = fTestSuites[i].children.length; let testSteps = []; let errorMessages = []; let screenshots = []; let stepsTimes = []; let tcPassedStepsCnt = 0; let tcFailedStepsCnt = 0; let tcSkippedStepsCnt = 0; for (let j = 0; j < stepsCnt; j++) { let step = fTestSuites[i].children[j].attr.name.replace('/"/g', '\''); stepsTimes.push(fTestSuites[i].children[j].attr.time); let firstChild = fTestSuites[i].children[j].firstChild; if (firstChild == null) { stepsPassed += 1; tcPassedStepsCnt += 1; styleColor = 'green'; cssStyle = '<span class="label label-success"><i class="glyphicon glyphicon-ok" style="line-height: 2"></i></span> &nbsp;'; } else if (firstChild.name === 'failure') { stepsFailed += 1; tcFailedStepsCnt += 1; styleColor = 'red'; cssStyle = '<span class="label label-danger"><i class="glyphicon glyphicon-remove" style="line-height: 2"></i></span>&nbsp;'; } else if (firstChild.name === 'skipped') { stepsSkipped += 1; tcSkippedStepsCnt += 1; styleColor = 'grey'; cssStyle = '<span class="label label-default"><i class="glyphicon glyphicon-off" style="line-height: 2"></i></span>&nbsp;'; } if (testResult === 'Failed') { if (firstChild != null) { errorMessages.push(firstChild.attr.message); var splitChar = fTestSuites[i].attr.name.indexOf('.') < fTestSuites[i].attr.name.indexOf(' ') ? '.' : ' '; const [screenshotPrefix] = fTestSuites[i].attr.name.split(splitChar); const screenshotSuffix = fTestSuites[i].children[j].attr.name.replace(/\W/g, '').substring(0, 15); screenshots.push(screenshotPrefix + screenshotSuffix + '.png'); } else { errorMessages.push(''); screenshots.push(''); } } stepDetails = stepDetails + '<li style="color:' + styleColor + '">' + cssStyle + step + '</li>'; testSteps.push('<li style="color:' + styleColor + '">' + cssStyle + step + '</li>'); } stepDetails = stepDetails.replace(/\n/g, ';'); let csvRowData = { tcId: i + 1, moduleName: moduleName, className: className, testResult: testResult, timeStamp: timeStamp, time: time, stepCnt: stepsCnt, tcPassedStepsCnt: tcPassedStepsCnt, tcFailedStepsCnt: tcFailedStepsCnt, tcSkippedStepsCnt: tcSkippedStepsCnt, stepDetails: stepDetails, errorMessages: errorMessages, screenshots: screenshots, testSteps: testSteps, stepsTimes: stepsTimes }; csvRecords.push(csvRowData); if (testResult === 'Passed') csvRecordsPass.push(csvRowData); else if (testResult === 'Failed') csvRecordsFail.push(csvRowData); else if (testResult === 'Skipped') csvRecordsSkipped.push(csvRowData); } // CSV Report Generation let allTestsData = []; allTestsData.push('"TC ID"@"MODULE NAME"@"CLASS NAME"@"TEST RESULT"@"STEPS COUNT"@"STEPS DETAILS"'); for (let i = 0; i < csvRecords.length; i++) { let row = '"' + csvRecords[i].tcId + '"@"' + csvRecords[i].moduleName + '"@"' + csvRecords[i].className + '"@"' + csvRecords[i].testResult + '"@"' + csvRecords[i].stepCnt + '"@"' + csvRecords[i].stepDetails + '"'; allTestsData.push(row); } // HTML Report Generation var moduleLevelMap = {}; var overallTime = 0; for (var i = 0; i < csvRecords.length; i++) { var key = csvRecords[i].moduleName; var value = { passCount: 0, failCount: 0, skipCount: 0, time: 0, timeInHMS: '' }; if (moduleLevelMap[key] != null) { value = moduleLevelMap[key]; value.time += Number(csvRecords[i].time); if (csvRecords[i].testResult === 'Passed') { value.passCount += 1; tcPassed += 1; } else if (csvRecords[i].testResult === 'Failed') { value.failCount += 1; tcFailed += 1; } else if (csvRecords[i].testResult === 'Skipped') { value.skipCount += 1; tcSkipped += 1; } value.timeInHMS = getTime(value.time); moduleLevelMap[key] = value; } else { value.time = Number(csvRecords[i].time); if (csvRecords[i].testResult === 'Passed') { value.passCount = 1; tcPassed += 1; } else if (csvRecords[i].testResult === 'Failed') { value.failCount = 1; tcFailed += 1; } else if (csvRecords[i].testResult === 'Skipped') { value.skipCount = 1; tcSkipped += 1; } value.timeInHMS = getTime(value.time); moduleLevelMap[key] = value; } } overallTime = calculateRunTime(timeStampArr); let filePath = ''; if (testConfig.outputFilename === undefined) { filePath = getPath('/Automation-test-report.html', testConfig['outputPath'] || './'); } else { filePath = getPath('/' + testConfig['outputFilename'] + '.html', testConfig['outputPath'] || './'); } // Write the HTML report file fileSystem.writeFileSync( filePath, _.template(readFile(getPath('summary.tmpl')))({ projectName: testConfig.projectName, browser: testConfig.platform + ' ' + testConfig.browserVersion, reportDate: new Date(), reportDirectory: filePath, tcPassed: tcPassed, tcFailed: tcFailed, tcSkipped: tcSkipped, stepsPassed: stepsPassed, stepsFailed: stepsFailed, stepsSkipped: stepsSkipped, moduleLevelMap: moduleLevelMap, csvRecordsPass: csvRecordsPass, csvRecordsFail: csvRecordsFail, csvRecordsSkipped: csvRecordsSkipped, overallTime: overallTime, piechart: readFile(getPath('piechart.js')) }) ); } catch (ex) { console.log('Error in generating the HTML report. Stack trace : ' + ex); } } }; module.exports = HTMLReport;