cucumber-html-reporter
Advanced tools
Comparing version 5.5.1 to 6.0.0
@@ -0,1 +1,6 @@ | ||
### 6.0.0 (Mar-02-2023) | ||
* upgraded to be compatible with cucumber v8.9.1 | ||
* upgraded all other dependencies to their latest versions | ||
### 5.1.0 (Dec-15-2019) | ||
@@ -2,0 +7,0 @@ |
@@ -27,10 +27,10 @@ /*-----------------------------------------------------------------------------------------*\ | ||
var reporter = require('./lib/reporter'); | ||
const reporter = require('./lib/reporter'); | ||
function generateReport(options, callback) { | ||
return reporter.generate(options, callback); | ||
return reporter.generate(options, callback); | ||
} | ||
module.exports = { | ||
generate: generateReport | ||
generate: generateReport, | ||
}; |
@@ -1,6 +0,4 @@ | ||
'use strict'; | ||
// const _ = require('lodash'); | ||
const path = require('path'); | ||
var _ = require('lodash'); | ||
var path = require('path'); | ||
/** | ||
@@ -14,37 +12,42 @@ * hierarchyReporter.js | ||
/** | ||
* Review each feature in the suite, and find the common baseDir that is shared by all of them. | ||
* We will later use this as the basis from which to construct the feature hierarchy-- | ||
* the basedir prefix needs to be removed since it is not important. | ||
*/ | ||
var getBaseDir = function (suite) { | ||
var baseDir = []; | ||
module.exports = { | ||
/** | ||
* Review each feature in the suite, and find the common baseDir that is shared by all of them. | ||
* We will later use this as the basis from which to construct the feature hierarchy-- | ||
* the basedir prefix needs to be removed since it is not important. | ||
*/ | ||
getBaseDir: function (suite) { | ||
let baseDir = []; | ||
suite.features.forEach(function (feature) { | ||
var uriParts = feature.uri.split(path.sep); | ||
if (!baseDir.length) { | ||
baseDir = uriParts; | ||
} else { | ||
for (var i = uriParts.length; i > 0; i--) { | ||
if ((baseDir.length > i) && (baseDir[i] !== uriParts[i])) { | ||
baseDir.length = i; | ||
} | ||
} | ||
} | ||
baseDir = feature.uri.split(path.sep); | ||
// let uriParts = feature.uri.split(path.sep); | ||
// if (!baseDir?.length) { | ||
// baseDir = uriParts; | ||
// // console.log('this is the result 1 ===> ', suite); | ||
// } else { | ||
// for (let i = uriParts.length; i > 0; i--) { | ||
// // for (let i = 0, l = uriParts.length; i < l; i++) { | ||
// if ((baseDir.length > i) && (baseDir[i] !== uriParts[i])) { | ||
// baseDir.length = i; | ||
// // console.log('this is the result ===> ', baseDir.length = i) | ||
// } | ||
// } | ||
// } | ||
}); | ||
return baseDir.join(path.sep); | ||
}; | ||
}, | ||
/** | ||
* Given a feature, remove the basedir prefix and the feature name suffix from its URI | ||
* and return the remaining folders (if any) in an array. If the feature is at the top-level, | ||
* it will return [] | ||
* For example: | ||
* @param featureUri: '/home/cstrong/myproj/test/features/authentication/login/guestLogin.feature' | ||
* @param baseDir: '/home/cstrong/myproj/test/features' | ||
* @returns [ 'authentication', 'login' ] | ||
*/ | ||
var getFeatureHierarchy = function (featureUri, baseDir) { | ||
var noBaseDir = featureUri.slice(baseDir.length + 1); | ||
var noBadChars = noBaseDir.split('=').join('_'); | ||
var featureDirs = noBadChars.split(path.sep); | ||
/** | ||
* Given a feature, remove the basedir prefix and the feature name suffix from its URI | ||
* and return the remaining folders (if any) in an array. If the feature is at the top-level, | ||
* it will return [] | ||
* For example: | ||
* @param featureUri: '/home/cstrong/myproj/test/features/authentication/login/guestLogin.feature' | ||
* @param baseDir: '/home/cstrong/myproj/test/features' | ||
* @returns [ 'authentication', 'login' ] | ||
*/ | ||
getFeatureHierarchy: function (featureUri, baseDir) { | ||
let noBaseDir = featureUri.slice(baseDir.length + 1); | ||
let noBadChars = noBaseDir.split('=').join('_'); | ||
let featureDirs = noBadChars.split(path.sep); | ||
@@ -55,15 +58,14 @@ // remove the feature name itself | ||
return featureDirs; | ||
}; | ||
}, | ||
/** | ||
* Given the top-level suite and the hierarchy to build, recursively create the hierarchy | ||
* of sub-suites (if needed) and return the lowest level sub-suite. | ||
* | ||
* @param suite | ||
* @param hierarchy e.g. [ 'authentication', 'login' ] | ||
* @returns suite object or null if there is no hierarchy | ||
*/ | ||
var findOrCreateSubSuite = function (suite, hierarchy) { | ||
/* | ||
/** | ||
* Given the top-level suite and the hierarchy to build, recursively create the hierarchy | ||
* of sub-suites (if needed) and return the lowest level sub-suite. | ||
* | ||
* @param suite | ||
* @param hierarchy e.g. [ 'authentication', 'login' ] | ||
* @returns suite object or null if there is no hierarchy | ||
*/ | ||
findOrCreateSubSuite: function (suite, hierarchy) { | ||
/** | ||
Create a new sub-suite correspond to a folder name. The suite will contain the features that are defined | ||
@@ -75,58 +77,52 @@ within that folder, and/or sub-suites corresponding to any sub-folders that themselves may contain features. | ||
function newSubSuite(name, parent) { | ||
return { | ||
name: { | ||
plain: name, | ||
sanitized: name | ||
}, | ||
passed: 0, | ||
failed: 0, | ||
ambiguous: 0, | ||
skipped: 0, | ||
parent: parent, | ||
features: [], | ||
suites: [] | ||
}; | ||
return { | ||
name: { | ||
plain: name, | ||
sanitized: name, | ||
}, | ||
passed: 0, | ||
failed: 0, | ||
ambiguous: 0, | ||
skipped: 0, | ||
parent: parent, | ||
features: [], | ||
suites: [], | ||
}; | ||
} | ||
if (hierarchy.length < 1) { | ||
return null; | ||
return null; | ||
} | ||
var subSuiteName = hierarchy[0]; | ||
let subSuiteName = hierarchy[0]; | ||
if (!suite.suites) { | ||
suite.suites = []; | ||
suite.suites = []; | ||
} | ||
var subSuite = suite.suites.find(function (s) { | ||
return s.name.plain === subSuiteName; | ||
let subSuite = suite.suites.find(function (s) { | ||
return s.name.plain === subSuiteName; | ||
}); | ||
if (!subSuite) { | ||
subSuite = newSubSuite(subSuiteName, suite); | ||
suite.suites.push(subSuite); | ||
let subSuite = newSubSuite(subSuiteName, suite); | ||
suite.suites.push(subSuite); | ||
} | ||
if (hierarchy.length === 1) { | ||
return subSuite; | ||
return subSuite; | ||
} else { | ||
return findOrCreateSubSuite(subSuite, hierarchy.slice(1)); | ||
return this.findOrCreateSubSuite(subSuite, hierarchy.slice(1)); | ||
} | ||
}; | ||
}, | ||
/** | ||
* Increment stat such as failed, ambiguous or passed for the current suite | ||
* and follow the parent attribute (if any) recursively up the tree, incrementing all. | ||
* That way the top level suite accumulates all results from child and grandchild suites | ||
* | ||
* @param subSuite | ||
* @param attrName ('passed', 'failed', 'ambiguous', or 'skipped') | ||
*/ | ||
var recursivelyIncrementStat = function (subSuite, attrName) { | ||
/** | ||
* Increment stat such as failed, ambiguous or passed for the current suite | ||
* and follow the parent attribute (if any) recursively up the tree, incrementing all. | ||
* That way the top level suite accumulates all results from child and grandchild suites | ||
* | ||
* @param subSuite | ||
* @param attrName ('passed', 'failed', 'ambiguous', or 'skipped') | ||
*/ | ||
recursivelyIncrementStat: function (subSuite, attrName) { | ||
subSuite[attrName] = subSuite[attrName] + 1; | ||
if (subSuite.parent) { | ||
recursivelyIncrementStat(subSuite.parent, attrName); | ||
this.recursivelyIncrementStat(subSuite.parent, attrName); | ||
} | ||
}, | ||
}; | ||
module.exports = { | ||
getBaseDir: getBaseDir, | ||
getFeatureHierarchy: getFeatureHierarchy, | ||
findOrCreateSubSuite: findOrCreateSubSuite, | ||
recursivelyIncrementStat: recursivelyIncrementStat | ||
}; |
@@ -1,10 +0,11 @@ | ||
'use strict'; | ||
// 'use strict'; | ||
const jsonFile = require('jsonfile'); | ||
const find = require('find'); | ||
const path = require('path'); | ||
var jsonFile = require('jsonfile'); | ||
var find = require('find'); | ||
const collectJSONS = function (options) { | ||
const jsonOutput = []; | ||
const featureCollection = new Map(); | ||
let files; | ||
var collectJSONS = function (options) { | ||
var jsonOutput = []; | ||
var files; | ||
try { | ||
@@ -19,6 +20,26 @@ files = find.fileSync(/\.json$/, options.jsonDir); | ||
function mergeJSONS(file) { | ||
var cucumberJson = jsonFile.readFileSync(file); | ||
let cucumberJson = jsonFile.readFileSync(file); | ||
function trackScenarioRetries(scenarios) { | ||
// HACK: Very brittle. Will track if cucumber json file name is not in format command.1.1.log.json | ||
let basename = path.basename(file, ".log.json"); | ||
let retried = basename.split(".")[2] ?? "0"; | ||
retried = parseInt(retried); | ||
scenarios.forEach( (scenario) => { | ||
scenario["retried"] = retried; | ||
}); | ||
} | ||
function collect(json) { | ||
jsonOutput.push(json); | ||
trackScenarioRetries(json["elements"] ?? []); | ||
let featureKey = json["uri"] ?? "Feature: URI Not Present"; | ||
if (featureCollection.has(featureKey)) { | ||
const featureItem = featureCollection.get(featureKey); | ||
const elements = featureItem["elements"] ?? []; | ||
elements.push(...(json["elements"] ?? [])); | ||
featureItem["elements"] = elements; | ||
featureCollection.set(featureKey, featureItem); | ||
} else { | ||
featureCollection.set(featureKey, json); | ||
} | ||
} | ||
@@ -42,3 +63,3 @@ | ||
if (typeof featureItem["elements"][0]["steps"][0]["output"][0] !== 'undefined') { | ||
var timestamp = featureItem["elements"][0]["steps"][0]["output"][0]; | ||
const timestamp = featureItem["elements"][0]["steps"][0]["output"][0]; | ||
featureItem["timestamp"] = Date.parse(timestamp.match(/[0-9]{4}-.+:[0-9]{2}/g)); | ||
@@ -52,2 +73,6 @@ } | ||
featureCollection.forEach( (feature, _) => { | ||
jsonOutput.push(feature); | ||
}); | ||
jsonOutput.map(addTimestamp); | ||
@@ -54,0 +79,0 @@ if (!jsonOutput.filter(f => !f.timestamp).length) { |
@@ -1,549 +0,607 @@ | ||
'use strict'; | ||
var jsonFile = require('jsonfile'); | ||
var _ = require('lodash'); | ||
var fs = require('fs-extra'); | ||
var path = require('path'); | ||
var jsonDir = require('./jsonDir'); | ||
var open = require('open'); | ||
// 'use strict'; | ||
const chalk = require('chalk'); | ||
const jsonFile = require('jsonfile'); | ||
const _ = require('lodash'); | ||
const fs = require('fs-extra'); | ||
const path = require('path'); | ||
const jsonDir = require('./jsonDir'); | ||
const emoji = require('node-emoji'); | ||
var searchFileUp = require('./searchFileUp'); | ||
var hierarchyReporter = require('./hierarchyReporter'); | ||
const guid = require('uuid/v4'); | ||
const isBase64 = (data) => /^(?:[A-Z0-9+\/]{4})*(?:[A-Z0-9+\/]{2}==|[A-Z0-9+\/]{3}=|[A-Z0-9+\/]{4})$/i.test(data); | ||
const searchFileUp = require('./searchFileUp'); | ||
const hierarchyReporter = require('./hierarchyReporter'); | ||
const guid = require('uuid').v4; | ||
const open = require('open'); | ||
let isBase64 = (data) => /^(?:[A-Z0-9+/]{4})*(?:[A-Z0-9+/]{2}==|[A-Z0-9+/]{3}=|[A-Z0-9+/]{4})$/i.test(data); | ||
var generateReport = function (options) { | ||
var featureOutput = jsonFile.readFileSync(options.jsonFile); | ||
var packageJsonPath = searchFileUp('package.json'); | ||
var packageJson = {}; | ||
try { | ||
packageJson = packageJsonPath && jsonFile.readFileSync(packageJsonPath, 'utf8'); | ||
} catch (err) { | ||
console.warn('No package.json file found in: ' + packageJsonPath + ', using default name and version.'); | ||
packageJson.name = 'default'; | ||
packageJson.version = '0.0.0'; | ||
} | ||
let stageRerunCount = getStageReRunCount(); | ||
var sanitize = function (name, find) { | ||
var unsafeCharacters = find || /[/\|:"*?<>]/g; | ||
if (name !== undefined) { | ||
name = name.trim().replace(unsafeCharacters, '_'); | ||
} | ||
return name; | ||
}; | ||
const generateReport = function (options) { | ||
let featureOutput = jsonFile.readFileSync(options.jsonFile); | ||
let packageJsonPath = searchFileUp('package.json'); | ||
let packageJson = {}; | ||
try { | ||
packageJson = packageJsonPath && jsonFile.readFileSync(packageJsonPath, 'utf8'); | ||
} catch (err) { | ||
console.warn('No package.json file found in: ' + packageJsonPath + ', using default name and version.'); | ||
packageJson.name = 'default'; | ||
packageJson.version = '0.0.0'; | ||
} | ||
featureOutput.summary = { | ||
isFailed: false, | ||
passed: 0, | ||
failed: 0, | ||
ambiguous: 0, | ||
skipped: 0, | ||
notdefined: 0, | ||
pending: 0 | ||
}; | ||
const sanitize = function (name, find) { | ||
const unsafeCharacters = find || /[/|:"*?<>]/g; | ||
if (name !== undefined) { | ||
name = name.trim().replace(unsafeCharacters, '_'); | ||
} | ||
return name; | ||
}; | ||
var result = { | ||
status: { | ||
passed: 'passed', | ||
failed: 'failed', | ||
skipped: 'skipped', | ||
pending: 'pending', | ||
undefined: 'undefined', | ||
ambiguous: 'ambiguous' | ||
} | ||
}; | ||
featureOutput.summary = { | ||
isFailed: false, | ||
passed: 0, | ||
failed: 0, | ||
ambiguous: 0, | ||
skipped: 0, | ||
notdefined: 0, | ||
pending: 0, | ||
}; | ||
var suite = { | ||
name: { | ||
plain: options.name || packageJson && packageJson.name, | ||
sanitized: sanitize(options.name || packageJson && packageJson.name, /[^a-z|0-9]/g) | ||
}, | ||
brandTitle: options.brandTitle, | ||
version: packageJson && packageJson.version, | ||
time: new Date(), | ||
features: featureOutput, | ||
passed: 0, | ||
failed: 0, | ||
ambiguous: 0, | ||
totalTime: 0, | ||
suites: [], | ||
scenarios: { | ||
passed: 0, | ||
failed: 0, | ||
skipped: 0, | ||
pending: 0, | ||
notdefined: 0, | ||
ambiguous: 0 | ||
} | ||
}; | ||
const result = { | ||
status: { | ||
passed: 'passed', | ||
failed: 'failed', | ||
skipped: 'skipped', | ||
pending: 'pending', | ||
undefined: 'undefined', | ||
ambiguous: 'ambiguous', | ||
}, | ||
}; | ||
var createReportDirectoryIfNotExists = function () { | ||
if (!fs.existsSync(options.output)) { | ||
fs.mkdirsSync(path.dirname(options.output)); | ||
} | ||
}; | ||
let suite = { | ||
name: { | ||
plain: options.name || (packageJson && packageJson.name), | ||
sanitized: sanitize(options.name || (packageJson && packageJson.name), /[^a-z|0-9]/g), | ||
}, | ||
brandTitle: options.brandTitle, | ||
version: packageJson && packageJson.version, | ||
time: new Date(), | ||
features: featureOutput, | ||
passed: 0, | ||
failed: 0, | ||
ambiguous: 0, | ||
rerun: 0, | ||
totalTime: 0, | ||
suites: [], | ||
scenarios: { | ||
passed: 0, | ||
failed: 0, | ||
skipped: 0, | ||
pending: 0, | ||
notdefined: 0, | ||
ambiguous: 0, | ||
rerun: 0, | ||
getTotal: function () { | ||
return this.passed + this.failed + this.skipped + this.pending + this.notdefined + this.ambiguous; | ||
}, | ||
}, | ||
}; | ||
createReportDirectoryIfNotExists(); | ||
function getColumnLayoutWidth() { | ||
const FULL_WIDTH = 12; | ||
const HALF_WIDTH = 6; | ||
if(options.columnLayout === 1) { | ||
return FULL_WIDTH; | ||
} else { | ||
return HALF_WIDTH; | ||
} | ||
const createReportDirectoryIfNotExists = function () { | ||
if (!fs.existsSync(options.output)) { | ||
fs.mkdirsSync(path.dirname(options.output)); | ||
} | ||
/** | ||
* Make human-readable duration for scenario steps | ||
* Sample Input: "2005366787" | ||
* Sample Output: "2s 5ms" | ||
*/ | ||
var calculateDuration = function (durationInNanoSeconds) { | ||
// convert it to MILLI_SECONDS | ||
var durationInMillis = _.floor(durationInNanoSeconds / 1000000); | ||
}; | ||
var oneMilliSecond = 1000; | ||
var oneMinute = 60 * oneMilliSecond; | ||
var formattedDuration = '0s'; | ||
createReportDirectoryIfNotExists(); | ||
function format(min, sec, ms) { | ||
var MINUTES = 'm '; | ||
var SECONDS = 's '; | ||
var MILLI_SECONDS = 'ms'; | ||
var formattedTimeStamp = ''; | ||
function getColumnLayoutWidth() { | ||
const FULL_WIDTH = 12; | ||
const HALF_WIDTH = 6; | ||
min > 0 ? formattedTimeStamp += min + MINUTES : ''; | ||
sec > 0 ? formattedTimeStamp += sec + SECONDS : ''; | ||
ms > 0 ? formattedTimeStamp += ms + MILLI_SECONDS : ''; | ||
if (options.columnLayout === 1) { | ||
return FULL_WIDTH; | ||
} else { | ||
return HALF_WIDTH; | ||
} | ||
} | ||
/** | ||
* Make human-readable duration for scenario steps | ||
* Sample Input: "2005366787" | ||
* Sample Output: "2s 5ms" | ||
*/ | ||
const calculateDuration = function (durationInNanoSeconds) { | ||
// convert it to MILLI_SECONDS | ||
const durationInMillis = _.floor(durationInNanoSeconds / 1000000); | ||
return formattedTimeStamp.trim().length === 0 ? '< 1ms' : formattedTimeStamp; | ||
} | ||
let oneMilliSecond = 1000; | ||
let oneMinute = 60 * oneMilliSecond; | ||
let formattedDuration = '0s'; | ||
if (!isNaN(durationInMillis)) { | ||
function format(min, sec, ms) { | ||
const MINUTES = 'm '; | ||
const SECONDS = 's '; | ||
const MILLI_SECONDS = 'ms'; | ||
let formattedTimeStamp = ''; | ||
var min = _.floor(durationInMillis / oneMinute); | ||
var sec = _.floor((durationInMillis % oneMinute) / oneMilliSecond); | ||
var ms = durationInMillis % oneMilliSecond; | ||
min > 0 ? (formattedTimeStamp += min + MINUTES) : ''; | ||
sec > 0 ? (formattedTimeStamp += sec + SECONDS) : ''; | ||
ms > 0 ? (formattedTimeStamp += ms + MILLI_SECONDS) : ''; | ||
formattedDuration = format(min, sec, ms); | ||
} | ||
return formattedTimeStamp.trim().length === 0 ? '< 1ms' : formattedTimeStamp; | ||
} | ||
return formattedDuration; | ||
}; | ||
if (!isNaN(durationInMillis)) { | ||
const min = _.floor(durationInMillis / oneMinute); | ||
const sec = _.floor((durationInMillis % oneMinute) / oneMilliSecond); | ||
const ms = durationInMillis % oneMilliSecond; | ||
var preventOverlappingTheScenarioTitle = function (element) { | ||
var counter = 0; | ||
formattedDuration = format(min, sec, ms); | ||
} | ||
if (element.passed) counter++; | ||
if (element.notdefined) counter++; | ||
if (element.pending) counter++; | ||
if (element.skipped) counter++; | ||
if (element.failed) counter++; | ||
if (element.ambiguous) counter++; | ||
return formattedDuration; | ||
}; | ||
counter = (counter * 20) + 10; | ||
const preventOverlappingTheScenarioTitle = function (element) { | ||
let counter = 0; | ||
return counter + 'px'; | ||
}; | ||
if (element.passed) counter++; | ||
if (element.notdefined) counter++; | ||
if (element.pending) counter++; | ||
if (element.skipped) counter++; | ||
if (element.failed) counter++; | ||
if (element.ambiguous) counter++; | ||
var readFileForRespectiveTemplates = function (filename) { | ||
if (filename === 'script.js' && options.theme === 'foundation') { | ||
return readFile('../_common/foundation/' + filename); | ||
} | ||
return ((options.theme === 'bootstrap') || (options.theme === 'hierarchy')) ? readFile('../_common/bootstrap.hierarchy/' + filename) : readFile(filename); | ||
}; | ||
counter = counter * 20 + 10; | ||
if (element.retried) { | ||
// 90px fixed width | ||
counter = Math.max(counter, 90); | ||
} | ||
/** | ||
* NOTE: This method is used by hierarchy report template, harmless for others. | ||
* Creates the HTML fragments for any features assigned to this suite, | ||
* and stores them in `featureMarkup` attribute of the suite so we can render them in index.tmpl | ||
* | ||
* @param suite | ||
*/ | ||
return counter + 'px'; | ||
}; | ||
var getFeaturesTemplate = function (suite) { | ||
return _.template(readFileForRespectiveTemplates('features.html'))({ | ||
suite: suite, | ||
_: _, | ||
calculateDuration: calculateDuration, | ||
columnLayoutWidth: getColumnLayoutWidth(), | ||
decideScenarioTitlePadding: preventOverlappingTheScenarioTitle, | ||
guid: guid | ||
}); | ||
}; | ||
const readFileForRespectiveTemplates = function (filename) { | ||
if (filename === 'script.js' && options.theme === 'foundation') { | ||
return readFile('../_common/foundation/' + filename); | ||
} | ||
return options.theme === 'bootstrap' || options.theme === 'hierarchy' | ||
? readFile('../_common/bootstrap.hierarchy/' + filename) | ||
: readFile(filename); | ||
}; | ||
var setupSubSuiteTemplates = function (suite) { | ||
suite.featureMarkup = '<div style="display: none;">No features</div>'; | ||
if (suite.features && suite.features.length) { | ||
suite.featureMarkup = getFeaturesTemplate(suite); | ||
} | ||
for (var i = 0; i < suite.suites.length; i++) { | ||
var subSuite = suite.suites[i]; | ||
setupSubSuiteTemplates(subSuite); | ||
} | ||
}; | ||
/** | ||
* NOTE: This method is used by hierarchy report template, harmless for others. | ||
* Creates the HTML fragments for any features assigned to this suite, | ||
* and stores them in `featureMarkup` attribute of the suite so we can render them in index.tmpl | ||
* | ||
* @param suite | ||
*/ | ||
var parseScenarioHooks = function(data) { | ||
return data.map(step => { | ||
const match = step.match && step.match.location ? step.match : {location: 'can not be determined'}; | ||
const getFeaturesTemplate = function (suite) { | ||
return _.template(readFileForRespectiveTemplates('features.html'))({ | ||
suite: suite, | ||
_: _, | ||
calculateDuration: calculateDuration, | ||
columnLayoutWidth: getColumnLayoutWidth(), | ||
decideScenarioTitlePadding: preventOverlappingTheScenarioTitle, | ||
guid: guid, | ||
}); | ||
}; | ||
if(step.embeddings == undefined){ | ||
return {} | ||
} | ||
const setupSubSuiteTemplates = function (suite) { | ||
suite.featureMarkup = '<div style="display: none;">No features</div>'; | ||
if (suite.features && suite.features.length) { | ||
suite.featureMarkup = getFeaturesTemplate(suite); | ||
} | ||
for (let i = 0; i < suite.suites.length; i++) { | ||
const subSuite = suite.suites[i]; | ||
setupSubSuiteTemplates(subSuite); | ||
} | ||
}; | ||
return { | ||
arguments: step.arguments || [], | ||
result: step.result, | ||
match, | ||
embeddings: step.embeddings || [] | ||
} | ||
}) | ||
}; | ||
const parseScenarioHooks = function (data) { | ||
return data.map((step) => { | ||
const match = step.match && step.match.location ? step.match : { location: 'can not be determined' }; | ||
var setStats = function (suite) { | ||
var featureOutput = suite.features; | ||
var topLevelFeatures = []; | ||
var featuresSummary = suite.features.summary; | ||
var screenshotsDirectory; | ||
suite.reportAs = 'Features'; | ||
if(options.screenshotsDirectory) { | ||
screenshotsDirectory = options.screenshotsDirectory; | ||
} else { | ||
screenshotsDirectory = options.output ? path.join(options.output, '..', 'screenshots') : 'screenshots'; | ||
} | ||
if (step.embeddings === undefined) { | ||
return {}; | ||
} | ||
var basedir = hierarchyReporter.getBaseDir(suite); | ||
return { | ||
arguments: step.arguments || [], | ||
result: step.result, | ||
match, | ||
embeddings: step.embeddings || [], | ||
}; | ||
}); | ||
}; | ||
featureOutput.forEach(function (feature) { | ||
feature.hierarchy = hierarchyReporter.getFeatureHierarchy(feature.uri, basedir); | ||
feature.scenarios = {}; | ||
feature.scenarios.passed = 0; | ||
feature.scenarios.failed = 0; | ||
feature.scenarios.notdefined = 0; | ||
feature.scenarios.skipped = 0; | ||
feature.scenarios.pending = 0; | ||
feature.scenarios.ambiguous = 0; | ||
feature.scenarios.count = 0; | ||
feature.time = 0; | ||
featuresSummary.isFailed = false; | ||
featuresSummary.isAmbiguous = false; | ||
const setStats = function (suite) { | ||
const featureOutput = suite.features; | ||
const topLevelFeatures = []; | ||
const featuresSummary = suite.features.summary; | ||
let screenshotsDirectory; | ||
suite.reportAs = 'Features'; | ||
if (options.screenshotsDirectory) { | ||
screenshotsDirectory = options.screenshotsDirectory; | ||
} else { | ||
screenshotsDirectory = options.output ? path.join(options.output, '..', 'screenshots') : 'screenshots'; | ||
} | ||
if (!feature.elements) { | ||
return; | ||
} | ||
const basedir = hierarchyReporter.getBaseDir(suite); | ||
if (feature.elements) { | ||
feature.elements.map(scenario => { | ||
const {before, after} = scenario; | ||
featureOutput.forEach(function (feature) { | ||
feature.hierarchy = hierarchyReporter.getFeatureHierarchy(feature.uri, basedir); | ||
feature.scenarios = {}; | ||
feature.scenarios.passed = 0; | ||
feature.scenarios.failed = 0; | ||
feature.scenarios.notdefined = 0; | ||
feature.scenarios.skipped = 0; | ||
feature.scenarios.pending = 0; | ||
feature.scenarios.ambiguous = 0; | ||
feature.scenarios.rerun = 0; | ||
feature.scenarios.count = 0; | ||
feature.time = 0; | ||
featuresSummary.isFailed = false; | ||
featuresSummary.isAmbiguous = false; | ||
if (before) { | ||
scenario.steps = parseScenarioHooks(before).concat(scenario.steps); | ||
} | ||
if (after) { | ||
scenario.steps = scenario.steps.concat(parseScenarioHooks(after)); | ||
} | ||
}) | ||
} | ||
if (!feature.elements) { | ||
return; | ||
} | ||
feature.elements.forEach(function (element) { | ||
element.passed = 0; | ||
element.failed = 0; | ||
element.notdefined = 0; | ||
element.skipped = 0; | ||
element.pending = 0; | ||
element.ambiguous = 0; | ||
element.time = 0; | ||
element.timestamp = ''; | ||
element.notes = ''; | ||
if (feature.elements) { | ||
feature.elements.map((scenario) => { | ||
const { before, after } = scenario; | ||
if (element.type === 'background') { | ||
return; | ||
} | ||
if (before) { | ||
scenario.steps = parseScenarioHooks(before).concat(scenario.steps); | ||
} | ||
if (after) { | ||
scenario.steps = scenario.steps.concat(parseScenarioHooks(after)); | ||
} | ||
}); | ||
} | ||
element.steps.forEach(function (step, count) { | ||
if (step.embeddings !== undefined) { | ||
step.embeddings.forEach(function (embedding) { | ||
feature.elements.forEach(function (element) { | ||
element.passed = 0; | ||
element.failed = 0; | ||
element.notdefined = 0; | ||
element.skipped = 0; | ||
element.pending = 0; | ||
element.ambiguous = 0; | ||
element.time = 0; | ||
element.timestamp = ''; | ||
element.notes = ''; | ||
var embeddingType = {}; | ||
if (element.type === 'background') { | ||
return; | ||
} | ||
if (embedding.mime_type) { | ||
embeddingType = embedding.mime_type; | ||
} else if (embedding.media) { | ||
embeddingType = embedding.media.type; | ||
} | ||
if (['text/plain', 'text/html', 'application/json'].includes(embeddingType)) { | ||
var decoded; | ||
element.steps.forEach(function (step, count) { | ||
if (step.embeddings !== undefined) { | ||
step.embeddings.forEach(function (embedding) { | ||
let embeddingType = {}; | ||
if (isBase64(embedding.data)) { | ||
decoded = Buffer.from(embedding.data, 'base64').toString('utf8'); | ||
} else { | ||
decoded = embedding.data; | ||
} | ||
if (embedding.mime_type) { | ||
embeddingType = embedding.mime_type; | ||
} else if (embedding.media) { | ||
embeddingType = embedding.media.type; | ||
} | ||
if (['text/plain', 'text/html', 'application/json'].includes(embeddingType)) { | ||
let decoded; | ||
if (!step.text) { | ||
step.text = decoded; | ||
} else { | ||
step.text = step.text.concat(`<br>${decoded}`); | ||
} | ||
} else if (embeddingType === 'image/png') { | ||
step.image = 'data:image/png;base64,' + embedding.data; | ||
if (isBase64(embedding.data)) { | ||
decoded = Buffer.from(embedding.data, 'base64').toString('utf8'); | ||
} else { | ||
decoded = embedding.data; | ||
} | ||
if (options.storeScreenshots && options.storeScreenshots === true) { | ||
if (!step.text) { | ||
step.text = decoded; | ||
} else { | ||
step.text = step.text.concat(`<br>${decoded}`); | ||
} | ||
} else if (embeddingType === 'image/png') { | ||
step.image = 'data:image/png;base64,' + embedding.data; | ||
var name = sanitize(step.name || step.keyword, /[^a-zA-Z0-9-]+/g); // Only allow URL-friendly file names | ||
if (!fs.existsSync(screenshotsDirectory)) { | ||
fs.mkdirSync(screenshotsDirectory); | ||
} | ||
name = name + '_' + Math.round(Math.random() * 10000) + '.png'; //randomize the file name | ||
var filename = path.join(screenshotsDirectory, name); | ||
fs.writeFileSync(filename, embedding.data, 'base64'); | ||
if (options.noInlineScreenshots) step.image = path.relative(path.join(options.output, '..'), filename); | ||
} | ||
} else if (embeddingType === 'image/gif') { | ||
step.image = 'data:image/gif;base64,' + embedding.data; | ||
if (options.storeScreenshots && options.storeScreenshots === true) { | ||
let name = sanitize(step.name || step.keyword, /[^a-zA-Z0-9-]+/g); // Only allow URL-friendly file names | ||
if (!fs.existsSync(screenshotsDirectory)) { | ||
fs.mkdirSync(screenshotsDirectory); | ||
} | ||
name = name + '_' + Math.round(Math.random() * 10000) + '.png'; //randomize the file name | ||
const filename = path.join(screenshotsDirectory, name); | ||
fs.writeFileSync(filename, embedding.data, 'base64'); | ||
if (options.noInlineScreenshots) | ||
step.image = path.relative(path.join(options.output, '..'), filename); | ||
} | ||
} else if (embeddingType === 'image/gif') { | ||
step.image = 'data:image/gif;base64,' + embedding.data; | ||
if (options.storeScreenshots && options.storeScreenshots === true) { | ||
if (options.storeScreenshots && options.storeScreenshots === true) { | ||
let name = sanitize(step.name || step.keyword, /[^a-zA-Z0-9-]+/g); // Only allow URL-friendly file names | ||
if (!fs.existsSync(screenshotsDirectory)) { | ||
fs.mkdirSync(screenshotsDirectory); | ||
} | ||
name = name + '_' + Math.round(Math.random() * 10000) + '.gif'; //randomize the file name | ||
const filename = path.join(screenshotsDirectory, name); | ||
fs.writeFileSync(filename, embedding.data, 'base64'); | ||
if (options.noInlineScreenshots) | ||
step.image = path.relative(path.join(options.output, '..'), filename); | ||
} | ||
} else { | ||
const file = 'data:application/octet-stream;base64,' + embedding.data; | ||
const fileType = embedding.mime_type.split('/')[1]; | ||
step.text = step.text || ''; | ||
step.text = step.text.concat( | ||
'<a href="' + file + '" download="file.' + fileType + '">download file</a>' | ||
); | ||
} | ||
}); | ||
} | ||
var name = sanitize(step.name || step.keyword, /[^a-zA-Z0-9-]+/g); // Only allow URL-friendly file names | ||
if (!fs.existsSync(screenshotsDirectory)) { | ||
fs.mkdirSync(screenshotsDirectory); | ||
} | ||
name = name + '_' + Math.round(Math.random() * 10000) + '.gif'; //randomize the file name | ||
var filename = path.join(screenshotsDirectory, name); | ||
fs.writeFileSync(filename, embedding.data, 'base64'); | ||
if (options.noInlineScreenshots) step.image = path.relative(path.join(options.output, '..'), filename); | ||
} | ||
} else { | ||
var file = 'data:application/octet-stream;base64,' + embedding.data; | ||
var fileType = embedding.mime_type.split('/')[1]; | ||
step.text = step.text || ''; | ||
step.text = step.text.concat('<a href="'+file+'" download="file.'+fileType+'">download file</a>'); | ||
} | ||
}); | ||
} | ||
if (!step.result || (step.hidden && !step.text && !step.image)) { | ||
return 0; | ||
} | ||
if (!step.result || (step.hidden && !step.text && !step.image)) { | ||
return 0; | ||
} | ||
if (step.result.duration) element.time += step.result.duration; | ||
if (step.result.duration) element.time += step.result.duration; | ||
if (step.output) { | ||
if (options.scenarioTimestamp && count === 0) { | ||
element.timestamp = step.output[0]; | ||
} | ||
step.output.forEach(function (o) { | ||
element.notes += o + '<br/>'; | ||
}); | ||
} | ||
if (step.output) { | ||
if (options.scenarioTimestamp && count == 0) { | ||
element.timestamp = step.output[0]; | ||
} | ||
step.output.forEach(function(o) { | ||
element.notes += o + '<br/>'; | ||
}); | ||
} | ||
switch (step.result.status) { | ||
case result.status.passed: | ||
return element.passed++; | ||
case result.status.failed: | ||
return element.failed++; | ||
case result.status.undefined: | ||
return element.notdefined++; | ||
case result.status.pending: | ||
return element.pending++; | ||
case result.status.ambiguous: | ||
return element.ambiguous++; | ||
default: | ||
break; | ||
} | ||
switch (step.result.status) { | ||
case result.status.passed: | ||
return element.passed++; | ||
case result.status.failed: | ||
return element.failed++; | ||
case result.status.undefined: | ||
return element.notdefined++; | ||
case result.status.pending: | ||
return element.pending++; | ||
case result.status.ambiguous: | ||
return element.ambiguous++; | ||
default: | ||
break; | ||
} | ||
element.skipped++; | ||
}); | ||
element.skipped++; | ||
}); | ||
if (element.time > 0) { | ||
feature.time += element.time; | ||
} | ||
if (element.time > 0) { | ||
feature.time += element.time; | ||
} | ||
feature.scenarios.count++; | ||
feature.scenarios.count++; | ||
if (element.failed > 0) { | ||
feature.scenarios.failed++; | ||
featuresSummary.isFailed = true; | ||
return suite.scenarios.failed++; | ||
} | ||
if (element.failed > 0) { | ||
feature.scenarios.failed++; | ||
featuresSummary.isFailed = true; | ||
return suite.scenarios.failed++; | ||
} | ||
if (element.ambiguous > 0) { | ||
feature.scenarios.ambiguous++; | ||
featuresSummary.isAmbiguous = true; | ||
return suite.scenarios.ambiguous++; | ||
} | ||
if (element.ambiguous > 0) { | ||
feature.scenarios.ambiguous++; | ||
featuresSummary.isAmbiguous = true; | ||
return suite.scenarios.ambiguous++; | ||
} | ||
if (element.notdefined > 0) { | ||
feature.scenarios.notdefined++; | ||
return suite.scenarios.notdefined++; | ||
} | ||
if (element.notdefined > 0) { | ||
feature.scenarios.notdefined++; | ||
return suite.scenarios.notdefined++; | ||
} | ||
if (element.pending > 0) { | ||
feature.scenarios.pending++; | ||
return suite.scenarios.pending++; | ||
} | ||
if (element.pending > 0) { | ||
feature.scenarios.pending++; | ||
return suite.scenarios.pending++; | ||
} | ||
if (element.skipped > 0) { | ||
feature.scenarios.skipped++; | ||
return suite.scenarios.skipped++; | ||
} | ||
if (element.skipped > 0) { | ||
feature.scenarios.skipped++; | ||
return suite.scenarios.skipped++; | ||
} | ||
if (element.passed > 0) { | ||
feature.scenarios.passed++; | ||
return suite.scenarios.passed++; | ||
} | ||
}); | ||
if (stageRerunCount > 0) { | ||
feature.scenarios.rerun = stageRerunCount; | ||
suite.scenarios.rerun = stageRerunCount; | ||
} | ||
if (element.passed > 0) { | ||
feature.scenarios.passed++; | ||
return suite.scenarios.passed++; | ||
} | ||
let subSuite = undefined; | ||
if (options.theme === 'hierarchy') { | ||
subSuite = hierarchyReporter.findOrCreateSubSuite(suite, feature.hierarchy); | ||
} | ||
if (subSuite) { | ||
subSuite.features.push(feature); | ||
} else { | ||
topLevelFeatures.push(feature); | ||
} | ||
}); | ||
if (featuresSummary.isFailed) { | ||
featuresSummary.failed++; | ||
subSuite ? hierarchyReporter.recursivelyIncrementStat(subSuite, 'failed') : suite.failed++; | ||
} else if (featuresSummary.isAmbiguous) { | ||
featuresSummary.ambiguous++; | ||
subSuite ? hierarchyReporter.recursivelyIncrementStat(subSuite, 'ambiguous') : suite.ambiguous++; | ||
} else if (feature.scenarios.count === feature.scenarios.skipped) { | ||
featuresSummary.skipped++; | ||
subSuite ? hierarchyReporter.recursivelyIncrementStat(subSuite, 'skipped') : suite.skipped++; | ||
} else if (feature.scenarios.count === feature.scenarios.notdefined) { | ||
featuresSummary.notdefined++; | ||
subSuite ? hierarchyReporter.recursivelyIncrementStat(subSuite, 'passed') : suite.passed++; | ||
} else if (feature.scenarios.count === feature.scenarios.pending) { | ||
featuresSummary.pending++; | ||
subSuite ? hierarchyReporter.recursivelyIncrementStat(subSuite, 'passed') : suite.passed++; | ||
} else { | ||
featuresSummary.passed++; | ||
subSuite ? hierarchyReporter.recursivelyIncrementStat(subSuite, 'passed') : suite.passed++; | ||
} | ||
var subSuite = undefined; | ||
if (options.theme === 'hierarchy') { | ||
subSuite = hierarchyReporter.findOrCreateSubSuite(suite, feature.hierarchy); | ||
} | ||
if (subSuite) { | ||
subSuite.features.push(feature); | ||
} else { | ||
topLevelFeatures.push(feature); | ||
} | ||
if (options.reportSuiteAsScenarios) { | ||
suite.failed = suite.scenarios.failed; | ||
suite.passed = suite.scenarios.passed; | ||
suite.ambiguous = suite.scenarios.ambiguous; | ||
suite.skipped = suite.scenarios.skipped; | ||
suite.rerun = suite.scenarios.rerun; | ||
suite.reportAs = 'scenarios'; | ||
} | ||
if (featuresSummary.isFailed) { | ||
featuresSummary.failed++; | ||
subSuite ? hierarchyReporter.recursivelyIncrementStat(subSuite, 'failed') : suite.failed++; | ||
} else if (featuresSummary.isAmbiguous) { | ||
featuresSummary.ambiguous++; | ||
subSuite ? hierarchyReporter.recursivelyIncrementStat(subSuite, 'ambiguous') : suite.ambiguous++; | ||
} else if (feature.scenarios.count === feature.scenarios.skipped) { | ||
featuresSummary.skipped++; | ||
subSuite ? hierarchyReporter.recursivelyIncrementStat(subSuite, 'skipped') : suite.skipped++; | ||
} else if (feature.scenarios.count === feature.scenarios.notdefined) { | ||
featuresSummary.notdefined++; | ||
subSuite ? hierarchyReporter.recursivelyIncrementStat(subSuite, 'passed') : suite.passed++; | ||
} else if (feature.scenarios.count === feature.scenarios.pending) { | ||
featuresSummary.pending++; | ||
subSuite ? hierarchyReporter.recursivelyIncrementStat(subSuite, 'passed') : suite.passed++; | ||
} else { | ||
featuresSummary.passed++; | ||
subSuite ? hierarchyReporter.recursivelyIncrementStat(subSuite, 'passed') : suite.passed++; | ||
} | ||
if (feature.time) { | ||
suite.totalTime += feature.time; | ||
} | ||
if (options.reportSuiteAsScenarios) { | ||
suite.failed = suite.scenarios.failed; | ||
suite.passed = suite.scenarios.passed; | ||
suite.ambiguous = suite.scenarios.ambiguous; | ||
suite.skipped = suite.scenarios.skipped; | ||
suite.reportAs = 'scenarios'; | ||
} | ||
suite.features = topLevelFeatures; | ||
suite.features.summary = featuresSummary; | ||
if (feature.time) { | ||
suite.totalTime += feature.time | ||
} | ||
return suite; | ||
}); | ||
suite.features = topLevelFeatures; | ||
suite.features.summary = featuresSummary; | ||
suite.totalTime = calculateDuration(suite.totalTime); | ||
return suite; | ||
if (options.theme === 'hierarchy') { | ||
setupSubSuiteTemplates(suite); | ||
} | ||
}); | ||
if (options.metadata) suite.metadata = options.metadata; | ||
suite.totalTime = calculateDuration(suite.totalTime); | ||
return suite; | ||
}; | ||
if (options.theme === 'hierarchy') { | ||
setupSubSuiteTemplates(suite); | ||
} | ||
if (options.metadata) suite.metadata = options.metadata; | ||
return suite; | ||
}; | ||
function readFile(fileName) { | ||
function getPath(name) { | ||
//use custom template based on user's requirement | ||
if (options.templateDir && fs.existsSync(path.join(options.templateDir, name))) { | ||
return path.join(options.templateDir, name); | ||
} else { | ||
return path.join(__dirname, '..', 'templates', options.theme, name); | ||
} | ||
} | ||
return fs.readFileSync(getPath(fileName), 'utf-8'); | ||
function readFile(fileName) { | ||
function getPath(name) { | ||
//use custom template based on user's requirement | ||
if (options.templateDir && fs.existsSync(path.join(options.templateDir, name))) { | ||
return path.join(options.templateDir, name); | ||
} else { | ||
return path.join(__dirname, '..', 'templates', options.theme, name); | ||
} | ||
} | ||
suite = setStats(suite); | ||
return fs.readFileSync(getPath(fileName), 'utf-8'); | ||
} | ||
fs.writeFileSync( | ||
options.output, | ||
_.template(readFile('index.html'))({ | ||
suite: suite, | ||
features: getFeaturesTemplate(suite), | ||
styles: readFileForRespectiveTemplates('style.css'), | ||
script: readFileForRespectiveTemplates('script.js'), | ||
screenshot: readFile('../_common/screenshot.js'), | ||
piechart: ((options.theme === 'bootstrap') || (options.theme === 'hierarchy')) ? readFileForRespectiveTemplates('piechart.js') : undefined, | ||
guid: guid | ||
}) | ||
); | ||
suite = setStats(suite); | ||
console.log('\n' + | ||
chalk.green.bold(emoji.emojify(':rocket:') + ' Cucumber HTML report ' + chalk.blue.bold(options.output) + ' generated successfully ') + | ||
emoji.emojify(':thumbsup:') | ||
); | ||
fs.writeFileSync( | ||
options.output, | ||
_.template(readFile('index.html'))({ | ||
suite: suite, | ||
features: getFeaturesTemplate(suite), | ||
styles: readFileForRespectiveTemplates('style.css'), | ||
script: readFileForRespectiveTemplates('script.js'), | ||
screenshot: readFile('../_common/screenshot.js'), | ||
piechart: | ||
options.theme === 'bootstrap' || options.theme === 'hierarchy' | ||
? readFileForRespectiveTemplates('piechart.js') | ||
: undefined, | ||
guid: guid, | ||
}) | ||
); | ||
console.log( | ||
'\n' + | ||
chalk.green.bold( | ||
emoji.emojify(':rocket:') + | ||
' Cucumber HTML report ' + | ||
chalk.blue.bold(options.output) + | ||
' generated successfully ' | ||
) + | ||
emoji.emojify(':thumbsup:') | ||
); | ||
}; | ||
function generate(options, callback) { | ||
function isValidJsonFile() { | ||
// options.jsonFile = options.jsonFile || options.output + '.json'; | ||
options.jsonFile = options.jsonFile || options.output + '.json' || options.output + '.ndjson'; | ||
function isValidJsonFile() { | ||
options.jsonFile = options.jsonFile || options.output + '.json'; | ||
function isAFile(filePath) { | ||
try { | ||
return fs.statSync(filePath).isFile(); | ||
} catch (err) { | ||
return false; | ||
} | ||
} | ||
function isAFile(filePath) { | ||
try { | ||
return fs.statSync(filePath).isFile(); | ||
} catch (err) { | ||
return false; | ||
} | ||
} | ||
if(!isAFile(options.jsonFile)) { | ||
var jsonFilePath = options.jsonFile; | ||
var dynamicReportJsonFileName = fs.readdirSync(jsonFilePath, 'utf-8'); | ||
options.jsonFile = jsonFilePath + "/" + dynamicReportJsonFileName[0]; | ||
} | ||
try { | ||
JSON.parse(JSON.stringify(jsonFile.readFileSync(options.jsonFile))); | ||
return true; | ||
} catch (e) { | ||
console.log('\n' + | ||
chalk.bold.red(emoji.emojify(':warning: ') + emoji.emojify(':disappointed: ') + 'Unable to parse cucumberjs output into json: \'%s\'', options.jsonFile, e) | ||
); | ||
if (callback) { | ||
callback('Unable to parse cucumberjs output into json: \'' + options.jsonFile + '\'. Error: ' + e); | ||
} else { | ||
return false; | ||
} | ||
} | ||
if (!isAFile(options.jsonFile)) { | ||
const jsonFilePath = options.jsonFile; | ||
const dynamicReportJsonFileName = fs.readdirSync(jsonFilePath, 'utf-8'); | ||
options.jsonFile = jsonFilePath + '/' + dynamicReportJsonFileName[0]; | ||
} | ||
async function launchReport() { | ||
if (fs.existsSync(options.output) && (options.launchReport || options.launchReport === 'true')) { | ||
await open(options.output, {wait: false}); | ||
} | ||
try { | ||
JSON.parse(JSON.stringify(jsonFile.readFileSync(options.jsonFile))); | ||
return true; | ||
} catch (e) { | ||
console.log( | ||
'\n' + | ||
'\n' + | ||
chalk.bold.red( | ||
emoji.emojify(':warning: ') + | ||
emoji.emojify(':disappointed: ') + | ||
"Unable to parse cucumberjs output into json: '%s'", | ||
options.jsonFile, | ||
e | ||
) | ||
); | ||
if (callback) { | ||
callback('Unable to parse cucumberjs output into json: \'' + options.jsonFile + '\'. Error: ' + e); | ||
} else { | ||
return false; | ||
} | ||
} | ||
} | ||
if (options.jsonDir) { | ||
jsonDir.collectJSONS(options) | ||
async function launchReport() { | ||
if (fs.existsSync(options.output) && (options.launchReport || options.launchReport === 'true')) { | ||
await open(options.output, { wait: false }); | ||
} | ||
} | ||
if (isValidJsonFile()) { | ||
generateReport(options); | ||
launchReport(); | ||
return callback ? callback() : true; | ||
if (options.jsonDir) { | ||
jsonDir.collectJSONS(options); | ||
} | ||
if (isValidJsonFile()) { | ||
generateReport(options); | ||
launchReport(); | ||
return callback ? callback() : true; | ||
} | ||
} | ||
// Specific to LambdaTest | ||
function getStageReRunCount() { | ||
let retryCount = undefined; | ||
const metaFile = process.env.META_FILE; | ||
try { | ||
const jobReports = jsonFile.readFileSync(metaFile); | ||
retryCount = 0; | ||
if ( | ||
!!jobReports && | ||
!!jobReports['JobSummary'] && | ||
!!jobReports['JobSummary']['Tasks'] && | ||
jobReports['JobSummary']['Tasks'] instanceof Array | ||
) { | ||
jobReports['JobSummary']['Tasks'].forEach((task) => { | ||
if (!!task && !!task['stages'] && !!task['stages']['retried'] && !isNaN(task['stages']['retried'])) { | ||
// +<num> makes sure that a numeric constiable is getting read as a number | ||
retryCount += +task['stages']['retried']; | ||
} | ||
}); | ||
} | ||
} catch (err) { | ||
retryCount = undefined; | ||
} | ||
return retryCount; | ||
} | ||
module.exports = { | ||
generate: generate | ||
generate: generate, | ||
}; |
@@ -1,27 +0,27 @@ | ||
'use strict'; | ||
// 'use strict'; | ||
var fs = require('fs-extra'); | ||
var path = require('path'); | ||
const fs = require('fs-extra'); | ||
const path = require('path'); | ||
function searchFileUp(fileName) { | ||
var pathParts = process.cwd().split(path.sep); | ||
const pathParts = process.cwd().split(path.sep); | ||
var filePath = pathParts.concat([fileName]).join(path.sep); | ||
let filePath = pathParts.concat([fileName]).join(path.sep); | ||
while (!exists(filePath) && pathParts.length) { | ||
pathParts.pop(); | ||
filePath = pathParts.concat([fileName]).join(path.sep); | ||
} | ||
while (!exists(filePath) && pathParts.length) { | ||
pathParts.pop(); | ||
filePath = pathParts.concat([fileName]).join(path.sep); | ||
} | ||
return filePath; | ||
return filePath; | ||
} | ||
function exists(filePath) { | ||
try { | ||
return fs.statSync(filePath).isFile(); | ||
} catch (err) { | ||
return false; | ||
} | ||
try { | ||
return fs.statSync(filePath).isFile(); | ||
} catch (err) { | ||
return false; | ||
} | ||
} | ||
module.exports = searchFileUp; | ||
module.exports = searchFileUp; |
{ | ||
"name": "cucumber-html-reporter", | ||
"version": "5.5.1", | ||
"version": "6.0.0", | ||
"description": "Generates Cucumber HTML reports in three different themes", | ||
@@ -13,2 +13,6 @@ "main": "index.js", | ||
{ | ||
"name": "larryg01", | ||
"url": "https://github.com/larryg01" | ||
}, | ||
{ | ||
"name": "Galileo1", | ||
@@ -15,0 +19,0 @@ "url": "https://github.com/Galileo1" |
@@ -5,3 +5,3 @@ # cucumber-html-reporter | ||
[![Build Status](https://travis-ci.org/gkushang/cucumber-html-reporter.svg?branch=develop)](https://travis-ci.org/gkushang/cucumber-html-reporter) [![npm](https://img.shields.io/npm/v/cucumber-html-reporter.svg)](https://www.npmjs.com/package/cucumber-html-reporter) [![Dependency Status](https://david-dm.org/gkushang/cucumber-html-reporter.svg)](https://david-dm.org/gkushang/cucumber-html-reporter) [![Code Climate](https://codeclimate.com/github/gkushang/cucumber-html-reporter/badges/gpa.svg)](https://codeclimate.com/github/gkushang/cucumber-html-reporter) [![License](https://img.shields.io/npm/l/cucumber-html-reporter.svg)](LICENSE) [![contributors](https://img.shields.io/github/contributors/gkushang/cucumber-html-reporter.svg)](https://github.com/gkushang/cucumber-html-reporter/graphs/contributors) | ||
[![Build Status](https://travis-ci.org/gkushang/cucumber-html-reporter.svg?branch=develop)](https://travis-ci.org/gkushang/cucumber-html-reporter) [![npm](https://img.shields.io/npm/v/cucumber-html-reporter.svg)](https://www.npmjs.com/package/cucumber-html-reporter) [![Code Climate](https://codeclimate.com/github/gkushang/cucumber-html-reporter/badges/gpa.svg)](https://codeclimate.com/github/gkushang/cucumber-html-reporter) [![License](https://img.shields.io/npm/l/cucumber-html-reporter.svg)](LICENSE) [![contributors](https://img.shields.io/github/contributors/gkushang/cucumber-html-reporter.svg)](https://github.com/gkushang/cucumber-html-reporter/graphs/contributors) | ||
@@ -34,3 +34,4 @@ | ||
* Latest version supports Cucumber 3 | ||
* Latest version supports Cucumber 8 | ||
* Install `cucumber-html-reporter@5.5.0` for cucumber version `< Cucumber@8` | ||
* Install `cucumber-html-reporter@2.0.3` for cucumber version `< Cucumber@3` | ||
@@ -45,3 +46,3 @@ * Install `cucumber-html-reporter@0.5.0` for cucumber version `< Cucumber@2` | ||
1. Install the package through npm | ||
1. Install the package through npm or yarn | ||
2. Create an index.js and specify the options. Example of `bootstrap` theme: | ||
@@ -255,9 +256,12 @@ | ||
**for Cucumber V1** | ||
**for Cucumber V8** | ||
```javascript | ||
driver.takeScreenshot().then(function (buffer) { | ||
return scenario.attach(new Buffer(buffer, 'base64'), 'image/png'); | ||
}; | ||
let world = this; | ||
return driver.takeScreenshot().then((screenShot) => { | ||
// screenShot is a base-64 encoded PNG | ||
world.attach(screenShot, 'image/png'); | ||
}); | ||
``` | ||
@@ -276,2 +280,11 @@ | ||
**for Cucumber V1** | ||
```javascript | ||
driver.takeScreenshot().then(function (buffer) { | ||
return scenario.attach(new Buffer(buffer, 'base64'), 'image/png'); | ||
}; | ||
``` | ||
#### Attach Plain Text to HTML report | ||
@@ -278,0 +291,0 @@ |
function drawChart(chartData) { | ||
var data = google.visualization.arrayToDataTable([ | ||
['Task', 'Cucumber Results'], | ||
['Passed', chartData.passed], | ||
['Failed', chartData.failed], | ||
['Pending', chartData.pending], | ||
['Undefined', chartData.notdefined], | ||
['Ambiguous', chartData.ambiguous], | ||
['Skipped', chartData.skipped] | ||
]); | ||
let data = google.visualization.arrayToDataTable([ | ||
['Task', 'Cucumber Results'], | ||
['Passed', chartData.passed], | ||
['Failed', chartData.failed], | ||
['Pending', chartData.pending], | ||
['Undefined', chartData.notdefined], | ||
['Ambiguous', chartData.ambiguous], | ||
['Skipped', chartData.skipped], | ||
['Re-run', chartData.rerun], | ||
]); | ||
var total = chartData.passed + chartData.failed + (chartData.pending || 0) + (chartData.notdefined || 0) + (chartData.ambiguous || 0) + (chartData.skipped || 0); | ||
var title; | ||
let total = | ||
chartData.passed + | ||
chartData.failed + | ||
(chartData.pending || 0) + | ||
(chartData.notdefined || 0) + | ||
(chartData.ambiguous || 0) + | ||
(chartData.skipped || 0) || | ||
chartData.rerun || | ||
0; | ||
let title; | ||
if (total === 1) { | ||
title = total + ' ' + chartData.title.slice(0, -1) | ||
} else { | ||
title = total + ' ' + chartData.title; | ||
} | ||
if (total === 1) { | ||
title = total + ' ' + chartData.title.slice(0, -1); | ||
} else { | ||
title = total + ' ' + chartData.title; | ||
} | ||
var options = { | ||
width: '100%', | ||
height: 240, | ||
title: title, | ||
is3D: true, | ||
colors: ['#5cb85c', '#d9534f', '#999', '#5bc0de', '#428bca', '#f0ad4e'], | ||
fontSize: '13', | ||
fontName: '"Helvetica Neue", "Helvetica", Helvetica, Arial, sans-serif', | ||
slices: { | ||
1: {offset: 0.4}, | ||
2: {offset: 0.4}, | ||
3: {offset: 0.4}, | ||
4: {offset: 0.4}, | ||
5: {offset: 0.4}, | ||
6: {offset: 0.4} | ||
}, | ||
titleTextStyle: { | ||
fontSize: '13', | ||
color: '#5e5e5e' | ||
} | ||
}; | ||
let options = { | ||
width: '100%', | ||
height: 240, | ||
title: title, | ||
is3D: true, | ||
colors: ['#5cb85c', '#d9534f', '#999', '#5bc0de', '#428bca', '#f0ad4e', '#ff9933'], | ||
fontSize: '13', | ||
fontName: '"Helvetica Neue", "Helvetica", Helvetica, Arial, sans-serif', | ||
slices: { | ||
1: { offset: 0.4 }, | ||
2: { offset: 0.4 }, | ||
3: { offset: 0.4 }, | ||
4: { offset: 0.4 }, | ||
5: { offset: 0.4 }, | ||
6: { offset: 0.4 }, | ||
7: { offset: 0.4 }, | ||
}, | ||
titleTextStyle: { | ||
fontSize: '13', | ||
color: '#5e5e5e', | ||
}, | ||
}; | ||
var chart = new google.visualization.PieChart(document.getElementById('piechart_' + chartData.title.toLowerCase())); | ||
let chart = new google.visualization.PieChart(document.getElementById('piechart_' + chartData.title.toLowerCase())); | ||
function selectHandler() { | ||
var selectedItem = chart.getSelection()[0]; | ||
if (selectedItem) { | ||
var featureStatus = data.getValue(selectedItem.row, 0); | ||
if (featureStatus === 'Passed'){ | ||
var x = $('.feature-passed'); | ||
}else{ | ||
var x = $('.feature-failed'); | ||
} | ||
if (x && x.css('display') === "none") { | ||
x.css('display', 'block'); | ||
} else { | ||
x.css('display', 'none'); | ||
} | ||
} | ||
} | ||
google.visualization.events.addListener(chart, 'select', selectHandler); | ||
chart.draw(data, options); | ||
chart.draw(data, options); | ||
} |
@@ -1,18 +0,22 @@ | ||
$(document).ready(function() { | ||
$('.collapse').on('hide.bs.collapse', function(e) { | ||
e.stopPropagation(); | ||
$(this).prev().removeClass('open'); | ||
}).on('show.bs.collapse', function(e) { | ||
e.stopPropagation(); | ||
$(this).prev().addClass('open'); | ||
$(document).ready(function () { | ||
$('.collapse') | ||
.on('hide.bs.collapse', function (e) { | ||
e.stopPropagation(); | ||
$(this).prev().removeClass('open'); | ||
}) | ||
.on('show.bs.collapse', function (e) { | ||
e.stopPropagation(); | ||
$(this).prev().addClass('open'); | ||
}); | ||
var $generated = $('.generated-on'); | ||
let $generated = $('.generated-on'); | ||
$generated.text('Generated ' + moment($generated.text()).fromNow()); | ||
let timestamp = $generated.text(); | ||
$generated.text('Report generated ' + moment(timestamp).fromNow()); | ||
$generated.prop('title', new Date(timestamp).toISOString()); | ||
}); | ||
function toggle(className) { | ||
var x = $(className); | ||
if ( x.css('display') === "none") { | ||
let x = $(className); | ||
if (x.css('display') === 'none') { | ||
x.css('display', 'block'); | ||
@@ -19,0 +23,0 @@ } else { |
@@ -1,28 +0,25 @@ | ||
window.onload = function() { | ||
window.onload = function () { | ||
// Accordion hide/show | ||
let accordionTitles = document.getElementsByClassName('accordion-title'); | ||
// Accordion hide/show | ||
var accordionTitles = document.getElementsByClassName('accordion-title'); | ||
// Convert node list to array | ||
Array.prototype.slice.call(accordionTitles).forEach(function (title) { | ||
title.onclick = function () { | ||
let content = nextElement(title); | ||
let style = window.getComputedStyle(content); | ||
let display = style.getPropertyValue('display'); | ||
// Convert node list to array | ||
Array.prototype.slice.call(accordionTitles).forEach(function(title) { | ||
if (display === 'block') { | ||
content.style.display = 'none'; | ||
} else { | ||
content.style.display = 'block'; | ||
} | ||
title.onclick = function() { | ||
return false; | ||
}; | ||
}); | ||
var content = nextElement(title); | ||
var style = window.getComputedStyle(content); | ||
var display = style.getPropertyValue('display'); | ||
if (display === 'block') { | ||
content.style.display = 'none'; | ||
} else { | ||
content.style.display = 'block'; | ||
} | ||
return false; | ||
} | ||
}); | ||
// Update build time to since | ||
var buildTimeElem = document.getElementById("buildTime"); | ||
buildTimeElem.innerHTML = 'Built ' + moment(buildTimeElem.innerHTML).fromNow(); | ||
// Update build time to since | ||
let buildTimeElem = document.getElementById('buildTime'); | ||
buildTimeElem.innerHTML = 'Built ' + moment(buildTimeElem.innerHTML).fromNow(); | ||
}; | ||
@@ -35,7 +32,7 @@ | ||
function nextElement(elem) { | ||
do { | ||
elem = elem.nextSibling; | ||
} while (elem && elem.nodeType !== 1); | ||
do { | ||
elem = elem.nextSibling; | ||
} while (elem && elem.nodeType !== 1); | ||
return elem; | ||
return elem; | ||
} |
@@ -1,19 +0,19 @@ | ||
$('a.toggle').on('click', function(e) { | ||
e.preventDefault(); | ||
$('a.toggle').on('click', function (e) { | ||
e.preventDefault(); | ||
if (!$(this).hasClass('collapse')) { | ||
if ($(this).text() === 'Screenshot -') { | ||
// $(this).text('Screenshot +'); | ||
$(this).next('a.screenshot').find('img').hide(); | ||
} else if($(this).text() === 'Screenshot +') { | ||
// $(this).text('Screenshot -'); | ||
$(this).next('a.screenshot').find('img').show(); | ||
} | ||
if (!$(this).hasClass('collapse')) { | ||
if ($(this).text() === 'Screenshot -') { | ||
// $(this).text('Screenshot +'); | ||
$(this).next('a.screenshot').find('img').hide(); | ||
} else if ($(this).text() === 'Screenshot +') { | ||
// $(this).text('Screenshot -'); | ||
$(this).next('a.screenshot').find('img').show(); | ||
} | ||
} | ||
if ($(this).text().includes(' -')) { | ||
$(this).text($(this).text().replace(' -', ' +')); | ||
} else { | ||
$(this).text($(this).text().replace(' +', ' -')); | ||
} | ||
if ($(this).text().includes(' -')) { | ||
$(this).text($(this).text().replace(' -', ' +')); | ||
} else { | ||
$(this).text($(this).text().replace(' +', ' -')); | ||
} | ||
}); |
@@ -1,15 +0,15 @@ | ||
function toggleScreenshot(e){ | ||
if(this.innerText === "Screenshot -"){ | ||
this.innerText = "Screenshot +"; | ||
this.nextElementSibling.style.display = "none"; | ||
} else { | ||
this.innerText = "Screenshot -"; | ||
this.nextElementSibling.style.display = "block"; | ||
} | ||
function toggleScreenshot(e) { | ||
if (this.innerText === 'Screenshot -') { | ||
this.innerText = 'Screenshot +'; | ||
this.nextElementSibling.style.display = 'none'; | ||
} else { | ||
this.innerText = 'Screenshot -'; | ||
this.nextElementSibling.style.display = 'block'; | ||
} | ||
} | ||
var toggleEls = document.querySelectorAll("a.toggle"); | ||
let toggleEls = document.querySelectorAll('a.toggle'); | ||
for(var i = 0; i < toggleEls.length; i++){ | ||
toggleEls[i].addEventListener("click", toggleScreenshot); | ||
for (let i = 0; i < toggleEls.length; i++) { | ||
toggleEls[i].addEventListener('click', toggleScreenshot); | ||
} |
'use strict'; | ||
var chai = require('chai'); | ||
var fs = require('fs-extra'); | ||
var path = require('path'); | ||
const chai = require('chai'); | ||
const fs = require('fs-extra'); | ||
const path = require('path'); | ||
var should = chai.should(); | ||
const should = chai.should(); | ||
module.exports = function assertHtmlReports(outputDirectory) { | ||
function isReportExists(report) { | ||
try { | ||
return fs.statSync(report).isFile(); | ||
} catch (e) { | ||
return false; | ||
} | ||
function isReportExists(report) { | ||
try { | ||
return fs.statSync(report).isFile(); | ||
} catch (e) { | ||
return false; | ||
} | ||
} | ||
function isDirectoryExists(dir) { | ||
return fs.existsSync(dir); | ||
} | ||
function isDirectoryExists(dir) { | ||
return fs.existsSync(dir); | ||
} | ||
var hierarchyHtmlFile = path.join(outputDirectory, 'cucumber_report_hierarchy.html'); | ||
var bootstrapHtmlFile = path.join(outputDirectory, 'cucumber_report_bootstrap.html'); | ||
var foundationHtmlFile = path.join(outputDirectory, 'cucumber_report_foundation.html'); | ||
var simpleHtmlFile = path.join(outputDirectory, 'cucumber_report_simple.html'); | ||
const hierarchyHtmlFile = path.join(outputDirectory, 'cucumber_report_hierarchy.html'); | ||
const bootstrapHtmlFile = path.join(outputDirectory, 'cucumber_report_bootstrap.html'); | ||
const foundationHtmlFile = path.join(outputDirectory, 'cucumber_report_foundation.html'); | ||
const simpleHtmlFile = path.join(outputDirectory, 'cucumber_report_simple.html'); | ||
isReportExists(hierarchyHtmlFile).should.be.equal(true, 'hierarchyHtmlFile file \'' + hierarchyHtmlFile + '\' does not exist'); | ||
isReportExists(bootstrapHtmlFile).should.be.equal(true, 'bootstrapHtmlFile file \'' + bootstrapHtmlFile + '\' does not exist'); | ||
isReportExists(foundationHtmlFile).should.be.equal(true, 'foundationHtmlFile file \'' + foundationHtmlFile + '\' does not exist'); | ||
isReportExists(simpleHtmlFile).should.be.equal(true, 'simpleHtmlFile file \'' + simpleHtmlFile + '\' does not exist'); | ||
isDirectoryExists(path.join(outputDirectory, '..', '..','screenshots')).should.be.equal(true, 'screenshots directory does not exists, at "parentDirectory/screenshots"'); | ||
isReportExists(hierarchyHtmlFile).should.be.equal( | ||
true, | ||
'hierarchyHtmlFile file ' + hierarchyHtmlFile + ' does not exist' | ||
); | ||
isReportExists(bootstrapHtmlFile).should.be.equal( | ||
true, | ||
'bootstrapHtmlFile file' + bootstrapHtmlFile + ' does not exist' | ||
); | ||
isReportExists(foundationHtmlFile).should.be.equal( | ||
true, | ||
'foundationHtmlFile file' + foundationHtmlFile + ' does not exist' | ||
); | ||
isReportExists(simpleHtmlFile).should.be.equal(true, 'simpleHtmlFile file ' + simpleHtmlFile + ' does not exist'); | ||
isDirectoryExists(path.join(outputDirectory, '..', '..', 'screenshots')).should.be.equal( | ||
true, | ||
'screenshots directory does not exists, at "parentDirectory/screenshots"' | ||
); | ||
}; |
@@ -1,90 +0,90 @@ | ||
var path = require('path'); | ||
var fs = require('fs-extra'); | ||
var find = require('find'); | ||
var reporter = require('../index'); | ||
var assertHtmlReports = require('./assert/assertHtmlReports'); | ||
const path = require('path'); | ||
const fs = require('fs-extra'); | ||
const find = require('find'); | ||
const reporter = require('../index.js'); | ||
const assertHtmlReports = require('./assert/assertHtmlReports'); | ||
var theme = { | ||
hierarchy: 'hierarchy', | ||
bootstrap: 'bootstrap', | ||
foundation: 'foundation', | ||
simple: 'simple' | ||
let theme = { | ||
hierarchy: 'hierarchy', | ||
bootstrap: 'bootstrap', | ||
foundation: 'foundation', | ||
simple: 'simple', | ||
}; | ||
var outputDirectory = 'test/report'; | ||
var jsonFile = 'test/report/cucumber_report.json'; | ||
var jsonDir = 'test/report/multi'; | ||
let outputDirectory = 'test/report'; | ||
let jsonFile = 'test/report/cucumber_report.json'; | ||
let jsonDir = 'test/report/multi'; | ||
function removeReports() { | ||
var files = find.fileSync(/\.html/, outputDirectory); | ||
files.map(function (file) { | ||
fs.unlinkSync(file); | ||
}); | ||
let files = find.fileSync(/\.html/, outputDirectory); | ||
files.map(function (file) { | ||
fs.unlinkSync(file); | ||
}); | ||
} | ||
function getOptions(theme) { | ||
return { | ||
name: '@cucumber-html-reporter/*&!@#$%)(~<>`', //this tests for the sanitized hyperlinks on report, otherwise this should be plain text english | ||
theme: theme, | ||
output: path.join(outputDirectory, 'cucumber_report_' + theme + '.html'), | ||
reportSuiteAsScenarios: true, | ||
launchReport: true, | ||
storeScreenshots: true, | ||
screenshotsDirectory: 'screenshots/', | ||
metadata: { | ||
'App Version': '0.3.2', | ||
'Test Environment': 'STAGING', | ||
'Browser': 'Chrome 54.0.2840.98', | ||
'Platform': 'Windows 10', | ||
'Parallel': 'Scenarios', | ||
'Executed': 'Remote' | ||
} | ||
}; | ||
return { | ||
name: '@cucumber-html-reporter/*&!@#$%)(~<>`', //this tests for the sanitized hyperlinks on report, otherwise this should be plain text english | ||
theme: theme, | ||
output: path.join(outputDirectory, 'cucumber_report_' + theme + '.html'), | ||
reportSuiteAsScenarios: true, | ||
// TODO: change launchReport back to 'true' before final merge | ||
launchReport: false, | ||
storeScreenshots: true, | ||
screenshotsDirectory: 'screenshots/', | ||
metadata: { | ||
'App Version': '0.3.2', | ||
'Test Environment': 'STAGING', | ||
Browser: 'Chrome 54.0.2840.98', | ||
Platform: 'Windows 10', | ||
Parallel: 'Scenarios', | ||
Executed: 'Remote', | ||
}, | ||
}; | ||
} | ||
function getJsonFileOptions(theme) { | ||
var options = getOptions(theme); | ||
options.jsonFile = jsonFile; | ||
return options; | ||
let options = getOptions(theme); | ||
options.jsonFile = jsonFile; | ||
return options; | ||
} | ||
function getJsonDirOptions(theme) { | ||
var options = getOptions(theme); | ||
options.jsonDir = jsonDir; | ||
return options; | ||
let options = getOptions(theme); | ||
options.jsonDir = jsonDir; | ||
return options; | ||
} | ||
function assertJsonFile() { | ||
//Generate Hierarchy theme report | ||
reporter.generate(getJsonFileOptions(theme.hierarchy)); | ||
//Generate Hierarchy theme report | ||
reporter.generate(getJsonFileOptions(theme.hierarchy)); | ||
//Generate Bootstrap theme report | ||
reporter.generate(getJsonFileOptions(theme.bootstrap)); | ||
//Generate Bootstrap theme report | ||
reporter.generate(getJsonFileOptions(theme.bootstrap)); | ||
//Generate Foundation theme report | ||
reporter.generate(getJsonFileOptions(theme.foundation)); | ||
//Generate Foundation theme report | ||
reporter.generate(getJsonFileOptions(theme.foundation)); | ||
//Generate Simple theme report | ||
reporter.generate(getJsonFileOptions(theme.simple)); | ||
//Generate Simple theme report | ||
reporter.generate(getJsonFileOptions(theme.simple)); | ||
//assert reports | ||
assertHtmlReports(outputDirectory); | ||
//assert reports | ||
assertHtmlReports(outputDirectory); | ||
} | ||
function assertJsonDir() { | ||
//Generate Hierarchy theme report | ||
reporter.generate(getJsonDirOptions(theme.hierarchy)); | ||
//Generate Hierarchy theme report | ||
reporter.generate(getJsonDirOptions(theme.hierarchy)); | ||
// Generate Bootstrap theme report | ||
reporter.generate(getJsonDirOptions(theme.bootstrap)); | ||
// Generate Bootstrap theme report | ||
reporter.generate(getJsonDirOptions(theme.bootstrap)); | ||
//Generate Foundation theme report | ||
reporter.generate(getJsonDirOptions(theme.foundation)); | ||
//Generate Foundation theme report | ||
reporter.generate(getJsonDirOptions(theme.foundation)); | ||
//Generate Simple theme report | ||
reporter.generate(getJsonDirOptions(theme.simple)); | ||
//Generate Simple theme report | ||
reporter.generate(getJsonDirOptions(theme.simple)); | ||
//assert reports | ||
assertHtmlReports(outputDirectory); | ||
//assert reports | ||
assertHtmlReports(outputDirectory); | ||
} | ||
@@ -97,2 +97,1 @@ | ||
assertJsonFile(); | ||
@@ -1,28 +0,27 @@ | ||
'use strict'; | ||
const { Before, After } = require('@cucumber/cucumber'); | ||
const Before = require('cucumber').Before; | ||
const After = require('cucumber').After; | ||
// const chalk = require('chalk'); | ||
const chalk = require('chalk'); | ||
// Before(function (scenario, callback) { | ||
// console.log( '\n' + chalk.blue.bgYellow.bold('TESTING: ') + chalk.white.bgBlue.bold(' console.log() should not break the report')); | ||
// this.scenario = scenario; | ||
// callback(); | ||
// }); | ||
Before(function (scenario, callback) { | ||
console.log( '\n' + chalk.blue.bgYellow.bold('TESTING: ') + chalk.white.bgBlue.bold(' console.log() should not break the report')); | ||
this.scenario = scenario; | ||
callback(); | ||
}); | ||
Before({ tags: '@testPassing' }, function (scenario, callback) { | ||
this.attach( | ||
'Tests INFO will print here.' + | ||
'<br>To attach INFO to Any steps, use scenario.attach function in your step definitions as shown below.' + | ||
'<br><br>If you pass HTML\'s to scenario.attach then reporter will format accordingly <br>' + | ||
'<br>Simple String : scenario.attach(\'sample data\')' + | ||
'<br>Pretty JSON : scenario.attach(JSON.stringify(json, null, 2))' + | ||
'<br>HTML Link : scenario.attach(\'format the link with html-a tag\'' | ||
); | ||
Before({tags: '@testPassing'}, function (scenario, callback) { | ||
this.attach('Tests INFO will print here.' + | ||
'<br>To attach INFO to Any steps, use scenario.attach function in your step definitions as shown below.' + | ||
'<br><br>If you pass HTML\'s to scenario.attach then reporter will format accordingly <br>' + | ||
'<br>Simple String : scenario.attach(\'sample data\')' + | ||
'<br>Pretty JSON : scenario.attach(JSON.stringify(json, null, 2))' + | ||
'<br>HTML Link : scenario.attach(\'format the link with html-a tag\''); | ||
this.attach('some text'); | ||
callback(); | ||
this.attach('some text'); | ||
callback(); | ||
}); | ||
After({tags: '@testPassing'}, function (scenario, callback) { | ||
callback(); | ||
After({ tags: '@testPassing' }, function (scenario, callback) { | ||
callback(); | ||
}); |
@@ -1,87 +0,83 @@ | ||
'use strict'; | ||
const { Given, When, Then } = require('@cucumber/cucumber'); | ||
const Given = require('cucumber').Given; | ||
const Then = require('cucumber').Then; | ||
const When = require('cucumber').When; | ||
Then(/^this feature runs with background$/, function (callback) { | ||
callback(); | ||
callback(); | ||
}); | ||
Then(/^Fred runs a(?: passing|) cucumber scenario$/, function (callback) { | ||
callback(); | ||
callback(); | ||
}); | ||
Then(/^Fred runs a passing <pre> cucumber step with 2 seconds timeout/, function (callback) { | ||
setTimeout(callback, 2000); | ||
setTimeout(callback, 2000); | ||
}); | ||
Then(/^Fred runs a passing cucumber scenario with the below content$/, function (docString, callback) { | ||
callback(); | ||
callback(); | ||
}); | ||
Given(/^Fred runs a passing cucumber scenario on behalf of "([^"]*)"/, function (name, callback) { | ||
setTimeout(callback, 1000); | ||
callback(null, 'pending'); | ||
setTimeout(callback, 1000); | ||
// callback(null, 'pending'); | ||
}); | ||
Then(/^he provides cucumber JSON file to reporter$/, function (callback) { | ||
callback(); | ||
callback(); | ||
}); | ||
Then(/^Fred runs a failing cucumber scenario$/, function (callback) { | ||
callback(); | ||
callback(); | ||
}); | ||
Then(/^a failing scenario captures a screenshot$/, function (callback) { | ||
var imageData = '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7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7P0/LNizqWeuQHIAAAAASUVORK5CYII='; | ||
this.attach(new Buffer(imageData, 'base64'), 'image/png'); | ||
callback(); | ||
let imageData = | ||
'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7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7Ak4AAAAgOwJOAAAAIDsCTgAAACA7P0/LNizqWeuQHIAAAAASUVORK5CYII='; | ||
this.attach(new Buffer.from(imageData, 'base64'), 'image/png'); | ||
callback(); | ||
}); | ||
Then(/^a failing scenario captures a json payload/, function (callback) { | ||
var jsonData = new Buffer(JSON.stringify({ key: 'value' })).toString('base64'); | ||
this.attach(new Buffer(jsonData, 'base64'), 'application/json'); | ||
callback(); | ||
let jsonData = new Buffer.from(JSON.stringify({ key: 'value' })).toString('base64'); | ||
this.attach(new Buffer.from(jsonData, 'base64'), 'application/json'); | ||
callback(); | ||
}); | ||
Then(/^he throws the pending exception from this step$/, function (callback) { | ||
callback(null, 'pending'); | ||
callback(null, 'pending'); | ||
}); | ||
Then(/^cucumber-html-reporter should report pending step with code-snippets in HTML report$/, function (callback) { | ||
callback(); | ||
callback(); | ||
}); | ||
Then(/^Fred attaches the "([^"]*)" to the Given step of passing cucumber scenario$/, function (testData, callback) { | ||
this.attach(testData); | ||
this.attach(testData); | ||
var myJsonObject = { | ||
name: 'cucumber-html-reporter', | ||
format: 'html' | ||
}; | ||
let myJsonObject = { | ||
name: 'cucumber-html-reporter', | ||
format: 'html', | ||
}; | ||
this.attach(JSON.stringify(myJsonObject, null, 2)); | ||
this.attach(JSON.stringify(myJsonObject, null, 2)); | ||
callback(); | ||
callback(); | ||
}); | ||
Then(/^cucumber-html-reporter should create HTML report/, function (callback) { | ||
callback(); | ||
callback(); | ||
}); | ||
Given(/^Fred runs a passing scenario for the following data set$/, function (table, callback) { | ||
// Write code here that turns the phrase above into concrete actions | ||
callback(); | ||
// Write code here that turns the phrase above into concrete actions | ||
callback(); | ||
}); | ||
When(/^he left this step to be ambiguous$/, function (callback) { | ||
//Write code here that turns the phrase above into concrete actions | ||
callback(); | ||
//Write code here that turns the phrase above into concrete actions | ||
callback(); | ||
}); | ||
When(/^he left this step as a pending$/, function (callback) { | ||
// Write code here that turns the phrase above into concrete actions | ||
callback(null, 'pending'); | ||
// Write code here that turns the phrase above into concrete actions | ||
callback(null, 'pending'); | ||
}); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
1982030
51
2776
325
6