qagentic-reporter 0.1.32 → 0.1.34

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.
@@ -939,6 +939,7 @@ var QAgenticCypressReporter = class {
939
939
  end: /* @__PURE__ */ new Date(),
940
940
  duration: 0
941
941
  };
942
+ this.failedTestResults = [];
942
943
  this.projectName = process.env.QAGENTIC_PROJECT_NAME || config.projectId || "Cypress E2E Tests";
943
944
  this.environment = process.env.QAGENTIC_ENVIRONMENT || process.env.NODE_ENV || "e2e";
944
945
  const apiUrl = process.env.QAGENTIC_API_URL || "http://localhost:8080";
@@ -1006,10 +1007,13 @@ var QAgenticCypressReporter = class {
1006
1007
  const displayError = test.displayError;
1007
1008
  if (errorInfo) {
1008
1009
  testResult.errorMessage = errorInfo.message || "Test failed";
1009
- testResult.stackTrace = errorInfo.stack || errorInfo.toString();
1010
+ testResult.stackTrace = errorInfo.stack || errorInfo.codeFrame || errorInfo.toString() || displayError || "";
1010
1011
  testResult.errorType = errorInfo.name || "AssertionError";
1011
1012
  } else if (displayError) {
1012
1013
  testResult.errorMessage = displayError;
1014
+ if (displayError.includes("\n")) {
1015
+ testResult.stackTrace = displayError;
1016
+ }
1013
1017
  testResult.errorType = "AssertionError";
1014
1018
  } else {
1015
1019
  testResult.errorMessage = "Test assertion failed";
@@ -1020,13 +1024,51 @@ var QAgenticCypressReporter = class {
1020
1024
  type: testResult.errorType,
1021
1025
  hasStackTrace: !!testResult.stackTrace
1022
1026
  });
1023
- if (test.invocationDetails?.relativeFile) {
1024
- const testFileName = test.invocationDetails.relativeFile.replace(/\.ts$/, "");
1025
- const screenshotPath = path2__namespace.join(
1027
+ this.failedTestResults.push({
1028
+ testResult,
1029
+ test
1030
+ });
1031
+ }
1032
+ this.stats.tests++;
1033
+ if (test.state === "passed") this.stats.passes++;
1034
+ if (test.state === "failed") this.stats.failures++;
1035
+ if (test.state === "pending") this.stats.pending++;
1036
+ await this.reporter.reportTest(testResult);
1037
+ } catch (error) {
1038
+ console.warn("[QAagentic] Failed to report test:", error);
1039
+ }
1040
+ }
1041
+ async attachScreenshots() {
1042
+ console.log("[QAagentic] Attaching screenshots to failed tests");
1043
+ for (const { testResult, test } of this.failedTestResults) {
1044
+ if (test.invocationDetails?.relativeFile) {
1045
+ const testFileName = test.invocationDetails.relativeFile.replace(/\.ts$/, "");
1046
+ const testName = test.title[test.title.length - 1];
1047
+ const fullTestTitle = test.title.join(", ");
1048
+ const screenshotPaths = [
1049
+ // Mochawesome report assets location with full title
1050
+ path2__namespace.join(
1051
+ process.cwd(),
1052
+ "cypress/reports/assets",
1053
+ testFileName,
1054
+ `${fullTestTitle} -- ${testName} (failed).png`
1055
+ ),
1056
+ // Alternative: without full title path
1057
+ path2__namespace.join(
1058
+ process.cwd(),
1059
+ "cypress/reports/assets",
1060
+ testFileName,
1061
+ `${testName} (failed).png`
1062
+ ),
1063
+ // Legacy cypress/screenshots location
1064
+ path2__namespace.join(
1026
1065
  process.cwd(),
1027
1066
  "cypress/screenshots",
1028
- `${testFileName} -- ${test.title[test.title.length - 1]} (failed).png`
1029
- );
1067
+ `${testFileName} -- ${testName} (failed).png`
1068
+ )
1069
+ ];
1070
+ let screenshotFound = false;
1071
+ for (const screenshotPath of screenshotPaths) {
1030
1072
  console.log("[QAagentic] Looking for screenshot at:", screenshotPath);
1031
1073
  if (fs2__namespace.existsSync(screenshotPath)) {
1032
1074
  try {
@@ -1041,22 +1083,19 @@ var QAgenticCypressReporter = class {
1041
1083
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
1042
1084
  });
1043
1085
  console.log("[QAagentic] Added screenshot attachment:", screenshotPath);
1086
+ screenshotFound = true;
1087
+ break;
1044
1088
  } catch (err) {
1045
1089
  console.warn("[QAagentic] Failed to read screenshot:", err);
1046
1090
  }
1047
- } else {
1048
- console.log("[QAagentic] Screenshot not found at:", screenshotPath);
1049
1091
  }
1050
1092
  }
1093
+ if (!screenshotFound) {
1094
+ console.log("[QAagentic] No screenshots found for test:", testName);
1095
+ }
1051
1096
  }
1052
- this.stats.tests++;
1053
- if (test.state === "passed") this.stats.passes++;
1054
- if (test.state === "failed") this.stats.failures++;
1055
- if (test.state === "pending") this.stats.pending++;
1056
- await this.reporter.reportTest(testResult);
1057
- } catch (error) {
1058
- console.warn("[QAagentic] Failed to report test:", error);
1059
1097
  }
1098
+ this.failedTestResults = [];
1060
1099
  }
1061
1100
  async finalizeRun() {
1062
1101
  if (this.runFinalized || !this.currentRun) return;
@@ -1086,13 +1125,17 @@ var QAgenticCypressReporter = class {
1086
1125
  };
1087
1126
  function setupQAgentic(on, config) {
1088
1127
  const reporter = new QAgenticCypressReporter(config);
1128
+ on("test:after:run", (test, runnable) => {
1129
+ });
1089
1130
  on("after:spec", (_spec, results) => {
1090
1131
  return (async () => {
1091
1132
  if (!results?.tests) return;
1092
1133
  try {
1134
+ await new Promise((resolve) => setTimeout(resolve, 1e3));
1093
1135
  for (const test of results.tests) {
1094
1136
  await reporter.onTestEnd(test);
1095
1137
  }
1138
+ await reporter.attachScreenshots();
1096
1139
  await reporter.finalizeRun();
1097
1140
  await new Promise((resolve) => setTimeout(resolve, 2e3));
1098
1141
  } catch (error) {