Skip to content
This repository has been archived by the owner on May 1, 2024. It is now read-only.

Commit

Permalink
breaking: represent the feature file tree in sidebar buttons (#41)
Browse files Browse the repository at this point in the history
BEAKING CHANGE:  breaks method param order
  • Loading branch information
nikitaprabhakar authored and Tobiah committed Apr 10, 2020
1 parent 8d47a4e commit f943279
Show file tree
Hide file tree
Showing 15 changed files with 1,526 additions and 706 deletions.
29 changes: 2 additions & 27 deletions .travis/regenerateDocsReport.js
Original file line number Diff line number Diff line change
@@ -1,34 +1,9 @@
#!/usr/bin/env node
const fs = require('fs');
const path = require('path');
const { exec } = require('child_process');
const Generator = require('../src/Generator');

const FILE_ENCODING = 'utf-8';

const getFeatureFiles = (directoryName) => {
if (directoryName.endsWith('node_modules')) {
return [];
}

// Recurse on directories:
const isDirectory = (source) => fs.lstatSync(source).isDirectory();
const getDirectories = (source) => fs
.readdirSync(source)
.map((name) => path.join(source, name))
.filter(isDirectory);
const subDirectories = getDirectories(directoryName);
const featureFiles = [];
subDirectories.forEach((subDirectory) => featureFiles.push(...getFeatureFiles(subDirectory)));

// Add feature files from this directory.
const allFiles = fs.readdirSync(directoryName);
const localFeatureFiles = allFiles.filter((item) => item.endsWith('.feature'));
localFeatureFiles.forEach((featureFileName) => featureFiles.push(`${directoryName}/${featureFileName}`));
return featureFiles;
};

const featureFiles = getFeatureFiles(path.resolve(__dirname, '../'));
new Generator().generate(featureFiles, 'cucumber-forge-report-generator').then((result) => {
fs.writeFileSync(path.resolve(__dirname, '../docs/index.html'), result, FILE_ENCODING);
});
const report = new Generator().generate(path.resolve(__dirname, '../'), 'cucumber-forge-report-generator')
fs.writeFileSync(path.resolve(__dirname, '../docs/index.html'), report, FILE_ENCODING);
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
[![Build Status](https://travis-ci.com/cerner/cucumber-forge-report-generator.svg?branch=master)](https://travis-ci.com/cerner/cucumber-forge-report-generator)

# _About_

_Note: this repository contains the library for generating Cucumber reports. [Cucumber Forge Desktop](https://github.com/cerner/cucumber-forge-desktop) is a user-friendly desktop application for creating reports with cucumber-forge-report-generator._

The cucumber-forge-report-generator can be used to create clean HTML reports without having to build the project or run the tests. Of course, no pass/fail information for the scenarios is included in the report since the tests are not executed.
Expand All @@ -19,12 +20,14 @@ Many other solutions exist for creating reports based on the output of Cucumber

# _Usage_

Sample - Generates a report from two feature files with the scenarios filtered by a tag:
Sample - Generates a report for the feature files in a given directory with the scenarios filtered by a tag:

```js
const Generator = require('cucumber-forge-report-generator');
const generator = new Generator();
const htmlReportString = generator.generate([filePathString1, filePathString2], 'Project Name', 'TagFilter');
const htmlReportString = generator.generate(featureDirectoryPath, 'Project Name', 'TagFilter');
```

Detailed usage documentation can be found [here](https://engineering.cerner.com/cucumber-forge-report-generator/).

# _Availability_
Expand All @@ -38,6 +41,7 @@ This project is built on [Travis](https://travis-ci.com/cerner/cucumber-forge-re
# _Building_

Development Environment:

* [NPM](https://www.npmjs.com/) - ^6.4.1
* [Node.Js](https://nodejs.org) - ^10.14.1

Expand Down
35 changes: 22 additions & 13 deletions features/generate_report.feature
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Feature: Report Generation
<I want> to generate HTML reports directly from feature files

Background:
Given there is a file named 'dog_care.feature' with the following contents:
Given there is a file named 'dog_care.feature' in the 'feature/dog' directory with the following contents:
"""
@pet_care @dogs
Feature: Dog Care
Expand Down Expand Up @@ -34,7 +34,7 @@ Feature: Report Generation
| backwards | lick my hand |
| forwards | growl |
"""
And there is a file named 'cat_care.feature' with the following contents:
And there is a file named 'cat_care.feature' in the 'feature/cat' directory with the following contents:
"""
@pet_care @cats
Feature: Cat Care
Expand Down Expand Up @@ -65,15 +65,16 @@ Feature: Report Generation
| backwards |
| forwards |
"""
And the variable 'dogCarePath' contains the path to 'dog_care.feature'
And the variable 'catCarePath' contains the path to 'cat_care.feature'
And the variable 'dogCarePath' contains the path to the 'feature/dog' directory
And the variable 'catCarePath' contains the path to the 'feature/cat' directory
And the variable 'allFeaturesPath' contains the path to the 'feature' directory

Scenario: Generating an HTML report for a feature file
Given the current date is {current_date}
And the username of the current user is {username}
When a report is generated with the code "new Generator().generate([this.dogCarePath])"
When a report is generated with the code "new Generator().generate(this.dogCarePath)"
Then the title on the report will be "Feature documentation - {current_date}"
And the report will inculude CSS styling
And the report will include CSS styling
And the report will include a favicon
And the report will contain 1 feature
And the report will contain 2 scenarios
Expand All @@ -82,27 +83,29 @@ Feature: Report Generation
And the project title on the sidebar will be "Feature documentation"
And the header on the sidebar will be "{username} - {current_date}"
And the footer on the sidebar will be "Cucumber Forge"
And the sidebar will contain 1 directory button
And the sidebar will contain 1 feature button
And the sidebar will contain 2 scenario buttons

Scenario: Generating an HTML report for multiple feature files
When a report is generated with the code "new Generator().generate([this.dogCarePath, this.catCarePath])"
Scenario: Generating an HTML report for multiple feature files in different directories
When a report is generated with the code "new Generator().generate(this.allFeaturesPath)"
Then the report will contain 2 features
And the report will contain 4 scenarios
And the sidebar will contain 2 directory buttons
And the sidebar will contain 2 feature buttons
And the sidebar will contain 4 scenario buttons

Scenario: Generating an HTML report when the project name is provided
Given the current date is {current_date}
When a report is generated with the code "new Generator().generate([this.dogCarePath], 'Pet Project')"
When a report is generated with the code "new Generator().generate(this.dogCarePath, 'Pet Project')"
Then the title on the report will be "Pet Project - {current_date}"
And the project title on the sidebar will be "Pet Project"

Scenario Outline: Generating an HTML report filtered by a tag
The features and scenarios included in a report can be filtered based on their tags.
The provided tag can optionally be prefixed with '@'.

When a report is generated with the code "new Generator().generate([this.dogCarePath, this.catCarePath], null, <tag:>)"
When a report is generated with the code "new Generator().generate(this.allFeaturesPath, null, <tag:>)"
Then the report will contain 2 features
And the report will contain 2 scenarios
And the report name on the sidebar will be <tag:>
Expand All @@ -114,7 +117,13 @@ Feature: Report Generation
| 'feeding' |
| '@feeding' |

Scenario: Generating a report when no feature files are provided
@exception
Scenario: Generating a report when no path is provided
When a report is generated with the code "new Generator().generate()"
Then the report will contain 0 features
And the sidebar will contain 0 feature buttons
Then an error will be thrown with the message "A feature directory path must be provided."

@exception
Scenario: Generating a report when no feature files are provided
Given the variable 'noFeaturesPath' contains the path to a directory with no feature files
When a report is generated with the code "new Generator().generate(this.noFeaturesPath)"
Then an error will be thrown with the message "No feature files were found in the given directory."
54 changes: 45 additions & 9 deletions features/support/generationSteps.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,35 @@ const FILE_ENCODING = 'utf-8';
// eslint-disable-next-line no-unused-vars
const Generator = require('../../src/Generator');

Given('there is a file named {string} with the following contents:', function (fileName, contents) {
const filePath = path.resolve(__dirname, fileName);
Given('there is a file named {string} in the {string} directory with the following contents:', function (fileName, fileDirectory, contents) {
const dirPaths = fileDirectory.split('/');
let dirPath = path.resolve(__dirname, dirPaths[0]);
if (!fs.existsSync(dirPath)) {
fs.mkdirSync(dirPath);
this.featureDirs.push(dirPath);
}
if (dirPaths.length > 1) {
dirPath = path.resolve(dirPath, dirPaths[1]);
if (!fs.existsSync(dirPath)) {
fs.mkdirSync(dirPath);
this.featureDirs.push(dirPath);
}
}
const filePath = path.resolve(dirPath, fileName);
this.featureFiles.push(filePath);
fs.writeFileSync(filePath, contents, FILE_ENCODING);
});

Given('the variable {string} contains the path to {string}', function (variableName, fileName) {
this[variableName] = path.resolve(__dirname, fileName);
Given('the variable {string} contains the path to the {string} directory', function (variableName, fileName) {
this[variableName] = path.resolve(__dirname, ...fileName.split('/'));
});

Given('the variable {string} contains the path to a directory with no feature files', function (variableName) {
const dirPath = path.resolve(__dirname, 'noFeatures');
fs.mkdirSync(dirPath);
this.featureDirs.push(dirPath);

this[variableName] = dirPath;
});

Given(/^the current date is \{current_date\}$/, function () {
Expand All @@ -31,17 +52,27 @@ Given(/^the username of the current user is \{username\}$/, function () {
});

When('a report is generated with the code {string}', function (generationFunction) {
// eslint-disable-next-line no-eval
return eval(generationFunction)
.then(output => this.setOutput(output));
try {
// eslint-disable-next-line no-eval
this.setOutput(eval(generationFunction));
} catch (error) {
if (!this.exceptionScenario) {
throw error;
}
this.setOutput(error);
}
});

Then('an error will be thrown with the message {string}', function (errMsg) {
expect(this.output.message).to.eq(errMsg);
});

Then('the title on the report will be {string}', function (reportTitle) {
const title = reportTitle.replace('{current_date}', this.currentDate);
expect(this.outputHTML.title).to.eql(title);
});

Then('the report will inculude CSS styling', function () {
Then('the report will include CSS styling', function () {
const styles = this.outputHTML.getElementsByTagName('STYLE');
expect(styles.length).to.eql(1);
const style = styles.item(0);
Expand Down Expand Up @@ -88,10 +119,15 @@ Then('the report will contain {int} scenario(s)', function (scenarioCount) {
Then('the report will not contain gherkin comments', function () {
const commentPattern = new RegExp('^#.*');
const comments = Array.from(this.outputHTML.getElementsByTagName('*'))
.filter(obj => commentPattern.test(obj.innerHTML));
.filter((obj) => commentPattern.test(obj.innerHTML));
expect(comments.length).to.eql(0);
});

Then('the sidebar will contain {int} directory button(s)', function (directoryButtonCount) {
const directoryButtons = this.outputHTML.getElementsByClassName('directory-button');
expect(directoryButtons.length).to.eql(directoryButtonCount);
});

Then('the sidebar will contain {int} feature button(s)', function (featureButtonCount) {
const featureButtons = this.outputHTML.getElementsByClassName('feature-button');
expect(featureButtons.length).to.eql(featureButtonCount);
Expand Down
Loading

0 comments on commit f943279

Please sign in to comment.