Last active
August 4, 2020 16:34
-
-
Save Phenomite/038c57cdaf95b8b8383a0fd522919662 to your computer and use it in GitHub Desktop.
Cucumber Report JSON Generator - Subfolder recurse for screenshots (fix for Issue#1)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function addScreenshots() { | |
/* Credits: https://gist.github.com/kethinov/6658166#gistcomment-3178557 */ | |
/* Prepend the given path segment */ | |
const prependPathSegment = pathSegment => location => path.join(pathSegment, location); | |
/* fs.readdir but with relative paths */ | |
const readdirPreserveRelativePath = location => fs.readdirSync(location).map(prependPathSegment(location)); | |
/* Recursive fs.readdir but with relative paths */ | |
const readdirRecursive = location => readdirPreserveRelativePath(location) | |
.reduce((result, currentValue) => fs.statSync(currentValue).isDirectory() | |
? result.concat(readdirRecursive(currentValue)) | |
: result.concat(currentValue), []); | |
const screenshots = readdirRecursive(path.resolve(screenshotsDir)).filter(file => { | |
return file.indexOf('.png') > -1 | |
}); | |
/* This is an awful hack to allow matching with the cucumberReportMap */ | |
const featuresList = screenshots.map(x => x.split(/(?:\\|\/)+/).slice(-2)[0]) | |
.filter((value, index, self) => self.indexOf(value) === index); | |
console.log("\nProcessing features:"); | |
console.dir(featuresList); | |
console.log("\nProcessing screenshots:"); | |
console.dir(screenshots); | |
/** Edit: We have already recursed and have the paths to all screenshots | |
* Thus we jump right into the inner loop | |
**/ | |
featuresList.forEach(feature => { | |
screenshots.forEach(screenshot => { | |
// regex to parse 'I can use scenario outlines with examples' from either of these: | |
// - Getting Started -- I can use scenario outlines with examples (example #1) (failed).png | |
// - Getting Started -- I can use scenario outlines with examples (failed).png | |
// Now includes ability to process cucumber statement with the word "screenshot": | |
// - Getting Started -- I can use scenario outlines with examples.png | |
const regex = /(?<=--\ ).+?((?=\ \(example\ #\d+\))|(?=\ \(failed\))|(?=\.\w{3}))/g; | |
const [scenarioName] = screenshot.match(regex); | |
console.info(chalk.blue('\n Adding screenshot to cucumber-json report for')); | |
console.info(chalk.blue(` '${scenarioName}'`)); | |
// Find all scenarios matching the scenario name of the screenshot. | |
// This is important when using the scenario outline mechanism | |
const myScenarios = cucumberReportMap[feature][0].elements.filter( | |
e => scenarioName.includes(e.name) | |
); | |
if (!myScenarios) { return; } | |
myScenarios.forEach(myScenario => { | |
let myStep; | |
if (screenshot.includes('(failed)')) { | |
myStep = myScenario.steps.find( | |
step => step.result.status === 'failed' | |
); | |
} else { | |
myStep = myScenario.steps.find( | |
step => step.name.includes('screenshot') | |
); | |
} | |
if (!myStep) { | |
console.info(chalk.blue("Not adding data!")); | |
return | |
} | |
const data = fs.readFileSync( | |
path.resolve(screenshot) // Since we now already have full location! | |
//path.join(screenshotsDir, feature, screenshot) | |
); | |
if (data) { | |
const base64Image = Buffer.from(data, 'binary').toString('base64') | |
if (!myStep.embeddings) { | |
myStep.embeddings = [] | |
} else { | |
//remove existing screenshot | |
myStep.embeddings.pop(); | |
} | |
myStep.embeddings.push({ data: base64Image, mime_type: 'image/png' }); | |
} | |
}); | |
//Write JSON with screenshot back to report file. | |
console.log(path.join(cucumberJsonDir, cucumberReportFileMap[feature])); | |
fs.writeFileSync( | |
path.join(cucumberJsonDir, cucumberReportFileMap[feature]), | |
JSON.stringify(cucumberReportMap[feature], null, jsonIndentLevel) | |
); | |
}); | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks for the info. I am usingwebnexusmobile's code to generate reports. I am able to generate reports using the code. If there are any failures in any scenarios and when I run node ./cypress/reporting/report.js to generate reports with screenshots getting that error. Here is the code
#!/usr/bin/env node
/**
*/
const report = require('multiple-cucumber-html-reporter')
const fs = require('fs-extra')
const path = require('path')
const chalk = require('chalk')
const cucumberJsonDir = './cypress/test-results/cucumber-json'
const cucumberReportFileMap = {}
const cucumberReportMap = {}
const jsonIndentLevel = 2
const htmlReportDir = './cypress/test-results/html'
const screenshotsDir = './cypress/screenshots'
// const snapshotDir = './cypress/snapshots'
getCucumberReportMaps()
addScreenshots()
// addSnapshots()
generateReport()
function getCucumberReportMaps() {
const files = fs.readdirSync(cucumberJsonDir).filter(file => {
return file.indexOf('.json') > -1
})
files.forEach(file => {
const json = JSON.parse(
fs.readFileSync(path.join(cucumberJsonDir, file))
)
if (!json[0]) { return }
const [feature] = json[0].uri.split('/').reverse()
cucumberReportFileMap[feature] = file
cucumberReportMap[feature] = json
})
}
function addScreenshots() {
/* Credits:
https://gist.github.com/kethinov/6658166#gistcomment-3178557
https://gist.github.com/Phenomite/038c57cdaf95b8b8383a0fd522919662
*/
// Prepend the given path segment
const prependPathSegment = pathSegment => location => path.join(pathSegment, location)
// fs.readdir but with relative paths
const readdirPreserveRelativePath = location => fs.readdirSync(location).map(prependPathSegment(location))
// Recursive fs.readdir but with relative paths
const readdirRecursive = location => readdirPreserveRelativePath(location)
.reduce((result, currentValue) => fs.statSync(currentValue).isDirectory()
? result.concat(readdirRecursive(currentValue))
: result.concat(currentValue), [])
const screenshots = readdirRecursive(path.resolve(screenshotsDir)).filter(file => {
return file.indexOf('.png') > -1
})
// Extract feature list from screenshot list
const featuresList = Array.from(new Set(screenshots.map(x => x.match(/[\w-_.]+.feature/g)[0])))
featuresList.forEach(feature => {
screenshots.forEach(screenshot => {
// regex to parse 'I can use scenario outlines with examples' from either of these:
// - Getting Started -- I can use scenario outlines with examples (example #1) (failed).png
// - Getting Started -- I can use scenario outlines with examples (failed).png
// - Getting Started -- I can use scenario outlines with examples.png
const regex = /(?<=--\ ).+?((?=\ (example\ #\d+))|(?=\ (failed))|(?=.\w{3}))/g
const [scenarioName] = screenshot.match(regex)
console.info(chalk.blue('\n Adding screenshot to cucumber-json report for'))
console.info(chalk.blue(
'${scenarioName}'
))// Find all scenarios matching the scenario name of the screenshot.
// This is important when using the scenario outline mechanism
const myScenarios = cucumberReportMap[feature][0].elements.filter(
e => scenarioName.includes(e.name)
)
if (!myScenarios) { return }
let foundFailedStep = false
myScenarios.forEach(myScenario => {
if (foundFailedStep) {
return
}
let myStep
if (screenshot.includes('(failed)')) {
myStep = myScenario.steps.find(
step => step.result.status === 'failed'
)
} else {
myStep = myScenario.steps.find(
step => step.name.includes('screenshot')
)
}
if (!myStep) {
return
}
const data = fs.readFileSync(
path.resolve(screenshot)
)
if (data) {
const base64Image = Buffer.from(data, 'binary').toString('base64')
if (!myStep.embeddings) {
myStep.embeddings = []
myStep.embeddings.push({ data: base64Image, mime_type: 'image/png' })
foundFailedStep = true
}
}
})
//Write JSON with screenshot back to report file.
fs.writeFileSync(
path.join(cucumberJsonDir, cucumberReportFileMap[feature]),
JSON.stringify(cucumberReportMap[feature], null, jsonIndentLevel)
)
})
})
}
function generateReport() {
if (!fs.existsSync(cucumberJsonDir)) {
console.warn(chalk.yellow(
WARNING: Folder './${cucumberJsonDir}' not found. REPORT CANNOT BE CREATED!
))} else {
report.generate({
jsonDir: cucumberJsonDir,
reportPath: htmlReportDir,
displayDuration: true,
pageTitle: 'System-Test Report',
reportName:
System-Test Report - ${new Date().toLocaleString()}
,metadata: {
browser: {
name: 'chrome'
},
device: 'VM',
platform: {
name: 'linux'
}
}
})
}
}