@elisra-devops/docgen-data-provider 1.95.0 → 1.97.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.
@@ -223,6 +223,11 @@ export default class ResultDataProvider {
223
223
  * Executes a work-item GET by URL and applies consistent warning/error handling.
224
224
  */
225
225
  private fetchWorkItemByUrl;
226
+ /**
227
+ * Returns true when the snapshot includes a non-empty test steps XML payload.
228
+ */
229
+ private hasStepsInWorkItemSnapshot;
230
+ private logRunlessSnapshotDecision;
226
231
  /**
227
232
  * Resolves runless test case data using ordered fallbacks:
228
233
  * 1) point-based `asOf` snapshot, 2) explicit revision, 3) suite payload snapshot, 4) latest WI.
@@ -2764,6 +2764,7 @@ class ResultDataProvider {
2764
2764
  const parsedAsOf = new Date(String(asOfTimestamp || '').trim());
2765
2765
  if (!Number.isFinite(id) || id <= 0 || Number.isNaN(parsedAsOf.getTime()))
2766
2766
  return null;
2767
+ logger_1.default.debug(`[RunlessResolver] Fetching work item ${id} by asOf (raw="${String(asOfTimestamp || '')}", normalized="${parsedAsOf.toISOString()}", expandAll=${String(expandAll)})`);
2767
2768
  const query = [`asOf=${encodeURIComponent(parsedAsOf.toISOString())}`];
2768
2769
  if (expandAll) {
2769
2770
  query.push(`$expand=all`);
@@ -2791,22 +2792,62 @@ class ResultDataProvider {
2791
2792
  return null;
2792
2793
  }
2793
2794
  }
2795
+ /**
2796
+ * Returns true when the snapshot includes a non-empty test steps XML payload.
2797
+ */
2798
+ hasStepsInWorkItemSnapshot(workItemData) {
2799
+ const stepsXml = this.extractStepsXmlFromFieldsMap((workItemData === null || workItemData === void 0 ? void 0 : workItemData.fields) || {});
2800
+ return String(stepsXml || '').trim() !== '';
2801
+ }
2802
+ logRunlessSnapshotDecision(testCaseId, source, snapshot) {
2803
+ var _a;
2804
+ if (!snapshot) {
2805
+ logger_1.default.debug(`[RunlessResolver] TC ${testCaseId}: source=${source}, snapshot=none`);
2806
+ return;
2807
+ }
2808
+ const stepsXml = this.extractStepsXmlFromFieldsMap((snapshot === null || snapshot === void 0 ? void 0 : snapshot.fields) || {});
2809
+ const stepsLength = String(stepsXml || '').trim().length;
2810
+ logger_1.default.debug(`[RunlessResolver] TC ${testCaseId}: source=${source}, rev=${String((_a = snapshot === null || snapshot === void 0 ? void 0 : snapshot.rev) !== null && _a !== void 0 ? _a : '')}, hasSteps=${String(stepsLength > 0)}, stepsLength=${String(stepsLength)}`);
2811
+ }
2794
2812
  /**
2795
2813
  * Resolves runless test case data using ordered fallbacks:
2796
2814
  * 1) point-based `asOf` snapshot, 2) explicit revision, 3) suite payload snapshot, 4) latest WI.
2797
2815
  */
2798
2816
  async resolveRunlessTestCaseData(projectName, testCaseId, suiteTestCaseRevision, pointAsOfTimestamp, fallbackSnapshot, expandAll) {
2817
+ let bestSnapshotWithoutSteps = null;
2799
2818
  if (pointAsOfTimestamp) {
2800
2819
  const asOfSnapshot = await this.fetchWorkItemByAsOf(projectName, testCaseId, pointAsOfTimestamp, expandAll);
2801
- if (asOfSnapshot)
2802
- return asOfSnapshot;
2820
+ this.logRunlessSnapshotDecision(testCaseId, 'asOf', asOfSnapshot);
2821
+ if (asOfSnapshot) {
2822
+ if (this.hasStepsInWorkItemSnapshot(asOfSnapshot))
2823
+ return asOfSnapshot;
2824
+ bestSnapshotWithoutSteps = asOfSnapshot;
2825
+ }
2826
+ }
2827
+ else {
2828
+ logger_1.default.debug(`[RunlessResolver] TC ${testCaseId}: asOf timestamp is empty, skipping asOf fetch`);
2803
2829
  }
2804
2830
  const revisionSnapshot = await this.fetchWorkItemByRevision(projectName, testCaseId, suiteTestCaseRevision, expandAll);
2805
- if (revisionSnapshot)
2806
- return revisionSnapshot;
2807
- if (fallbackSnapshot)
2808
- return fallbackSnapshot;
2809
- return this.fetchWorkItemLatest(projectName, testCaseId, expandAll);
2831
+ this.logRunlessSnapshotDecision(testCaseId, `revision:${String(suiteTestCaseRevision)}`, revisionSnapshot);
2832
+ if (revisionSnapshot) {
2833
+ if (this.hasStepsInWorkItemSnapshot(revisionSnapshot))
2834
+ return revisionSnapshot;
2835
+ bestSnapshotWithoutSteps = bestSnapshotWithoutSteps || revisionSnapshot;
2836
+ }
2837
+ this.logRunlessSnapshotDecision(testCaseId, 'suiteSnapshot', fallbackSnapshot);
2838
+ if (fallbackSnapshot) {
2839
+ if (this.hasStepsInWorkItemSnapshot(fallbackSnapshot))
2840
+ return fallbackSnapshot;
2841
+ bestSnapshotWithoutSteps = bestSnapshotWithoutSteps || fallbackSnapshot;
2842
+ }
2843
+ const latestSnapshot = await this.fetchWorkItemLatest(projectName, testCaseId, expandAll);
2844
+ this.logRunlessSnapshotDecision(testCaseId, 'latest', latestSnapshot);
2845
+ if (latestSnapshot) {
2846
+ if (this.hasStepsInWorkItemSnapshot(latestSnapshot))
2847
+ return latestSnapshot;
2848
+ bestSnapshotWithoutSteps = bestSnapshotWithoutSteps || latestSnapshot;
2849
+ }
2850
+ return bestSnapshotWithoutSteps;
2810
2851
  }
2811
2852
  /**
2812
2853
  * Fetches result data based on the Work Item Test Reporter.
@@ -2840,6 +2881,7 @@ class ResultDataProvider {
2840
2881
  const pointAsOfTimestamp = useRunlessAsOf
2841
2882
  ? String((point === null || point === void 0 ? void 0 : point.pointAsOfTimestamp) || '').trim()
2842
2883
  : '';
2884
+ logger_1.default.debug(`[RunlessResolver] Start TC ${String(testCaseId)}: useRunlessAsOf=${String(useRunlessAsOf)}, pointAsOfTimestamp="${pointAsOfTimestamp}", suiteRevision=${String(suiteTestCaseRevision)}, pointOutcome="${String((point === null || point === void 0 ? void 0 : point.outcome) || '')}"`);
2843
2885
  const fallbackSnapshot = this.buildWorkItemSnapshotFromSuiteTestCase(suiteTestCaseItem, testCaseId, String((point === null || point === void 0 ? void 0 : point.testCaseName) || ''));
2844
2886
  const testCaseData = await this.resolveRunlessTestCaseData(projectName, testCaseId, suiteTestCaseRevision, pointAsOfTimestamp, fallbackSnapshot, isTestReporter);
2845
2887
  if (!testCaseData) {
@@ -3587,14 +3629,26 @@ class ResultDataProvider {
3587
3629
  */
3588
3630
  createIterationsMap(iterations, isTestReporter, includeNotRunTestCases) {
3589
3631
  return iterations.reduce((map, iterationItem) => {
3590
- if ((isTestReporter && iterationItem.lastRunId && iterationItem.lastResultId) ||
3591
- iterationItem.iteration) {
3632
+ const hasRunIdentifiers = (iterationItem === null || iterationItem === void 0 ? void 0 : iterationItem.lastRunId) !== undefined &&
3633
+ (iterationItem === null || iterationItem === void 0 ? void 0 : iterationItem.lastRunId) !== null &&
3634
+ String(iterationItem === null || iterationItem === void 0 ? void 0 : iterationItem.lastRunId).trim() !== '' &&
3635
+ (iterationItem === null || iterationItem === void 0 ? void 0 : iterationItem.lastResultId) !== undefined &&
3636
+ (iterationItem === null || iterationItem === void 0 ? void 0 : iterationItem.lastResultId) !== null &&
3637
+ String(iterationItem === null || iterationItem === void 0 ? void 0 : iterationItem.lastResultId).trim() !== '';
3638
+ if (hasRunIdentifiers) {
3592
3639
  const key = `${iterationItem.lastRunId}-${iterationItem.lastResultId}-${iterationItem.testCaseId}`;
3593
3640
  map[key] = iterationItem;
3594
3641
  }
3595
3642
  else if (includeNotRunTestCases) {
3596
3643
  const key = `${iterationItem.testCaseId}`;
3597
3644
  map[key] = iterationItem;
3645
+ if (isTestReporter && (iterationItem === null || iterationItem === void 0 ? void 0 : iterationItem.iteration)) {
3646
+ logger_1.default.debug(`[RunlessResolver] createIterationsMap: mapped runless testCaseId=${String(iterationItem === null || iterationItem === void 0 ? void 0 : iterationItem.testCaseId)} to case-only key`);
3647
+ }
3648
+ }
3649
+ else if ((iterationItem === null || iterationItem === void 0 ? void 0 : iterationItem.iteration) && !isTestReporter) {
3650
+ const key = `${iterationItem.lastRunId}-${iterationItem.lastResultId}-${iterationItem.testCaseId}`;
3651
+ map[key] = iterationItem;
3598
3652
  }
3599
3653
  return map;
3600
3654
  }, {});