@elisra-devops/docgen-data-provider 1.84.0 → 1.86.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/modules/ResultDataProvider.d.ts +2 -0
- package/bin/modules/ResultDataProvider.js +201 -45
- package/bin/modules/ResultDataProvider.js.map +1 -1
- package/bin/tests/modules/ResultDataProvider.test.js +269 -0
- package/bin/tests/modules/ResultDataProvider.test.js.map +1 -1
- package/package.json +1 -1
- package/src/modules/ResultDataProvider.ts +221 -40
- package/src/tests/modules/ResultDataProvider.test.ts +324 -0
|
@@ -88,6 +88,7 @@ export default class ResultDataProvider {
|
|
|
88
88
|
private buildMewpCoverageL3L4Rows;
|
|
89
89
|
private buildMewpCoverageRows;
|
|
90
90
|
private resolveCoverageBugResponsibility;
|
|
91
|
+
private buildMewpTestCaseResponsibilityMap;
|
|
91
92
|
private resolveMewpL2RunStatus;
|
|
92
93
|
private fetchMewpScopedTestData;
|
|
93
94
|
private extractRelNumberFromSuite;
|
|
@@ -134,6 +135,7 @@ export default class ResultDataProvider {
|
|
|
134
135
|
private extractLinkedWorkItemIdsFromRelations;
|
|
135
136
|
private extractMewpRequirementIdentifier;
|
|
136
137
|
private deriveMewpResponsibility;
|
|
138
|
+
private deriveMewpTestCaseResponsibility;
|
|
137
139
|
private deriveMewpSubSystem;
|
|
138
140
|
private resolveBugResponsibility;
|
|
139
141
|
private resolveMewpResponsibility;
|
|
@@ -306,6 +306,7 @@ class ResultDataProvider {
|
|
|
306
306
|
const requirements = this.collapseMewpRequirementFamilies(allRequirements, (scopedRequirementKeys === null || scopedRequirementKeys === void 0 ? void 0 : scopedRequirementKeys.size) ? scopedRequirementKeys : undefined);
|
|
307
307
|
const l2ToLinkedL1BaseKeys = await this.buildMewpL2ToLinkedL1BaseKeys(allRequirements, projectName, testData);
|
|
308
308
|
const requirementSapWbsByBaseKey = this.buildRequirementSapWbsByBaseKey(allRequirements);
|
|
309
|
+
const testCaseResponsibilityById = await this.buildMewpTestCaseResponsibilityMap(testData, projectName);
|
|
309
310
|
const externalBugsByTestCase = await this.loadExternalBugsByTestCase(options === null || options === void 0 ? void 0 : options.externalBugsFile);
|
|
310
311
|
const externalL3L4ByBaseKey = await this.loadExternalL3L4ByBaseKey(options === null || options === void 0 ? void 0 : options.externalL3L4File, requirementSapWbsByBaseKey);
|
|
311
312
|
const hasExternalBugsFile = !!String(((_a = options === null || options === void 0 ? void 0 : options.externalBugsFile) === null || _a === void 0 ? void 0 : _a.name) ||
|
|
@@ -442,7 +443,7 @@ class ResultDataProvider {
|
|
|
442
443
|
logger_1.default.warn(`MEWP coverage join diagnostics: no overlap between external bug test cases and failed test cases. ` +
|
|
443
444
|
`Bug rows remain empty because bugs are shown only for failed L2s.`);
|
|
444
445
|
}
|
|
445
|
-
const rows = this.buildMewpCoverageRows(requirements, requirementIndex, observedTestCaseIdsByRequirement, linkedRequirementsByTestCase, externalL3L4ByBaseKey, externalBugsByTestCase, externalJoinKeysByL2);
|
|
446
|
+
const rows = this.buildMewpCoverageRows(requirements, requirementIndex, observedTestCaseIdsByRequirement, linkedRequirementsByTestCase, externalL3L4ByBaseKey, externalBugsByTestCase, externalJoinKeysByL2, testCaseResponsibilityById);
|
|
446
447
|
const coverageRowStats = rows.reduce((acc, row) => {
|
|
447
448
|
const hasBug = Number((row === null || row === void 0 ? void 0 : row['Bug ID']) || 0) > 0;
|
|
448
449
|
const hasL3 = String((row === null || row === void 0 ? void 0 : row['L3 REQ ID']) || '').trim() !== '';
|
|
@@ -557,34 +558,56 @@ class ResultDataProvider {
|
|
|
557
558
|
diagnostics.testCasesWithoutMentionedCustomerIds += 1;
|
|
558
559
|
}
|
|
559
560
|
const mentionedBaseKeys = new Set([...mentionedL2Only].map((code) => this.toRequirementKey(code)).filter((code) => !!code));
|
|
560
|
-
const expectedFamilyCodes = new Set();
|
|
561
|
-
for (const baseKey of mentionedBaseKeys) {
|
|
562
|
-
const familyCodes = requirementFamilies.get(baseKey);
|
|
563
|
-
if (familyCodes === null || familyCodes === void 0 ? void 0 : familyCodes.size) {
|
|
564
|
-
familyCodes.forEach((code) => expectedFamilyCodes.add(code));
|
|
565
|
-
}
|
|
566
|
-
else {
|
|
567
|
-
for (const code of mentionedL2Only) {
|
|
568
|
-
if (this.toRequirementKey(code) === baseKey)
|
|
569
|
-
expectedFamilyCodes.add(code);
|
|
570
|
-
}
|
|
571
|
-
}
|
|
572
|
-
}
|
|
573
561
|
const linkedFullCodesRaw = ((_c = linkedRequirementsByTestCase.get(testCaseId)) === null || _c === void 0 ? void 0 : _c.fullCodes) || new Set();
|
|
574
562
|
const linkedFullCodes = (scopedRequirementKeys === null || scopedRequirementKeys === void 0 ? void 0 : scopedRequirementKeys.size) && linkedFullCodesRaw.size > 0
|
|
575
563
|
? new Set([...linkedFullCodesRaw].filter((code) => scopedRequirementKeys.has(this.toRequirementKey(code))))
|
|
576
564
|
: linkedFullCodesRaw;
|
|
577
565
|
const linkedBaseKeys = new Set([...linkedFullCodes].map((code) => this.toRequirementKey(code)).filter((code) => !!code));
|
|
578
|
-
const
|
|
566
|
+
const mentionedCodesByBase = new Map();
|
|
567
|
+
for (const code of mentionedL2Only) {
|
|
579
568
|
const baseKey = this.toRequirementKey(code);
|
|
580
569
|
if (!baseKey)
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
570
|
+
continue;
|
|
571
|
+
if (!mentionedCodesByBase.has(baseKey))
|
|
572
|
+
mentionedCodesByBase.set(baseKey, new Set());
|
|
573
|
+
mentionedCodesByBase.get(baseKey).add(code);
|
|
574
|
+
}
|
|
575
|
+
// Context-based direction A logic:
|
|
576
|
+
// 1) If no member of family is linked -> report only base SR (Step X: SR0054).
|
|
577
|
+
// 2) If family is partially linked -> report only specific missing members.
|
|
578
|
+
// 3) If family fully linked -> report nothing for that family.
|
|
579
|
+
const missingBaseWhenFamilyUncovered = new Set();
|
|
580
|
+
const missingSpecificMentionedNoFamily = new Set();
|
|
581
|
+
const missingFamilyMembers = new Set();
|
|
582
|
+
for (const [baseKey, mentionedCodes] of mentionedCodesByBase.entries()) {
|
|
583
|
+
const familyCodes = requirementFamilies.get(baseKey);
|
|
584
|
+
if (familyCodes === null || familyCodes === void 0 ? void 0 : familyCodes.size) {
|
|
585
|
+
const missingInFamily = [...familyCodes].filter((code) => !linkedFullCodes.has(code));
|
|
586
|
+
if (missingInFamily.length === 0)
|
|
587
|
+
continue;
|
|
588
|
+
const linkedInFamilyCount = familyCodes.size - missingInFamily.length;
|
|
589
|
+
if (linkedInFamilyCount === 0) {
|
|
590
|
+
missingBaseWhenFamilyUncovered.add(baseKey);
|
|
591
|
+
}
|
|
592
|
+
else {
|
|
593
|
+
for (const code of missingInFamily) {
|
|
594
|
+
missingFamilyMembers.add(code);
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
continue;
|
|
598
|
+
}
|
|
599
|
+
// Fallback path when family data is unavailable for this base key.
|
|
600
|
+
for (const code of mentionedCodes) {
|
|
601
|
+
const hasSpecificSuffix = /-\d+$/.test(code);
|
|
602
|
+
if (hasSpecificSuffix) {
|
|
603
|
+
if (!linkedFullCodes.has(code))
|
|
604
|
+
missingSpecificMentionedNoFamily.add(code);
|
|
605
|
+
}
|
|
606
|
+
else if (!linkedBaseKeys.has(baseKey)) {
|
|
607
|
+
missingBaseWhenFamilyUncovered.add(baseKey);
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
}
|
|
588
611
|
// Direction B is family-based: if any member of a family is mentioned in Expected Result,
|
|
589
612
|
// linked members of that same family are not considered "linked but not mentioned".
|
|
590
613
|
const extraLinked = [...linkedFullCodes].filter((code) => {
|
|
@@ -604,13 +627,18 @@ class ResultDataProvider {
|
|
|
604
627
|
}
|
|
605
628
|
mentionedButNotLinkedByStep.get(normalizedStepRef).add(normalizedRequirementId);
|
|
606
629
|
};
|
|
607
|
-
const
|
|
608
|
-
const
|
|
609
|
-
|
|
630
|
+
const sortedMissingSpecificMentionedNoFamily = [...missingSpecificMentionedNoFamily].sort((a, b) => a.localeCompare(b));
|
|
631
|
+
const sortedMissingBaseWhenFamilyUncovered = [...missingBaseWhenFamilyUncovered].sort((a, b) => a.localeCompare(b));
|
|
632
|
+
const sortedMissingFamilyMembers = [...missingFamilyMembers].sort((a, b) => a.localeCompare(b));
|
|
633
|
+
for (const code of sortedMissingSpecificMentionedNoFamily) {
|
|
610
634
|
const stepRef = mentionedCodeFirstStep.get(code) || 'Step ?';
|
|
611
635
|
appendMentionedButNotLinked(code, stepRef);
|
|
612
636
|
}
|
|
613
|
-
for (const
|
|
637
|
+
for (const baseKey of sortedMissingBaseWhenFamilyUncovered) {
|
|
638
|
+
const stepRef = mentionedBaseFirstStep.get(baseKey) || 'Step ?';
|
|
639
|
+
appendMentionedButNotLinked(baseKey, stepRef);
|
|
640
|
+
}
|
|
641
|
+
for (const code of sortedMissingFamilyMembers) {
|
|
614
642
|
const baseKey = this.toRequirementKey(code);
|
|
615
643
|
const stepRef = mentionedBaseFirstStep.get(baseKey) || 'Step ?';
|
|
616
644
|
appendMentionedButNotLinked(code, stepRef);
|
|
@@ -644,7 +672,9 @@ class ResultDataProvider {
|
|
|
644
672
|
logger_1.default.debug(`MEWP internal validation parse diagnostics: ` +
|
|
645
673
|
`testCaseId=${testCaseId} parsedSteps=${executableSteps.length} ` +
|
|
646
674
|
`stepsWithMentions=${mentionEntries.length} customerIdsFound=${mentionedL2Only.size} ` +
|
|
647
|
-
`linkedRequirements=${linkedFullCodes.size} mentionedButNotLinked=${
|
|
675
|
+
`linkedRequirements=${linkedFullCodes.size} mentionedButNotLinked=${sortedMissingSpecificMentionedNoFamily.length +
|
|
676
|
+
sortedMissingBaseWhenFamilyUncovered.length +
|
|
677
|
+
sortedMissingFamilyMembers.length} ` +
|
|
648
678
|
`linkedButNotMentioned=${sortedExtraLinked.length} status=${validationStatus} ` +
|
|
649
679
|
`customerIdSample='${[...mentionedL2Only].slice(0, 5).join(', ')}'`);
|
|
650
680
|
rows.push({
|
|
@@ -813,7 +843,7 @@ class ResultDataProvider {
|
|
|
813
843
|
return String((a === null || a === void 0 ? void 0 : a.l4Id) || '').localeCompare(String((b === null || b === void 0 ? void 0 : b.l4Id) || ''));
|
|
814
844
|
});
|
|
815
845
|
}
|
|
816
|
-
buildMewpCoverageRows(requirements, requirementIndex, observedTestCaseIdsByRequirement, linkedRequirementsByTestCase, l3l4ByBaseKey, externalBugsByTestCase, externalJoinKeysByL2) {
|
|
846
|
+
buildMewpCoverageRows(requirements, requirementIndex, observedTestCaseIdsByRequirement, linkedRequirementsByTestCase, l3l4ByBaseKey, externalBugsByTestCase, externalJoinKeysByL2, testCaseResponsibilityById) {
|
|
817
847
|
var _a;
|
|
818
848
|
const rows = [];
|
|
819
849
|
const linkedByRequirement = this.invertBaseRequirementLinks(linkedRequirementsByTestCase);
|
|
@@ -847,7 +877,7 @@ class ResultDataProvider {
|
|
|
847
877
|
const bugId = Number((bug === null || bug === void 0 ? void 0 : bug.id) || 0);
|
|
848
878
|
if (!Number.isFinite(bugId) || bugId <= 0)
|
|
849
879
|
continue;
|
|
850
|
-
aggregatedBugs.set(bugId, Object.assign(Object.assign({}, bug), { responsibility: this.resolveCoverageBugResponsibility(String((bug === null || bug === void 0 ? void 0 : bug.responsibility) || ''), requirement) }));
|
|
880
|
+
aggregatedBugs.set(bugId, Object.assign(Object.assign({}, bug), { responsibility: this.resolveCoverageBugResponsibility(String((bug === null || bug === void 0 ? void 0 : bug.responsibility) || ''), requirement, String((testCaseResponsibilityById === null || testCaseResponsibilityById === void 0 ? void 0 : testCaseResponsibilityById.get(testCaseId)) || '')) }));
|
|
851
881
|
}
|
|
852
882
|
}
|
|
853
883
|
}
|
|
@@ -874,18 +904,114 @@ class ResultDataProvider {
|
|
|
874
904
|
}
|
|
875
905
|
return rows;
|
|
876
906
|
}
|
|
877
|
-
resolveCoverageBugResponsibility(rawResponsibility, requirement) {
|
|
878
|
-
const
|
|
907
|
+
resolveCoverageBugResponsibility(rawResponsibility, requirement, testCaseResponsibility = '') {
|
|
908
|
+
const normalizeDisplay = (value) => {
|
|
909
|
+
const direct = String(value || '').trim();
|
|
910
|
+
if (!direct)
|
|
911
|
+
return '';
|
|
912
|
+
const resolved = this.resolveMewpResponsibility(this.toMewpComparableText(direct));
|
|
913
|
+
if (resolved === 'ESUK')
|
|
914
|
+
return 'ESUK';
|
|
915
|
+
if (resolved === 'IL')
|
|
916
|
+
return 'Elisra';
|
|
917
|
+
return direct;
|
|
918
|
+
};
|
|
919
|
+
const direct = normalizeDisplay(rawResponsibility);
|
|
879
920
|
if (direct && direct.toLowerCase() !== 'unknown')
|
|
880
921
|
return direct;
|
|
881
|
-
const
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
922
|
+
const fromTestCase = normalizeDisplay(testCaseResponsibility);
|
|
923
|
+
if (fromTestCase && fromTestCase.toLowerCase() !== 'unknown')
|
|
924
|
+
return fromTestCase;
|
|
925
|
+
const fromRequirement = normalizeDisplay(String((requirement === null || requirement === void 0 ? void 0 : requirement.responsibility) || ''));
|
|
926
|
+
if (fromRequirement && fromRequirement.toLowerCase() !== 'unknown')
|
|
927
|
+
return fromRequirement;
|
|
928
|
+
return direct || fromTestCase || fromRequirement || 'Unknown';
|
|
929
|
+
}
|
|
930
|
+
async buildMewpTestCaseResponsibilityMap(testData, projectName) {
|
|
931
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
|
|
932
|
+
const out = new Map();
|
|
933
|
+
const unresolved = new Set();
|
|
934
|
+
const extractFromWorkItemFields = (workItemFields) => {
|
|
935
|
+
const fields = {};
|
|
936
|
+
if (!Array.isArray(workItemFields))
|
|
937
|
+
return fields;
|
|
938
|
+
for (const field of workItemFields) {
|
|
939
|
+
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]
|
|
940
|
+
.map((item) => String(item || '').trim())
|
|
941
|
+
.filter((item) => !!item);
|
|
942
|
+
for (const key of keyCandidates) {
|
|
943
|
+
fields[key] = field === null || field === void 0 ? void 0 : field.value;
|
|
944
|
+
}
|
|
945
|
+
}
|
|
946
|
+
return fields;
|
|
947
|
+
};
|
|
948
|
+
for (const suite of testData || []) {
|
|
949
|
+
const testCasesItems = Array.isArray(suite === null || suite === void 0 ? void 0 : suite.testCasesItems) ? suite.testCasesItems : [];
|
|
950
|
+
for (const testCase of testCasesItems) {
|
|
951
|
+
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);
|
|
952
|
+
if (!Number.isFinite(testCaseId) || testCaseId <= 0 || out.has(testCaseId))
|
|
953
|
+
continue;
|
|
954
|
+
const workItemFieldsMap = ((_b = testCase === null || testCase === void 0 ? void 0 : testCase.workItem) === null || _b === void 0 ? void 0 : _b.fields) || {};
|
|
955
|
+
const workItemFieldsList = extractFromWorkItemFields((_c = testCase === null || testCase === void 0 ? void 0 : testCase.workItem) === null || _c === void 0 ? void 0 : _c.workItemFields);
|
|
956
|
+
const directFieldAliases = Object.fromEntries(Object.entries({
|
|
957
|
+
'System.AreaPath': ((_d = testCase === null || testCase === void 0 ? void 0 : testCase.workItem) === null || _d === void 0 ? void 0 : _d.areaPath) ||
|
|
958
|
+
((_e = testCase === null || testCase === void 0 ? void 0 : testCase.workItem) === null || _e === void 0 ? void 0 : _e.AreaPath) ||
|
|
959
|
+
(testCase === null || testCase === void 0 ? void 0 : testCase.areaPath) ||
|
|
960
|
+
(testCase === null || testCase === void 0 ? void 0 : testCase.AreaPath) ||
|
|
961
|
+
((_f = testCase === null || testCase === void 0 ? void 0 : testCase.testCase) === null || _f === void 0 ? void 0 : _f.areaPath) ||
|
|
962
|
+
((_g = testCase === null || testCase === void 0 ? void 0 : testCase.testCase) === null || _g === void 0 ? void 0 : _g.AreaPath),
|
|
963
|
+
'Area Path': ((_h = testCase === null || testCase === void 0 ? void 0 : testCase.workItem) === null || _h === void 0 ? void 0 : _h['Area Path']) ||
|
|
964
|
+
(testCase === null || testCase === void 0 ? void 0 : testCase['Area Path']) ||
|
|
965
|
+
((_j = testCase === null || testCase === void 0 ? void 0 : testCase.testCase) === null || _j === void 0 ? void 0 : _j['Area Path']),
|
|
966
|
+
AreaPath: ((_k = testCase === null || testCase === void 0 ? void 0 : testCase.workItem) === null || _k === void 0 ? void 0 : _k.AreaPath) ||
|
|
967
|
+
(testCase === null || testCase === void 0 ? void 0 : testCase.AreaPath) ||
|
|
968
|
+
((_l = testCase === null || testCase === void 0 ? void 0 : testCase.testCase) === null || _l === void 0 ? void 0 : _l.AreaPath),
|
|
969
|
+
}).filter(([, value]) => value !== undefined && value !== null && String(value).trim() !== ''));
|
|
970
|
+
const fromWorkItem = this.deriveMewpTestCaseResponsibility(Object.assign(Object.assign(Object.assign({}, directFieldAliases), workItemFieldsList), workItemFieldsMap));
|
|
971
|
+
if (fromWorkItem) {
|
|
972
|
+
out.set(testCaseId, fromWorkItem);
|
|
973
|
+
}
|
|
974
|
+
else {
|
|
975
|
+
unresolved.add(testCaseId);
|
|
976
|
+
}
|
|
977
|
+
}
|
|
978
|
+
const testPointsItems = Array.isArray(suite === null || suite === void 0 ? void 0 : suite.testPointsItems) ? suite.testPointsItems : [];
|
|
979
|
+
for (const testPoint of testPointsItems) {
|
|
980
|
+
const testCaseId = Number((testPoint === null || testPoint === void 0 ? void 0 : testPoint.testCaseId) || ((_m = testPoint === null || testPoint === void 0 ? void 0 : testPoint.testCase) === null || _m === void 0 ? void 0 : _m.id) || 0);
|
|
981
|
+
if (!Number.isFinite(testCaseId) || testCaseId <= 0 || out.has(testCaseId))
|
|
982
|
+
continue;
|
|
983
|
+
const fromPoint = this.deriveMewpTestCaseResponsibility({
|
|
984
|
+
'System.AreaPath': (testPoint === null || testPoint === void 0 ? void 0 : testPoint.areaPath) || (testPoint === null || testPoint === void 0 ? void 0 : testPoint.AreaPath),
|
|
985
|
+
'Area Path': testPoint === null || testPoint === void 0 ? void 0 : testPoint['Area Path'],
|
|
986
|
+
AreaPath: testPoint === null || testPoint === void 0 ? void 0 : testPoint.AreaPath,
|
|
987
|
+
});
|
|
988
|
+
if (fromPoint) {
|
|
989
|
+
out.set(testCaseId, fromPoint);
|
|
990
|
+
unresolved.delete(testCaseId);
|
|
991
|
+
}
|
|
992
|
+
else {
|
|
993
|
+
unresolved.add(testCaseId);
|
|
994
|
+
}
|
|
995
|
+
}
|
|
996
|
+
}
|
|
997
|
+
if (unresolved.size > 0) {
|
|
998
|
+
try {
|
|
999
|
+
const workItems = await this.fetchWorkItemsByIds(projectName, [...unresolved], false);
|
|
1000
|
+
for (const workItem of workItems || []) {
|
|
1001
|
+
const testCaseId = Number((workItem === null || workItem === void 0 ? void 0 : workItem.id) || 0);
|
|
1002
|
+
if (!Number.isFinite(testCaseId) || testCaseId <= 0 || out.has(testCaseId))
|
|
1003
|
+
continue;
|
|
1004
|
+
const resolved = this.deriveMewpTestCaseResponsibility((workItem === null || workItem === void 0 ? void 0 : workItem.fields) || {});
|
|
1005
|
+
if (!resolved)
|
|
1006
|
+
continue;
|
|
1007
|
+
out.set(testCaseId, resolved);
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
1010
|
+
catch (error) {
|
|
1011
|
+
logger_1.default.warn(`MEWP coverage: failed to enrich test-case responsibility fallback: ${(error === null || error === void 0 ? void 0 : error.message) || error}`);
|
|
1012
|
+
}
|
|
1013
|
+
}
|
|
1014
|
+
return out;
|
|
889
1015
|
}
|
|
890
1016
|
resolveMewpL2RunStatus(input) {
|
|
891
1017
|
if (((input === null || input === void 0 ? void 0 : input.failed) || 0) > 0)
|
|
@@ -1998,11 +2124,42 @@ class ResultDataProvider {
|
|
|
1998
2124
|
return fromExplicitLabel;
|
|
1999
2125
|
if (explicitSapWbsByLabel)
|
|
2000
2126
|
return explicitSapWbsByLabel;
|
|
2001
|
-
const
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2127
|
+
const areaPathCandidates = [
|
|
2128
|
+
fields === null || fields === void 0 ? void 0 : fields['System.AreaPath'],
|
|
2129
|
+
fields === null || fields === void 0 ? void 0 : fields['Area Path'],
|
|
2130
|
+
fields === null || fields === void 0 ? void 0 : fields['AreaPath'],
|
|
2131
|
+
];
|
|
2132
|
+
for (const candidate of areaPathCandidates) {
|
|
2133
|
+
const normalized = this.toMewpComparableText(candidate);
|
|
2134
|
+
const resolved = this.resolveMewpResponsibility(normalized);
|
|
2135
|
+
if (resolved)
|
|
2136
|
+
return resolved;
|
|
2137
|
+
}
|
|
2138
|
+
const keyHints = ['sapwbs', 'responsibility', 'owner', 'areapath', 'area path'];
|
|
2139
|
+
for (const [key, value] of Object.entries(fields || {})) {
|
|
2140
|
+
const normalizedKey = String(key || '').toLowerCase();
|
|
2141
|
+
if (!keyHints.some((hint) => normalizedKey.includes(hint)))
|
|
2142
|
+
continue;
|
|
2143
|
+
const resolved = this.resolveMewpResponsibility(this.toMewpComparableText(value));
|
|
2144
|
+
if (resolved)
|
|
2145
|
+
return resolved;
|
|
2146
|
+
}
|
|
2147
|
+
return '';
|
|
2148
|
+
}
|
|
2149
|
+
// Test-case responsibility must come from test-case path context (not SAPWBS).
|
|
2150
|
+
deriveMewpTestCaseResponsibility(fields) {
|
|
2151
|
+
const areaPathCandidates = [
|
|
2152
|
+
fields === null || fields === void 0 ? void 0 : fields['System.AreaPath'],
|
|
2153
|
+
fields === null || fields === void 0 ? void 0 : fields['Area Path'],
|
|
2154
|
+
fields === null || fields === void 0 ? void 0 : fields['AreaPath'],
|
|
2155
|
+
];
|
|
2156
|
+
for (const candidate of areaPathCandidates) {
|
|
2157
|
+
const normalized = this.toMewpComparableText(candidate);
|
|
2158
|
+
const resolved = this.resolveMewpResponsibility(normalized);
|
|
2159
|
+
if (resolved)
|
|
2160
|
+
return resolved;
|
|
2161
|
+
}
|
|
2162
|
+
const keyHints = ['areapath', 'area path', 'responsibility', 'owner'];
|
|
2006
2163
|
for (const [key, value] of Object.entries(fields || {})) {
|
|
2007
2164
|
const normalizedKey = String(key || '').toLowerCase();
|
|
2008
2165
|
if (!keyHints.some((hint) => normalizedKey.includes(hint)))
|
|
@@ -2404,7 +2561,6 @@ class ResultDataProvider {
|
|
|
2404
2561
|
logger_1.default.warn(`Invalid run result ${runId} or result ${resultId}`);
|
|
2405
2562
|
return null;
|
|
2406
2563
|
}
|
|
2407
|
-
logger_1.default.warn(`Current Test point for Test case ${point.testCaseId} is in Active state`);
|
|
2408
2564
|
const url = `${this.orgUrl}${projectName}/_apis/wit/workItems/${point.testCaseId}?$expand=all`;
|
|
2409
2565
|
const testCaseData = await tfs_1.TFSServices.getItemContent(url, this.token);
|
|
2410
2566
|
const newResultData = {
|