@elisra-devops/docgen-data-provider 1.89.0 → 1.91.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 +0 -4
- package/bin/modules/ResultDataProvider.d.ts +4 -3
- package/bin/modules/ResultDataProvider.js +103 -137
- package/bin/modules/ResultDataProvider.js.map +1 -1
- package/bin/tests/modules/ResultDataProvider.test.js +97 -3
- package/bin/tests/modules/ResultDataProvider.test.js.map +1 -1
- package/package.json +1 -1
- package/src/models/mewp-reporting.ts +0 -5
- package/src/modules/ResultDataProvider.ts +106 -153
- package/src/tests/modules/ResultDataProvider.test.ts +112 -3
|
@@ -13,10 +13,6 @@ export interface MewpExternalFileRef {
|
|
|
13
13
|
export interface MewpCoverageRequestOptions {
|
|
14
14
|
externalBugsFile?: MewpExternalFileRef | null;
|
|
15
15
|
externalL3L4File?: MewpExternalFileRef | null;
|
|
16
|
-
debugMode?: boolean;
|
|
17
|
-
}
|
|
18
|
-
export interface MewpInternalValidationRequestOptions {
|
|
19
|
-
debugMode?: boolean;
|
|
20
16
|
}
|
|
21
17
|
export interface MewpRequirementStepSummary {
|
|
22
18
|
passed: number;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { OpenPcrRequest } from '../models/tfs-data';
|
|
2
|
-
import type { MewpCoverageFlatPayload, MewpExternalFilesValidationResponse, MewpCoverageRequestOptions, MewpExternalFileRef, MewpInternalValidationFlatPayload
|
|
2
|
+
import type { MewpCoverageFlatPayload, MewpExternalFilesValidationResponse, MewpCoverageRequestOptions, MewpExternalFileRef, MewpInternalValidationFlatPayload } from '../models/mewp-reporting';
|
|
3
3
|
/**
|
|
4
4
|
* Provides methods to fetch, process, and summarize test data from Azure DevOps.
|
|
5
5
|
*
|
|
@@ -70,7 +70,7 @@ export default class ResultDataProvider {
|
|
|
70
70
|
* Rows are one Requirement-TestCase pair; uncovered requirements are emitted with empty test-case columns.
|
|
71
71
|
*/
|
|
72
72
|
getMewpL2CoverageFlatResults(testPlanId: string, projectName: string, selectedSuiteIds: number[] | undefined, linkedQueryRequest?: any, options?: MewpCoverageRequestOptions): Promise<MewpCoverageFlatPayload>;
|
|
73
|
-
getMewpInternalValidationFlatResults(testPlanId: string, projectName: string, selectedSuiteIds: number[] | undefined, linkedQueryRequest?: any
|
|
73
|
+
getMewpInternalValidationFlatResults(testPlanId: string, projectName: string, selectedSuiteIds: number[] | undefined, linkedQueryRequest?: any): Promise<MewpInternalValidationFlatPayload>;
|
|
74
74
|
validateMewpExternalFiles(options: {
|
|
75
75
|
externalBugsFile?: MewpExternalFileRef | null;
|
|
76
76
|
externalL3L4File?: MewpExternalFileRef | null;
|
|
@@ -138,6 +138,8 @@ export default class ResultDataProvider {
|
|
|
138
138
|
private isExcludedL3L4BySapWbs;
|
|
139
139
|
private normalizeMewpRequirementCode;
|
|
140
140
|
private normalizeMewpRequirementCodeWithSuffix;
|
|
141
|
+
private compareMewpRequirementCodes;
|
|
142
|
+
private formatStepScopedRequirementGroups;
|
|
141
143
|
private formatRequirementCodesGroupedByFamily;
|
|
142
144
|
private toMewpComparableText;
|
|
143
145
|
private fetchTestPlanName;
|
|
@@ -237,7 +239,6 @@ export default class ResultDataProvider {
|
|
|
237
239
|
* @returns A promise that resolves to the result data.
|
|
238
240
|
*/
|
|
239
241
|
private fetchResultDataBasedOnWi;
|
|
240
|
-
private logMewpRunScenarioDebugMatrix;
|
|
241
242
|
/**
|
|
242
243
|
* Converts a run status string into a human-readable format.
|
|
243
244
|
*
|
|
@@ -348,9 +348,6 @@ 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
|
-
}
|
|
354
351
|
for (const runResult of runResults) {
|
|
355
352
|
const testCaseId = this.extractMewpTestCaseId(runResult);
|
|
356
353
|
const rawActionResults = Array.isArray((_j = runResult === null || runResult === void 0 ? void 0 : runResult.iteration) === null || _j === void 0 ? void 0 : _j.actionResults)
|
|
@@ -478,8 +475,8 @@ class ResultDataProvider {
|
|
|
478
475
|
return defaultPayload;
|
|
479
476
|
}
|
|
480
477
|
}
|
|
481
|
-
async getMewpInternalValidationFlatResults(testPlanId, projectName, selectedSuiteIds, linkedQueryRequest
|
|
482
|
-
var _a, _b
|
|
478
|
+
async getMewpInternalValidationFlatResults(testPlanId, projectName, selectedSuiteIds, linkedQueryRequest) {
|
|
479
|
+
var _a, _b;
|
|
483
480
|
const defaultPayload = {
|
|
484
481
|
sheetName: `MEWP Internal Validation - Plan ${testPlanId}`,
|
|
485
482
|
columnOrder: [...ResultDataProvider.INTERNAL_VALIDATION_COLUMNS],
|
|
@@ -492,6 +489,31 @@ class ResultDataProvider {
|
|
|
492
489
|
const linkedRequirementsByTestCase = await this.buildLinkedRequirementsByTestCase(allRequirements, testData, projectName);
|
|
493
490
|
const scopedRequirementKeys = await this.resolveMewpRequirementScopeKeysFromQuery(linkedQueryRequest, allRequirements, linkedRequirementsByTestCase);
|
|
494
491
|
const requirementFamilies = this.buildRequirementFamilyMap(allRequirements, (scopedRequirementKeys === null || scopedRequirementKeys === void 0 ? void 0 : scopedRequirementKeys.size) ? scopedRequirementKeys : undefined);
|
|
492
|
+
const linkedFullCodesByTestCase = new Map();
|
|
493
|
+
const linkedFamilyCodesAcrossTestCases = new Map();
|
|
494
|
+
const linkedFullCodesAcrossTestCases = new Set();
|
|
495
|
+
const linkedBaseKeysAcrossTestCases = new Set();
|
|
496
|
+
for (const [linkedTestCaseId, links] of linkedRequirementsByTestCase.entries()) {
|
|
497
|
+
const rawFullCodes = (links === null || links === void 0 ? void 0 : links.fullCodes) || new Set();
|
|
498
|
+
const filteredFullCodes = (scopedRequirementKeys === null || scopedRequirementKeys === void 0 ? void 0 : scopedRequirementKeys.size) && rawFullCodes.size > 0
|
|
499
|
+
? new Set([...rawFullCodes].filter((code) => scopedRequirementKeys.has(this.toRequirementKey(code))))
|
|
500
|
+
: rawFullCodes;
|
|
501
|
+
linkedFullCodesByTestCase.set(linkedTestCaseId, filteredFullCodes);
|
|
502
|
+
for (const code of filteredFullCodes) {
|
|
503
|
+
const normalizedCode = this.normalizeMewpRequirementCodeWithSuffix(code);
|
|
504
|
+
if (!normalizedCode)
|
|
505
|
+
continue;
|
|
506
|
+
linkedFullCodesAcrossTestCases.add(normalizedCode);
|
|
507
|
+
const baseKey = this.toRequirementKey(normalizedCode);
|
|
508
|
+
if (!baseKey)
|
|
509
|
+
continue;
|
|
510
|
+
linkedBaseKeysAcrossTestCases.add(baseKey);
|
|
511
|
+
if (!linkedFamilyCodesAcrossTestCases.has(baseKey)) {
|
|
512
|
+
linkedFamilyCodesAcrossTestCases.set(baseKey, new Set());
|
|
513
|
+
}
|
|
514
|
+
linkedFamilyCodesAcrossTestCases.get(baseKey).add(normalizedCode);
|
|
515
|
+
}
|
|
516
|
+
}
|
|
495
517
|
const rows = [];
|
|
496
518
|
const stepsXmlByTestCase = this.buildTestCaseStepsXmlMap(testData);
|
|
497
519
|
const testCaseTitleMap = this.buildMewpTestCaseTitleMap(testData);
|
|
@@ -515,10 +537,6 @@ class ResultDataProvider {
|
|
|
515
537
|
logger_1.default.info(`MEWP internal validation steps source summary: testCases=${allTestCaseIds.size} ` +
|
|
516
538
|
`fromSuitePayload=${preloadedStepXmlCount} fromWorkItemFallback=${fallbackStepLoadStats.loadedFromFallback} ` +
|
|
517
539
|
`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
|
-
}
|
|
522
540
|
const validL2BaseKeys = new Set([...requirementFamilies.keys()]);
|
|
523
541
|
const diagnostics = {
|
|
524
542
|
totalTestCases: 0,
|
|
@@ -565,11 +583,7 @@ class ResultDataProvider {
|
|
|
565
583
|
diagnostics.testCasesWithoutMentionedCustomerIds += 1;
|
|
566
584
|
}
|
|
567
585
|
const mentionedBaseKeys = new Set([...mentionedL2Only].map((code) => this.toRequirementKey(code)).filter((code) => !!code));
|
|
568
|
-
const
|
|
569
|
-
const linkedFullCodes = (scopedRequirementKeys === null || scopedRequirementKeys === void 0 ? void 0 : scopedRequirementKeys.size) && linkedFullCodesRaw.size > 0
|
|
570
|
-
? new Set([...linkedFullCodesRaw].filter((code) => scopedRequirementKeys.has(this.toRequirementKey(code))))
|
|
571
|
-
: linkedFullCodesRaw;
|
|
572
|
-
const linkedBaseKeys = new Set([...linkedFullCodes].map((code) => this.toRequirementKey(code)).filter((code) => !!code));
|
|
586
|
+
const linkedFullCodes = linkedFullCodesByTestCase.get(testCaseId) || new Set();
|
|
573
587
|
const mentionedCodesByBase = new Map();
|
|
574
588
|
for (const code of mentionedL2Only) {
|
|
575
589
|
const baseKey = this.toRequirementKey(code);
|
|
@@ -579,42 +593,28 @@ class ResultDataProvider {
|
|
|
579
593
|
mentionedCodesByBase.set(baseKey, new Set());
|
|
580
594
|
mentionedCodesByBase.get(baseKey).add(code);
|
|
581
595
|
}
|
|
582
|
-
//
|
|
583
|
-
// 1)
|
|
584
|
-
//
|
|
585
|
-
//
|
|
596
|
+
// Direction A logic:
|
|
597
|
+
// 1) Base mention ("SR0054") is parent-level only and considered covered
|
|
598
|
+
// if any member of that family is linked across scoped test cases.
|
|
599
|
+
// 2) Child mention ("SR0054-1") is exact-match and checked across scoped test cases.
|
|
586
600
|
const missingBaseWhenFamilyUncovered = new Set();
|
|
587
601
|
const missingSpecificMentionedNoFamily = new Set();
|
|
588
|
-
const missingFamilyMembers = new Set();
|
|
589
602
|
for (const [baseKey, mentionedCodes] of mentionedCodesByBase.entries()) {
|
|
590
603
|
const familyCodes = requirementFamilies.get(baseKey);
|
|
591
604
|
const mentionedCodesList = [...mentionedCodes];
|
|
592
605
|
const hasBaseMention = mentionedCodesList.some((code) => !/-\d+$/.test(code));
|
|
593
606
|
const mentionedSpecificMembers = mentionedCodesList.filter((code) => /-\d+$/.test(code));
|
|
594
607
|
if (familyCodes === null || familyCodes === void 0 ? void 0 : familyCodes.size) {
|
|
595
|
-
|
|
596
|
-
//
|
|
608
|
+
const familyLinkedCodes = linkedFamilyCodesAcrossTestCases.get(baseKey) || new Set();
|
|
609
|
+
// Base mention ("SR0054") is satisfied by any linked member in the same family.
|
|
597
610
|
if (hasBaseMention) {
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
const targetFamilyCodes = childFamilyCodes.length > 0 ? childFamilyCodes : familyCodesList;
|
|
601
|
-
const missingInTargetFamily = targetFamilyCodes.filter((code) => !linkedFullCodes.has(code));
|
|
602
|
-
if (missingInTargetFamily.length > 0) {
|
|
603
|
-
const hasAnyLinkedInFamily = familyCodesList.some((code) => linkedFullCodes.has(code));
|
|
604
|
-
if (!hasAnyLinkedInFamily) {
|
|
605
|
-
missingBaseWhenFamilyUncovered.add(baseKey);
|
|
606
|
-
}
|
|
607
|
-
else {
|
|
608
|
-
for (const code of missingInTargetFamily) {
|
|
609
|
-
missingFamilyMembers.add(code);
|
|
610
|
-
}
|
|
611
|
-
}
|
|
611
|
+
if (familyLinkedCodes.size === 0) {
|
|
612
|
+
missingBaseWhenFamilyUncovered.add(baseKey);
|
|
612
613
|
}
|
|
613
|
-
continue;
|
|
614
614
|
}
|
|
615
|
-
// Specific mention ("SR0054-1") validates as exact-match only.
|
|
615
|
+
// Specific mention ("SR0054-1") validates as exact-match only across scoped test cases.
|
|
616
616
|
for (const code of mentionedSpecificMembers) {
|
|
617
|
-
if (!
|
|
617
|
+
if (!familyLinkedCodes.has(code)) {
|
|
618
618
|
missingSpecificMentionedNoFamily.add(code);
|
|
619
619
|
}
|
|
620
620
|
}
|
|
@@ -624,11 +624,11 @@ class ResultDataProvider {
|
|
|
624
624
|
for (const code of mentionedCodes) {
|
|
625
625
|
const hasSpecificSuffix = /-\d+$/.test(code);
|
|
626
626
|
if (hasSpecificSuffix) {
|
|
627
|
-
if (!
|
|
627
|
+
if (!linkedFullCodesAcrossTestCases.has(code)) {
|
|
628
628
|
missingSpecificMentionedNoFamily.add(code);
|
|
629
629
|
}
|
|
630
630
|
}
|
|
631
|
-
else if (!
|
|
631
|
+
else if (!linkedBaseKeysAcrossTestCases.has(baseKey)) {
|
|
632
632
|
missingBaseWhenFamilyUncovered.add(baseKey);
|
|
633
633
|
}
|
|
634
634
|
}
|
|
@@ -654,7 +654,6 @@ class ResultDataProvider {
|
|
|
654
654
|
};
|
|
655
655
|
const sortedMissingSpecificMentionedNoFamily = [...missingSpecificMentionedNoFamily].sort((a, b) => a.localeCompare(b));
|
|
656
656
|
const sortedMissingBaseWhenFamilyUncovered = [...missingBaseWhenFamilyUncovered].sort((a, b) => a.localeCompare(b));
|
|
657
|
-
const sortedMissingFamilyMembers = [...missingFamilyMembers].sort((a, b) => a.localeCompare(b));
|
|
658
657
|
for (const code of sortedMissingSpecificMentionedNoFamily) {
|
|
659
658
|
const stepRef = mentionedCodeFirstStep.get(code) || 'Step ?';
|
|
660
659
|
appendMentionedButNotLinked(code, stepRef);
|
|
@@ -663,11 +662,6 @@ class ResultDataProvider {
|
|
|
663
662
|
const stepRef = mentionedBaseFirstStep.get(baseKey) || 'Step ?';
|
|
664
663
|
appendMentionedButNotLinked(baseKey, stepRef);
|
|
665
664
|
}
|
|
666
|
-
for (const code of sortedMissingFamilyMembers) {
|
|
667
|
-
const baseKey = this.toRequirementKey(code);
|
|
668
|
-
const stepRef = mentionedBaseFirstStep.get(baseKey) || 'Step ?';
|
|
669
|
-
appendMentionedButNotLinked(code, stepRef);
|
|
670
|
-
}
|
|
671
665
|
const sortedExtraLinked = [...new Set(extraLinked)]
|
|
672
666
|
.map((code) => this.normalizeMewpRequirementCodeWithSuffix(code))
|
|
673
667
|
.filter((code) => !!code)
|
|
@@ -686,11 +680,11 @@ class ResultDataProvider {
|
|
|
686
680
|
return String(a[0]).localeCompare(String(b[0]));
|
|
687
681
|
})
|
|
688
682
|
.map(([stepRef, requirementIds]) => {
|
|
689
|
-
|
|
690
|
-
return `${stepRef}: ${groupedRequirementList}`;
|
|
683
|
+
return this.formatStepScopedRequirementGroups(stepRef, requirementIds);
|
|
691
684
|
})
|
|
692
|
-
.join('\n')
|
|
693
|
-
|
|
685
|
+
.join('\n')
|
|
686
|
+
.trim();
|
|
687
|
+
const linkedButNotMentioned = this.formatRequirementCodesGroupedByFamily(sortedExtraLinked).trim();
|
|
694
688
|
const validationStatus = mentionedButNotLinked || linkedButNotMentioned ? 'Fail' : 'Pass';
|
|
695
689
|
if (validationStatus === 'Fail')
|
|
696
690
|
diagnostics.failingRows += 1;
|
|
@@ -698,8 +692,7 @@ class ResultDataProvider {
|
|
|
698
692
|
`testCaseId=${testCaseId} parsedSteps=${executableSteps.length} ` +
|
|
699
693
|
`stepsWithMentions=${mentionEntries.length} customerIdsFound=${mentionedL2Only.size} ` +
|
|
700
694
|
`linkedRequirements=${linkedFullCodes.size} mentionedButNotLinked=${sortedMissingSpecificMentionedNoFamily.length +
|
|
701
|
-
sortedMissingBaseWhenFamilyUncovered.length +
|
|
702
|
-
sortedMissingFamilyMembers.length} ` +
|
|
695
|
+
sortedMissingBaseWhenFamilyUncovered.length} ` +
|
|
703
696
|
`linkedButNotMentioned=${sortedExtraLinked.length} status=${validationStatus} ` +
|
|
704
697
|
`customerIdSample='${[...mentionedL2Only].slice(0, 5).join(', ')}'`);
|
|
705
698
|
rows.push({
|
|
@@ -2152,6 +2145,47 @@ class ResultDataProvider {
|
|
|
2152
2145
|
return `SR${match[1]}-${match[2]}`;
|
|
2153
2146
|
return `SR${match[1]}`;
|
|
2154
2147
|
}
|
|
2148
|
+
compareMewpRequirementCodes(a, b) {
|
|
2149
|
+
const normalizeComparableCode = (value) => {
|
|
2150
|
+
const normalizedCode = this.normalizeMewpRequirementCodeWithSuffix(value);
|
|
2151
|
+
const match = /^SR(\d+)(?:-(\d+))?$/i.exec(normalizedCode);
|
|
2152
|
+
if (!match) {
|
|
2153
|
+
return {
|
|
2154
|
+
base: Number.POSITIVE_INFINITY,
|
|
2155
|
+
hasSuffix: 1,
|
|
2156
|
+
suffix: Number.POSITIVE_INFINITY,
|
|
2157
|
+
raw: String(value || ''),
|
|
2158
|
+
};
|
|
2159
|
+
}
|
|
2160
|
+
return {
|
|
2161
|
+
base: Number(match[1]),
|
|
2162
|
+
hasSuffix: match[2] ? 1 : 0,
|
|
2163
|
+
suffix: match[2] ? Number(match[2]) : -1,
|
|
2164
|
+
raw: normalizedCode,
|
|
2165
|
+
};
|
|
2166
|
+
};
|
|
2167
|
+
const left = normalizeComparableCode(a);
|
|
2168
|
+
const right = normalizeComparableCode(b);
|
|
2169
|
+
if (left.base !== right.base)
|
|
2170
|
+
return left.base - right.base;
|
|
2171
|
+
if (left.hasSuffix !== right.hasSuffix)
|
|
2172
|
+
return left.hasSuffix - right.hasSuffix;
|
|
2173
|
+
if (left.suffix !== right.suffix)
|
|
2174
|
+
return left.suffix - right.suffix;
|
|
2175
|
+
return left.raw.localeCompare(right.raw);
|
|
2176
|
+
}
|
|
2177
|
+
formatStepScopedRequirementGroups(stepRef, requirementIds) {
|
|
2178
|
+
const groupedRequirementList = this.formatRequirementCodesGroupedByFamily(requirementIds);
|
|
2179
|
+
if (!groupedRequirementList)
|
|
2180
|
+
return `${stepRef}:`;
|
|
2181
|
+
const groupedLines = groupedRequirementList
|
|
2182
|
+
.split('\n')
|
|
2183
|
+
.map((line) => String(line || '').trim())
|
|
2184
|
+
.filter((line) => line.length > 0);
|
|
2185
|
+
if (groupedLines.length <= 1)
|
|
2186
|
+
return `${stepRef}: ${groupedLines[0] || ''}`.trim();
|
|
2187
|
+
return `${stepRef}:\n${groupedLines.map((line) => `- ${line}`).join('\n')}`.trim();
|
|
2188
|
+
}
|
|
2155
2189
|
formatRequirementCodesGroupedByFamily(codes) {
|
|
2156
2190
|
const byBaseKey = new Map();
|
|
2157
2191
|
for (const rawCode of codes || []) {
|
|
@@ -2166,12 +2200,16 @@ class ResultDataProvider {
|
|
|
2166
2200
|
if (byBaseKey.size === 0)
|
|
2167
2201
|
return '';
|
|
2168
2202
|
return [...byBaseKey.entries()]
|
|
2169
|
-
.sort((a, b) => a[0]
|
|
2203
|
+
.sort((a, b) => this.compareMewpRequirementCodes(a[0], b[0]))
|
|
2170
2204
|
.map(([baseKey, members]) => {
|
|
2171
|
-
const sortedMembers = [...members].sort((a, b) =>
|
|
2205
|
+
const sortedMembers = [...members].sort((a, b) => this.compareMewpRequirementCodes(a, b));
|
|
2172
2206
|
if (sortedMembers.length <= 1)
|
|
2173
2207
|
return sortedMembers[0];
|
|
2174
|
-
|
|
2208
|
+
const nonBaseMembers = sortedMembers.filter((member) => member !== baseKey);
|
|
2209
|
+
if (nonBaseMembers.length > 0) {
|
|
2210
|
+
return `${baseKey}: ${nonBaseMembers.join(', ')}`;
|
|
2211
|
+
}
|
|
2212
|
+
return baseKey;
|
|
2175
2213
|
})
|
|
2176
2214
|
.join('\n');
|
|
2177
2215
|
}
|
|
@@ -3164,71 +3202,6 @@ class ResultDataProvider {
|
|
|
3164
3202
|
async fetchResultDataBasedOnWi(projectName, runId, resultId) {
|
|
3165
3203
|
return this.fetchResultDataBasedOnWiBase(projectName, runId, resultId);
|
|
3166
3204
|
}
|
|
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
|
-
}
|
|
3232
3205
|
/**
|
|
3233
3206
|
* Converts a run status string into a human-readable format.
|
|
3234
3207
|
*
|
|
@@ -3532,10 +3505,6 @@ class ResultDataProvider {
|
|
|
3532
3505
|
}
|
|
3533
3506
|
resultData.iterationDetails.push(iteration);
|
|
3534
3507
|
}
|
|
3535
|
-
const originalActionResultsCount = Array.isArray(iteration === null || iteration === void 0 ? void 0 : iteration.actionResults)
|
|
3536
|
-
? iteration.actionResults.length
|
|
3537
|
-
: 0;
|
|
3538
|
-
resultData._debugOriginalActionResultsCount = originalActionResultsCount;
|
|
3539
3508
|
if (resultData.stepsResultXml && iteration) {
|
|
3540
3509
|
const actionResults = Array.isArray(iteration.actionResults) ? iteration.actionResults : [];
|
|
3541
3510
|
const actionResultsWithSharedModels = actionResults.filter((result) => result.sharedStepModel);
|
|
@@ -4077,13 +4046,13 @@ class ResultDataProvider {
|
|
|
4077
4046
|
*/
|
|
4078
4047
|
async fetchResultDataForTestReporter(projectName, testSuiteId, point, selectedFields, isQueryMode, includeAllHistory = false) {
|
|
4079
4048
|
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) => {
|
|
4080
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w
|
|
4049
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w;
|
|
4081
4050
|
const { lastRunId, lastResultId, configurationName, lastResultDetails } = point;
|
|
4082
4051
|
try {
|
|
4083
4052
|
const iteration = ((_a = resultData.iterationDetails) === null || _a === void 0 ? void 0 : _a.length) > 0
|
|
4084
4053
|
? resultData.iterationDetails[((_b = resultData.iterationDetails) === null || _b === void 0 ? void 0 : _b.length) - 1]
|
|
4085
4054
|
: undefined;
|
|
4086
|
-
const
|
|
4055
|
+
const testOutcome = this.getTestOutcome(resultData);
|
|
4087
4056
|
if (!(resultData === null || resultData === void 0 ? void 0 : resultData.testCase) || !(resultData === null || resultData === void 0 ? void 0 : resultData.testSuite)) {
|
|
4088
4057
|
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)}`);
|
|
4089
4058
|
}
|
|
@@ -4108,16 +4077,13 @@ class ResultDataProvider {
|
|
|
4108
4077
|
relatedCRs: resultData.relatedCRs || undefined,
|
|
4109
4078
|
lastRunResult: undefined,
|
|
4110
4079
|
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),
|
|
4114
4080
|
};
|
|
4115
4081
|
// Process all custom fields from resultData.filteredFields
|
|
4116
4082
|
if (resultData.filteredFields) {
|
|
4117
4083
|
const customFields = this.standardCustomField(resultData.filteredFields);
|
|
4118
4084
|
resultDataResponse.customFields = customFields;
|
|
4119
4085
|
}
|
|
4120
|
-
const filteredFields = (
|
|
4086
|
+
const filteredFields = (_l = selectedFields === null || selectedFields === void 0 ? void 0 : selectedFields.filter((field) => field.includes('@runResultField'))) === null || _l === void 0 ? void 0 : _l.map((field) => field.split('@')[0]);
|
|
4121
4087
|
if (filteredFields && filteredFields.length > 0) {
|
|
4122
4088
|
for (const field of filteredFields) {
|
|
4123
4089
|
switch (field) {
|
|
@@ -4127,13 +4093,13 @@ class ResultDataProvider {
|
|
|
4127
4093
|
case 'testCaseResult':
|
|
4128
4094
|
if (lastRunId === undefined || lastResultId === undefined) {
|
|
4129
4095
|
resultDataResponse.testCaseResult = {
|
|
4130
|
-
resultMessage: `${this.convertRunStatus(
|
|
4096
|
+
resultMessage: `${this.convertRunStatus(testOutcome)}`,
|
|
4131
4097
|
url: '',
|
|
4132
4098
|
};
|
|
4133
4099
|
}
|
|
4134
4100
|
else {
|
|
4135
4101
|
resultDataResponse.testCaseResult = {
|
|
4136
|
-
resultMessage: `${this.convertRunStatus(
|
|
4102
|
+
resultMessage: `${this.convertRunStatus(testOutcome)} in Run ${lastRunId}`,
|
|
4137
4103
|
url: `${this.orgUrl}${projectName}/_testManagement/runs?runId=${lastRunId}&_a=resultSummary&resultId=${lastResultId}`,
|
|
4138
4104
|
};
|
|
4139
4105
|
}
|
|
@@ -4145,16 +4111,16 @@ class ResultDataProvider {
|
|
|
4145
4111
|
resultDataResponse.failureType = resultData.failureType;
|
|
4146
4112
|
break;
|
|
4147
4113
|
case 'runBy':
|
|
4148
|
-
if (!((
|
|
4149
|
-
logger_1.default.debug(`[RunResult] Missing runBy for testCaseId=${String((
|
|
4114
|
+
if (!((_m = lastResultDetails === null || lastResultDetails === void 0 ? void 0 : lastResultDetails.runBy) === null || _m === void 0 ? void 0 : _m.displayName)) {
|
|
4115
|
+
logger_1.default.debug(`[RunResult] Missing runBy for testCaseId=${String((_q = (_p = (_o = resultData === null || resultData === void 0 ? void 0 : resultData.testCase) === null || _o === void 0 ? void 0 : _o.id) !== null && _p !== void 0 ? _p : point === null || point === void 0 ? void 0 : point.testCaseId) !== null && _q !== void 0 ? _q : 'unknown')} (lastRunId=${String(lastRunId !== null && lastRunId !== void 0 ? lastRunId : '')}, lastResultId=${String(lastResultId !== null && lastResultId !== void 0 ? lastResultId : '')}). lastResultDetails=${this.stringifyForDebug(lastResultDetails, 2000)}`);
|
|
4150
4116
|
}
|
|
4151
|
-
resultDataResponse.runBy = (
|
|
4117
|
+
resultDataResponse.runBy = (_s = (_r = lastResultDetails === null || lastResultDetails === void 0 ? void 0 : lastResultDetails.runBy) === null || _r === void 0 ? void 0 : _r.displayName) !== null && _s !== void 0 ? _s : '';
|
|
4152
4118
|
break;
|
|
4153
4119
|
case 'executionDate':
|
|
4154
4120
|
if (!(lastResultDetails === null || lastResultDetails === void 0 ? void 0 : lastResultDetails.dateCompleted)) {
|
|
4155
|
-
logger_1.default.debug(`[RunResult] Missing dateCompleted for testCaseId=${String((
|
|
4121
|
+
logger_1.default.debug(`[RunResult] Missing dateCompleted for testCaseId=${String((_v = (_u = (_t = resultData === null || resultData === void 0 ? void 0 : resultData.testCase) === null || _t === void 0 ? void 0 : _t.id) !== null && _u !== void 0 ? _u : point === null || point === void 0 ? void 0 : point.testCaseId) !== null && _v !== void 0 ? _v : 'unknown')} (lastRunId=${String(lastRunId !== null && lastRunId !== void 0 ? lastRunId : '')}, lastResultId=${String(lastResultId !== null && lastResultId !== void 0 ? lastResultId : '')}). lastResultDetails=${this.stringifyForDebug(lastResultDetails, 2000)}`);
|
|
4156
4122
|
}
|
|
4157
|
-
resultDataResponse.executionDate = (
|
|
4123
|
+
resultDataResponse.executionDate = (_w = lastResultDetails === null || lastResultDetails === void 0 ? void 0 : lastResultDetails.dateCompleted) !== null && _w !== void 0 ? _w : '';
|
|
4158
4124
|
break;
|
|
4159
4125
|
case 'configurationName':
|
|
4160
4126
|
resultDataResponse.configurationName = configurationName;
|