Skip to content

Commit 0e143c1

Browse files
authored
Feature/testcase report and assertion raw editor (#21)
* Report downloads and assertion raw editor implemented * Added feature for changing the order of assertions * bumped up the version
1 parent 4fa4d98 commit 0e143c1

File tree

6 files changed

+642
-358
lines changed

6 files changed

+642
-358
lines changed

audit-resolve.json

Lines changed: 387 additions & 307 deletions
Large diffs are not rendered by default.

package-lock.json

Lines changed: 21 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "ml-testing-toolkit-ui",
3-
"version": "9.5.5",
3+
"version": "10.1.1",
44
"description": "Frontend UI for Mojaloop Testing Toolkit",
55
"main": "index.js",
66
"repository": {
@@ -47,11 +47,13 @@
4747
"@progress/kendo-theme-default": "^4.10.0",
4848
"ace-builds": "1.3.1",
4949
"antd": "^3.26.4",
50+
"array-move": "2.2.1",
5051
"axios": "^0.19.0",
5152
"bootstrap": "^4.4.1",
5253
"brace": "^0.11.1",
5354
"chart.js": "2.7.3",
5455
"classnames": "2.2.6",
56+
"js-file-download": "0.4.12",
5557
"json-schema-faker": "^0.5.0-rc23",
5658
"jsoneditor": "^8.0.0",
5759
"jsoneditor-react": "^2.0.0",
@@ -71,6 +73,7 @@
7173
"react-json-editor-ajrm": "^2.5.9",
7274
"react-router-dom": "4.3.1",
7375
"react-scripts": "3.4.0",
76+
"react-sortable-hoc": "1.11.0",
7477
"reactstrap": "7.1.0",
7578
"socket.io-client": "^2.3.0"
7679
},

src/test/unit/views/outbound/TestAssertions.test.jsx

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,19 @@ Enzyme.configure({ disableLifecycleMethods: true })
1111

1212
const { shallow, render, mount } =Enzyme
1313

14+
15+
// Mock the Json Editor third party component used
16+
jest.mock('jsoneditor-react', () => {
17+
return function DummyJsonEditor(props) {
18+
return (
19+
<div>
20+
Dummy JSON Editor
21+
</div>
22+
)
23+
}
24+
})
25+
26+
1427
describe('TestAssertions', () => {
1528
describe('ConfigurableParameter', () => {
1629
const rootParameters = {}

src/views/outbound/OutboundRequest.jsx

Lines changed: 63 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,13 @@ import socketIOClient from "socket.io-client";
3333
import Header from "../../components/Headers/Header.jsx";
3434

3535

36-
import { Input, Row, Col, Affix, Descriptions, Modal, Icon, message, Popover, Upload, Progress } from 'antd';
36+
import { Input, Row, Col, Affix, Descriptions, Modal, Icon, message, Popover, Upload, Progress, Menu, Dropdown } from 'antd';
3737

3838
import axios from 'axios';
3939
import TestCaseEditor from './TestCaseEditor'
4040
import TestCaseViewer from './TestCaseViewer'
4141
import getConfig from '../../utils/getConfig'
42+
import FileDownload from 'js-file-download'
4243

4344
class InputValues extends React.Component {
4445

@@ -170,7 +171,8 @@ class OutboundRequest extends React.Component {
170171
showTestCaseIndex: null,
171172
renameTestCase: false,
172173
totalPassedCount: 0,
173-
totalAssertionsCount: 0
174+
totalAssertionsCount: 0,
175+
testReport: null
174176
};
175177
}
176178

@@ -221,6 +223,7 @@ class OutboundRequest extends React.Component {
221223
handleIncomingProgress = (progress) => {
222224
if (progress.status === 'FINISHED') {
223225
message.success({ content: 'Test case finished', key: 'outboundSendProgress', duration: 2 });
226+
this.setState({testReport: progress.totalResult})
224227
} else {
225228
let testCase = this.state.template.test_cases.find(item => item.id === progress.testCaseId)
226229
let request = testCase.requests.find(item => item.id === progress.requestId)
@@ -267,13 +270,15 @@ class OutboundRequest extends React.Component {
267270
// Initialize counts to zero
268271
this.state.totalPassedCount = 0
269272
this.state.totalAssertionsCount = 0
273+
this.state.testReport = null
274+
270275

271276
const outboundRequestID = Math.random().toString(36).substring(7);
272277
message.loading({ content: 'Sending the outbound request...', key: 'outboundSendProgress' });
273278
const { apiBaseUrl } = getConfig()
274279
this.state.template = this.convertTemplate(this.state.template)
275280
await axios.post(apiBaseUrl + "/api/outbound/template/" + outboundRequestID, this.state.template, { headers: { 'Content-Type': 'application/json' } })
276-
message.success({ content: 'Test case initiated', key: 'outboundSendProgress', duration: 2 });
281+
message.loading({ content: 'Executing the test cases...', key: 'outboundSendProgress', duration: 10 });
277282

278283
// Set the status to waiting for all the requests
279284
for (let i in this.state.template.test_cases) {
@@ -418,7 +423,6 @@ class OutboundRequest extends React.Component {
418423
var content = e.target.result;
419424
try {
420425
var intern = JSON.parse(content);
421-
console.log(file_to_read)
422426
this.setState({template: intern, additionalData: { importedFilename: file_to_read.name }})
423427
this.autoSave = true
424428
message.success({ content: 'File Loaded', key: 'importFileProgress', duration: 2 });
@@ -427,6 +431,35 @@ class OutboundRequest extends React.Component {
427431
}
428432
};
429433
fileRead.readAsText(file_to_read);
434+
}
435+
436+
handleDownloadReport = async (event) => {
437+
switch(event.key) {
438+
case 'json':
439+
const jsonReportFileName = this.state.testReport.name + (this.state.testReport.runtimeInformation ? '-' + this.state.testReport.runtimeInformation.completedTimeISO : '') + '.json'
440+
FileDownload(JSON.stringify(this.state.testReport, null, 2), jsonReportFileName)
441+
break
442+
case 'pdf':
443+
case 'html':
444+
default:
445+
message.loading({ content: 'Generating the report...', key: 'downloadReportProgress', duration: 10 });
446+
const { apiBaseUrl } = getConfig()
447+
const reportFormat = event.key
448+
const response = await axios.post(apiBaseUrl + "/api/reports/testcase/" + reportFormat, this.state.testReport, { headers: { 'Content-Type': 'application/json' }, responseType: 'blob' })
449+
let downloadFilename = "test." + reportFormat
450+
if (response.headers['content-disposition']) {
451+
const disposition = response.headers['content-disposition']
452+
if (disposition && disposition.indexOf('attachment') !== -1) {
453+
var filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
454+
var matches = filenameRegex.exec(disposition);
455+
if (matches != null && matches[1]) {
456+
downloadFilename = matches[1].replace(/['"]/g, '');
457+
}
458+
}
459+
}
460+
FileDownload(response.data, downloadFilename)
461+
message.success({ content: 'Report Generated', key: 'downloadReportProgress', duration: 2 });
462+
}
430463

431464
}
432465

@@ -475,6 +508,16 @@ class OutboundRequest extends React.Component {
475508
return null
476509
}
477510

511+
downloadReportMenu = () => {
512+
return (
513+
<Menu onClick={this.handleDownloadReport}>
514+
<Menu.Item key='json'>JSON format</Menu.Item>
515+
<Menu.Item key='pdf'>PDF report</Menu.Item>
516+
<Menu.Item key='html'>HTML report</Menu.Item>
517+
</Menu>
518+
)
519+
}
520+
478521
render() {
479522

480523
const createNewTestCaseDialogContent = (
@@ -695,6 +738,22 @@ class OutboundRequest extends React.Component {
695738
New Template
696739
</Button>
697740
</Popover>
741+
{
742+
this.state.testReport
743+
? (
744+
<Dropdown overlay={this.downloadReportMenu()}>
745+
<Button
746+
className="float-right"
747+
color="danger"
748+
size="sm"
749+
onClick={e => e.preventDefault()}
750+
>
751+
Download Report
752+
</Button>
753+
</Dropdown>
754+
)
755+
: null
756+
}
698757
</Col>
699758
</Row>
700759
</CardBody>

0 commit comments

Comments
 (0)