@elisra-devops/docgen-data-provider 1.73.0 → 1.75.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 +4 -0
- package/bin/modules/ResultDataProvider.js +146 -37
- package/bin/modules/ResultDataProvider.js.map +1 -1
- package/bin/tests/modules/ResultDataProvider.test.js +42 -10
- package/bin/tests/modules/ResultDataProvider.test.js.map +1 -1
- package/package.json +1 -1
- package/src/modules/ResultDataProvider.ts +186 -38
- package/src/tests/modules/ResultDataProvider.test.ts +55 -10
|
@@ -77,6 +77,10 @@ export default class ResultDataProvider {
|
|
|
77
77
|
mapAttachmentsUrl(runResults: any[], project: string): any[];
|
|
78
78
|
private buildMewpCoverageSheetName;
|
|
79
79
|
private createMewpCoverageRow;
|
|
80
|
+
private formatMewpCustomerId;
|
|
81
|
+
private buildMewpCoverageRows;
|
|
82
|
+
private buildMewpTestCaseTitleMap;
|
|
83
|
+
private extractMewpTestCaseId;
|
|
80
84
|
private buildTestCaseStepsXmlMap;
|
|
81
85
|
private extractStepsXmlFromWorkItemFields;
|
|
82
86
|
private classifyRequirementStepOutcome;
|
|
@@ -284,7 +284,7 @@ class ResultDataProvider {
|
|
|
284
284
|
* Rows are one Requirement-TestCase pair; uncovered requirements are emitted with empty test-case columns.
|
|
285
285
|
*/
|
|
286
286
|
async getMewpL2CoverageFlatResults(testPlanId, projectName, selectedSuiteIds) {
|
|
287
|
-
var _a;
|
|
287
|
+
var _a, _b;
|
|
288
288
|
const defaultPayload = {
|
|
289
289
|
sheetName: `MEWP L2 Coverage - Plan ${testPlanId}`,
|
|
290
290
|
columnOrder: [...ResultDataProvider.MEWP_L2_COVERAGE_COLUMNS],
|
|
@@ -299,22 +299,25 @@ class ResultDataProvider {
|
|
|
299
299
|
return Object.assign(Object.assign({}, defaultPayload), { sheetName: this.buildMewpCoverageSheetName(planName, testPlanId) });
|
|
300
300
|
}
|
|
301
301
|
const requirementIndex = new Map();
|
|
302
|
+
const observedTestCaseIdsByRequirement = new Map();
|
|
302
303
|
const requirementKeys = new Set();
|
|
303
304
|
requirements.forEach((requirement) => {
|
|
304
305
|
const key = this.toRequirementKey(requirement.requirementId);
|
|
305
306
|
if (!key)
|
|
306
307
|
return;
|
|
307
308
|
requirementKeys.add(key);
|
|
308
|
-
if (!requirementIndex.has(key)) {
|
|
309
|
-
requirementIndex.set(key, { passed: 0, failed: 0, notRun: 0 });
|
|
310
|
-
}
|
|
311
309
|
});
|
|
312
310
|
const parsedDefinitionStepsByTestCase = new Map();
|
|
313
311
|
const testCaseStepsXmlMap = this.buildTestCaseStepsXmlMap(testData);
|
|
312
|
+
const testCaseTitleMap = this.buildMewpTestCaseTitleMap(testData);
|
|
314
313
|
const runResults = await this.fetchAllResultDataTestReporter(testData, projectName, [], false, false);
|
|
315
314
|
for (const runResult of runResults) {
|
|
316
|
-
const testCaseId =
|
|
317
|
-
const
|
|
315
|
+
const testCaseId = this.extractMewpTestCaseId(runResult);
|
|
316
|
+
const runTestCaseTitle = this.toMewpComparableText(((_a = runResult === null || runResult === void 0 ? void 0 : runResult.testCase) === null || _a === void 0 ? void 0 : _a.name) || (runResult === null || runResult === void 0 ? void 0 : runResult.testCaseName) || (runResult === null || runResult === void 0 ? void 0 : runResult.testCaseTitle));
|
|
317
|
+
if (Number.isFinite(testCaseId) && testCaseId > 0 && runTestCaseTitle && !testCaseTitleMap.has(testCaseId)) {
|
|
318
|
+
testCaseTitleMap.set(testCaseId, runTestCaseTitle);
|
|
319
|
+
}
|
|
320
|
+
const actionResults = Array.isArray((_b = runResult === null || runResult === void 0 ? void 0 : runResult.iteration) === null || _b === void 0 ? void 0 : _b.actionResults)
|
|
318
321
|
? runResult.iteration.actionResults
|
|
319
322
|
: [];
|
|
320
323
|
const hasExecutedRun = Number((runResult === null || runResult === void 0 ? void 0 : runResult.lastRunId) || 0) > 0 && Number((runResult === null || runResult === void 0 ? void 0 : runResult.lastResultId) || 0) > 0;
|
|
@@ -323,7 +326,7 @@ class ResultDataProvider {
|
|
|
323
326
|
if (actionResult === null || actionResult === void 0 ? void 0 : actionResult.isSharedStepTitle)
|
|
324
327
|
continue;
|
|
325
328
|
const stepStatus = this.classifyRequirementStepOutcome(actionResult === null || actionResult === void 0 ? void 0 : actionResult.outcome);
|
|
326
|
-
this.accumulateRequirementCountsFromStepText(`${String((actionResult === null || actionResult === void 0 ? void 0 : actionResult.action) || '')} ${String((actionResult === null || actionResult === void 0 ? void 0 : actionResult.expected) || '')}`, stepStatus, requirementKeys, requirementIndex);
|
|
329
|
+
this.accumulateRequirementCountsFromStepText(`${String((actionResult === null || actionResult === void 0 ? void 0 : actionResult.action) || '')} ${String((actionResult === null || actionResult === void 0 ? void 0 : actionResult.expected) || '')}`, stepStatus, testCaseId, requirementKeys, requirementIndex, observedTestCaseIdsByRequirement);
|
|
327
330
|
}
|
|
328
331
|
continue;
|
|
329
332
|
}
|
|
@@ -345,16 +348,10 @@ class ResultDataProvider {
|
|
|
345
348
|
for (const step of definitionSteps) {
|
|
346
349
|
if (step === null || step === void 0 ? void 0 : step.isSharedStepTitle)
|
|
347
350
|
continue;
|
|
348
|
-
this.accumulateRequirementCountsFromStepText(`${String((step === null || step === void 0 ? void 0 : step.action) || '')} ${String((step === null || step === void 0 ? void 0 : step.expected) || '')}`, 'notRun', requirementKeys, requirementIndex);
|
|
351
|
+
this.accumulateRequirementCountsFromStepText(`${String((step === null || step === void 0 ? void 0 : step.action) || '')} ${String((step === null || step === void 0 ? void 0 : step.expected) || '')}`, 'notRun', testCaseId, requirementKeys, requirementIndex, observedTestCaseIdsByRequirement);
|
|
349
352
|
}
|
|
350
353
|
}
|
|
351
|
-
const rows =
|
|
352
|
-
const key = this.toRequirementKey(requirement.requirementId);
|
|
353
|
-
const summary = key && requirementIndex.has(key)
|
|
354
|
-
? requirementIndex.get(key)
|
|
355
|
-
: { passed: 0, failed: 0, notRun: 0 };
|
|
356
|
-
return this.createMewpCoverageRow(requirement, summary);
|
|
357
|
-
});
|
|
354
|
+
const rows = this.buildMewpCoverageRows(requirements, requirementIndex, observedTestCaseIdsByRequirement, testCaseTitleMap);
|
|
358
355
|
return {
|
|
359
356
|
sheetName: this.buildMewpCoverageSheetName(planName, testPlanId),
|
|
360
357
|
columnOrder: [...ResultDataProvider.MEWP_L2_COVERAGE_COLUMNS],
|
|
@@ -397,21 +394,108 @@ class ResultDataProvider {
|
|
|
397
394
|
const suffix = String(planName || '').trim() || `Plan ${testPlanId}`;
|
|
398
395
|
return `MEWP L2 Coverage - ${suffix}`;
|
|
399
396
|
}
|
|
400
|
-
createMewpCoverageRow(requirement, stepSummary) {
|
|
401
|
-
const
|
|
402
|
-
const
|
|
403
|
-
const
|
|
404
|
-
const
|
|
397
|
+
createMewpCoverageRow(requirement, testCaseId, testCaseTitle, stepSummary) {
|
|
398
|
+
const customerId = this.formatMewpCustomerId(requirement.requirementId);
|
|
399
|
+
const customerTitle = this.toMewpComparableText(requirement.title);
|
|
400
|
+
const responsibility = this.toMewpComparableText(requirement.responsibility);
|
|
401
|
+
const safeTestCaseId = Number.isFinite(testCaseId) && Number(testCaseId) > 0 ? Number(testCaseId) : '';
|
|
405
402
|
return {
|
|
406
|
-
'Customer
|
|
407
|
-
'
|
|
408
|
-
'
|
|
409
|
-
|
|
410
|
-
'
|
|
403
|
+
'Customer ID': customerId,
|
|
404
|
+
'Title (Customer name)': customerTitle,
|
|
405
|
+
'Responsibility - SAPWBS (ESUK/IL)': responsibility,
|
|
406
|
+
'Test case id': safeTestCaseId,
|
|
407
|
+
'Test case title': String(testCaseTitle || '').trim(),
|
|
411
408
|
'Number of passed steps': Number.isFinite(stepSummary === null || stepSummary === void 0 ? void 0 : stepSummary.passed) ? stepSummary.passed : 0,
|
|
412
409
|
'Number of failed steps': Number.isFinite(stepSummary === null || stepSummary === void 0 ? void 0 : stepSummary.failed) ? stepSummary.failed : 0,
|
|
413
|
-
'Number of
|
|
410
|
+
'Number of not run tests': Number.isFinite(stepSummary === null || stepSummary === void 0 ? void 0 : stepSummary.notRun) ? stepSummary.notRun : 0,
|
|
411
|
+
};
|
|
412
|
+
}
|
|
413
|
+
formatMewpCustomerId(rawValue) {
|
|
414
|
+
const normalized = this.normalizeMewpRequirementCode(this.toMewpComparableText(rawValue));
|
|
415
|
+
if (normalized)
|
|
416
|
+
return normalized;
|
|
417
|
+
const onlyDigits = String(rawValue || '').replace(/\D/g, '');
|
|
418
|
+
if (onlyDigits)
|
|
419
|
+
return `SR${onlyDigits}`;
|
|
420
|
+
return '';
|
|
421
|
+
}
|
|
422
|
+
buildMewpCoverageRows(requirements, requirementIndex, observedTestCaseIdsByRequirement, testCaseTitleMap) {
|
|
423
|
+
var _a;
|
|
424
|
+
const rows = [];
|
|
425
|
+
for (const requirement of requirements) {
|
|
426
|
+
const key = this.toRequirementKey(requirement.requirementId);
|
|
427
|
+
const linkedTestCaseIds = ((requirement === null || requirement === void 0 ? void 0 : requirement.linkedTestCaseIds) || []).filter((id) => Number.isFinite(id) && Number(id) > 0);
|
|
428
|
+
const observedTestCaseIds = key
|
|
429
|
+
? Array.from(observedTestCaseIdsByRequirement.get(key) || [])
|
|
430
|
+
: [];
|
|
431
|
+
const testCaseIds = Array.from(new Set([...linkedTestCaseIds, ...observedTestCaseIds])).sort((a, b) => a - b);
|
|
432
|
+
if (testCaseIds.length === 0) {
|
|
433
|
+
rows.push(this.createMewpCoverageRow(requirement, undefined, '', {
|
|
434
|
+
passed: 0,
|
|
435
|
+
failed: 0,
|
|
436
|
+
notRun: 0,
|
|
437
|
+
}));
|
|
438
|
+
continue;
|
|
439
|
+
}
|
|
440
|
+
for (const testCaseId of testCaseIds) {
|
|
441
|
+
const summary = key
|
|
442
|
+
? ((_a = requirementIndex.get(key)) === null || _a === void 0 ? void 0 : _a.get(testCaseId)) || { passed: 0, failed: 0, notRun: 0 }
|
|
443
|
+
: { passed: 0, failed: 0, notRun: 0 };
|
|
444
|
+
rows.push(this.createMewpCoverageRow(requirement, testCaseId, String(testCaseTitleMap.get(testCaseId) || ''), summary));
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
return rows;
|
|
448
|
+
}
|
|
449
|
+
buildMewpTestCaseTitleMap(testData) {
|
|
450
|
+
var _a, _b, _c, _d, _e;
|
|
451
|
+
const map = new Map();
|
|
452
|
+
const readTitleFromWorkItemFields = (workItemFields) => {
|
|
453
|
+
if (!Array.isArray(workItemFields))
|
|
454
|
+
return '';
|
|
455
|
+
for (const field of workItemFields) {
|
|
456
|
+
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, field === null || field === void 0 ? void 0 : field.id]
|
|
457
|
+
.map((item) => String(item || '').toLowerCase().trim());
|
|
458
|
+
const isTitleField = keyCandidates.includes('system.title') || keyCandidates.includes('title');
|
|
459
|
+
if (!isTitleField)
|
|
460
|
+
continue;
|
|
461
|
+
const value = this.toMewpComparableText(field === null || field === void 0 ? void 0 : field.value);
|
|
462
|
+
if (value)
|
|
463
|
+
return value;
|
|
464
|
+
}
|
|
465
|
+
return '';
|
|
414
466
|
};
|
|
467
|
+
for (const suite of testData || []) {
|
|
468
|
+
const testPointsItems = Array.isArray(suite === null || suite === void 0 ? void 0 : suite.testPointsItems) ? suite.testPointsItems : [];
|
|
469
|
+
for (const point of testPointsItems) {
|
|
470
|
+
const pointTestCaseId = 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));
|
|
471
|
+
if (!Number.isFinite(pointTestCaseId) || pointTestCaseId <= 0 || map.has(pointTestCaseId))
|
|
472
|
+
continue;
|
|
473
|
+
const pointTitle = this.toMewpComparableText((point === null || point === void 0 ? void 0 : point.testCaseName) || ((_b = point === null || point === void 0 ? void 0 : point.testCase) === null || _b === void 0 ? void 0 : _b.name));
|
|
474
|
+
if (pointTitle)
|
|
475
|
+
map.set(pointTestCaseId, pointTitle);
|
|
476
|
+
}
|
|
477
|
+
const testCasesItems = Array.isArray(suite === null || suite === void 0 ? void 0 : suite.testCasesItems) ? suite.testCasesItems : [];
|
|
478
|
+
for (const testCase of testCasesItems) {
|
|
479
|
+
const id = Number(((_c = testCase === null || testCase === void 0 ? void 0 : testCase.workItem) === null || _c === void 0 ? void 0 : _c.id) || (testCase === null || testCase === void 0 ? void 0 : testCase.testCaseId) || (testCase === null || testCase === void 0 ? void 0 : testCase.id));
|
|
480
|
+
if (!Number.isFinite(id) || id <= 0 || map.has(id))
|
|
481
|
+
continue;
|
|
482
|
+
const fromDirectFields = this.toMewpComparableText((testCase === null || testCase === void 0 ? void 0 : testCase.testCaseName) || (testCase === null || testCase === void 0 ? void 0 : testCase.name) || ((_d = testCase === null || testCase === void 0 ? void 0 : testCase.workItem) === null || _d === void 0 ? void 0 : _d.name));
|
|
483
|
+
if (fromDirectFields) {
|
|
484
|
+
map.set(id, fromDirectFields);
|
|
485
|
+
continue;
|
|
486
|
+
}
|
|
487
|
+
const fromWorkItemField = readTitleFromWorkItemFields((_e = testCase === null || testCase === void 0 ? void 0 : testCase.workItem) === null || _e === void 0 ? void 0 : _e.workItemFields);
|
|
488
|
+
if (fromWorkItemField) {
|
|
489
|
+
map.set(id, fromWorkItemField);
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
return map;
|
|
494
|
+
}
|
|
495
|
+
extractMewpTestCaseId(runResult) {
|
|
496
|
+
var _a;
|
|
497
|
+
const testCaseId = Number((runResult === null || runResult === void 0 ? void 0 : runResult.testCaseId) || ((_a = runResult === null || runResult === void 0 ? void 0 : runResult.testCase) === null || _a === void 0 ? void 0 : _a.id) || 0);
|
|
498
|
+
return Number.isFinite(testCaseId) ? testCaseId : 0;
|
|
415
499
|
}
|
|
416
500
|
buildTestCaseStepsXmlMap(testData) {
|
|
417
501
|
var _a, _b;
|
|
@@ -461,15 +545,25 @@ class ResultDataProvider {
|
|
|
461
545
|
return 'failed';
|
|
462
546
|
return 'notRun';
|
|
463
547
|
}
|
|
464
|
-
accumulateRequirementCountsFromStepText(stepText, status, requirementKeys, counters) {
|
|
548
|
+
accumulateRequirementCountsFromStepText(stepText, status, testCaseId, requirementKeys, counters, observedTestCaseIdsByRequirement) {
|
|
549
|
+
if (!Number.isFinite(testCaseId) || testCaseId <= 0)
|
|
550
|
+
return;
|
|
465
551
|
const codes = this.extractRequirementCodesFromText(stepText);
|
|
466
552
|
for (const code of codes) {
|
|
467
553
|
if (requirementKeys.size > 0 && !requirementKeys.has(code))
|
|
468
554
|
continue;
|
|
469
555
|
if (!counters.has(code)) {
|
|
470
|
-
counters.set(code,
|
|
556
|
+
counters.set(code, new Map());
|
|
557
|
+
}
|
|
558
|
+
const perTestCaseCounters = counters.get(code);
|
|
559
|
+
if (!perTestCaseCounters.has(testCaseId)) {
|
|
560
|
+
perTestCaseCounters.set(testCaseId, { passed: 0, failed: 0, notRun: 0 });
|
|
561
|
+
}
|
|
562
|
+
if (!observedTestCaseIdsByRequirement.has(code)) {
|
|
563
|
+
observedTestCaseIdsByRequirement.set(code, new Set());
|
|
471
564
|
}
|
|
472
|
-
|
|
565
|
+
observedTestCaseIdsByRequirement.get(code).add(testCaseId);
|
|
566
|
+
const counter = perTestCaseCounters.get(testCaseId);
|
|
473
567
|
if (status === 'passed')
|
|
474
568
|
counter.passed += 1;
|
|
475
569
|
else if (status === 'failed')
|
|
@@ -547,7 +641,7 @@ ORDER BY [System.Id]`;
|
|
|
547
641
|
return {
|
|
548
642
|
workItemId: Number((wi === null || wi === void 0 ? void 0 : wi.id) || 0),
|
|
549
643
|
requirementId: this.extractMewpRequirementIdentifier(fields, Number((wi === null || wi === void 0 ? void 0 : wi.id) || 0)),
|
|
550
|
-
title:
|
|
644
|
+
title: this.toMewpComparableText((fields === null || fields === void 0 ? void 0 : fields['System.Title']) || (wi === null || wi === void 0 ? void 0 : wi.title)),
|
|
551
645
|
responsibility: this.deriveMewpResponsibility(fields),
|
|
552
646
|
linkedTestCaseIds: this.extractLinkedTestCaseIdsFromRequirement((wi === null || wi === void 0 ? void 0 : wi.relations) || []),
|
|
553
647
|
};
|
|
@@ -649,9 +743,21 @@ ORDER BY [System.Id]`;
|
|
|
649
743
|
const titleCode = this.normalizeMewpRequirementCode(title);
|
|
650
744
|
if (titleCode)
|
|
651
745
|
return titleCode;
|
|
652
|
-
return
|
|
746
|
+
return fallbackWorkItemId ? `SR${fallbackWorkItemId}` : '';
|
|
653
747
|
}
|
|
654
748
|
deriveMewpResponsibility(fields) {
|
|
749
|
+
const explicitSapWbs = this.toMewpComparableText(fields === null || fields === void 0 ? void 0 : fields['Custom.SAPWBS']);
|
|
750
|
+
const fromExplicitSapWbs = this.resolveMewpResponsibility(explicitSapWbs);
|
|
751
|
+
if (fromExplicitSapWbs)
|
|
752
|
+
return fromExplicitSapWbs;
|
|
753
|
+
if (explicitSapWbs)
|
|
754
|
+
return explicitSapWbs;
|
|
755
|
+
const explicitSapWbsByLabel = this.toMewpComparableText(fields === null || fields === void 0 ? void 0 : fields['SAPWBS']);
|
|
756
|
+
const fromExplicitLabel = this.resolveMewpResponsibility(explicitSapWbsByLabel);
|
|
757
|
+
if (fromExplicitLabel)
|
|
758
|
+
return fromExplicitLabel;
|
|
759
|
+
if (explicitSapWbsByLabel)
|
|
760
|
+
return explicitSapWbsByLabel;
|
|
655
761
|
const areaPath = this.toMewpComparableText(fields === null || fields === void 0 ? void 0 : fields['System.AreaPath']);
|
|
656
762
|
const fromAreaPath = this.resolveMewpResponsibility(areaPath);
|
|
657
763
|
if (fromAreaPath)
|
|
@@ -704,6 +810,9 @@ ORDER BY [System.Id]`;
|
|
|
704
810
|
const uniqueName = value.uniqueName;
|
|
705
811
|
if (uniqueName)
|
|
706
812
|
return String(uniqueName).trim();
|
|
813
|
+
const objectValue = value.value;
|
|
814
|
+
if (objectValue !== undefined && objectValue !== null)
|
|
815
|
+
return String(objectValue).trim();
|
|
707
816
|
}
|
|
708
817
|
return String(value).trim();
|
|
709
818
|
}
|
|
@@ -2541,14 +2650,14 @@ ORDER BY [System.Id]`;
|
|
|
2541
2650
|
}
|
|
2542
2651
|
}
|
|
2543
2652
|
ResultDataProvider.MEWP_L2_COVERAGE_COLUMNS = [
|
|
2544
|
-
'Customer
|
|
2545
|
-
'
|
|
2546
|
-
'
|
|
2547
|
-
'
|
|
2548
|
-
'
|
|
2653
|
+
'Customer ID',
|
|
2654
|
+
'Title (Customer name)',
|
|
2655
|
+
'Responsibility - SAPWBS (ESUK/IL)',
|
|
2656
|
+
'Test case id',
|
|
2657
|
+
'Test case title',
|
|
2549
2658
|
'Number of passed steps',
|
|
2550
2659
|
'Number of failed steps',
|
|
2551
|
-
'Number of
|
|
2660
|
+
'Number of not run tests',
|
|
2552
2661
|
];
|
|
2553
2662
|
exports.default = ResultDataProvider;
|
|
2554
2663
|
//# sourceMappingURL=ResultDataProvider.js.map
|