--- /dev/null
+/* Copyright (c) 2019 AT&T Intellectual Property. #\r
+# #\r
+# Licensed under the Apache License, Version 2.0 (the "License"); #\r
+# you may not use this file except in compliance with the License. #\r
+# You may obtain a copy of the License at #\r
+# #\r
+# http://www.apache.org/licenses/LICENSE-2.0 #\r
+# #\r
+# Unless required by applicable law or agreed to in writing, software #\r
+# distributed under the License is distributed on an "AS IS" BASIS, #\r
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #\r
+# See the License for the specific language governing permissions and #\r
+# limitations under the License. #\r
+##############################################################################*/\r
+\r
+\r
+import { Injectable } from '@angular/core';\r
+import { FeathersService } from 'app/shared/services/feathers.service';\r
+import { TestExecutionService } from 'app/shared/services/test-execution.service';\r
+import { Observable, Subject, from } from 'rxjs';\r
+import { MatDialog } from '@angular/material';\r
+import { GroupService } from 'app/shared/services/group.service';\r
+import * as moment from 'moment';\r
+import { SchedulingService } from 'app/shared/services/scheduling.service';\r
+import { TestInstanceService } from 'app/shared/services/test-instance.service';\r
+import { string, number } from '@amcharts/amcharts4/core';\r
+import { group } from '@angular/animations';\r
+export interface StatsFilter {\r
+ startDate?: Date,\r
+ endDate?: Date,\r
+ selectedTestDefinitions?: Array<any>,\r
+ selectedTestInstances?: Array<any>\r
+}\r
+\r
+@Injectable({\r
+ providedIn: 'root'\r
+})\r
+\r
+//this service serves as the controller between the dashboard's data management and the components' UI.\r
+export class StatsService {\r
+\r
+ //set default filters\r
+ public filters: StatsFilter = {\r
+ startDate: moment().subtract(1, 'weeks').toDate(),\r
+ endDate: moment().toDate()\r
+ }\r
+\r
+ public executionList: Array<any> = [];\r
+\r
+ public testDefinitionData = {\r
+ //Executions Array thats made of objects with date, test definition name, and count\r
+ "Executions": [],\r
+ //Array of Results for the Pie Chart\r
+ "Results": [],\r
+ }\r
+ public testInstanceData = {\r
+ //Executions for Each Test Instance\r
+ "Executions": [],\r
+ //For multilinechart, objects made of test instance names, and execution count for each one.\r
+ "Individual_Exec": []\r
+ };\r
+\r
+ //list if test instance names\r
+ public testInstances = [];\r
+ //list of scheduled tests gotten from agenda in db.\r
+ public scheduledTests = [];\r
+\r
+ //these are filter objects attached to stats service that are updated whenever user confirms from filter modal. \r
+ //They are updated in the filter functions below.\r
+ // public tdFilters = {\r
+ // startDate: {},\r
+ // endDate: {},\r
+ // selected: [],\r
+ // }\r
+ // public tiFilters = {\r
+ // startDate: {},\r
+ // endDate: {},\r
+ // selectedTDs: [],\r
+ // selectedTIs: [],\r
+ // //this limit is for the amount of multiple series being displayed on the multiline chart according to default/filters.\r
+ // multiLineLimit: 5,\r
+ // }\r
+ // public scheduleFilters = {\r
+ // startDate: {},\r
+ // endDate: {},\r
+ // timeRangeStart: {},\r
+ // timeRangeEnd: {},\r
+ // selectedInstances: [],\r
+ // }\r
+\r
+ //these are for triggering the listeners located in the chart components.\r
+ //executionsChange subjects are triggered when user filters.\r
+ public tdExecutionsChange: Subject<Object> = new Subject<Object>();\r
+ public tiExecutionsChange: Subject<Object> = new Subject<Object>();\r
+ public scheduleChange: Subject<Object> = new Subject<Object>();\r
+ public finishedDefaultData: Subject<Object> = new Subject<Object>();\r
+ public startDefaultData: Subject<Object> = new Subject<Object>();\r
+ public startTDExecutionCall: Subject<Object> = new Subject<Object>();\r
+ public startTIExecutionCall: Subject<Object> = new Subject<Object>();\r
+ public windowResized: Subject<Object> = new Subject<Object>();\r
+ public startScheduleCall: Subject<Object> = new Subject<Object>();\r
+\r
+ constructor(public feathers: FeathersService, public testExecution: TestExecutionService,\r
+ public _groups: GroupService, public testInstanceService: TestInstanceService, public schedService: SchedulingService) {\r
+\r
+ //listening for whether user changes group, if so, variables are reset (rest are inside defaultData, we can work on consistency).\r
+ //and we get default data for the new group passed in.\r
+ // this.getDefaultData(this._groups.getGroup());\r
+ // this._groups.groupChange().subscribe(group => {\r
+ // this.getDefaultData(group);\r
+ // });\r
+\r
+ }\r
+\r
+ \r
+\r
+ //these are trigger functions that we call in the data manipulating functions below.\r
+ //the purpose of these functions is to let the listeners set up in the chart components know that the data has been updated.\r
+ //then the chart components recall the data using getData().\r
+ checkWindow() {\r
+ return this.windowResized;\r
+ }\r
+\r
+ onDefaultDataCallStarted() {\r
+ return this.startDefaultData;\r
+ }\r
+\r
+ onTDExecutionChangeStarted() {\r
+ return this.startTDExecutionCall;\r
+ }\r
+\r
+ onTIExecutionChangeStarted() {\r
+ return this.startTIExecutionCall;\r
+ }\r
+\r
+ onScheduleChangeStarted() {\r
+ return this.startScheduleCall;\r
+ }\r
+\r
+ onDefaultDataCallFinished() {\r
+ return this.finishedDefaultData;\r
+ }\r
+\r
+ onTDExecutionChangeFinished() {\r
+ return this.tdExecutionsChange;\r
+ }\r
+\r
+ onTIExecutionChangeFinished() {\r
+ return this.tiExecutionsChange;\r
+ }\r
+\r
+ onScheduleChangeFinished() {\r
+ return this.scheduleChange;\r
+ }\r
+\r
+ //one giant getter where we pass in the name of what we want and switch case it.\r
+\r
+ //This function is called in the components and returns the relavent array for the component.\r
+ getData(name: string) {\r
+ let outputData = {};\r
+\r
+ switch (name) {\r
+ case "TD_Executions":\r
+ return this.testDefinitionData.Executions;\r
+ case "TD_Results":\r
+ return this.testDefinitionData.Results;\r
+ case "testInstances":\r
+ return this.testInstanceData.Executions;\r
+ case "Schedule":\r
+ return this.scheduledTests;\r
+ // case "multiLineData":\r
+ // //limitting the series being displayed.\r
+ // return this.testInstanceData.Individual_Exec.slice(0, this.tiFilters.multiLineLimit);\r
+ }\r
+ //console.log(outputData);\r
+ return outputData;\r
+ }\r
+\r
+ //this gets called from the filter modal when the user confirms their filters.\r
+ filterData(allFilters, tdFilters, tiFilters, schedFilters) {\r
+ //this.filterAll(allFilters);\r
+ this.filterTDs(tdFilters);\r
+ this.filterTIs(tiFilters);\r
+ this.filterSchedule(schedFilters)\r
+ }\r
+\r
+ //this is still under the works, the purpose of this is to filter ALL the components of the dashboard if they have common filtering grounds.\r
+ filterAll(allFilters) {\r
+ //console.log('Filtering everything')\r
+ //console.log(allFilters);\r
+ if (allFilters.startDate != "" || allFilters.endDate != "") {\r
+ if (allFilters.endDate == "") {\r
+ this.testDefinitionData.Executions = this.testDefinitionData.Executions.filter(execution => (\r
+ execution.startTime >= allFilters.startDate\r
+ ))\r
+ } else if (allFilters.startDate == "") {\r
+ this.testDefinitionData.Executions = this.testDefinitionData.Executions.filter(execution => (\r
+ execution.startTime <= allFilters.endDate\r
+ ))\r
+ } else {\r
+ this.testDefinitionData.Executions = this.testDefinitionData.Executions.filter(execution => (\r
+ execution.startTime >= allFilters.startDate &&\r
+ execution.date <= allFilters.endDate\r
+ ))\r
+ }\r
+ }\r
+ }\r
+\r
+ /*\r
+ this function takes in test definition filters and queries data accordingly.\r
+ improvement needed: if the filters provided do not require querying at all, the function should narrow the currently existing data. This\r
+ will be faster than requerying in those cases and improve loading times.\r
+ */\r
+ async filterTDs(tdFilters) {\r
+\r
+ /*\r
+ checking if the filters passed in are empty, if so do nothing, if not, trigger a start call that lets the components know querying is going to begin.\r
+ these start..Call() functions are so chart components can turn on their loading indicators.\r
+ */\r
+ // if (tdFilters.startDate == "" && tdFilters.endDate == "" && tdFilters.selected.length == 0) return;\r
+ // else this.startTDExecutionCall.next(tdFilters);\r
+\r
+ // //updating filter objects attached to stats service so we can use the service getters to get them where we want in the charts component code.\r
+ // this.tdFilters = tdFilters;\r
+\r
+ // //if no range is passed in we use the default range of past 2 months.\r
+ // let startDate = tdFilters.startDate == "" ? new Date(moment().subtract(2, 'weeks').format('L')) : new Date(tdFilters.startDate);\r
+ // let endDate = tdFilters.endDate == "" ? moment().toDate() : new Date(tdFilters.endDate);\r
+ // //update service filters accordingly. \r
+ // this.tdFilters.startDate = startDate;\r
+ // this.tdFilters.endDate = endDate;\r
+ //variable of id's of the test definitions selected in the filters.\r
+ let selectedIDs = this.filters.selectedTestDefinitions.map(item => item.id);\r
+\r
+ //Promise that queries the data according the filters. We use a promise so we wait for the data to query before the components render.\r
+ await new Promise((resolve, reject) => {\r
+\r
+ //feathers query time.\r
+ this.testExecution.find({\r
+ //get the data relevant to the group.\r
+ groupId: this._groups.getGroup()["_id"],\r
+ //thse are gonna go in the data objects.\r
+ $select: [\r
+ 'historicTestDefinition.testName',\r
+ 'startTime',\r
+ 'testResult'\r
+ ],\r
+ //UNLIMITED DATA BABY.\r
+ $limit: -1,\r
+ //sort according to ascending dates.\r
+ $sort: {\r
+ startTime: 1,\r
+ },\r
+ //select the start and end dates from the filter dates.\r
+ startTime: {\r
+ $gte: this.filters.startDate,\r
+ $lte: this.filters.endDate,\r
+ },\r
+ //select the test definitions according to the selected ones in the filters.\r
+ 'historicTestDefinition._id': {\r
+ $in: selectedIDs\r
+ }\r
+ }).subscribe(result => {\r
+\r
+ //console.log(result)\r
+\r
+ //resetting real quick cuz why not.\r
+ this.testDefinitionData = {\r
+ "Executions": [],\r
+ "Results": [],\r
+ }\r
+\r
+ //pretty self explanitory.\r
+ let fetchedData = result as Array<any>;\r
+ let currentExecutionsData = this.testDefinitionData.Executions;\r
+\r
+ /*\r
+ for each new fetched json we got with the selected stuff we specified in the feathers query,\r
+ we need to organize and distribute them accordingly to our service's data objects. For example, the json objects consist of\r
+ 'historicTestDefinition.testName',\r
+ 'startTime',\r
+ 'testResult',\r
+ test results belong in the results array, the rest needs to be organzied in the executions array,\r
+ thats what the populate methods are for.\r
+ */\r
+ for (let index in fetchedData) {\r
+ let newItem = fetchedData[index];\r
+\r
+ //for consistency we're supposed to pass current data to both we'll fix that later, but for now the piechart one just calls the current results data\r
+ //inside itself.\r
+ this.populateLineChartData(newItem, currentExecutionsData);\r
+ this.populatePieChartData(newItem);\r
+ }\r
+ resolve();\r
+ })\r
+ }).then(res => {\r
+ //console.log(res);\r
+\r
+ //trigger that querying is done and the test definition executions data has been changed. Line chart and pie chart listen for this.\r
+ this.tdExecutionsChange.next(res);\r
+ })\r
+ }\r
+\r
+ //similar stuffies. just small differences.\r
+ async filterTIs(tiFilters) {\r
+\r
+ // if (tiFilters.startDate == "" && tiFilters.endDate == "" && tiFilters.selectedTDs.length == 0 && tiFilters.selectedTIs.length == 0) return;\r
+ // else this.startTIExecutionCall.next(tiFilters);\r
+\r
+ // this.tiFilters = tiFilters;\r
+ // if (tiFilters.selectedTIs.length > 0 && tiFilters.selectedTDs.length > 0) this.tiFilters.multiLineLimit = tiFilters.selectedTIs.length + tiFilters.selectedTDs.length;\r
+ // else if (tiFilters.selectedTIs.length > 0) this.tiFilters.multiLineLimit = tiFilters.selectedTIs.length;\r
+ // else if (tiFilters.selectedTDs.length > 0) this.tiFilters.multiLineLimit = tiFilters.selectedTDs.length;\r
+ // else this.tiFilters.multiLineLimit = 5;\r
+\r
+ // let startDate = tiFilters.startDate == "" ? new Date(moment().subtract(2, 'weeks').format('L')) : new Date(tiFilters.startDate);\r
+ // let endDate = tiFilters.endDate == "" ? moment().toDate() : new Date(tiFilters.endDate);\r
+\r
+ // this.tiFilters.startDate = startDate;\r
+ // this.tiFilters.endDate = endDate;\r
+ // console.log(tiFilters.selectedTDs)\r
+\r
+ await new Promise((resolve, reject) => {\r
+ this.testExecution.find({\r
+ groupId: this._groups.getGroup()["_id"],\r
+ $limit: -1,\r
+ startTime: {\r
+ $gte: this.filters.startDate,\r
+ $lte: this.filters.endDate,\r
+ },\r
+ $select: [\r
+ 'startTime',\r
+ 'endTime',\r
+ 'historicTestDefinition.testName',\r
+ 'historicTestInstance.testInstanceName',\r
+ ],\r
+ $or: [\r
+ {\r
+ 'historicTestDefinition._id': {\r
+ $in: tiFilters.selectedTDs\r
+ }\r
+ },\r
+ {\r
+ 'historicTestInstance._id': {\r
+ $in: tiFilters.selectedTIs\r
+ }\r
+ }\r
+ ]\r
+\r
+ }).subscribe(result => {\r
+ this.testInstanceData = {\r
+ "Executions": [],\r
+ "Individual_Exec": []\r
+ }\r
+ //console.log(result)\r
+ let fetchedData = result as Array<any>;\r
+ for (let index in fetchedData) {\r
+ let newItem = fetchedData[index];\r
+ this.populateBarChartData(newItem);\r
+ this.populateMultiLineChartData(newItem);\r
+ }\r
+ this.testInstanceData.Executions.sort((a, b) => b.Count - a.Count);\r
+ this.testInstanceData.Individual_Exec.sort((a, b) => b.total - a.total);\r
+\r
+ resolve();\r
+ })\r
+ }).then(res => {\r
+ this.tiExecutionsChange.next(res);\r
+ //console.log(this.testInstanceData.Executions);\r
+ })\r
+\r
+ }\r
+\r
+ //similar stuffies just smol differneces.\r
+ async filterSchedule(schedFilters) {\r
+\r
+ //console.log(schedFilters);\r
+ // this.scheduleFilters = schedFilters;\r
+ // //console.log(schedFilters.selectedInstances);\r
+\r
+ // if (schedFilters.startDate == "" &&\r
+ // schedFilters.endDate == "" &&\r
+ // schedFilters.selectedInstances.length == 0) {\r
+ // return;\r
+ // } else this.startScheduleCall.next(schedFilters);\r
+\r
+ // let startDate = schedFilters.startDate == "" ? new Date(moment().toDate()) : new Date(schedFilters.startDate);\r
+ // let endDate = schedFilters.endDate == "" ? new Date(moment().add(2, 'weeks').format('L')) : new Date(schedFilters.endDate);\r
+\r
+ // this.scheduleFilters.startDate = startDate;\r
+ // this.scheduleFilters.endDate = endDate;\r
+\r
+ \r
+ this.schedService.find({\r
+ $select: ["data.testSchedule._testInstanceId", 'nextRunAt'],\r
+ $limit: -1,\r
+ }).subscribe(result => {\r
+ this.scheduledTests = [];\r
+ //console.log(result);\r
+ let fetchedData = result as Array<any>;\r
+ let resultingData: Array<any> = fetchedData;\r
+ if (schedFilters.selectedInstances.length !== 0) {\r
+ resultingData = fetchedData.filter(el => {\r
+ let fetchedID = el.data.testSchedule._testInstanceId;\r
+ let selectedIDs = schedFilters.selectedInstances as Array<any>;\r
+ let condition = selectedIDs.includes(fetchedID.toString());\r
+ //console.log(condition);\r
+ return condition;\r
+ })\r
+ }\r
+\r
+ resultingData = resultingData.filter(el => {\r
+ let schedDate = new Date(el.nextRunAt);\r
+ return schedDate >= this.filters.startDate && schedDate <= this.filters.endDate;\r
+ })\r
+\r
+ for (let index in resultingData) {\r
+ let checkIfTestBelongsToUserGroup = this.testInstances.findIndex(testInstances => testInstances.id === resultingData[index].data.testSchedule._testInstanceId);\r
+ if (checkIfTestBelongsToUserGroup >= 0) {\r
+ if (resultingData[index].nextRunAt) {\r
+ let d1 = new Date(resultingData[index].nextRunAt);\r
+ this.scheduledTests.push({\r
+ id: resultingData[index].data.testSchedule._testInstanceId,\r
+ name: this.testInstances[checkIfTestBelongsToUserGroup].name,\r
+ dateExec: d1.toDateString(),\r
+ timeExec: d1.toLocaleTimeString()\r
+ })\r
+ }\r
+ }\r
+ }\r
+ this.scheduleChange.next();\r
+ });\r
+ \r
+\r
+\r
+ }\r
+\r
+ //getters for the filter objects.\r
+ // getTDFilters() {\r
+ // return this.tdFilters;\r
+ // }\r
+\r
+ // getTIFilters() {\r
+ // return this.tiFilters;\r
+ // }\r
+\r
+ // getSchedFilters() {\r
+ // return this.scheduleFilters;\r
+ // }\r
+\r
+ calcTime(execution) {\r
+ var end = new Date(execution.endTime);\r
+ var start = new Date(execution.startTime);\r
+ var executionTime = (end.getTime() - start.getTime()) / 1000;\r
+ return executionTime;\r
+ }\r
+\r
+ //This function takes an execution that was retrieved from the Database and takes the data it needs for the line chart. \r
+ populateLineChartData(execution, currentData) {\r
+ let executionDate = new Date(execution.startTime)\r
+\r
+ // Looks to see if the date already has an execution./\r
+ let indexOfItemFound = currentData.findIndex((element) => {\r
+\r
+ return (\r
+ executionDate.getFullYear() === element.date.getFullYear() &&\r
+ executionDate.getMonth() === element.date.getMonth() &&\r
+ executionDate.getDate() === element.date.getDate()\r
+ )\r
+ })\r
+\r
+ //If the date is not found. Push a new date into the array with a count of one\r
+ if (currentData[indexOfItemFound] == undefined) {\r
+ currentData.push({\r
+ date: new Date(executionDate.getFullYear(), executionDate.getMonth(), executionDate.getDate()),\r
+ count: 1\r
+ })\r
+ // else update the count\r
+ } else currentData[indexOfItemFound].count += 1;\r
+ }\r
+\r
+\r
+ //Takes an execution and pushes the result/count or updates the count. For the Pie Chart\r
+ populatePieChartData(execution) {\r
+\r
+ //Check if result is already present in the array. \r
+ var checkIfPresent = this.testDefinitionData.Results.find(Results => Results.Name === execution.testResult);\r
+ \r
+ //If not present, add it to TOPSTATs with a default count of 1. \r
+ if (!checkIfPresent) {\r
+ \r
+ var color;\r
+ //Set the color for the pie chart.\r
+ if (execution.testResult == "COMPLETED"){\r
+ color = "#0D47A1";\r
+ }else if (execution.testResult == "FAILED")\r
+ color = "#DD2C00";\r
+ else if (execution.testResult == "UNKNOWN")\r
+ color = "#C4CBD4";\r
+ else if (execution.testResult == "SUCCESS")\r
+ color = "#42d660";\r
+ else if (execution.testResult == "success")\r
+ color = "#42d660";\r
+ else if (execution.testResult == "STARTED")\r
+ color = "#29E3E8";\r
+ else if (execution.testResult == "FAILURE")\r
+ color = "#FC9100";\r
+ else if (execution.testResult == "STOPPED")\r
+ color = "#900C3F";\r
+ else if (execution.testResult == "TERMINATED")\r
+ color = "#AC00FC";\r
+ else if (execution.testResult == "UNAUTHORIZED")\r
+ color = "#7A6E6E";\r
+ else if (execution.testResult == "DOES_NOT_EXIST")\r
+ color = "#000000";\r
+ else if (execution.testResult == "ERROR")\r
+ color = "#eb2acd"\r
+ else if (execution.testResult == "WORKFLOW_ERROR")\r
+ color = "#194f24"\r
+ else\r
+ color = "#000000".replace(/0/g, function () { return (~~(Math.random() * 16)).toString(16); });\r
+\r
+ //Push the execution with the count and color.\r
+ this.testDefinitionData.Results.push({ Name: execution.testResult, Count: 1, color: color });\r
+ } else {\r
+\r
+ //Find index of the testResult and update the count by 1.\r
+ var position = this.testDefinitionData.Results.findIndex(Results => Results.Name === execution.testResult);\r
+ this.testDefinitionData.Results[position].Count += 1;\r
+ }\r
+ }\r
+\r
+ //Takes an execution and pushes result into the barchart. \r
+ populateBarChartData(execution) {\r
+\r
+ //check if test instance is present in the array. \r
+ var checkIfPresent = this.testInstanceData.Executions.find(Instances => Instances.id === execution.historicTestInstance._id);\r
+\r
+ //calculates the time it took for the execution/\r
+ var executionTime = this.calcTime(execution);\r
+ \r
+ //If execution is not present, push the test instance with a count of 1.\r
+ if (!checkIfPresent) {\r
+ //If not present, add it to testInstanceData with a default count of 1. \r
+\r
+ this.testInstanceData.Executions.push({\r
+ Name: execution.historicTestInstance.testInstanceName,\r
+ id: execution.historicTestInstance._id,\r
+ testResult: execution.testResult,\r
+ executionTime: executionTime,\r
+ Count: 1,\r
+ Average: executionTime\r
+ });\r
+ } else {\r
+ // If Present update count and execution time. \r
+ var position = this.testInstanceData.Executions.findIndex(Instances => Instances.id === execution.historicTestInstance._id);\r
+ this.testInstanceData.Executions[position].Count += 1;\r
+ this.testInstanceData.Executions[position].executionTime += executionTime;\r
+ this.testInstanceData.Executions[position].Average = this.testInstanceData.Executions[position].executionTime / this.testInstanceData.Executions[position].Count;\r
+ }\r
+\r
+ }\r
+\r
+ //queries data for the scheduled tests. \r
+ getScheduledTests(groupId) {\r
+\r
+ //Queries a list of test instances by group ID\r
+ this.testInstanceService.find({\r
+ groupId: groupId['_id'],\r
+ $select: ["_id", "testInstanceName", "groupId"],\r
+ $limit: -1\r
+ }).subscribe(result => {\r
+\r
+ //Iterate through the list and add the test instances to the list. \r
+ for (var index in result) {\r
+ var checkIfPresent = this.testInstances.find(id => id === result[index]._id);\r
+ if (!checkIfPresent)\r
+ this.testInstances.push({ id: result[index]._id, name: result[index].testInstanceName });\r
+ }\r
+ });\r
+\r
+ //Queries all of the scheduled tests. \r
+ this.schedService.find({\r
+\r
+ $select: ["data.testSchedule._testInstanceId", 'nextRunAt'],\r
+ $limit: -1,\r
+ $sort: {\r
+ startTime: 1\r
+ },\r
+\r
+ }).subscribe(result => {\r
+\r
+ this.scheduledTests = [];\r
+ for (var index in result) {\r
+\r
+ //If the scheduled testinstance is owned by the group, push the result. \r
+ var checkIfTestBelongsToUserGroup = this.testInstances.findIndex(testInstances => testInstances.id === result[index].data.testSchedule._testInstanceId);\r
+ if (checkIfTestBelongsToUserGroup >= 0) {\r
+\r
+ //If the next run at is valid, the test is scheduled.\r
+ if (result[index].nextRunAt) {\r
+ let d1 = new Date(result[index].nextRunAt);\r
+ this.scheduledTests.push({\r
+ id: result[index].data.testSchedule._testInstanceId,\r
+ name: this.testInstances[checkIfTestBelongsToUserGroup].name,\r
+ dateExec: d1.toDateString(),\r
+ timeExec: d1.toLocaleTimeString()\r
+ });\r
+ }\r
+ }\r
+ }\r
+ });\r
+ }\r
+\r
+ //populate multi line chart\r
+ populateMultiLineChartData(execution) {\r
+\r
+ let executionDate = new Date(execution.startTime)\r
+ let currentData = this.testInstanceData.Individual_Exec;\r
+ let count = 1;\r
+ //find if Instance is already present in the array. \r
+ let position = this.testInstanceData.Individual_Exec.findIndex(Instances => Instances.id === execution.historicTestInstance._id);\r
+\r
+ //First execution for this instance\r
+ if (currentData[position] == undefined) {\r
+ currentData.push({\r
+ testInstanceName: execution.historicTestInstance.testInstanceName,\r
+ testDefinitionName: execution.historicTestDefinition.testDefintionName,\r
+ id: execution.historicTestInstance._id,\r
+ dateData: [{ date: executionDate, count: count, name: execution.historicTestInstance.testInstanceName }],\r
+ total: 1\r
+ })\r
+ //execution already present\r
+ } else {\r
+ //find index of Date\r
+ let indexOfDate = currentData[position].dateData.findIndex((element) => {\r
+ return (\r
+ executionDate.getFullYear() === element.date.getFullYear() &&\r
+ executionDate.getMonth() === element.date.getMonth() &&\r
+ executionDate.getDate() === element.date.getDate()\r
+ )\r
+ });\r
+\r
+ //Check if the exeuction date is valid for this instance. If it is not present, push a new date and count. \r
+ if (currentData[position].dateData[indexOfDate] == undefined) {\r
+ let count = 1;\r
+ //Push the new Date\r
+ currentData[position].dateData.push({ date: executionDate, count: count, name: execution.historicTestInstance.testInstanceName, id: execution.historicTestInstance._id});\r
+ currentData[position].total++;\r
+ } else {\r
+ //date is already present\r
+ currentData[position].dateData[indexOfDate].count++;\r
+ currentData[position].total++;\r
+ }\r
+ }\r
+ }\r
+ //Gets the initial data for the default page. \r
+ async getDefaultData(group, query?) { \r
+ if(!group){\r
+ return;\r
+ }\r
+ \r
+ this.scheduledTests = [];\r
+\r
+ this.startDefaultData.next(group);\r
+ let groupId = group;\r
+ //let startDate = moment().subtract(2, 'weeks').toDate();\r
+ \r
+ //query sheduled tests\r
+ //this.getScheduledTests(group);\r
+\r
+ if(!query){\r
+ query = {\r
+ groupId: groupId['_id'],\r
+ $select: [\r
+ 'startTime',\r
+ 'endTime',\r
+ "historicTestDefinition._id",\r
+ "historicTestDefinition.testName",\r
+ "historicTestInstance._id",\r
+ "historicTestInstance.testInstanceName",\r
+ "testHeadResults.startTime",\r
+ "testHeadResults.endTime",\r
+ "testHeadResults.testHeadName",\r
+ "testHeadResults.testHeadId",\r
+ "testHeadResults.testHeadGroupId",\r
+ "testHeadResults.statusCode",\r
+ 'testResult'\r
+ ],\r
+ $limit: -1,\r
+ $sort: {\r
+ startTime: 1\r
+ },\r
+ startTime: {\r
+ $gte: this.filters.startDate,\r
+ $lte: this.filters.endDate\r
+ }\r
+ }\r
+ }\r
+\r
+ //Query test Executions\r
+ await new Promise((resolve, reject) => {\r
+ this.testExecution.find(query).subscribe(result => {\r
+\r
+ //reset arrays\r
+ this.testDefinitionData = {\r
+ //Executions Array thats made of objects with date, tdName, result\r
+ "Executions": [],\r
+ "Results": [],\r
+ }\r
+ this.testInstanceData = {\r
+ "Executions": [],\r
+ "Individual_Exec": []\r
+ };\r
+\r
+ this.executionList = result as Array<any>;\r
+ let currentData = this.testDefinitionData.Executions;\r
+\r
+ \r
+\r
+ //iterate through the results and populate the appropriate arrays. \r
+ for (let index in this.executionList) {\r
+\r
+ let newItem = this.executionList[index];\r
+\r
+ //get default line chart Data\r
+ this.populateLineChartData(newItem, currentData);\r
+\r
+ //get pie chart data. \r
+ this.populatePieChartData(newItem);\r
+\r
+ //Get BarChart Data\r
+ //this.populateBarChartData(newItem);\r
+\r
+ //get multi line chart data\r
+ //this.populateMultiLineChartData(newItem);\r
+ }\r
+\r
+ //sort the two arrays descending.\r
+ this.testInstanceData.Executions.sort((a, b) => b.Count - a.Count);\r
+ this.testInstanceData.Individual_Exec.sort((a, b) => b.total - a.total);\r
+ resolve();\r
+ }, err => {\r
+ reject(err);\r
+ });\r
+ }).then(res => {\r
+\r
+ // this.tdFilters = {\r
+ // startDate: moment().subtract(2, 'weeks').toDate(),\r
+ // endDate: moment().toDate(),\r
+ // selected: [],\r
+ // };\r
+ // this.tiFilters = {\r
+ // startDate: moment().subtract(2, 'weeks').toDate(),\r
+ // endDate: moment().toDate(),\r
+ // selectedTDs: [],\r
+ // selectedTIs: [],\r
+ // multiLineLimit: 5,\r
+ // }\r
+ this.finishedDefaultData.next(res);\r
+ })\r
+ }\r
+\r
+\r
+}\r