@elisra-devops/docgen-data-provider 1.35.0 → 1.36.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/models/tfs-data.d.ts +17 -0
- package/bin/modules/GitDataProvider.d.ts +4 -1
- package/bin/modules/GitDataProvider.js +16 -8
- package/bin/modules/GitDataProvider.js.map +1 -1
- package/bin/modules/ResultDataProvider.d.ts +1 -0
- package/bin/modules/ResultDataProvider.js +168 -104
- package/bin/modules/ResultDataProvider.js.map +1 -1
- package/package.json +1 -1
- package/src/models/tfs-data.ts +12 -0
- package/src/modules/GitDataProvider.ts +16 -8
- package/src/modules/ResultDataProvider.ts +190 -103
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import DataProviderUtils from '../utils/DataProviderUtils';
|
|
2
2
|
import { TFSServices } from '../helpers/tfs';
|
|
3
|
-
import { OpenPcrRequest, TestSteps } from '../models/tfs-data';
|
|
3
|
+
import { OpenPcrRequest, PlainTestResult, TestSteps } from '../models/tfs-data';
|
|
4
4
|
import logger from '../utils/logger';
|
|
5
5
|
import Utils from '../utils/testStepParserHelper';
|
|
6
6
|
import TicketsDataProvider from './TicketsDataProvider';
|
|
@@ -584,6 +584,7 @@ export default class ResultDataProvider {
|
|
|
584
584
|
testCaseUrl: `${this.orgUrl}${projectName}/_workitems/edit/${testPoint.testCaseReference.id}`,
|
|
585
585
|
configurationName: testPoint.configuration?.name,
|
|
586
586
|
outcome: testPoint.results?.outcome || 'Not Run',
|
|
587
|
+
testSuite: testPoint.testSuite,
|
|
587
588
|
lastRunId: testPoint.results?.lastTestRunId,
|
|
588
589
|
lastResultId: testPoint.results?.lastResultId,
|
|
589
590
|
lastResultDetails: testPoint.results?.lastResultDetails,
|
|
@@ -598,6 +599,7 @@ export default class ResultDataProvider {
|
|
|
598
599
|
testCaseId: testPoint.testCase.id,
|
|
599
600
|
testCaseName: testPoint.testCase.name,
|
|
600
601
|
testCaseUrl: `${this.orgUrl}${projectName}/_workitems/edit/${testPoint.testCase.id}`,
|
|
602
|
+
testSuite: testPoint.testSuite,
|
|
601
603
|
configurationName: testPoint.configuration?.name,
|
|
602
604
|
outcome: testPoint.outcome || 'Not Run',
|
|
603
605
|
lastRunId: testPoint.lastTestRun?.id,
|
|
@@ -657,12 +659,76 @@ export default class ResultDataProvider {
|
|
|
657
659
|
resultId: string,
|
|
658
660
|
isTestReporter: boolean = false,
|
|
659
661
|
selectedFields?: string[],
|
|
660
|
-
isQueryMode?: boolean
|
|
662
|
+
isQueryMode?: boolean,
|
|
663
|
+
point?: any
|
|
661
664
|
): Promise<any> {
|
|
662
665
|
try {
|
|
666
|
+
let filteredFields: any = {};
|
|
667
|
+
let relatedRequirements: any[] = [];
|
|
668
|
+
let relatedBugs: any[] = [];
|
|
669
|
+
let relatedCRs: any[] = [];
|
|
663
670
|
if (runId === '0' || resultId === '0') {
|
|
664
|
-
|
|
665
|
-
|
|
671
|
+
if (!point) {
|
|
672
|
+
logger.warn(`Invalid run result ${runId} or result ${resultId}`);
|
|
673
|
+
return null;
|
|
674
|
+
}
|
|
675
|
+
logger.warn(`Current Test point for Test case ${point.testCaseId} is in Active state`);
|
|
676
|
+
const url = `${this.orgUrl}${projectName}/_apis/wit/workItems/${point.testCaseId}?$expand=all`;
|
|
677
|
+
const testCaseData = await TFSServices.getItemContent(url, this.token);
|
|
678
|
+
const newResultData: PlainTestResult = {
|
|
679
|
+
id: 0,
|
|
680
|
+
outcome: point.outcome,
|
|
681
|
+
revision: testCaseData?.rev || 1,
|
|
682
|
+
testCase: { id: point.testCaseId, name: point.testCaseName },
|
|
683
|
+
state: testCaseData?.fields?.['System.State'] || 'Active',
|
|
684
|
+
priority: testCaseData?.fields?.['Microsoft.VSTS.TCM.Priority'] || 0,
|
|
685
|
+
createdDate: testCaseData?.fields?.['System.CreatedDate'] || '0001-01-01T00:00:00',
|
|
686
|
+
testSuite: point.testSuite,
|
|
687
|
+
failureType: 'None',
|
|
688
|
+
};
|
|
689
|
+
if (isQueryMode) {
|
|
690
|
+
this.appendQueryRelations(point.testCaseId, relatedRequirements, relatedBugs, relatedCRs);
|
|
691
|
+
} else {
|
|
692
|
+
const filteredLinkedFields = selectedFields
|
|
693
|
+
?.filter((field: string) => field.includes('@linked'))
|
|
694
|
+
?.map((field: string) => field.split('@')[0]);
|
|
695
|
+
const selectedLinkedFieldSet = new Set(filteredLinkedFields);
|
|
696
|
+
const { relations } = testCaseData;
|
|
697
|
+
if (relations) {
|
|
698
|
+
await this.appendLinkedRelations(
|
|
699
|
+
relations,
|
|
700
|
+
relatedRequirements,
|
|
701
|
+
relatedBugs,
|
|
702
|
+
relatedCRs,
|
|
703
|
+
testCaseData,
|
|
704
|
+
selectedLinkedFieldSet
|
|
705
|
+
);
|
|
706
|
+
}
|
|
707
|
+
selectedLinkedFieldSet.clear();
|
|
708
|
+
}
|
|
709
|
+
const filteredTestCaseFields = selectedFields
|
|
710
|
+
?.filter((field: string) => field.includes('@testCaseWorkItemField'))
|
|
711
|
+
?.map((field: string) => field.split('@')[0]);
|
|
712
|
+
const selectedFieldSet = new Set(filteredTestCaseFields);
|
|
713
|
+
// Filter fields based on selected field set
|
|
714
|
+
if (selectedFieldSet.size !== 0) {
|
|
715
|
+
filteredFields = Object.keys(testCaseData.fields)
|
|
716
|
+
.filter((key) => selectedFieldSet.has(key))
|
|
717
|
+
.reduce((obj: any, key) => {
|
|
718
|
+
obj[key] = testCaseData.fields[key]?.displayName ?? testCaseData.fields[key];
|
|
719
|
+
return obj;
|
|
720
|
+
}, {});
|
|
721
|
+
}
|
|
722
|
+
selectedFieldSet.clear();
|
|
723
|
+
return {
|
|
724
|
+
...newResultData,
|
|
725
|
+
stepsResultXml: testCaseData.fields['Microsoft.VSTS.TCM.Steps'] || undefined,
|
|
726
|
+
testCaseRevision: testCaseData.rev,
|
|
727
|
+
filteredFields,
|
|
728
|
+
relatedRequirements,
|
|
729
|
+
relatedBugs,
|
|
730
|
+
relatedCRs,
|
|
731
|
+
};
|
|
666
732
|
}
|
|
667
733
|
const url = `${this.orgUrl}${projectName}/_apis/test/runs/${runId}/results/${resultId}?detailsToInclude=Iterations`;
|
|
668
734
|
const resultData = await TFSServices.getItemContent(url, this.token);
|
|
@@ -674,15 +740,12 @@ export default class ResultDataProvider {
|
|
|
674
740
|
const expandParam = isTestReporter ? '?$expand=all' : '';
|
|
675
741
|
const wiUrl = `${this.orgUrl}${projectName}/_apis/wit/workItems/${resultData.testCase.id}/revisions/${resultData.testCaseRevision}${expandParam}`;
|
|
676
742
|
const wiByRevision = await TFSServices.getItemContent(wiUrl, this.token);
|
|
677
|
-
|
|
678
|
-
let relatedRequirements: any[] = [];
|
|
679
|
-
let relatedBugs: any[] = [];
|
|
680
|
-
let relatedCRs: any[] = [];
|
|
743
|
+
|
|
681
744
|
// Process selected fields if provided
|
|
682
745
|
if (isTestReporter) {
|
|
683
746
|
// Process related requirements if needed
|
|
684
747
|
if (isQueryMode) {
|
|
685
|
-
this.appendQueryRelations(resultData, relatedRequirements, relatedBugs, relatedCRs);
|
|
748
|
+
this.appendQueryRelations(resultData.testCase.id, relatedRequirements, relatedBugs, relatedCRs);
|
|
686
749
|
} else {
|
|
687
750
|
const filteredLinkedFields = selectedFields
|
|
688
751
|
?.filter((field: string) => field.includes('@linked'))
|
|
@@ -718,6 +781,7 @@ export default class ResultDataProvider {
|
|
|
718
781
|
}
|
|
719
782
|
return {
|
|
720
783
|
...resultData,
|
|
784
|
+
|
|
721
785
|
stepsResultXml: wiByRevision.fields['Microsoft.VSTS.TCM.Steps'] || undefined,
|
|
722
786
|
analysisAttachments,
|
|
723
787
|
testCaseRevision: resultData.testCaseRevision,
|
|
@@ -740,13 +804,13 @@ export default class ResultDataProvider {
|
|
|
740
804
|
};
|
|
741
805
|
|
|
742
806
|
private appendQueryRelations(
|
|
743
|
-
|
|
807
|
+
testCaseId: any,
|
|
744
808
|
relatedRequirements: any[],
|
|
745
809
|
relatedBugs: any[],
|
|
746
810
|
relatedCRs: any[]
|
|
747
811
|
) {
|
|
748
812
|
if (this.testToAssociatedItemMap.size !== 0) {
|
|
749
|
-
const relatedItemSet = this.testToAssociatedItemMap.get(Number(
|
|
813
|
+
const relatedItemSet = this.testToAssociatedItemMap.get(Number(testCaseId));
|
|
750
814
|
if (relatedItemSet) {
|
|
751
815
|
for (const relatedItem of relatedItemSet) {
|
|
752
816
|
const { id, fields, _links } = relatedItem;
|
|
@@ -943,6 +1007,7 @@ export default class ResultDataProvider {
|
|
|
943
1007
|
?.filter((field: string) => field.includes('@stepsRunProperties'))
|
|
944
1008
|
?.map((field: string) => field.split('@')[0]) || []
|
|
945
1009
|
);
|
|
1010
|
+
const iterationsMap = this.createIterationsMap(iterations, isTestReporter, includeNotRunTestCases);
|
|
946
1011
|
|
|
947
1012
|
for (const testItem of testData) {
|
|
948
1013
|
for (const point of testItem.testPointsItems) {
|
|
@@ -957,25 +1022,20 @@ export default class ResultDataProvider {
|
|
|
957
1022
|
continue;
|
|
958
1023
|
}
|
|
959
1024
|
}
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
if (!includeItemsWithNoIterations && !fetchedTestCase.iteration) continue;
|
|
975
|
-
|
|
976
|
-
// Determine if we should process at step level
|
|
977
|
-
this.AppendResults(options, fetchedTestCase, filteredFields, testItem, point, detailedResults);
|
|
978
|
-
}
|
|
1025
|
+
const iterationKey =
|
|
1026
|
+
!point.lastRunId || !point.lastResultId
|
|
1027
|
+
? `${testCase.workItem.id}`
|
|
1028
|
+
: `${point.lastRunId}-${point.lastResultId}-${testCase.workItem.id}`;
|
|
1029
|
+
const fetchedTestCase =
|
|
1030
|
+
iterationsMap[iterationKey] || (includeNotRunTestCases ? testCase : undefined);
|
|
1031
|
+
// First check if fetchedTestCase exists
|
|
1032
|
+
if (!fetchedTestCase) continue;
|
|
1033
|
+
|
|
1034
|
+
// Then separately check for iteration only if configured not to include items without iterations
|
|
1035
|
+
if (!includeItemsWithNoIterations && !fetchedTestCase.iteration) continue;
|
|
1036
|
+
|
|
1037
|
+
// Determine if we should process at step level
|
|
1038
|
+
this.AppendResults(options, fetchedTestCase, filteredFields, testItem, point, detailedResults);
|
|
979
1039
|
}
|
|
980
1040
|
}
|
|
981
1041
|
return detailedResults;
|
|
@@ -1090,15 +1150,18 @@ export default class ResultDataProvider {
|
|
|
1090
1150
|
*/
|
|
1091
1151
|
private createIterationsMap(
|
|
1092
1152
|
iterations: any[],
|
|
1093
|
-
|
|
1094
|
-
|
|
1153
|
+
isTestReporter: boolean,
|
|
1154
|
+
includeNotRunTestCases: boolean
|
|
1095
1155
|
): Record<string, any> {
|
|
1096
1156
|
return iterations.reduce((map, iterationItem) => {
|
|
1097
1157
|
if (
|
|
1098
1158
|
(isTestReporter && iterationItem.lastRunId && iterationItem.lastResultId) ||
|
|
1099
1159
|
iterationItem.iteration
|
|
1100
1160
|
) {
|
|
1101
|
-
const key = `${iterationItem.lastRunId}-${iterationItem.lastResultId}-${testCaseId}`;
|
|
1161
|
+
const key = `${iterationItem.lastRunId}-${iterationItem.lastResultId}-${iterationItem.testCaseId}`;
|
|
1162
|
+
map[key] = iterationItem;
|
|
1163
|
+
} else if (includeNotRunTestCases) {
|
|
1164
|
+
const key = `${iterationItem.testCaseId}`;
|
|
1102
1165
|
map[key] = iterationItem;
|
|
1103
1166
|
}
|
|
1104
1167
|
return map;
|
|
@@ -1154,6 +1217,7 @@ export default class ResultDataProvider {
|
|
|
1154
1217
|
private async fetchAllResultDataBase(
|
|
1155
1218
|
testData: any[],
|
|
1156
1219
|
projectName: string,
|
|
1220
|
+
isTestReporter: boolean,
|
|
1157
1221
|
fetchStrategy: (projectName: string, testSuiteId: string, point: any, ...args: any[]) => Promise<any>,
|
|
1158
1222
|
additionalArgs: any[] = []
|
|
1159
1223
|
): Promise<any[]> {
|
|
@@ -1164,9 +1228,9 @@ export default class ResultDataProvider {
|
|
|
1164
1228
|
const { testSuiteId, testPointsItems } = item;
|
|
1165
1229
|
|
|
1166
1230
|
// Filter and sort valid points
|
|
1167
|
-
const validPoints =
|
|
1168
|
-
|
|
1169
|
-
|
|
1231
|
+
const validPoints = isTestReporter
|
|
1232
|
+
? testPointsItems
|
|
1233
|
+
: testPointsItems.filter((point: any) => point && point.lastRunId && point.lastResultId);
|
|
1170
1234
|
|
|
1171
1235
|
// Fetch results for each point sequentially
|
|
1172
1236
|
for (const point of validPoints) {
|
|
@@ -1185,7 +1249,7 @@ export default class ResultDataProvider {
|
|
|
1185
1249
|
* Fetches result data for all test points within the given test data, sequentially to avoid context-related errors.
|
|
1186
1250
|
*/
|
|
1187
1251
|
private async fetchAllResultData(testData: any[], projectName: string): Promise<any[]> {
|
|
1188
|
-
return this.fetchAllResultDataBase(testData, projectName, (projectName, testSuiteId, point) =>
|
|
1252
|
+
return this.fetchAllResultDataBase(testData, projectName, false, (projectName, testSuiteId, point) =>
|
|
1189
1253
|
this.fetchResultData(projectName, testSuiteId, point)
|
|
1190
1254
|
);
|
|
1191
1255
|
}
|
|
@@ -1219,69 +1283,69 @@ export default class ResultDataProvider {
|
|
|
1219
1283
|
createResponseObject: (resultData: any, testSuiteId: string, point: any, ...args: any[]) => any,
|
|
1220
1284
|
additionalArgs: any[] = []
|
|
1221
1285
|
): Promise<any> {
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
logger.warn(`Invalid lastRunId or lastResultId for point: ${JSON.stringify(point)}`);
|
|
1225
|
-
return null;
|
|
1226
|
-
} else if (lastRunId === '0' || lastResultId === '0') {
|
|
1227
|
-
logger.warn(`Invalid lastRunId or lastResultId: ${lastRunId}, ${lastResultId}`);
|
|
1228
|
-
return null;
|
|
1229
|
-
}
|
|
1230
|
-
const resultData = await fetchResultMethod(
|
|
1231
|
-
projectName,
|
|
1232
|
-
lastRunId.toString(),
|
|
1233
|
-
lastResultId.toString(),
|
|
1234
|
-
...additionalArgs
|
|
1235
|
-
);
|
|
1236
|
-
|
|
1237
|
-
const iteration =
|
|
1238
|
-
resultData.iterationDetails.length > 0
|
|
1239
|
-
? resultData.iterationDetails[resultData.iterationDetails.length - 1]
|
|
1240
|
-
: undefined;
|
|
1286
|
+
try {
|
|
1287
|
+
const { lastRunId, lastResultId } = point;
|
|
1241
1288
|
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
(
|
|
1289
|
+
const resultData = await fetchResultMethod(
|
|
1290
|
+
projectName,
|
|
1291
|
+
lastRunId?.toString() || '0',
|
|
1292
|
+
lastResultId?.toString() || '0',
|
|
1293
|
+
...additionalArgs
|
|
1245
1294
|
);
|
|
1246
1295
|
|
|
1247
|
-
const
|
|
1296
|
+
const iteration =
|
|
1297
|
+
resultData.iterationDetails?.length > 0
|
|
1298
|
+
? resultData.iterationDetails[resultData.iterationDetails.length - 1]
|
|
1299
|
+
: undefined;
|
|
1248
1300
|
|
|
1249
|
-
if (
|
|
1250
|
-
actionResultsWithSharedModels.
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
});
|
|
1254
|
-
}
|
|
1255
|
-
const stepsList = await this.testStepParserHelper.parseTestSteps(
|
|
1256
|
-
resultData.stepsResultXml,
|
|
1257
|
-
sharedStepIdToRevisionLookupMap
|
|
1258
|
-
);
|
|
1301
|
+
if (resultData.stepsResultXml && iteration) {
|
|
1302
|
+
const actionResultsWithSharedModels = iteration.actionResults.filter(
|
|
1303
|
+
(result: any) => result.sharedStepModel
|
|
1304
|
+
);
|
|
1259
1305
|
|
|
1260
|
-
|
|
1306
|
+
const sharedStepIdToRevisionLookupMap: Map<number, number> = new Map();
|
|
1261
1307
|
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1308
|
+
if (actionResultsWithSharedModels?.length > 0) {
|
|
1309
|
+
actionResultsWithSharedModels.forEach((actionResult: any) => {
|
|
1310
|
+
const { sharedStepModel } = actionResult;
|
|
1311
|
+
sharedStepIdToRevisionLookupMap.set(Number(sharedStepModel.id), Number(sharedStepModel.revision));
|
|
1312
|
+
});
|
|
1313
|
+
}
|
|
1314
|
+
const stepsList = await this.testStepParserHelper.parseTestSteps(
|
|
1315
|
+
resultData.stepsResultXml,
|
|
1316
|
+
sharedStepIdToRevisionLookupMap
|
|
1317
|
+
);
|
|
1318
|
+
|
|
1319
|
+
sharedStepIdToRevisionLookupMap.clear();
|
|
1320
|
+
|
|
1321
|
+
const stepMap = new Map<string, TestSteps>();
|
|
1322
|
+
for (const step of stepsList) {
|
|
1323
|
+
stepMap.set(step.stepId.toString(), step);
|
|
1324
|
+
}
|
|
1266
1325
|
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1326
|
+
for (const actionResult of iteration.actionResults) {
|
|
1327
|
+
const step = stepMap.get(actionResult.stepIdentifier);
|
|
1328
|
+
if (step) {
|
|
1329
|
+
actionResult.stepPosition = step.stepPosition;
|
|
1330
|
+
actionResult.action = step.action;
|
|
1331
|
+
actionResult.expected = step.expected;
|
|
1332
|
+
actionResult.isSharedStepTitle = step.isSharedStepTitle;
|
|
1333
|
+
}
|
|
1274
1334
|
}
|
|
1335
|
+
//Sort by step position
|
|
1336
|
+
iteration.actionResults = iteration.actionResults
|
|
1337
|
+
.filter((result: any) => result.stepPosition)
|
|
1338
|
+
.sort((a: any, b: any) => this.compareActionResults(a.stepPosition, b.stepPosition));
|
|
1275
1339
|
}
|
|
1276
|
-
//Sort by step position
|
|
1277
|
-
iteration.actionResults = iteration.actionResults
|
|
1278
|
-
.filter((result: any) => result.stepPosition)
|
|
1279
|
-
.sort((a: any, b: any) => this.compareActionResults(a.stepPosition, b.stepPosition));
|
|
1280
|
-
}
|
|
1281
1340
|
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1341
|
+
return resultData?.testCase
|
|
1342
|
+
? createResponseObject(resultData, testSuiteId, point, ...additionalArgs)
|
|
1343
|
+
: null;
|
|
1344
|
+
} catch (error: any) {
|
|
1345
|
+
logger.error(`Error occurred for point ${point.testCaseId}: ${error.message}`);
|
|
1346
|
+
logger.error(`Stack trace: ${error.stack}`);
|
|
1347
|
+
return null;
|
|
1348
|
+
}
|
|
1285
1349
|
}
|
|
1286
1350
|
|
|
1287
1351
|
/**
|
|
@@ -1301,7 +1365,7 @@ export default class ResultDataProvider {
|
|
|
1301
1365
|
lastRunId: point.lastRunId,
|
|
1302
1366
|
lastResultId: point.lastResultId,
|
|
1303
1367
|
iteration:
|
|
1304
|
-
resultData.iterationDetails
|
|
1368
|
+
resultData.iterationDetails?.length > 0
|
|
1305
1369
|
? resultData.iterationDetails[resultData.iterationDetails.length - 1]
|
|
1306
1370
|
: undefined,
|
|
1307
1371
|
testCaseRevision: resultData.testCaseRevision,
|
|
@@ -1698,9 +1762,18 @@ export default class ResultDataProvider {
|
|
|
1698
1762
|
runId: string,
|
|
1699
1763
|
resultId: string,
|
|
1700
1764
|
selectedFields?: string[],
|
|
1701
|
-
isQueryMode?: boolean
|
|
1765
|
+
isQueryMode?: boolean,
|
|
1766
|
+
point?: any
|
|
1702
1767
|
): Promise<any> {
|
|
1703
|
-
return this.fetchResultDataBasedOnWiBase(
|
|
1768
|
+
return this.fetchResultDataBasedOnWiBase(
|
|
1769
|
+
projectName,
|
|
1770
|
+
runId,
|
|
1771
|
+
resultId,
|
|
1772
|
+
true,
|
|
1773
|
+
selectedFields,
|
|
1774
|
+
isQueryMode,
|
|
1775
|
+
point
|
|
1776
|
+
);
|
|
1704
1777
|
}
|
|
1705
1778
|
|
|
1706
1779
|
/**
|
|
@@ -1724,6 +1797,7 @@ export default class ResultDataProvider {
|
|
|
1724
1797
|
return this.fetchAllResultDataBase(
|
|
1725
1798
|
testData,
|
|
1726
1799
|
projectName,
|
|
1800
|
+
true,
|
|
1727
1801
|
(projectName, testSuiteId, point, selectedFields, isQueryMode) =>
|
|
1728
1802
|
this.fetchResultDataForTestReporter(projectName, testSuiteId, point, selectedFields, isQueryMode),
|
|
1729
1803
|
[selectedFields, isQueryMode]
|
|
@@ -1833,16 +1907,15 @@ export default class ResultDataProvider {
|
|
|
1833
1907
|
projectName,
|
|
1834
1908
|
testSuiteId,
|
|
1835
1909
|
point,
|
|
1836
|
-
(project, runId, resultId, fields, isQueryMode) =>
|
|
1837
|
-
this.fetchResultDataBasedOnWiTestReporter(project, runId, resultId, fields, isQueryMode),
|
|
1910
|
+
(project, runId, resultId, fields, isQueryMode, point) =>
|
|
1911
|
+
this.fetchResultDataBasedOnWiTestReporter(project, runId, resultId, fields, isQueryMode, point),
|
|
1838
1912
|
(resultData, testSuiteId, point, selectedFields) => {
|
|
1839
1913
|
const { lastRunId, lastResultId, configurationName, lastResultDetails } = point;
|
|
1840
1914
|
try {
|
|
1841
1915
|
const iteration =
|
|
1842
|
-
resultData.iterationDetails
|
|
1843
|
-
? resultData.iterationDetails[resultData.iterationDetails
|
|
1916
|
+
resultData.iterationDetails?.length > 0
|
|
1917
|
+
? resultData.iterationDetails[resultData.iterationDetails?.length - 1]
|
|
1844
1918
|
: undefined;
|
|
1845
|
-
|
|
1846
1919
|
const resultDataResponse: any = {
|
|
1847
1920
|
testCaseName: `${resultData.testCase.name} - ${resultData.testCase.id}`,
|
|
1848
1921
|
testCaseId: resultData.testCase.id,
|
|
@@ -1883,10 +1956,7 @@ export default class ResultDataProvider {
|
|
|
1883
1956
|
resultDataResponse.priority = resultData.priority;
|
|
1884
1957
|
break;
|
|
1885
1958
|
case 'testCaseResult':
|
|
1886
|
-
const outcome =
|
|
1887
|
-
resultData.iterationDetails[resultData.iterationDetails.length - 1]?.outcome ||
|
|
1888
|
-
resultData.outcome ||
|
|
1889
|
-
'NotApplicable';
|
|
1959
|
+
const outcome = this.getTestOutcome(resultData);
|
|
1890
1960
|
if (lastRunId === undefined || lastResultId === undefined) {
|
|
1891
1961
|
resultDataResponse.testCaseResult = {
|
|
1892
1962
|
resultMessage: `${this.convertRunStatus(outcome)}`,
|
|
@@ -1927,10 +1997,27 @@ export default class ResultDataProvider {
|
|
|
1927
1997
|
return null;
|
|
1928
1998
|
}
|
|
1929
1999
|
},
|
|
1930
|
-
[selectedFields, isQueryMode]
|
|
2000
|
+
[selectedFields, isQueryMode, point]
|
|
1931
2001
|
);
|
|
1932
2002
|
}
|
|
1933
2003
|
|
|
2004
|
+
private getTestOutcome(resultData: any) {
|
|
2005
|
+
// Default outcome if nothing else is available
|
|
2006
|
+
const defaultOutcome = 'NotApplicable';
|
|
2007
|
+
|
|
2008
|
+
// Check if we have iteration details
|
|
2009
|
+
const hasIterationDetails = resultData?.iterationDetails && resultData.iterationDetails.length > 0;
|
|
2010
|
+
|
|
2011
|
+
if (hasIterationDetails) {
|
|
2012
|
+
// Get the last iteration's outcome if available
|
|
2013
|
+
const lastIteration = resultData.iterationDetails[resultData.iterationDetails.length - 1];
|
|
2014
|
+
return lastIteration?.outcome || resultData.outcome || defaultOutcome;
|
|
2015
|
+
}
|
|
2016
|
+
|
|
2017
|
+
// No iteration details, use result outcome or default
|
|
2018
|
+
return resultData.outcome || defaultOutcome;
|
|
2019
|
+
}
|
|
2020
|
+
|
|
1934
2021
|
private standardCustomField(fieldsToProcess: any, selectedColumns?: any[]): any {
|
|
1935
2022
|
const customFields: any = {};
|
|
1936
2023
|
if (selectedColumns) {
|