Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 15 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,15 @@ Jest reporter to generate hierarchical html report
### Installation

---

Install with npm

```shell
npm install htmlreport4jest --save-dev
```

Install with yarn

```shell
yarn add htmlreport4jest --dev
```
Expand Down Expand Up @@ -44,14 +47,15 @@ Executing the jest tests with above configuration will create a `result.html` un

The options below are specific to the reporter.

| Option Name | Type | Default | Description |
| :------------ | :------ | :----------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `title` | string | 'Jest Html Report' | Title of the generated html report |
| `reportPath` | string | './temp/' | Generated html file will be stored under the given path |
| `reportFileName` | string | 'result.html' | Name of the html report to be generated |
| `hideMenu` | boolen | false | Hides filter menu
| `expandResults` | boolen | false | Expand result tabs in report
| `expandMenuItems` | boolen | false | Expand menu nodes in menu
| Option Name | Type | Default | Description |
| :---------------- | :----- | :----------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `title` | string | 'Jest Html Report' | Title of the generated html report |
| `reportPath` | string | './temp/' | Generated html file will be stored under the given path |
| `reportFileName` | string | 'result.html' | Name of the html report to be generated |
| `hideMenu` | boolen | false | Hides filter menu |
| `expandResults` | boolen | false | Expand result tabs in report |
| `expandMenuItems` | boolen | false | Expand menu nodes in menu |
| `information` | array | | Displays information in the report. Information should be in below format. `[{title:"Environment",value:"CI",type:"string"}]`. Allowed values for type will be string and date. All date will be formated as dd-MMM-yyyy |

#### example add config options

Expand All @@ -63,10 +67,12 @@ The options below are specific to the reporter.
"title": 'Jest Html Report',
"reportPath": './temp/',
"reportFileName": 'result.html',
"hideMenu": true
"hideMenu": true,
"information": [{ title: 'Environment', value: 'CI', type: 'string' }]
}]
]
```

### Sample report

![Sample report](artifacts/Report.png)
Binary file modified artifacts/Report.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ module.exports = {
title: 'Test Report',
expandResults: true,
expandMenuItems: true,
information: [
{ title: 'Date', value: new Date(), type: 'date' },
{ title: 'Environment', value: 'CI', type: 'string' },
],
},
],
],
Expand Down
4 changes: 1 addition & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,7 @@
"url": "https://github.com/contactvinoth89/HTMLReport4Jest/issues"
},
"homepage": "https://github.com/contactvinoth89/HTMLReport4Jest#readme",
"dependencies": {
"fs": "^0.0.1-security"
},
"dependencies": {},
"scripts": {
"start": "webpack-dev-server --config webpack.development.config.js --open",
"build": "webpack --config webpack.build.config.js --mode production",
Expand Down
3 changes: 3 additions & 0 deletions src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,9 @@ class App extends Component {
expandResults={
this.state.testResults?.reporterOptions?.expandResults
}
information={
this.state.testResults?.reporterOptions?.information
}
/>
</div>
);
Expand Down
15 changes: 9 additions & 6 deletions src/Components/Main/Main.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
/* eslint-disable prettier/prettier */
import React, { Component } from 'react';
import './Main.css';
import Summary from '../Summary/Summary';
import GridHeader from '../Grid/GridHeader';
import GridTabView from '../Grid/GridTabView';
import Modal from './../Modal/Modal';
import PropTypes from 'prop-types';
import Information from '../Modal/Information';

class Main extends Component {
constructor(props) {
super(props);
Expand All @@ -26,15 +27,15 @@ class Main extends Component {
componentDidUpdate(prevProps) {
if (
prevProps.testResults.numFailedTests !==
this.props.testResults.numFailedTests ||
this.props.testResults.numFailedTests ||
prevProps.testResults.numPassedTests !==
this.props.testResults.numPassedTests ||
this.props.testResults.numPassedTests ||
prevProps.testResults.numTotalTests !==
this.props.testResults.numTotalTests ||
this.props.testResults.numTotalTests ||
prevProps.testResults.numPendingTests !==
this.props.testResults.numPendingTests ||
this.props.testResults.numPendingTests ||
prevProps.testResults.numTodoTests !==
this.props.testResults.numTodoTests
this.props.testResults.numTodoTests
) {
this.setState({
resultSummary: {
Expand All @@ -61,6 +62,7 @@ class Main extends Component {
return (
<div className="main">
<Summary resultSummary={this.state.resultSummary} />
<Information info={this.props.information}></Information>
<GridHeader />
<GridTabView
expandResults={this.props.expandResults}
Expand All @@ -79,5 +81,6 @@ class Main extends Component {
Main.propTypes = {
testResults: PropTypes.any.isRequired,
expandResults: PropTypes.any,
information: PropTypes.array,
};
export default Main;
71 changes: 71 additions & 0 deletions src/Components/Main/Main.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import '@testing-library/jest-dom';
import React from 'react';
import Main from './Main';
import { render } from '@testing-library/react';
test('Should display information', () => {
const testResults = {
title: 'All',
id: '1',
children: [
{
title: 'Test Title',
duration: 25,
status: 'passed',
id: '2',
failureMessages: [],
},
],
};

const information = [{ title: 'Title', value: 'Value', type: 'string' }];
const { container } = render(
<Main testResults={testResults} information={information}></Main>,
);
expect(container.querySelector('.infoWrapper').childNodes.length).toEqual(
2,
);
});

test('Should hide information when null', () => {
const testResults = {
title: 'All',
id: '1',
children: [
{
title: 'Test Title',
duration: 25,
status: 'passed',
id: '2',
failureMessages: [],
},
],
};
const { container } = render(
<Main testResults={testResults} information={null}></Main>,
);
expect(container.querySelector('.infoWrapper').childNodes.length).toEqual(
0,
);
});

test('Should hide information when undefined', () => {
const testResults = {
title: 'All',
id: '1',
children: [
{
title: 'Test Title',
duration: 25,
status: 'passed',
id: '2',
failureMessages: [],
},
],
};
const { container } = render(
<Main testResults={testResults} information={undefined}></Main>,
);
expect(container.querySelector('.infoWrapper').childNodes.length).toEqual(
0,
);
});
4 changes: 2 additions & 2 deletions src/Components/Modal/ErrorMessage.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import ErrorMessage from './ErrorMessage';
import { render } from '@testing-library/react';
test('Should return empty message when null', () => {
const { container } = render(<ErrorMessage messages={null}></ErrorMessage>);
expect(container.firstChild.firstChild).toBeEmpty();
expect(container.firstChild.firstChild).toBeEmptyDOMElement();
});
test('Should return empty message when empty', () => {
const { container } = render(<ErrorMessage messages={[]}></ErrorMessage>);
expect(container.firstChild.firstChild).toBeEmpty();
expect(container.firstChild.firstChild).toBeEmptyDOMElement();
});

test('Should return html message', () => {
Expand Down
1 change: 1 addition & 0 deletions src/Components/Modal/Information.css
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@
auto-fill,
minmax(150px, 1fr) minmax(300px, 2fr)
);
padding: 10px 0px;
}
27 changes: 19 additions & 8 deletions src/Components/Modal/Information.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,29 @@
import React, { Fragment } from 'react';
import PropTypes from 'prop-types';
import './Information.css';
import DateUtilities from './../../Utilities/DateUtilities';
export default class Information extends React.Component {
formatData(item) {
if (item?.type && item?.value && item.type === 'date') {
return new DateUtilities().formatDate(item.value);
} else {
return item?.value;
}
}
render() {
return (
<div className="infoWrapper">
{this.props.info.map((item, index) => {
return (
<Fragment key={index}>
<div className="box box1">{item.title}</div>
<div className="box box2">{item.value}</div>
</Fragment>
);
})}
{Array.isArray(this.props.info) &&
this.props.info.map((item, index) => {
return (
<Fragment key={index}>
<div className="box box1">{item.title}</div>
<div className="box box2">
{this.formatData(item)}
</div>
</Fragment>
);
})}
</div>
);
}
Expand Down
15 changes: 15 additions & 0 deletions src/Components/Modal/Information.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,25 @@ test('Return empty when array is empty', () => {
const { container } = render(<Information info={info}></Information>);
expect(container.firstChild.childNodes.length).toEqual(0);
});
test('Return empty when object is passed', () => {
const info = {};
const { container } = render(<Information info={info}></Information>);
expect(container.firstChild.childNodes.length).toEqual(0);
});
test('Should have title and value', () => {
const info = [{ title: 'Title', value: 'Value' }];
const { container } = render(<Information info={info}></Information>);
expect(container.firstChild.childNodes.length).toEqual(2);
expect(container.firstChild.childNodes[0].textContent).toEqual('Title');
expect(container.firstChild.childNodes[1].textContent).toEqual('Value');
});
test('Should have formatted date', () => {
const info = [
{ title: 'Title', value: '2020-08-08T12:04:14.473Z', type: 'date' },
];
const { container } = render(<Information info={info}></Information>);
expect(container.firstChild.childNodes.length).toEqual(2);
expect(container.firstChild.childNodes[1].textContent).toEqual(
'08-Aug-2020',
);
});
41 changes: 28 additions & 13 deletions src/Utilities/DateUtilities.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/* eslint-disable prettier/prettier */
export default class DateUtilities {
convertMillisecondsToTime(milliSeconds) {
if (milliSeconds && !isNaN(milliSeconds)) {
Expand All @@ -8,22 +7,38 @@ export default class DateUtilities {
if (Math.floor(hours) > 0) {
return `${Math.floor(hours)} hrs${
Math.floor(minutes % 60)
? ` : ${ Math.floor(minutes % 60) } mins`
? ` : ${Math.floor(minutes % 60)} mins`
: ''
}`;
}else if (Math.floor(minutes) > 0) {
}`;
} else if (Math.floor(minutes) > 0) {
return `${Math.floor(minutes)} mins${
Math.floor(seconds % 60)
? ` : ${ Math.floor(seconds % 60) } secs`
? ` : ${Math.floor(seconds % 60)} secs`
: ''
}`;
}else if (Math.floor(seconds) > 0) {
return `${Math.floor(seconds) } secs`;
}else
{return `${milliSeconds } ms`;}

}
}`;
} else if (Math.floor(seconds) > 0) {
return `${Math.floor(seconds)} secs`;
} else {
return `${milliSeconds} ms`;
}
}
return '';
}
formatDate(date) {
if (date) {
date = new Date(date);
const ye = new Intl.DateTimeFormat('en', {
year: 'numeric',
}).format(date);
const mo = new Intl.DateTimeFormat('en', { month: 'short' }).format(
date,
);
const da = new Intl.DateTimeFormat('en', { day: '2-digit' }).format(
date,
);
return `${da}-${mo}-${ye}`;
} else {
return '';

}
}
}
15 changes: 14 additions & 1 deletion src/Utilities/DateUtilities.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import DateUtilities from './DateUtilities';
describe('Timeformatting', () => {
describe('Time formatting', () => {
test('Should return empty for null', () => {
const data = null;
const result = new DateUtilities().convertMillisecondsToTime(data);
Expand Down Expand Up @@ -66,3 +66,16 @@ describe('Timeformatting', () => {
expect(result).toEqual('1 hrs : 1 mins');
});
});

describe('Date formatting', () => {
test('format date string', () => {
const data = '2020-08-08T12:04:14.473Z';
expect(new DateUtilities().formatDate(data)).toEqual('08-Aug-2020');
});
test('return empty string when null', () => {
expect(new DateUtilities().formatDate(null)).toEqual('');
});
test('return empty string when undefined', () => {
expect(new DateUtilities().formatDate(undefined)).toEqual('');
});
});