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.
@@ -911,6 +911,7 @@ var QAgenticCypressReporter = class {
911
911
  end: /* @__PURE__ */ new Date(),
912
912
  duration: 0
913
913
  };
914
+ this.failedTestResults = [];
914
915
  this.projectName = process.env.QAGENTIC_PROJECT_NAME || config.projectId || "Cypress E2E Tests";
915
916
  this.environment = process.env.QAGENTIC_ENVIRONMENT || process.env.NODE_ENV || "e2e";
916
917
  const apiUrl = process.env.QAGENTIC_API_URL || "http://localhost:8080";
@@ -978,10 +979,13 @@ var QAgenticCypressReporter = class {
978
979
  const displayError = test.displayError;
979
980
  if (errorInfo) {
980
981
  testResult.errorMessage = errorInfo.message || "Test failed";
981
- testResult.stackTrace = errorInfo.stack || errorInfo.toString();
982
+ testResult.stackTrace = errorInfo.stack || errorInfo.codeFrame || errorInfo.toString() || displayError || "";
982
983
  testResult.errorType = errorInfo.name || "AssertionError";
983
984
  } else if (displayError) {
984
985
  testResult.errorMessage = displayError;
986
+ if (displayError.includes("\n")) {
987
+ testResult.stackTrace = displayError;
988
+ }
985
989
  testResult.errorType = "AssertionError";
986
990
  } else {
987
991
  testResult.errorMessage = "Test assertion failed";
@@ -992,58 +996,10 @@ var QAgenticCypressReporter = class {
992
996
  type: testResult.errorType,
993
997
  hasStackTrace: !!testResult.stackTrace
994
998
  });
995
- if (test.invocationDetails?.relativeFile) {
996
- const testFileName = test.invocationDetails.relativeFile.replace(/\.ts$/, "");
997
- const testName = test.title[test.title.length - 1];
998
- const screenshotPaths = [
999
- // Mochawesome report assets location
1000
- path2.join(
1001
- process.cwd(),
1002
- "cypress/reports/assets",
1003
- testFileName,
1004
- `${test.title.join(", ")} -- ${testName} (failed).png`
1005
- ),
1006
- // Alternative: without full title path
1007
- path2.join(
1008
- process.cwd(),
1009
- "cypress/reports/assets",
1010
- testFileName,
1011
- `${testName} (failed).png`
1012
- ),
1013
- // Legacy cypress/screenshots location
1014
- path2.join(
1015
- process.cwd(),
1016
- "cypress/screenshots",
1017
- `${testFileName} -- ${testName} (failed).png`
1018
- )
1019
- ];
1020
- let screenshotFound = false;
1021
- for (const screenshotPath of screenshotPaths) {
1022
- console.log("[QAagentic] Looking for screenshot at:", screenshotPath);
1023
- if (fs2.existsSync(screenshotPath)) {
1024
- try {
1025
- const screenshotContent = fs2.readFileSync(screenshotPath);
1026
- testResult.attachments.push({
1027
- id: v4(),
1028
- name: "screenshot",
1029
- type: "image/png",
1030
- extension: "png",
1031
- content: screenshotContent.toString("base64"),
1032
- size: screenshotContent.length,
1033
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
1034
- });
1035
- console.log("[QAagentic] Added screenshot attachment:", screenshotPath);
1036
- screenshotFound = true;
1037
- break;
1038
- } catch (err) {
1039
- console.warn("[QAagentic] Failed to read screenshot:", err);
1040
- }
1041
- }
1042
- }
1043
- if (!screenshotFound) {
1044
- console.log("[QAagentic] No screenshots found for test:", testName);
1045
- }
1046
- }
999
+ this.failedTestResults.push({
1000
+ testResult,
1001
+ test
1002
+ });
1047
1003
  }
1048
1004
  this.stats.tests++;
1049
1005
  if (test.state === "passed") this.stats.passes++;
@@ -1054,6 +1010,65 @@ var QAgenticCypressReporter = class {
1054
1010
  console.warn("[QAagentic] Failed to report test:", error);
1055
1011
  }
1056
1012
  }
1013
+ async attachScreenshots() {
1014
+ console.log("[QAagentic] Attaching screenshots to failed tests");
1015
+ for (const { testResult, test } of this.failedTestResults) {
1016
+ if (test.invocationDetails?.relativeFile) {
1017
+ const testFileName = test.invocationDetails.relativeFile.replace(/\.ts$/, "");
1018
+ const testName = test.title[test.title.length - 1];
1019
+ const fullTestTitle = test.title.join(", ");
1020
+ const screenshotPaths = [
1021
+ // Mochawesome report assets location with full title
1022
+ path2.join(
1023
+ process.cwd(),
1024
+ "cypress/reports/assets",
1025
+ testFileName,
1026
+ `${fullTestTitle} -- ${testName} (failed).png`
1027
+ ),
1028
+ // Alternative: without full title path
1029
+ path2.join(
1030
+ process.cwd(),
1031
+ "cypress/reports/assets",
1032
+ testFileName,
1033
+ `${testName} (failed).png`
1034
+ ),
1035
+ // Legacy cypress/screenshots location
1036
+ path2.join(
1037
+ process.cwd(),
1038
+ "cypress/screenshots",
1039
+ `${testFileName} -- ${testName} (failed).png`
1040
+ )
1041
+ ];
1042
+ let screenshotFound = false;
1043
+ for (const screenshotPath of screenshotPaths) {
1044
+ console.log("[QAagentic] Looking for screenshot at:", screenshotPath);
1045
+ if (fs2.existsSync(screenshotPath)) {
1046
+ try {
1047
+ const screenshotContent = fs2.readFileSync(screenshotPath);
1048
+ testResult.attachments.push({
1049
+ id: v4(),
1050
+ name: "screenshot",
1051
+ type: "image/png",
1052
+ extension: "png",
1053
+ content: screenshotContent.toString("base64"),
1054
+ size: screenshotContent.length,
1055
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
1056
+ });
1057
+ console.log("[QAagentic] Added screenshot attachment:", screenshotPath);
1058
+ screenshotFound = true;
1059
+ break;
1060
+ } catch (err) {
1061
+ console.warn("[QAagentic] Failed to read screenshot:", err);
1062
+ }
1063
+ }
1064
+ }
1065
+ if (!screenshotFound) {
1066
+ console.log("[QAagentic] No screenshots found for test:", testName);
1067
+ }
1068
+ }
1069
+ }
1070
+ this.failedTestResults = [];
1071
+ }
1057
1072
  async finalizeRun() {
1058
1073
  if (this.runFinalized || !this.currentRun) return;
1059
1074
  this.runFinalized = true;
@@ -1086,9 +1101,11 @@ function setupQAgentic(on, config) {
1086
1101
  return (async () => {
1087
1102
  if (!results?.tests) return;
1088
1103
  try {
1104
+ await new Promise((resolve) => setTimeout(resolve, 1e3));
1089
1105
  for (const test of results.tests) {
1090
1106
  await reporter.onTestEnd(test);
1091
1107
  }
1108
+ await reporter.attachScreenshots();
1092
1109
  await reporter.finalizeRun();
1093
1110
  await new Promise((resolve) => setTimeout(resolve, 2e3));
1094
1111
  } catch (error) {