Skip to content

Commit 775d539

Browse files
Merge branch 'reports' of https://github.com/testsigmahq/testsigma into reports
2 parents 2d3d51f + 6ff6d8b commit 775d539

File tree

4 files changed

+107
-1
lines changed

4 files changed

+107
-1
lines changed

server/src/main/java/com/testsigma/controller/ReportsController.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import com.testsigma.specification.SearchOperation;
2424
import com.testsigma.web.request.ElementRequest;
2525
import com.testsigma.web.request.ElementScreenNameRequest;
26+
import com.testsigma.web.request.TestCaseRequest;
2627
import lombok.RequiredArgsConstructor;
2728
import lombok.extern.log4j.Log4j2;
2829
import org.json.JSONArray;
@@ -89,4 +90,11 @@ public List<FailuresByCategoryDTO> getFailuresByCategory(@RequestParam("versionI
8990
return this.reportsService.getFailuresByCategory(versionId);
9091
}
9192

93+
@RequestMapping(value = "/generate_query_report", method = RequestMethod.POST)
94+
@ResponseBody
95+
public ResponseEntity<Object> update(@RequestBody String query) throws TestsigmaException, SQLException, CloneNotSupportedException {
96+
List<Map<String,Object>> entities = this.reportsService.getQueryReport(query);
97+
return new ResponseEntity<>(entities, HttpStatus.OK);
98+
}
99+
92100
}

server/src/main/java/com/testsigma/service/ReportsService.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
import com.fasterxml.jackson.core.JsonProcessingException;
55
import com.fasterxml.jackson.core.type.TypeReference;
6+
import com.fasterxml.jackson.databind.ObjectMapper;
67
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
78
import com.testsigma.dto.*;
89
import com.testsigma.dto.export.TestCaseCloudXMLDTO;
@@ -33,6 +34,8 @@
3334
import org.springframework.data.jpa.domain.Specification;
3435
import org.springframework.stereotype.Service;
3536

37+
import javax.persistence.EntityManager;
38+
import javax.persistence.Query;
3639
import java.io.IOException;
3740
import java.lang.reflect.Method;
3841
import java.sql.SQLException;
@@ -49,6 +52,8 @@ public class ReportsService {
4952
private final TestCaseService testCaseService;
5053

5154
private final TestCaseRepository testCaseRepository;
55+
56+
private final EntityManager entityManager;
5257
public JSONArray getReport(Long reportId){
5358
JSONArray reportObject = new JSONArray();
5459
Optional<Report> report = reportsRepository.findById(reportId);
@@ -117,4 +122,28 @@ public List<LingeredTestsDTO> getLingeredTests(Long versionId){
117122
public List<FailuresByCategoryDTO> getFailuresByCategory(Long versionId){
118123
return testCaseRepository.getFailuresByCategory(versionId);
119124
}
125+
126+
public List<Map<String,Object>> getQueryReport(String query){
127+
try{
128+
Query nativeQuery = entityManager.createNativeQuery(query);
129+
List<Object> resultObject = nativeQuery.getResultList();
130+
ObjectMapper objectMapper = new ObjectMapper();
131+
List<Map<String,Object>> toBeReturned = new ArrayList<Map<String,Object>>();
132+
Integer i = 0;
133+
for(Object result:resultObject){
134+
String queryResult = objectMapper.writeValueAsString(result);
135+
queryResult = queryResult.substring(1); // index starts at zero
136+
queryResult = queryResult.substring(0, queryResult.length() - 1);
137+
List<Object> resultList = new ArrayList<Object>(Arrays.asList(queryResult.split(",")));
138+
Map<String, Object> resultIndex = new HashMap<>();
139+
resultIndex.put(i.toString(),resultList);
140+
toBeReturned.add(resultIndex);
141+
i++;
142+
}
143+
return toBeReturned;
144+
} catch(Exception e){
145+
log.error("This shouldnt come.....");
146+
return new ArrayList<Map<String,Object>>();
147+
}
148+
}
120149
}

ui/src/app/components/reports.component.ts

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import { Component, OnInit } from '@angular/core';
2-
import {ActivatedRoute} from "@angular/router";
2+
import {ActivatedRoute, Router} from "@angular/router";
33
import * as Highcharts from 'highcharts';
44
import {ReportsService} from "../services/reports.service";
55
import {AuthenticationGuard} from "../shared/guards/authentication.guard";
66
import jspdf from 'jspdf';
77
import html2canvas from 'html2canvas';
88
import {TestDeviceResult} from "../models/test-device-result.model";
99
import {TestSuiteResult} from "../models/test-suite-result.model";
10+
import {FormControl, FormGroup, Validators} from "@angular/forms";
1011

1112
@Component({
1213
selector: 'app-reports',
@@ -18,6 +19,7 @@ import {TestSuiteResult} from "../models/test-suite-result.model";
1819
export class ReportsComponent implements OnInit {
1920
constructor(
2021
private route: ActivatedRoute,
22+
public router: Router,
2123
public authGuard: AuthenticationGuard,
2224
public reportsService: ReportsService
2325
) {
@@ -28,6 +30,36 @@ export class ReportsComponent implements OnInit {
2830
public topFailuresChartOptions : Highcharts.Options;
2931
public lingeredTestsChartOptions : Highcharts.Options;
3032
public failuresByCategoryChartOptions : Highcharts.Options;
33+
public queryReportsForm: FormGroup;
34+
public modules: any[] = [
35+
{name:"TestCases"},
36+
{name:"TestSuites"},
37+
{name:"TestPlans"},
38+
];
39+
public dataSource: any[];
40+
public showTable = false;
41+
public columns = [
42+
{
43+
columnDef: 'position',
44+
header: 'No.',
45+
cell: (element: any) => `${element}`,
46+
},
47+
{
48+
columnDef: 'name',
49+
header: 'Name',
50+
cell: (element: any) => `${element}`,
51+
},
52+
{
53+
columnDef: 'weight',
54+
header: 'Weight',
55+
cell: (element: any) => `${element}`,
56+
},
57+
{
58+
columnDef: 'symbol',
59+
header: 'Symbol',
60+
cell: (element: any) => `${element}`,
61+
},
62+
];
3163

3264

3365
ngOnInit(): void {
@@ -36,6 +68,13 @@ export class ReportsComponent implements OnInit {
3668
this.populateTopFailuresChartOptions();
3769
this.populateLingeredTestsChartOptions();
3870
this.populateFailuresByCategoryChartOptions();
71+
this.isDashboard();
72+
this.router.onSameUrlNavigation = 'reload';
73+
this.queryReportsForm = new FormGroup({
74+
name: new FormControl("", [Validators.required, Validators.minLength(4), Validators.maxLength(250)]),
75+
description: new FormControl(""),
76+
module: new FormControl("")
77+
})
3978
}
4079

4180
populateFlakyTestsChartOptions() {
@@ -396,4 +435,25 @@ export class ReportsComponent implements OnInit {
396435
obj.categories = categories;
397436
return obj;
398437
}
438+
439+
isDashboard(){
440+
return this.router.url.indexOf("analytics")!=-1;
441+
}
442+
443+
goToPage(url){
444+
this.router.routeReuseStrategy.shouldReuseRoute = function () {
445+
return false;
446+
}
447+
this.router.onSameUrlNavigation = 'reload';
448+
this.router.navigate(['/reports', url]);
449+
}
450+
451+
getQueryReport(){
452+
let query = this.queryReportsForm.controls["description"].value;
453+
this.reportsService.runQueryReport(query).subscribe((res)=>{
454+
console.log(res);
455+
this.dataSource = res;
456+
this.showTable = true;
457+
});
458+
}
399459
}

ui/src/app/services/reports.service.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,4 +93,13 @@ export class ReportsService{
9393
);
9494
}
9595

96+
public runQueryReport(any: any): Observable<any> {
97+
return this.http.post<any>(this.URLConstants.reportsURL+"/generate_query_report", any, {
98+
headers: this.httpHeaders.contentTypeApplication
99+
}).pipe(
100+
map(data => data),
101+
catchError((error) => throwError(error))
102+
);
103+
}
104+
96105
}

0 commit comments

Comments
 (0)