@elisra-devops/docgen-data-provider 1.88.0 → 1.89.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/mewp-reporting.d.ts +2 -2
- package/bin/modules/ResultDataProvider.d.ts +7 -5
- package/bin/modules/ResultDataProvider.js +238 -240
- package/bin/modules/ResultDataProvider.js.map +1 -1
- package/bin/tests/modules/ResultDataProvider.test.js +50 -18
- package/bin/tests/modules/ResultDataProvider.test.js.map +1 -1
- package/package.json +1 -1
- package/src/models/mewp-reporting.ts +2 -2
- package/src/modules/ResultDataProvider.ts +278 -251
- package/src/tests/modules/ResultDataProvider.test.ts +73 -19
|
@@ -296,7 +296,7 @@ class ResultDataProvider {
|
|
|
296
296
|
};
|
|
297
297
|
try {
|
|
298
298
|
const planName = await this.fetchTestPlanName(testPlanId, projectName);
|
|
299
|
-
const testData = await this.fetchMewpScopedTestData(testPlanId, projectName, selectedSuiteIds
|
|
299
|
+
const testData = await this.fetchMewpScopedTestData(testPlanId, projectName, selectedSuiteIds);
|
|
300
300
|
const allRequirements = await this.fetchMewpL2Requirements(projectName);
|
|
301
301
|
if (allRequirements.length === 0) {
|
|
302
302
|
return Object.assign(Object.assign({}, defaultPayload), { sheetName: this.buildMewpCoverageSheetName(planName, testPlanId) });
|
|
@@ -348,6 +348,9 @@ class ResultDataProvider {
|
|
|
348
348
|
const parsedDefinitionStepsByTestCase = new Map();
|
|
349
349
|
const testCaseStepsXmlMap = this.buildTestCaseStepsXmlMap(testData);
|
|
350
350
|
const runResults = await this.fetchAllResultDataTestReporter(testData, projectName, [], false, false);
|
|
351
|
+
if (options === null || options === void 0 ? void 0 : options.debugMode) {
|
|
352
|
+
this.logMewpRunScenarioDebugMatrix(runResults, `coverage plan=${testPlanId}`);
|
|
353
|
+
}
|
|
351
354
|
for (const runResult of runResults) {
|
|
352
355
|
const testCaseId = this.extractMewpTestCaseId(runResult);
|
|
353
356
|
const rawActionResults = Array.isArray((_j = runResult === null || runResult === void 0 ? void 0 : runResult.iteration) === null || _j === void 0 ? void 0 : _j.actionResults)
|
|
@@ -484,7 +487,7 @@ class ResultDataProvider {
|
|
|
484
487
|
};
|
|
485
488
|
try {
|
|
486
489
|
const planName = await this.fetchTestPlanName(testPlanId, projectName);
|
|
487
|
-
const testData = await this.fetchMewpScopedTestData(testPlanId, projectName, selectedSuiteIds
|
|
490
|
+
const testData = await this.fetchMewpScopedTestData(testPlanId, projectName, selectedSuiteIds);
|
|
488
491
|
const allRequirements = await this.fetchMewpL2Requirements(projectName);
|
|
489
492
|
const linkedRequirementsByTestCase = await this.buildLinkedRequirementsByTestCase(allRequirements, testData, projectName);
|
|
490
493
|
const scopedRequirementKeys = await this.resolveMewpRequirementScopeKeysFromQuery(linkedQueryRequest, allRequirements, linkedRequirementsByTestCase);
|
|
@@ -512,6 +515,10 @@ class ResultDataProvider {
|
|
|
512
515
|
logger_1.default.info(`MEWP internal validation steps source summary: testCases=${allTestCaseIds.size} ` +
|
|
513
516
|
`fromSuitePayload=${preloadedStepXmlCount} fromWorkItemFallback=${fallbackStepLoadStats.loadedFromFallback} ` +
|
|
514
517
|
`stepsXmlAvailable=${stepsXmlByTestCase.size} unresolved=${fallbackStepLoadStats.unresolvedCount}`);
|
|
518
|
+
if (options === null || options === void 0 ? void 0 : options.debugMode) {
|
|
519
|
+
const debugRunResults = await this.fetchAllResultDataTestReporter(testData, projectName, [], false, false);
|
|
520
|
+
this.logMewpRunScenarioDebugMatrix(debugRunResults, `internal-validation plan=${testPlanId}`);
|
|
521
|
+
}
|
|
515
522
|
const validL2BaseKeys = new Set([...requirementFamilies.keys()]);
|
|
516
523
|
const diagnostics = {
|
|
517
524
|
totalTestCases: 0,
|
|
@@ -523,35 +530,6 @@ class ResultDataProvider {
|
|
|
523
530
|
};
|
|
524
531
|
for (const testCaseId of [...allTestCaseIds].sort((a, b) => a - b)) {
|
|
525
532
|
diagnostics.totalTestCases += 1;
|
|
526
|
-
const logList = (items, max = 12) => {
|
|
527
|
-
const values = [...items].map((item) => String(item || '').trim()).filter((item) => !!item);
|
|
528
|
-
const shown = values.slice(0, max);
|
|
529
|
-
const suffix = values.length > max ? ` ...(+${values.length - max} more)` : '';
|
|
530
|
-
return shown.join(', ') + suffix;
|
|
531
|
-
};
|
|
532
|
-
const logByFamily = (items, maxFamilies = 8, maxMembers = 10) => {
|
|
533
|
-
const map = new Map();
|
|
534
|
-
for (const item of items || []) {
|
|
535
|
-
const normalized = this.normalizeMewpRequirementCodeWithSuffix(String(item || ''));
|
|
536
|
-
if (!normalized)
|
|
537
|
-
continue;
|
|
538
|
-
const base = this.toRequirementKey(normalized) || normalized;
|
|
539
|
-
if (!map.has(base))
|
|
540
|
-
map.set(base, new Set());
|
|
541
|
-
map.get(base).add(normalized);
|
|
542
|
-
}
|
|
543
|
-
const entries = [...map.entries()]
|
|
544
|
-
.sort((a, b) => a[0].localeCompare(b[0]))
|
|
545
|
-
.slice(0, maxFamilies)
|
|
546
|
-
.map(([base, members]) => {
|
|
547
|
-
const sortedMembers = [...members].sort((a, b) => a.localeCompare(b));
|
|
548
|
-
const shownMembers = sortedMembers.slice(0, maxMembers);
|
|
549
|
-
const membersSuffix = sortedMembers.length > maxMembers ? ` ...(+${sortedMembers.length - maxMembers} more)` : '';
|
|
550
|
-
return `${base}=[${shownMembers.join(', ')}${membersSuffix}]`;
|
|
551
|
-
});
|
|
552
|
-
const suffix = map.size > maxFamilies ? ` ...(+${map.size - maxFamilies} families)` : '';
|
|
553
|
-
return entries.join(' | ') + suffix;
|
|
554
|
-
};
|
|
555
533
|
const stepsXml = stepsXmlByTestCase.get(testCaseId) || '';
|
|
556
534
|
const parsedSteps = stepsXml && String(stepsXml).trim() !== ''
|
|
557
535
|
? await this.testStepParserHelper.parseTestSteps(stepsXml, new Map())
|
|
@@ -592,13 +570,6 @@ class ResultDataProvider {
|
|
|
592
570
|
? new Set([...linkedFullCodesRaw].filter((code) => scopedRequirementKeys.has(this.toRequirementKey(code))))
|
|
593
571
|
: linkedFullCodesRaw;
|
|
594
572
|
const linkedBaseKeys = new Set([...linkedFullCodes].map((code) => this.toRequirementKey(code)).filter((code) => !!code));
|
|
595
|
-
const mentionStepSample = mentionEntries
|
|
596
|
-
.slice(0, 8)
|
|
597
|
-
.map((entry) => `${entry.stepRef}=[${logList(entry.codes, 6)}]`)
|
|
598
|
-
.join(' | ');
|
|
599
|
-
logger_1.default.debug(`MEWP internal validation trace: testCaseId=${testCaseId} ` +
|
|
600
|
-
`mentionSteps=${mentionEntries.length} mentionStepSample='${mentionStepSample}' ` +
|
|
601
|
-
`mentionedL2ByFamily='${logByFamily(mentionedL2Only)}' linkedByFamily='${logByFamily(linkedFullCodes)}'`);
|
|
602
573
|
const mentionedCodesByBase = new Map();
|
|
603
574
|
for (const code of mentionedL2Only) {
|
|
604
575
|
const baseKey = this.toRequirementKey(code);
|
|
@@ -620,82 +591,47 @@ class ResultDataProvider {
|
|
|
620
591
|
const mentionedCodesList = [...mentionedCodes];
|
|
621
592
|
const hasBaseMention = mentionedCodesList.some((code) => !/-\d+$/.test(code));
|
|
622
593
|
const mentionedSpecificMembers = mentionedCodesList.filter((code) => /-\d+$/.test(code));
|
|
623
|
-
let familyDecision = 'no-action';
|
|
624
|
-
let familyTargetCodes = [];
|
|
625
|
-
let familyMissingCodes = [];
|
|
626
|
-
let familyLinkedCodes = [];
|
|
627
|
-
let familyAllCodes = [];
|
|
628
594
|
if (familyCodes === null || familyCodes === void 0 ? void 0 : familyCodes.size) {
|
|
629
|
-
familyAllCodes = [...familyCodes].sort((a, b) => a.localeCompare(b));
|
|
630
|
-
familyLinkedCodes = familyAllCodes.filter((code) => linkedFullCodes.has(code));
|
|
631
595
|
// Base mention ("SR0054") validates against child coverage when children exist.
|
|
632
596
|
// If no child variants exist, fallback to the single standalone requirement code.
|
|
633
597
|
if (hasBaseMention) {
|
|
634
598
|
const familyCodesList = [...familyCodes];
|
|
635
599
|
const childFamilyCodes = familyCodesList.filter((code) => /-\d+$/.test(code));
|
|
636
600
|
const targetFamilyCodes = childFamilyCodes.length > 0 ? childFamilyCodes : familyCodesList;
|
|
637
|
-
familyTargetCodes = [...targetFamilyCodes].sort((a, b) => a.localeCompare(b));
|
|
638
601
|
const missingInTargetFamily = targetFamilyCodes.filter((code) => !linkedFullCodes.has(code));
|
|
639
|
-
familyMissingCodes = [...missingInTargetFamily].sort((a, b) => a.localeCompare(b));
|
|
640
602
|
if (missingInTargetFamily.length > 0) {
|
|
641
603
|
const hasAnyLinkedInFamily = familyCodesList.some((code) => linkedFullCodes.has(code));
|
|
642
604
|
if (!hasAnyLinkedInFamily) {
|
|
643
605
|
missingBaseWhenFamilyUncovered.add(baseKey);
|
|
644
|
-
familyDecision = 'base-mentioned-family-uncovered';
|
|
645
606
|
}
|
|
646
607
|
else {
|
|
647
608
|
for (const code of missingInTargetFamily) {
|
|
648
609
|
missingFamilyMembers.add(code);
|
|
649
610
|
}
|
|
650
|
-
familyDecision = 'base-mentioned-family-partial-missing-children';
|
|
651
611
|
}
|
|
652
612
|
}
|
|
653
|
-
else {
|
|
654
|
-
familyDecision = 'base-mentioned-family-fully-covered';
|
|
655
|
-
}
|
|
656
|
-
logger_1.default.debug(`MEWP internal validation family decision: testCaseId=${testCaseId} base=${baseKey} ` +
|
|
657
|
-
`mode=baseMention mentioned='${logList(mentionedCodesList)}' familyAll='${logList(familyAllCodes)}' ` +
|
|
658
|
-
`target='${logList(familyTargetCodes)}' linked='${logList(familyLinkedCodes)}' ` +
|
|
659
|
-
`missing='${logList(familyMissingCodes)}' decision=${familyDecision}`);
|
|
660
613
|
continue;
|
|
661
614
|
}
|
|
662
615
|
// Specific mention ("SR0054-1") validates as exact-match only.
|
|
663
|
-
const missingSpecificMembers = [];
|
|
664
616
|
for (const code of mentionedSpecificMembers) {
|
|
665
617
|
if (!linkedFullCodes.has(code)) {
|
|
666
618
|
missingSpecificMentionedNoFamily.add(code);
|
|
667
|
-
missingSpecificMembers.push(code);
|
|
668
619
|
}
|
|
669
620
|
}
|
|
670
|
-
familyDecision =
|
|
671
|
-
missingSpecificMembers.length > 0
|
|
672
|
-
? 'specific-mentioned-exact-missing'
|
|
673
|
-
: 'specific-mentioned-exact-covered';
|
|
674
|
-
logger_1.default.debug(`MEWP internal validation family decision: testCaseId=${testCaseId} base=${baseKey} ` +
|
|
675
|
-
`mode=specificMention mentioned='${logList(mentionedCodesList)}' familyAll='${logList(familyAllCodes)}' ` +
|
|
676
|
-
`linked='${logList(familyLinkedCodes)}' missingSpecific='${logList(missingSpecificMembers)}' ` +
|
|
677
|
-
`decision=${familyDecision}`);
|
|
678
621
|
continue;
|
|
679
622
|
}
|
|
680
623
|
// Fallback path when family data is unavailable for this base key.
|
|
681
|
-
const fallbackMissingSpecific = [];
|
|
682
|
-
let fallbackBaseMissing = false;
|
|
683
624
|
for (const code of mentionedCodes) {
|
|
684
625
|
const hasSpecificSuffix = /-\d+$/.test(code);
|
|
685
626
|
if (hasSpecificSuffix) {
|
|
686
627
|
if (!linkedFullCodes.has(code)) {
|
|
687
628
|
missingSpecificMentionedNoFamily.add(code);
|
|
688
|
-
fallbackMissingSpecific.push(code);
|
|
689
629
|
}
|
|
690
630
|
}
|
|
691
631
|
else if (!linkedBaseKeys.has(baseKey)) {
|
|
692
632
|
missingBaseWhenFamilyUncovered.add(baseKey);
|
|
693
|
-
fallbackBaseMissing = true;
|
|
694
633
|
}
|
|
695
634
|
}
|
|
696
|
-
logger_1.default.debug(`MEWP internal validation family decision: testCaseId=${testCaseId} base=${baseKey} ` +
|
|
697
|
-
`mode=noFamilyData mentioned='${logList(mentionedCodesList)}' linkedBasePresent=${linkedBaseKeys.has(baseKey)} ` +
|
|
698
|
-
`missingSpecific='${logList(fallbackMissingSpecific)}' missingBase=${fallbackBaseMissing}`);
|
|
699
635
|
}
|
|
700
636
|
// Direction B is family-based: if any member of a family is mentioned in Expected Result,
|
|
701
637
|
// linked members of that same family are not considered "linked but not mentioned".
|
|
@@ -753,14 +689,8 @@ class ResultDataProvider {
|
|
|
753
689
|
const groupedRequirementList = this.formatRequirementCodesGroupedByFamily(requirementIds);
|
|
754
690
|
return `${stepRef}: ${groupedRequirementList}`;
|
|
755
691
|
})
|
|
756
|
-
.join('
|
|
692
|
+
.join('\n');
|
|
757
693
|
const linkedButNotMentioned = this.formatRequirementCodesGroupedByFamily(sortedExtraLinked);
|
|
758
|
-
const rawMentionedByStepForLog = [...mentionedButNotLinkedByStep.entries()]
|
|
759
|
-
.map(([stepRef, requirementIds]) => `${stepRef}=[${logList(requirementIds, 8)}]`)
|
|
760
|
-
.join(' | ');
|
|
761
|
-
logger_1.default.debug(`MEWP internal validation grouped diagnostics: testCaseId=${testCaseId} ` +
|
|
762
|
-
`rawMentionedByStep='${rawMentionedByStepForLog}' groupedMentioned='${mentionedButNotLinked}' ` +
|
|
763
|
-
`rawLinkedOnlyByFamily='${logByFamily(sortedExtraLinked)}' groupedLinkedOnly='${linkedButNotMentioned}'`);
|
|
764
694
|
const validationStatus = mentionedButNotLinked || linkedButNotMentioned ? 'Fail' : 'Pass';
|
|
765
695
|
if (validationStatus === 'Fail')
|
|
766
696
|
diagnostics.failingRows += 1;
|
|
@@ -1117,126 +1047,9 @@ class ResultDataProvider {
|
|
|
1117
1047
|
return 'Pass';
|
|
1118
1048
|
return (input === null || input === void 0 ? void 0 : input.hasAnyTestCase) ? 'Not Run' : 'Not Run';
|
|
1119
1049
|
}
|
|
1120
|
-
async fetchMewpScopedTestData(testPlanId, projectName, selectedSuiteIds
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
return this.fetchTestData(suites, projectName, testPlanId, false);
|
|
1124
|
-
}
|
|
1125
|
-
const selectedSuites = await this.fetchTestSuites(testPlanId, projectName, selectedSuiteIds, true);
|
|
1126
|
-
const selectedRel = this.resolveMaxRelNumberFromSuites(selectedSuites);
|
|
1127
|
-
if (selectedRel <= 0) {
|
|
1128
|
-
return this.fetchTestData(selectedSuites, projectName, testPlanId, false);
|
|
1129
|
-
}
|
|
1130
|
-
const allSuites = await this.fetchTestSuites(testPlanId, projectName, undefined, true);
|
|
1131
|
-
const relScopedSuites = allSuites.filter((suite) => {
|
|
1132
|
-
const rel = this.extractRelNumberFromSuite(suite);
|
|
1133
|
-
return rel > 0 && rel <= selectedRel;
|
|
1134
|
-
});
|
|
1135
|
-
const suitesForFetch = relScopedSuites.length > 0 ? relScopedSuites : selectedSuites;
|
|
1136
|
-
const rawTestData = await this.fetchTestData(suitesForFetch, projectName, testPlanId, false);
|
|
1137
|
-
return this.reduceToLatestRelRunPerTestCase(rawTestData);
|
|
1138
|
-
}
|
|
1139
|
-
extractRelNumberFromSuite(suite) {
|
|
1140
|
-
const candidates = [
|
|
1141
|
-
suite === null || suite === void 0 ? void 0 : suite.suiteName,
|
|
1142
|
-
suite === null || suite === void 0 ? void 0 : suite.parentSuiteName,
|
|
1143
|
-
suite === null || suite === void 0 ? void 0 : suite.suitePath,
|
|
1144
|
-
suite === null || suite === void 0 ? void 0 : suite.testGroupName,
|
|
1145
|
-
];
|
|
1146
|
-
const pattern = /(?:^|[^a-z0-9])rel\s*([0-9]+)/i;
|
|
1147
|
-
for (const item of candidates) {
|
|
1148
|
-
const match = pattern.exec(String(item || ''));
|
|
1149
|
-
if (!match)
|
|
1150
|
-
continue;
|
|
1151
|
-
const parsed = Number(match[1]);
|
|
1152
|
-
if (Number.isFinite(parsed) && parsed > 0) {
|
|
1153
|
-
return parsed;
|
|
1154
|
-
}
|
|
1155
|
-
}
|
|
1156
|
-
return 0;
|
|
1157
|
-
}
|
|
1158
|
-
resolveMaxRelNumberFromSuites(suites) {
|
|
1159
|
-
let maxRel = 0;
|
|
1160
|
-
for (const suite of suites || []) {
|
|
1161
|
-
const rel = this.extractRelNumberFromSuite(suite);
|
|
1162
|
-
if (rel > maxRel)
|
|
1163
|
-
maxRel = rel;
|
|
1164
|
-
}
|
|
1165
|
-
return maxRel;
|
|
1166
|
-
}
|
|
1167
|
-
reduceToLatestRelRunPerTestCase(testData) {
|
|
1168
|
-
var _a, _b;
|
|
1169
|
-
const candidatesByTestCase = new Map();
|
|
1170
|
-
const testCaseDefinitionById = new Map();
|
|
1171
|
-
for (const suite of testData || []) {
|
|
1172
|
-
const rel = this.extractRelNumberFromSuite(suite);
|
|
1173
|
-
const testPointsItems = Array.isArray(suite === null || suite === void 0 ? void 0 : suite.testPointsItems) ? suite.testPointsItems : [];
|
|
1174
|
-
const testCasesItems = Array.isArray(suite === null || suite === void 0 ? void 0 : suite.testCasesItems) ? suite.testCasesItems : [];
|
|
1175
|
-
for (const testCase of testCasesItems) {
|
|
1176
|
-
const testCaseId = Number(((_a = testCase === null || testCase === void 0 ? void 0 : testCase.workItem) === null || _a === void 0 ? void 0 : _a.id) || (testCase === null || testCase === void 0 ? void 0 : testCase.testCaseId) || (testCase === null || testCase === void 0 ? void 0 : testCase.id) || 0);
|
|
1177
|
-
if (!Number.isFinite(testCaseId) || testCaseId <= 0)
|
|
1178
|
-
continue;
|
|
1179
|
-
if (!testCaseDefinitionById.has(testCaseId)) {
|
|
1180
|
-
testCaseDefinitionById.set(testCaseId, testCase);
|
|
1181
|
-
}
|
|
1182
|
-
}
|
|
1183
|
-
for (const point of testPointsItems) {
|
|
1184
|
-
const testCaseId = Number((point === null || point === void 0 ? void 0 : point.testCaseId) || ((_b = point === null || point === void 0 ? void 0 : point.testCase) === null || _b === void 0 ? void 0 : _b.id) || 0);
|
|
1185
|
-
if (!Number.isFinite(testCaseId) || testCaseId <= 0)
|
|
1186
|
-
continue;
|
|
1187
|
-
const runId = Number((point === null || point === void 0 ? void 0 : point.lastRunId) || 0);
|
|
1188
|
-
const resultId = Number((point === null || point === void 0 ? void 0 : point.lastResultId) || 0);
|
|
1189
|
-
const hasRun = runId > 0 && resultId > 0;
|
|
1190
|
-
if (!candidatesByTestCase.has(testCaseId)) {
|
|
1191
|
-
candidatesByTestCase.set(testCaseId, []);
|
|
1192
|
-
}
|
|
1193
|
-
candidatesByTestCase.get(testCaseId).push({
|
|
1194
|
-
point,
|
|
1195
|
-
rel,
|
|
1196
|
-
runId,
|
|
1197
|
-
resultId,
|
|
1198
|
-
hasRun,
|
|
1199
|
-
});
|
|
1200
|
-
}
|
|
1201
|
-
}
|
|
1202
|
-
const selectedPoints = [];
|
|
1203
|
-
const selectedTestCaseIds = new Set();
|
|
1204
|
-
for (const [testCaseId, candidates] of candidatesByTestCase.entries()) {
|
|
1205
|
-
const sorted = [...candidates].sort((a, b) => {
|
|
1206
|
-
if (a.hasRun !== b.hasRun)
|
|
1207
|
-
return a.hasRun ? -1 : 1;
|
|
1208
|
-
if (a.rel !== b.rel)
|
|
1209
|
-
return b.rel - a.rel;
|
|
1210
|
-
if (a.runId !== b.runId)
|
|
1211
|
-
return b.runId - a.runId;
|
|
1212
|
-
return b.resultId - a.resultId;
|
|
1213
|
-
});
|
|
1214
|
-
const chosen = sorted[0];
|
|
1215
|
-
if (!(chosen === null || chosen === void 0 ? void 0 : chosen.point))
|
|
1216
|
-
continue;
|
|
1217
|
-
selectedPoints.push(chosen.point);
|
|
1218
|
-
selectedTestCaseIds.add(testCaseId);
|
|
1219
|
-
}
|
|
1220
|
-
const selectedTestCases = [];
|
|
1221
|
-
for (const testCaseId of selectedTestCaseIds) {
|
|
1222
|
-
const definition = testCaseDefinitionById.get(testCaseId);
|
|
1223
|
-
if (definition) {
|
|
1224
|
-
selectedTestCases.push(definition);
|
|
1225
|
-
}
|
|
1226
|
-
}
|
|
1227
|
-
return [
|
|
1228
|
-
{
|
|
1229
|
-
testSuiteId: 'MEWP_REL_SCOPED',
|
|
1230
|
-
suiteId: 'MEWP_REL_SCOPED',
|
|
1231
|
-
suiteName: 'MEWP Rel Scoped',
|
|
1232
|
-
parentSuiteId: '',
|
|
1233
|
-
parentSuiteName: '',
|
|
1234
|
-
suitePath: 'MEWP Rel Scoped',
|
|
1235
|
-
testGroupName: 'MEWP Rel Scoped',
|
|
1236
|
-
testPointsItems: selectedPoints,
|
|
1237
|
-
testCasesItems: selectedTestCases,
|
|
1238
|
-
},
|
|
1239
|
-
];
|
|
1050
|
+
async fetchMewpScopedTestData(testPlanId, projectName, selectedSuiteIds) {
|
|
1051
|
+
const suites = await this.fetchTestSuites(testPlanId, projectName, selectedSuiteIds, true);
|
|
1052
|
+
return this.fetchTestData(suites, projectName, testPlanId, false);
|
|
1240
1053
|
}
|
|
1241
1054
|
async loadExternalBugsByTestCase(externalBugsFile) {
|
|
1242
1055
|
return this.mewpExternalIngestionUtils.loadExternalBugsByTestCase(externalBugsFile, {
|
|
@@ -1551,16 +1364,6 @@ class ResultDataProvider {
|
|
|
1551
1364
|
}
|
|
1552
1365
|
return out;
|
|
1553
1366
|
}
|
|
1554
|
-
extractRequirementCodesFromExpectedSteps(steps, includeSuffix) {
|
|
1555
|
-
const out = new Set();
|
|
1556
|
-
for (const step of Array.isArray(steps) ? steps : []) {
|
|
1557
|
-
if (step === null || step === void 0 ? void 0 : step.isSharedStepTitle)
|
|
1558
|
-
continue;
|
|
1559
|
-
const codes = this.extractRequirementCodesFromExpectedText((step === null || step === void 0 ? void 0 : step.expected) || '', includeSuffix);
|
|
1560
|
-
codes.forEach((code) => out.add(code));
|
|
1561
|
-
}
|
|
1562
|
-
return out;
|
|
1563
|
-
}
|
|
1564
1367
|
extractRequirementCodesFromExpectedText(text, includeSuffix) {
|
|
1565
1368
|
const out = new Set();
|
|
1566
1369
|
const source = this.normalizeRequirementStepText(text);
|
|
@@ -2370,7 +2173,7 @@ class ResultDataProvider {
|
|
|
2370
2173
|
return sortedMembers[0];
|
|
2371
2174
|
return `${baseKey}: ${sortedMembers.join(', ')}`;
|
|
2372
2175
|
})
|
|
2373
|
-
.join('
|
|
2176
|
+
.join('\n');
|
|
2374
2177
|
}
|
|
2375
2178
|
toMewpComparableText(value) {
|
|
2376
2179
|
if (value === null || value === undefined)
|
|
@@ -2653,6 +2456,120 @@ class ResultDataProvider {
|
|
|
2653
2456
|
const { value: testCases } = await tfs_1.TFSServices.getItemContent(url, this.token);
|
|
2654
2457
|
return testCases;
|
|
2655
2458
|
}
|
|
2459
|
+
attachSuiteTestCaseContextToPoints(testCasesItems, testPointsItems) {
|
|
2460
|
+
var _a;
|
|
2461
|
+
const points = Array.isArray(testPointsItems) ? testPointsItems : [];
|
|
2462
|
+
const testCases = Array.isArray(testCasesItems) ? testCasesItems : [];
|
|
2463
|
+
if (points.length === 0 || testCases.length === 0)
|
|
2464
|
+
return points;
|
|
2465
|
+
const byTestCaseId = new Map();
|
|
2466
|
+
for (const testCaseItem of testCases) {
|
|
2467
|
+
const testCaseId = Number(((_a = testCaseItem === null || testCaseItem === void 0 ? void 0 : testCaseItem.workItem) === null || _a === void 0 ? void 0 : _a.id) || (testCaseItem === null || testCaseItem === void 0 ? void 0 : testCaseItem.testCaseId) || (testCaseItem === null || testCaseItem === void 0 ? void 0 : testCaseItem.id) || 0);
|
|
2468
|
+
if (!Number.isFinite(testCaseId) || testCaseId <= 0 || byTestCaseId.has(testCaseId))
|
|
2469
|
+
continue;
|
|
2470
|
+
byTestCaseId.set(testCaseId, testCaseItem);
|
|
2471
|
+
}
|
|
2472
|
+
return points.map((point) => {
|
|
2473
|
+
var _a;
|
|
2474
|
+
const testCaseId = Number((point === null || point === void 0 ? void 0 : point.testCaseId) || ((_a = point === null || point === void 0 ? void 0 : point.testCase) === null || _a === void 0 ? void 0 : _a.id) || 0);
|
|
2475
|
+
if (!Number.isFinite(testCaseId) || testCaseId <= 0)
|
|
2476
|
+
return point;
|
|
2477
|
+
const suiteTestCase = byTestCaseId.get(testCaseId);
|
|
2478
|
+
if (!suiteTestCase)
|
|
2479
|
+
return point;
|
|
2480
|
+
return Object.assign(Object.assign({}, point), { suiteTestCase });
|
|
2481
|
+
});
|
|
2482
|
+
}
|
|
2483
|
+
extractWorkItemFieldsMap(workItemFields) {
|
|
2484
|
+
const fields = {};
|
|
2485
|
+
if (!Array.isArray(workItemFields))
|
|
2486
|
+
return fields;
|
|
2487
|
+
for (const field of workItemFields) {
|
|
2488
|
+
const keyCandidates = [field === null || field === void 0 ? void 0 : field.key, field === null || field === void 0 ? void 0 : field.name, field === null || field === void 0 ? void 0 : field.referenceName]
|
|
2489
|
+
.map((item) => String(item || '').trim())
|
|
2490
|
+
.filter((item) => !!item);
|
|
2491
|
+
for (const key of keyCandidates) {
|
|
2492
|
+
fields[key] = field === null || field === void 0 ? void 0 : field.value;
|
|
2493
|
+
}
|
|
2494
|
+
}
|
|
2495
|
+
return fields;
|
|
2496
|
+
}
|
|
2497
|
+
resolveSuiteTestCaseRevision(testCaseItem) {
|
|
2498
|
+
var _a, _b, _c, _d, _e;
|
|
2499
|
+
const revisionCandidates = [
|
|
2500
|
+
(_a = testCaseItem === null || testCaseItem === void 0 ? void 0 : testCaseItem.workItem) === null || _a === void 0 ? void 0 : _a.rev,
|
|
2501
|
+
(_b = testCaseItem === null || testCaseItem === void 0 ? void 0 : testCaseItem.workItem) === null || _b === void 0 ? void 0 : _b.revision,
|
|
2502
|
+
(_c = testCaseItem === null || testCaseItem === void 0 ? void 0 : testCaseItem.workItem) === null || _c === void 0 ? void 0 : _c.version,
|
|
2503
|
+
(_d = testCaseItem === null || testCaseItem === void 0 ? void 0 : testCaseItem.workItem) === null || _d === void 0 ? void 0 : _d.workItemRevision,
|
|
2504
|
+
(_e = testCaseItem === null || testCaseItem === void 0 ? void 0 : testCaseItem.workItem) === null || _e === void 0 ? void 0 : _e.workItemVersion,
|
|
2505
|
+
testCaseItem === null || testCaseItem === void 0 ? void 0 : testCaseItem.revision,
|
|
2506
|
+
testCaseItem === null || testCaseItem === void 0 ? void 0 : testCaseItem.workItemRevision,
|
|
2507
|
+
testCaseItem === null || testCaseItem === void 0 ? void 0 : testCaseItem.workItemVersion,
|
|
2508
|
+
];
|
|
2509
|
+
for (const candidate of revisionCandidates) {
|
|
2510
|
+
const parsed = Number(candidate || 0);
|
|
2511
|
+
if (Number.isFinite(parsed) && parsed > 0)
|
|
2512
|
+
return parsed;
|
|
2513
|
+
}
|
|
2514
|
+
return 0;
|
|
2515
|
+
}
|
|
2516
|
+
buildWorkItemSnapshotFromSuiteTestCase(testCaseItem, fallbackTestCaseId, fallbackTestCaseName = '') {
|
|
2517
|
+
var _a;
|
|
2518
|
+
if (!testCaseItem)
|
|
2519
|
+
return null;
|
|
2520
|
+
const testCaseId = Number(((_a = testCaseItem === null || testCaseItem === void 0 ? void 0 : testCaseItem.workItem) === null || _a === void 0 ? void 0 : _a.id) || (testCaseItem === null || testCaseItem === void 0 ? void 0 : testCaseItem.testCaseId) || (testCaseItem === null || testCaseItem === void 0 ? void 0 : testCaseItem.id) || fallbackTestCaseId || 0);
|
|
2521
|
+
if (!Number.isFinite(testCaseId) || testCaseId <= 0)
|
|
2522
|
+
return null;
|
|
2523
|
+
const workItem = (testCaseItem === null || testCaseItem === void 0 ? void 0 : testCaseItem.workItem) || {};
|
|
2524
|
+
const stepsXml = this.extractStepsXmlFromTestCaseItem(testCaseItem);
|
|
2525
|
+
const fieldsFromList = this.extractWorkItemFieldsMap(workItem === null || workItem === void 0 ? void 0 : workItem.workItemFields);
|
|
2526
|
+
const fieldsFromMap = (workItem === null || workItem === void 0 ? void 0 : workItem.fields) || {};
|
|
2527
|
+
const fields = Object.assign(Object.assign({}, fieldsFromList), fieldsFromMap);
|
|
2528
|
+
if (!fields['System.Title']) {
|
|
2529
|
+
const title = String((testCaseItem === null || testCaseItem === void 0 ? void 0 : testCaseItem.testCaseName) || (workItem === null || workItem === void 0 ? void 0 : workItem.name) || (testCaseItem === null || testCaseItem === void 0 ? void 0 : testCaseItem.name) || fallbackTestCaseName || '').trim();
|
|
2530
|
+
if (title) {
|
|
2531
|
+
fields['System.Title'] = title;
|
|
2532
|
+
}
|
|
2533
|
+
}
|
|
2534
|
+
if (stepsXml && !fields['Microsoft.VSTS.TCM.Steps']) {
|
|
2535
|
+
fields['Microsoft.VSTS.TCM.Steps'] = stepsXml;
|
|
2536
|
+
}
|
|
2537
|
+
return {
|
|
2538
|
+
id: testCaseId,
|
|
2539
|
+
rev: this.resolveSuiteTestCaseRevision(testCaseItem) || 1,
|
|
2540
|
+
fields,
|
|
2541
|
+
relations: Array.isArray(workItem === null || workItem === void 0 ? void 0 : workItem.relations) ? workItem.relations : [],
|
|
2542
|
+
};
|
|
2543
|
+
}
|
|
2544
|
+
async fetchWorkItemByRevision(projectName, workItemId, revision, expandAll = false) {
|
|
2545
|
+
const id = Number(workItemId || 0);
|
|
2546
|
+
const rev = Number(revision || 0);
|
|
2547
|
+
if (!Number.isFinite(id) || id <= 0 || !Number.isFinite(rev) || rev <= 0)
|
|
2548
|
+
return null;
|
|
2549
|
+
const expandParam = expandAll ? '?$expand=all' : '';
|
|
2550
|
+
const url = `${this.orgUrl}${projectName}/_apis/wit/workItems/${id}/revisions/${rev}${expandParam}`;
|
|
2551
|
+
try {
|
|
2552
|
+
return await tfs_1.TFSServices.getItemContent(url, this.token);
|
|
2553
|
+
}
|
|
2554
|
+
catch (error) {
|
|
2555
|
+
logger_1.default.warn(`Failed to fetch work item ${id} by revision ${rev}: ${(error === null || error === void 0 ? void 0 : error.message) || error}`);
|
|
2556
|
+
return null;
|
|
2557
|
+
}
|
|
2558
|
+
}
|
|
2559
|
+
async fetchWorkItemLatest(projectName, workItemId, expandAll = false) {
|
|
2560
|
+
const id = Number(workItemId || 0);
|
|
2561
|
+
if (!Number.isFinite(id) || id <= 0)
|
|
2562
|
+
return null;
|
|
2563
|
+
const expandParam = expandAll ? '?$expand=all' : '';
|
|
2564
|
+
const url = `${this.orgUrl}${projectName}/_apis/wit/workItems/${id}${expandParam}`;
|
|
2565
|
+
try {
|
|
2566
|
+
return await tfs_1.TFSServices.getItemContent(url, this.token);
|
|
2567
|
+
}
|
|
2568
|
+
catch (error) {
|
|
2569
|
+
logger_1.default.warn(`Failed to fetch latest work item ${id}: ${(error === null || error === void 0 ? void 0 : error.message) || error}`);
|
|
2570
|
+
return null;
|
|
2571
|
+
}
|
|
2572
|
+
}
|
|
2656
2573
|
/**
|
|
2657
2574
|
* Fetches result data based on the Work Item Test Reporter.
|
|
2658
2575
|
*
|
|
@@ -2668,7 +2585,7 @@ class ResultDataProvider {
|
|
|
2668
2585
|
* @returns A promise that resolves to the fetched result data.
|
|
2669
2586
|
*/
|
|
2670
2587
|
async fetchResultDataBasedOnWiBase(projectName, runId, resultId, isTestReporter = false, selectedFields, isQueryMode, point, includeAllHistory = false) {
|
|
2671
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
2588
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
2672
2589
|
try {
|
|
2673
2590
|
let filteredFields = {};
|
|
2674
2591
|
let relatedRequirements = [];
|
|
@@ -2679,16 +2596,29 @@ class ResultDataProvider {
|
|
|
2679
2596
|
logger_1.default.warn(`Invalid run result ${runId} or result ${resultId}`);
|
|
2680
2597
|
return null;
|
|
2681
2598
|
}
|
|
2682
|
-
const
|
|
2683
|
-
const
|
|
2599
|
+
const suiteTestCaseItem = point === null || point === void 0 ? void 0 : point.suiteTestCase;
|
|
2600
|
+
const testCaseId = Number((point === null || point === void 0 ? void 0 : point.testCaseId) || ((_a = suiteTestCaseItem === null || suiteTestCaseItem === void 0 ? void 0 : suiteTestCaseItem.workItem) === null || _a === void 0 ? void 0 : _a.id) || (suiteTestCaseItem === null || suiteTestCaseItem === void 0 ? void 0 : suiteTestCaseItem.testCaseId) || 0);
|
|
2601
|
+
const suiteTestCaseRevision = this.resolveSuiteTestCaseRevision(suiteTestCaseItem);
|
|
2602
|
+
const fallbackSnapshot = this.buildWorkItemSnapshotFromSuiteTestCase(suiteTestCaseItem, testCaseId, String((point === null || point === void 0 ? void 0 : point.testCaseName) || ''));
|
|
2603
|
+
let testCaseData = await this.fetchWorkItemByRevision(projectName, testCaseId, suiteTestCaseRevision, isTestReporter);
|
|
2604
|
+
if (!testCaseData) {
|
|
2605
|
+
testCaseData = fallbackSnapshot;
|
|
2606
|
+
}
|
|
2607
|
+
if (!testCaseData) {
|
|
2608
|
+
testCaseData = await this.fetchWorkItemLatest(projectName, testCaseId, isTestReporter);
|
|
2609
|
+
}
|
|
2610
|
+
if (!testCaseData) {
|
|
2611
|
+
logger_1.default.warn(`Could not resolve test case ${point.testCaseId} for runless point fallback.`);
|
|
2612
|
+
return null;
|
|
2613
|
+
}
|
|
2684
2614
|
const newResultData = {
|
|
2685
2615
|
id: 0,
|
|
2686
2616
|
outcome: point.outcome,
|
|
2687
|
-
revision: (testCaseData === null || testCaseData === void 0 ? void 0 : testCaseData.rev) || 1,
|
|
2688
|
-
testCase: { id:
|
|
2689
|
-
state: ((
|
|
2690
|
-
priority: ((
|
|
2691
|
-
createdDate: ((
|
|
2617
|
+
revision: Number((testCaseData === null || testCaseData === void 0 ? void 0 : testCaseData.rev) || suiteTestCaseRevision || 1),
|
|
2618
|
+
testCase: { id: String(testCaseId), name: point.testCaseName },
|
|
2619
|
+
state: ((_b = testCaseData === null || testCaseData === void 0 ? void 0 : testCaseData.fields) === null || _b === void 0 ? void 0 : _b['System.State']) || 'Active',
|
|
2620
|
+
priority: ((_c = testCaseData === null || testCaseData === void 0 ? void 0 : testCaseData.fields) === null || _c === void 0 ? void 0 : _c['Microsoft.VSTS.TCM.Priority']) || 0,
|
|
2621
|
+
createdDate: ((_d = testCaseData === null || testCaseData === void 0 ? void 0 : testCaseData.fields) === null || _d === void 0 ? void 0 : _d['System.CreatedDate']) || '0001-01-01T00:00:00',
|
|
2692
2622
|
testSuite: point.testSuite,
|
|
2693
2623
|
failureType: 'None',
|
|
2694
2624
|
};
|
|
@@ -2696,7 +2626,7 @@ class ResultDataProvider {
|
|
|
2696
2626
|
this.appendQueryRelations(point.testCaseId, relatedRequirements, relatedBugs, relatedCRs);
|
|
2697
2627
|
}
|
|
2698
2628
|
else {
|
|
2699
|
-
const filteredLinkedFields = (
|
|
2629
|
+
const filteredLinkedFields = (_e = selectedFields === null || selectedFields === void 0 ? void 0 : selectedFields.filter((field) => field.includes('@linked'))) === null || _e === void 0 ? void 0 : _e.map((field) => field.split('@')[0]);
|
|
2700
2630
|
const selectedLinkedFieldSet = new Set(filteredLinkedFields);
|
|
2701
2631
|
const { relations } = testCaseData;
|
|
2702
2632
|
if (relations) {
|
|
@@ -2704,7 +2634,7 @@ class ResultDataProvider {
|
|
|
2704
2634
|
}
|
|
2705
2635
|
selectedLinkedFieldSet.clear();
|
|
2706
2636
|
}
|
|
2707
|
-
const filteredTestCaseFields = (
|
|
2637
|
+
const filteredTestCaseFields = (_f = selectedFields === null || selectedFields === void 0 ? void 0 : selectedFields.filter((field) => field.includes('@testCaseWorkItemField'))) === null || _f === void 0 ? void 0 : _f.map((field) => field.split('@')[0]);
|
|
2708
2638
|
const selectedFieldSet = new Set(filteredTestCaseFields);
|
|
2709
2639
|
// Filter fields based on selected field set
|
|
2710
2640
|
if (selectedFieldSet.size !== 0) {
|
|
@@ -2718,7 +2648,7 @@ class ResultDataProvider {
|
|
|
2718
2648
|
}
|
|
2719
2649
|
}
|
|
2720
2650
|
selectedFieldSet.clear();
|
|
2721
|
-
return Object.assign(Object.assign({}, newResultData), { stepsResultXml: testCaseData.fields['Microsoft.VSTS.TCM.Steps'] || undefined, testCaseRevision: testCaseData.rev, filteredFields,
|
|
2651
|
+
return Object.assign(Object.assign({}, newResultData), { stepsResultXml: ((_g = testCaseData === null || testCaseData === void 0 ? void 0 : testCaseData.fields) === null || _g === void 0 ? void 0 : _g['Microsoft.VSTS.TCM.Steps']) || undefined, testCaseRevision: Number((testCaseData === null || testCaseData === void 0 ? void 0 : testCaseData.rev) || suiteTestCaseRevision || 1), filteredFields,
|
|
2722
2652
|
relatedRequirements,
|
|
2723
2653
|
relatedBugs,
|
|
2724
2654
|
relatedCRs });
|
|
@@ -2738,7 +2668,7 @@ class ResultDataProvider {
|
|
|
2738
2668
|
this.appendQueryRelations(resultData.testCase.id, relatedRequirements, relatedBugs, relatedCRs);
|
|
2739
2669
|
}
|
|
2740
2670
|
else {
|
|
2741
|
-
const filteredLinkedFields = (
|
|
2671
|
+
const filteredLinkedFields = (_h = selectedFields === null || selectedFields === void 0 ? void 0 : selectedFields.filter((field) => field.includes('@linked'))) === null || _h === void 0 ? void 0 : _h.map((field) => field.split('@')[0]);
|
|
2742
2672
|
const selectedLinkedFieldSet = new Set(filteredLinkedFields);
|
|
2743
2673
|
const { relations } = wiByRevision;
|
|
2744
2674
|
if (relations) {
|
|
@@ -2746,7 +2676,7 @@ class ResultDataProvider {
|
|
|
2746
2676
|
}
|
|
2747
2677
|
selectedLinkedFieldSet.clear();
|
|
2748
2678
|
}
|
|
2749
|
-
const filteredTestCaseFields = (
|
|
2679
|
+
const filteredTestCaseFields = (_j = selectedFields === null || selectedFields === void 0 ? void 0 : selectedFields.filter((field) => field.includes('@testCaseWorkItemField'))) === null || _j === void 0 ? void 0 : _j.map((field) => field.split('@')[0]);
|
|
2750
2680
|
const selectedFieldSet = new Set(filteredTestCaseFields);
|
|
2751
2681
|
// Filter fields based on selected field set
|
|
2752
2682
|
if (selectedFieldSet.size !== 0) {
|
|
@@ -2839,11 +2769,6 @@ class ResultDataProvider {
|
|
|
2839
2769
|
return (String((_b = (_a = process === null || process === void 0 ? void 0 : process.env) === null || _a === void 0 ? void 0 : _a.DOCGEN_VERBOSE_HISTORY_DEBUG) !== null && _b !== void 0 ? _b : '').toLowerCase() === 'true' ||
|
|
2840
2770
|
String((_d = (_c = process === null || process === void 0 ? void 0 : process.env) === null || _c === void 0 ? void 0 : _c.DOCGEN_VERBOSE_HISTORY_DEBUG) !== null && _d !== void 0 ? _d : '') === '1');
|
|
2841
2771
|
}
|
|
2842
|
-
isRunResultDebugEnabled() {
|
|
2843
|
-
var _a, _b, _c, _d;
|
|
2844
|
-
return (String((_b = (_a = process === null || process === void 0 ? void 0 : process.env) === null || _a === void 0 ? void 0 : _a.DOCGEN_DEBUG_RUNRESULT) !== null && _b !== void 0 ? _b : '').toLowerCase() === 'true' ||
|
|
2845
|
-
String((_d = (_c = process === null || process === void 0 ? void 0 : process.env) === null || _c === void 0 ? void 0 : _c.DOCGEN_DEBUG_RUNRESULT) !== null && _d !== void 0 ? _d : '') === '1');
|
|
2846
|
-
}
|
|
2847
2772
|
extractCommentText(comment) {
|
|
2848
2773
|
var _a, _b, _c, _d;
|
|
2849
2774
|
const rendered = comment === null || comment === void 0 ? void 0 : comment.renderedText;
|
|
@@ -3239,6 +3164,71 @@ class ResultDataProvider {
|
|
|
3239
3164
|
async fetchResultDataBasedOnWi(projectName, runId, resultId) {
|
|
3240
3165
|
return this.fetchResultDataBasedOnWiBase(projectName, runId, resultId);
|
|
3241
3166
|
}
|
|
3167
|
+
logMewpRunScenarioDebugMatrix(runResults, contextLabel) {
|
|
3168
|
+
var _a, _b;
|
|
3169
|
+
const results = Array.isArray(runResults) ? runResults : [];
|
|
3170
|
+
const matrix = {
|
|
3171
|
+
total: results.length,
|
|
3172
|
+
passOrFailWithActionResults: 0,
|
|
3173
|
+
runWithNoActionResults: 0,
|
|
3174
|
+
notApplicable: 0,
|
|
3175
|
+
noRunHistoryActive: 0,
|
|
3176
|
+
other: 0,
|
|
3177
|
+
};
|
|
3178
|
+
const samples = {
|
|
3179
|
+
passOrFailWithActionResults: [],
|
|
3180
|
+
runWithNoActionResults: [],
|
|
3181
|
+
notApplicable: [],
|
|
3182
|
+
noRunHistoryActive: [],
|
|
3183
|
+
other: [],
|
|
3184
|
+
};
|
|
3185
|
+
const pushSample = (bucket, id) => {
|
|
3186
|
+
if (!Number.isFinite(id) || id <= 0)
|
|
3187
|
+
return;
|
|
3188
|
+
if (samples[bucket].length >= 5)
|
|
3189
|
+
return;
|
|
3190
|
+
samples[bucket].push(id);
|
|
3191
|
+
};
|
|
3192
|
+
for (const item of results) {
|
|
3193
|
+
const testCaseId = Number((item === null || item === void 0 ? void 0 : item.testCaseId) || ((_a = item === null || item === void 0 ? void 0 : item.testCase) === null || _a === void 0 ? void 0 : _a.id) || 0);
|
|
3194
|
+
const hasRun = Number((item === null || item === void 0 ? void 0 : item.lastRunId) || 0) > 0 && Number((item === null || item === void 0 ? void 0 : item.lastResultId) || 0) > 0;
|
|
3195
|
+
const rawOutcome = String((item === null || item === void 0 ? void 0 : item._debugTestOutcome) || '').trim().toLowerCase();
|
|
3196
|
+
const rawState = String((item === null || item === void 0 ? void 0 : item._debugTestCaseState) || '').trim().toLowerCase();
|
|
3197
|
+
const originalActionResultsCount = Number((_b = item === null || item === void 0 ? void 0 : item._debugOriginalActionResultsCount) !== null && _b !== void 0 ? _b : -1);
|
|
3198
|
+
if (rawOutcome === 'notapplicable' || rawOutcome === 'not applicable') {
|
|
3199
|
+
matrix.notApplicable += 1;
|
|
3200
|
+
pushSample('notApplicable', testCaseId);
|
|
3201
|
+
continue;
|
|
3202
|
+
}
|
|
3203
|
+
if (hasRun && (rawOutcome === 'passed' || rawOutcome === 'failed') && originalActionResultsCount > 0) {
|
|
3204
|
+
matrix.passOrFailWithActionResults += 1;
|
|
3205
|
+
pushSample('passOrFailWithActionResults', testCaseId);
|
|
3206
|
+
continue;
|
|
3207
|
+
}
|
|
3208
|
+
if (hasRun && originalActionResultsCount === 0) {
|
|
3209
|
+
matrix.runWithNoActionResults += 1;
|
|
3210
|
+
pushSample('runWithNoActionResults', testCaseId);
|
|
3211
|
+
continue;
|
|
3212
|
+
}
|
|
3213
|
+
if (!hasRun && rawState === 'active') {
|
|
3214
|
+
matrix.noRunHistoryActive += 1;
|
|
3215
|
+
pushSample('noRunHistoryActive', testCaseId);
|
|
3216
|
+
continue;
|
|
3217
|
+
}
|
|
3218
|
+
matrix.other += 1;
|
|
3219
|
+
pushSample('other', testCaseId);
|
|
3220
|
+
}
|
|
3221
|
+
logger_1.default.info(`MEWP run debug matrix (${contextLabel}): total=${matrix.total}; ` +
|
|
3222
|
+
`passOrFailWithActionResults=${matrix.passOrFailWithActionResults}; ` +
|
|
3223
|
+
`runWithNoActionResults=${matrix.runWithNoActionResults}; ` +
|
|
3224
|
+
`notApplicable=${matrix.notApplicable}; ` +
|
|
3225
|
+
`noRunHistoryActive=${matrix.noRunHistoryActive}; other=${matrix.other}; ` +
|
|
3226
|
+
`samplePassFail=${samples.passOrFailWithActionResults.join(',') || '-'}; ` +
|
|
3227
|
+
`sampleNoAction=${samples.runWithNoActionResults.join(',') || '-'}; ` +
|
|
3228
|
+
`sampleNA=${samples.notApplicable.join(',') || '-'}; ` +
|
|
3229
|
+
`sampleNoRunActive=${samples.noRunHistoryActive.join(',') || '-'}; ` +
|
|
3230
|
+
`sampleOther=${samples.other.join(',') || '-'}`);
|
|
3231
|
+
}
|
|
3242
3232
|
/**
|
|
3243
3233
|
* Converts a run status string into a human-readable format.
|
|
3244
3234
|
*
|
|
@@ -3447,9 +3437,10 @@ class ResultDataProvider {
|
|
|
3447
3437
|
try {
|
|
3448
3438
|
const testCasesItems = await this.fetchTestCasesBySuiteId(projectName, testPlanId, suite.testSuiteId);
|
|
3449
3439
|
const testCaseIds = testCasesItems.map((testCase) => testCase.workItem.id);
|
|
3450
|
-
const
|
|
3440
|
+
const rawTestPointsItems = !fetchCrossPlans
|
|
3451
3441
|
? await this.fetchTestPoints(projectName, testPlanId, suite.testSuiteId)
|
|
3452
3442
|
: await this.fetchCrossTestPoints(projectName, testCaseIds);
|
|
3443
|
+
const testPointsItems = this.attachSuiteTestCaseContextToPoints(testCasesItems, rawTestPointsItems);
|
|
3453
3444
|
return Object.assign(Object.assign({}, suite), { testPointsItems, testCasesItems });
|
|
3454
3445
|
}
|
|
3455
3446
|
catch (error) {
|
|
@@ -3541,6 +3532,10 @@ class ResultDataProvider {
|
|
|
3541
3532
|
}
|
|
3542
3533
|
resultData.iterationDetails.push(iteration);
|
|
3543
3534
|
}
|
|
3535
|
+
const originalActionResultsCount = Array.isArray(iteration === null || iteration === void 0 ? void 0 : iteration.actionResults)
|
|
3536
|
+
? iteration.actionResults.length
|
|
3537
|
+
: 0;
|
|
3538
|
+
resultData._debugOriginalActionResultsCount = originalActionResultsCount;
|
|
3544
3539
|
if (resultData.stepsResultXml && iteration) {
|
|
3545
3540
|
const actionResults = Array.isArray(iteration.actionResults) ? iteration.actionResults : [];
|
|
3546
3541
|
const actionResultsWithSharedModels = actionResults.filter((result) => result.sharedStepModel);
|
|
@@ -4082,12 +4077,13 @@ class ResultDataProvider {
|
|
|
4082
4077
|
*/
|
|
4083
4078
|
async fetchResultDataForTestReporter(projectName, testSuiteId, point, selectedFields, isQueryMode, includeAllHistory = false) {
|
|
4084
4079
|
return this.fetchResultDataBase(projectName, testSuiteId, point, (project, runId, resultId, fields, isQueryMode, point, includeAllHistory) => this.fetchResultDataBasedOnWiTestReporter(project, runId, resultId, fields, isQueryMode, point, includeAllHistory), (resultData, testSuiteId, point, selectedFields) => {
|
|
4085
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w;
|
|
4080
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x;
|
|
4086
4081
|
const { lastRunId, lastResultId, configurationName, lastResultDetails } = point;
|
|
4087
4082
|
try {
|
|
4088
4083
|
const iteration = ((_a = resultData.iterationDetails) === null || _a === void 0 ? void 0 : _a.length) > 0
|
|
4089
4084
|
? resultData.iterationDetails[((_b = resultData.iterationDetails) === null || _b === void 0 ? void 0 : _b.length) - 1]
|
|
4090
4085
|
: undefined;
|
|
4086
|
+
const debugOutcome = this.getTestOutcome(resultData);
|
|
4091
4087
|
if (!(resultData === null || resultData === void 0 ? void 0 : resultData.testCase) || !(resultData === null || resultData === void 0 ? void 0 : resultData.testSuite)) {
|
|
4092
4088
|
logger_1.default.debug(`[RunResult] Missing testCase/testSuite for point testCaseId=${String((_c = point === null || point === void 0 ? void 0 : point.testCaseId) !== null && _c !== void 0 ? _c : 'unknown')} (lastRunId=${String(lastRunId !== null && lastRunId !== void 0 ? lastRunId : '')}, lastResultId=${String(lastResultId !== null && lastResultId !== void 0 ? lastResultId : '')}). hasTestCase=${Boolean(resultData === null || resultData === void 0 ? void 0 : resultData.testCase)} hasTestSuite=${Boolean(resultData === null || resultData === void 0 ? void 0 : resultData.testSuite)}`);
|
|
4093
4089
|
}
|
|
@@ -4112,13 +4108,16 @@ class ResultDataProvider {
|
|
|
4112
4108
|
relatedCRs: resultData.relatedCRs || undefined,
|
|
4113
4109
|
lastRunResult: undefined,
|
|
4114
4110
|
customFields: {}, // Create an object to store custom fields
|
|
4111
|
+
_debugTestOutcome: debugOutcome,
|
|
4112
|
+
_debugTestCaseState: String((resultData === null || resultData === void 0 ? void 0 : resultData.state) || ''),
|
|
4113
|
+
_debugOriginalActionResultsCount: Number((_l = resultData === null || resultData === void 0 ? void 0 : resultData._debugOriginalActionResultsCount) !== null && _l !== void 0 ? _l : -1),
|
|
4115
4114
|
};
|
|
4116
4115
|
// Process all custom fields from resultData.filteredFields
|
|
4117
4116
|
if (resultData.filteredFields) {
|
|
4118
4117
|
const customFields = this.standardCustomField(resultData.filteredFields);
|
|
4119
4118
|
resultDataResponse.customFields = customFields;
|
|
4120
4119
|
}
|
|
4121
|
-
const filteredFields = (
|
|
4120
|
+
const filteredFields = (_m = selectedFields === null || selectedFields === void 0 ? void 0 : selectedFields.filter((field) => field.includes('@runResultField'))) === null || _m === void 0 ? void 0 : _m.map((field) => field.split('@')[0]);
|
|
4122
4121
|
if (filteredFields && filteredFields.length > 0) {
|
|
4123
4122
|
for (const field of filteredFields) {
|
|
4124
4123
|
switch (field) {
|
|
@@ -4126,16 +4125,15 @@ class ResultDataProvider {
|
|
|
4126
4125
|
resultDataResponse.priority = resultData.priority;
|
|
4127
4126
|
break;
|
|
4128
4127
|
case 'testCaseResult':
|
|
4129
|
-
const outcome = this.getTestOutcome(resultData);
|
|
4130
4128
|
if (lastRunId === undefined || lastResultId === undefined) {
|
|
4131
4129
|
resultDataResponse.testCaseResult = {
|
|
4132
|
-
resultMessage: `${this.convertRunStatus(
|
|
4130
|
+
resultMessage: `${this.convertRunStatus(debugOutcome)}`,
|
|
4133
4131
|
url: '',
|
|
4134
4132
|
};
|
|
4135
4133
|
}
|
|
4136
4134
|
else {
|
|
4137
4135
|
resultDataResponse.testCaseResult = {
|
|
4138
|
-
resultMessage: `${this.convertRunStatus(
|
|
4136
|
+
resultMessage: `${this.convertRunStatus(debugOutcome)} in Run ${lastRunId}`,
|
|
4139
4137
|
url: `${this.orgUrl}${projectName}/_testManagement/runs?runId=${lastRunId}&_a=resultSummary&resultId=${lastResultId}`,
|
|
4140
4138
|
};
|
|
4141
4139
|
}
|
|
@@ -4147,16 +4145,16 @@ class ResultDataProvider {
|
|
|
4147
4145
|
resultDataResponse.failureType = resultData.failureType;
|
|
4148
4146
|
break;
|
|
4149
4147
|
case 'runBy':
|
|
4150
|
-
if (!((
|
|
4151
|
-
logger_1.default.debug(`[RunResult] Missing runBy for testCaseId=${String((
|
|
4148
|
+
if (!((_o = lastResultDetails === null || lastResultDetails === void 0 ? void 0 : lastResultDetails.runBy) === null || _o === void 0 ? void 0 : _o.displayName)) {
|
|
4149
|
+
logger_1.default.debug(`[RunResult] Missing runBy for testCaseId=${String((_r = (_q = (_p = resultData === null || resultData === void 0 ? void 0 : resultData.testCase) === null || _p === void 0 ? void 0 : _p.id) !== null && _q !== void 0 ? _q : point === null || point === void 0 ? void 0 : point.testCaseId) !== null && _r !== void 0 ? _r : 'unknown')} (lastRunId=${String(lastRunId !== null && lastRunId !== void 0 ? lastRunId : '')}, lastResultId=${String(lastResultId !== null && lastResultId !== void 0 ? lastResultId : '')}). lastResultDetails=${this.stringifyForDebug(lastResultDetails, 2000)}`);
|
|
4152
4150
|
}
|
|
4153
|
-
resultDataResponse.runBy = (
|
|
4151
|
+
resultDataResponse.runBy = (_t = (_s = lastResultDetails === null || lastResultDetails === void 0 ? void 0 : lastResultDetails.runBy) === null || _s === void 0 ? void 0 : _s.displayName) !== null && _t !== void 0 ? _t : '';
|
|
4154
4152
|
break;
|
|
4155
4153
|
case 'executionDate':
|
|
4156
4154
|
if (!(lastResultDetails === null || lastResultDetails === void 0 ? void 0 : lastResultDetails.dateCompleted)) {
|
|
4157
|
-
logger_1.default.debug(`[RunResult] Missing dateCompleted for testCaseId=${String((
|
|
4155
|
+
logger_1.default.debug(`[RunResult] Missing dateCompleted for testCaseId=${String((_w = (_v = (_u = resultData === null || resultData === void 0 ? void 0 : resultData.testCase) === null || _u === void 0 ? void 0 : _u.id) !== null && _v !== void 0 ? _v : point === null || point === void 0 ? void 0 : point.testCaseId) !== null && _w !== void 0 ? _w : 'unknown')} (lastRunId=${String(lastRunId !== null && lastRunId !== void 0 ? lastRunId : '')}, lastResultId=${String(lastResultId !== null && lastResultId !== void 0 ? lastResultId : '')}). lastResultDetails=${this.stringifyForDebug(lastResultDetails, 2000)}`);
|
|
4158
4156
|
}
|
|
4159
|
-
resultDataResponse.executionDate = (
|
|
4157
|
+
resultDataResponse.executionDate = (_x = lastResultDetails === null || lastResultDetails === void 0 ? void 0 : lastResultDetails.dateCompleted) !== null && _x !== void 0 ? _x : '';
|
|
4160
4158
|
break;
|
|
4161
4159
|
case 'configurationName':
|
|
4162
4160
|
resultDataResponse.configurationName = configurationName;
|