qagentic-reporter 0.1.33 → 0.1.35

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,58 +1024,10 @@ 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 testName = test.title[test.title.length - 1];
1026
- const screenshotPaths = [
1027
- // Mochawesome report assets location
1028
- path2__namespace.join(
1029
- process.cwd(),
1030
- "cypress/reports/assets",
1031
- testFileName,
1032
- `${test.title.join(", ")} -- ${testName} (failed).png`
1033
- ),
1034
- // Alternative: without full title path
1035
- path2__namespace.join(
1036
- process.cwd(),
1037
- "cypress/reports/assets",
1038
- testFileName,
1039
- `${testName} (failed).png`
1040
- ),
1041
- // Legacy cypress/screenshots location
1042
- path2__namespace.join(
1043
- process.cwd(),
1044
- "cypress/screenshots",
1045
- `${testFileName} -- ${testName} (failed).png`
1046
- )
1047
- ];
1048
- let screenshotFound = false;
1049
- for (const screenshotPath of screenshotPaths) {
1050
- console.log("[QAagentic] Looking for screenshot at:", screenshotPath);
1051
- if (fs2__namespace.existsSync(screenshotPath)) {
1052
- try {
1053
- const screenshotContent = fs2__namespace.readFileSync(screenshotPath);
1054
- testResult.attachments.push({
1055
- id: uuid.v4(),
1056
- name: "screenshot",
1057
- type: "image/png",
1058
- extension: "png",
1059
- content: screenshotContent.toString("base64"),
1060
- size: screenshotContent.length,
1061
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
1062
- });
1063
- console.log("[QAagentic] Added screenshot attachment:", screenshotPath);
1064
- screenshotFound = true;
1065
- break;
1066
- } catch (err) {
1067
- console.warn("[QAagentic] Failed to read screenshot:", err);
1068
- }
1069
- }
1070
- }
1071
- if (!screenshotFound) {
1072
- console.log("[QAagentic] No screenshots found for test:", testName);
1073
- }
1074
- }
1027
+ this.failedTestResults.push({
1028
+ testResult,
1029
+ test
1030
+ });
1075
1031
  }
1076
1032
  this.stats.tests++;
1077
1033
  if (test.state === "passed") this.stats.passes++;
@@ -1082,6 +1038,65 @@ var QAgenticCypressReporter = class {
1082
1038
  console.warn("[QAagentic] Failed to report test:", error);
1083
1039
  }
1084
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(
1065
+ process.cwd(),
1066
+ "cypress/screenshots",
1067
+ `${testFileName} -- ${testName} (failed).png`
1068
+ )
1069
+ ];
1070
+ let screenshotFound = false;
1071
+ for (const screenshotPath of screenshotPaths) {
1072
+ console.log("[QAagentic] Looking for screenshot at:", screenshotPath);
1073
+ if (fs2__namespace.existsSync(screenshotPath)) {
1074
+ try {
1075
+ const screenshotContent = fs2__namespace.readFileSync(screenshotPath);
1076
+ testResult.attachments.push({
1077
+ id: uuid.v4(),
1078
+ name: "screenshot",
1079
+ type: "image/png",
1080
+ extension: "png",
1081
+ content: screenshotContent.toString("base64"),
1082
+ size: screenshotContent.length,
1083
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
1084
+ });
1085
+ console.log("[QAagentic] Added screenshot attachment:", screenshotPath);
1086
+ screenshotFound = true;
1087
+ break;
1088
+ } catch (err) {
1089
+ console.warn("[QAagentic] Failed to read screenshot:", err);
1090
+ }
1091
+ }
1092
+ }
1093
+ if (!screenshotFound) {
1094
+ console.log("[QAagentic] No screenshots found for test:", testName);
1095
+ }
1096
+ }
1097
+ }
1098
+ this.failedTestResults = [];
1099
+ }
1085
1100
  async finalizeRun() {
1086
1101
  if (this.runFinalized || !this.currentRun) return;
1087
1102
  this.runFinalized = true;
@@ -1114,9 +1129,11 @@ function setupQAgentic(on, config) {
1114
1129
  return (async () => {
1115
1130
  if (!results?.tests) return;
1116
1131
  try {
1132
+ await new Promise((resolve) => setTimeout(resolve, 1e3));
1117
1133
  for (const test of results.tests) {
1118
1134
  await reporter.onTestEnd(test);
1119
1135
  }
1136
+ await reporter.attachScreenshots();
1120
1137
  await reporter.finalizeRun();
1121
1138
  await new Promise((resolve) => setTimeout(resolve, 2e3));
1122
1139
  } catch (error) {