Skip to content

feat/CUS-11074-Added send test plan results to email latest#352

Merged
akhil-testsigma merged 1 commit into
devfrom
feat/CUS-11074-Added-send-test-plan-results-to-email-latest-
Mar 5, 2026
Merged

feat/CUS-11074-Added send test plan results to email latest#352
akhil-testsigma merged 1 commit into
devfrom
feat/CUS-11074-Added-send-test-plan-results-to-email-latest-

Conversation

@akhil-testsigma
Copy link
Copy Markdown
Contributor

@akhil-testsigma akhil-testsigma commented Mar 4, 2026

Publish this addon as public (IN Region)

Addon Name: Send TestPlan Results To Email Latest
Jarvis Link: https://jarvis-in.testsigma.com/ui/tenants/3/addons
Jira : https://testsigma.atlassian.net/browse/CUS-11074
Added send test plan results to email latest

Summary by CodeRabbit

  • New Features
    • Email notifications for test plan results with detailed execution summary, including passed/failed/queued counts and timestamps
    • Failed test cases grouped by suite with environment and error details
    • HTML-formatted emails with direct links to execution reports and run results

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 4, 2026

📝 Walkthrough

Walkthrough

A new Maven module introducing a hook class that automatically sends test plan execution results via HTML email after test completion. The module includes project configuration, dependencies for API interaction and email delivery, and a comprehensive implementation for fetching results, formatting reports, and SMTP transmission.

Changes

Cohort / File(s) Summary
Maven Configuration
send_testplan_results_to_email_latest/pom.xml
Defines project coordinates (groupId: com.testsigma.addons, version 1.0.0), Maven properties for encoding and Java 11 target, and core dependencies including testsigma-java-sdk, javax.mail, Jackson, GSON, Selenium, and Appium libraries. Includes maven-shade-plugin for creating fat JAR and maven-source-plugin for source attachment.
Hook Implementation
send_testplan_results_to_email_latest/src/main/java/com/testsigma/addons/hook/SendTestPlanResultsToEmailLatest.java
Implements Hook class that executes after test plan completion. Fetches API key and recipient emails from test data, chains execution results across multiple runs, aggregates test case results with pass/fail counts, constructs detailed HTML email with per-run sections and failed case groupings, and sends via configurable SMTP. Includes 25+ helper methods for API interaction, data extraction, JSON parsing, HTML escaping, and email validation with comprehensive error handling.
Configuration
send_testplan_results_to_email_latest/src/main/resources/testsigma-sdk.properties
Stores testsigma-sdk.api.key JWT token for SDK authentication.

Sequence Diagram

sequenceDiagram
    actor User
    participant Hook as SendTestPlanResultsToEmailLatest
    participant API as Testsigma API
    participant SMTP as SMTP Service
    
    User->>Hook: Test plan execution completes
    Hook->>Hook: Extract API key & email recipients from test data
    Hook->>API: Build run ID chain, fetch all run details
    API-->>Hook: Return execution results for all runs
    Hook->>API: Paginate through test_case_results
    API-->>Hook: Return failed test cases & result metrics
    Hook->>Hook: Extract counts from testPlanResultMetric or run details
    Hook->>Hook: Construct HTML email with summary & failed cases by suite
    Hook->>SMTP: Send formatted HTML email to recipients
    SMTP-->>Hook: Email transmission confirmation/error
    Hook->>Hook: Log email outcome
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • vigneshtestsigma
  • Ganesh-Testsigma

Poem

🐰✉️ A hook so fine now sends the tale,
Of tests that pass and tests that fail!
Through SMTP clouds our mail takes flight,
With HTML dreams, so bold and bright. 🎉
Results consolidated, recipients gleam—
The test plan's song, our automation's dream!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 46.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat/CUS-11074-Added send test plan results to email latest' accurately describes the main change: introducing a new addon/feature that sends test plan results via email.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/CUS-11074-Added-send-test-plan-results-to-email-latest-

Warning

Review ran into problems

🔥 Problems

Git: Failed to clone repository. Please run the @coderabbitai full review command to re-trigger a full review. If the issue persists, set path_filters to include or exclude specific files.

Tip

Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs).
Share your feedback on Discord.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (1)
send_testplan_results_to_email_latest/pom.xml (1)

17-17: Update JUnit Jupiter to a stable GA version.

Line 17 uses 5.8.0-M1, a milestone pre-release. Replace with the latest stable GA version 5.14.3, which maintains Java 11 compatibility.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@send_testplan_results_to_email_latest/pom.xml` at line 17, Update the Maven
property <junit.jupiter.version> value from the pre-release "5.8.0-M1" to the
stable GA "5.14.3" so the project uses the latest stable JUnit Jupiter release
while retaining Java 11 compatibility; locate the <junit.jupiter.version>
property in the pom.xml and replace its value accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@send_testplan_results_to_email_latest/src/main/java/com/testsigma/addons/hook/SendTestPlanResultsToEmailLatest.java`:
- Around line 128-134: The current System.out.println and setSuccessMessage in
SendTestPlanResultsToEmailLatest expose full recipient email addresses via the
variables to and toList; change both places (the block using
System.out.println/setSuccessMessage and the other occurrence around line 836)
to avoid PII by logging only the recipient count and an optional non-identifying
summary (e.g., "1 recipient" or "N recipients") or a masked representation
(e.g., show only the domain or replace local-part with ****), and ensure
variables toList and to are not concatenated directly into log or message
strings.
- Around line 44-49: Remove the hardcoded SMTP credentials in
SendTestPlanResultsToEmailLatest (DEFAULT_FROM_EMAIL, SMTP_HOST, SMTP_PORT,
SMTP_USER, SMTP_PASSWORD) and instead load them from a secure runtime source
(e.g., environment variables, a injected configuration/property source, or a
secrets manager client) with proper validation and clear error handling when
missing; ensure SMTP_PASSWORD is never committed, provide a safe fallback or
fail-fast behavior, and document that the secret must be rotated and provided
via the chosen secret store at deployment time.
- Around line 62-68: Replace the hard-coded Long runId (302912L) with the actual
RunResult ID: use the runresult object’s ID (runresult.getId()) when assigning
runId so the hook operates on the current execution; locate the runId assignment
near buildRunIdsChain() and ensure the runId variable is a Long and set from
runresult.getId() before any subsequent API calls or processing.
- Around line 813-817: The SMTP send can block indefinitely because JavaMail
defaults to infinite socket timeouts; update the Properties object used to
create the mail Session (the props variable in SendTestPlanResultsToEmailLatest)
to include explicit timeout settings such as mail.smtp.connectiontimeout,
mail.smtp.timeout and mail.smtp.writetimeout (values in milliseconds, e.g.
"10000" for 10s) so Transport.send(msg) cannot hang indefinitely; add
props.put("mail.smtp.connectiontimeout", "10000"),
props.put("mail.smtp.timeout", "10000") and props.put("mail.smtp.writetimeout",
"10000") (or configurable values) alongside the existing mail.smtp.* properties
before creating the Session/calling Transport.send.

In
`@send_testplan_results_to_email_latest/src/main/resources/testsigma-sdk.properties`:
- Line 1: The committed API credential value for the property
testsigma-sdk.api.key must be removed and rotated immediately; replace the
literal value in testsigma-sdk.properties with a placeholder (e.g. empty or
${TESTSIGMA_API_KEY}) and change the application to read the real key from a
secure runtime source (environment variable, secret manager, or CI/CD secret
injection) rather than from source control; after replacing the file,
revoke/rotate the exposed JWT/API key in the provider console and update
deployments to use the new secret via your chosen secret-injection mechanism.

---

Nitpick comments:
In `@send_testplan_results_to_email_latest/pom.xml`:
- Line 17: Update the Maven property <junit.jupiter.version> value from the
pre-release "5.8.0-M1" to the stable GA "5.14.3" so the project uses the latest
stable JUnit Jupiter release while retaining Java 11 compatibility; locate the
<junit.jupiter.version> property in the pom.xml and replace its value
accordingly.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 838f68fe-3330-492f-a717-ddef534d2aa5

📥 Commits

Reviewing files that changed from the base of the PR and between 226ecf7 and 86608f7.

📒 Files selected for processing (3)
  • send_testplan_results_to_email_latest/pom.xml
  • send_testplan_results_to_email_latest/src/main/java/com/testsigma/addons/hook/SendTestPlanResultsToEmailLatest.java
  • send_testplan_results_to_email_latest/src/main/resources/testsigma-sdk.properties

Comment on lines +44 to +49
private static final String DEFAULT_FROM_EMAIL = "ent_support@testsigma.com";
private static final String SMTP_HOST = "smtp.gmail.com";
private static final String SMTP_PORT = "587";
private static final String SMTP_USER = "ent_support@testsigma.com";
private static final String SMTP_PASSWORD = "asla sdqa frwa uynz";

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Do not hardcode SMTP credentials in source.

Lines 47-49 contain static SMTP credentials (including password). This is a critical secret-management issue; rotate immediately and source credentials from secure runtime test data.

🔐 Suggested direction
-    private static final String SMTP_USER = "ent_support@testsigma.com";
-    private static final String SMTP_PASSWORD = "asla sdqa frwa uynz";
+    `@TestData`(reference = "{SMTP USER}")
+    private com.testsigma.sdk.TestData smtpUser;
+
+    `@TestData`(reference = "{SMTP PASSWORD}")
+    private com.testsigma.sdk.TestData smtpPassword;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@send_testplan_results_to_email_latest/src/main/java/com/testsigma/addons/hook/SendTestPlanResultsToEmailLatest.java`
around lines 44 - 49, Remove the hardcoded SMTP credentials in
SendTestPlanResultsToEmailLatest (DEFAULT_FROM_EMAIL, SMTP_HOST, SMTP_PORT,
SMTP_USER, SMTP_PASSWORD) and instead load them from a secure runtime source
(e.g., environment variables, a injected configuration/property source, or a
secrets manager client) with proper validation and clear error handling when
missing; ensure SMTP_PASSWORD is never committed, provide a safe fallback or
fail-fast behavior, and document that the secret must be rotated and provided
via the chosen secret store at deployment time.

Comment on lines +62 to +68
List<Long> runIdsInOrder = buildRunIdsChain();
// Long runId = runresult.getId();

Long runId = 302912L;

String tsApiToken = apiKey.getValue().toString().trim();
String toRaw = toEmail != null && toEmail.getValue() != null ? toEmail.getValue().toString().trim() : "";
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Remove debug run ID; use the actual @RunResult ID.

Line 65 hardcodes 302912L, so this hook can fetch/send results for the wrong execution. This is a correctness blocker.

✅ Suggested fix
         List<Long> runIdsInOrder = buildRunIdsChain();
-//        Long runId = runresult.getId();
-
-        Long runId = 302912L;
+        if (runresult == null || runresult.getId() == null) {
+            setErrorMessage("RunResult is unavailable for this hook execution.");
+            return Result.FAILED;
+        }
+        Long runId = runresult.getId();
 
-        String tsApiToken = apiKey.getValue().toString().trim();
+        if (apiKey == null || apiKey.getValue() == null || apiKey.getValue().toString().trim().isEmpty()) {
+            setErrorMessage("API KEY is required. Please set the API KEY test data.");
+            return Result.FAILED;
+        }
+        String tsApiToken = apiKey.getValue().toString().trim();
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
List<Long> runIdsInOrder = buildRunIdsChain();
// Long runId = runresult.getId();
Long runId = 302912L;
String tsApiToken = apiKey.getValue().toString().trim();
String toRaw = toEmail != null && toEmail.getValue() != null ? toEmail.getValue().toString().trim() : "";
List<Long> runIdsInOrder = buildRunIdsChain();
if (runresult == null || runresult.getId() == null) {
setErrorMessage("RunResult is unavailable for this hook execution.");
return Result.FAILED;
}
Long runId = runresult.getId();
if (apiKey == null || apiKey.getValue() == null || apiKey.getValue().toString().trim().isEmpty()) {
setErrorMessage("API KEY is required. Please set the API KEY test data.");
return Result.FAILED;
}
String tsApiToken = apiKey.getValue().toString().trim();
String toRaw = toEmail != null && toEmail.getValue() != null ? toEmail.getValue().toString().trim() : "";
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@send_testplan_results_to_email_latest/src/main/java/com/testsigma/addons/hook/SendTestPlanResultsToEmailLatest.java`
around lines 62 - 68, Replace the hard-coded Long runId (302912L) with the
actual RunResult ID: use the runresult object’s ID (runresult.getId()) when
assigning runId so the hook operates on the current execution; locate the runId
assignment near buildRunIdsChain() and ensure the runId variable is a Long and
set from runresult.getId() before any subsequent API calls or processing.

Comment on lines +128 to +134
System.out.println(toList.size() == 1
? "Test plan results email sent successfully to " + to
: "Test plan results email sent successfully to " + toList.size() + " recipients: " + to);

setSuccessMessage(toList.size() == 1
? "Test plan results email sent successfully to " + to
: "Test plan results email sent successfully to " + toList.size() + " recipients: " + to);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Avoid logging full recipient email addresses.

Lines 128-134 and Line 836 log raw recipient lists. That’s avoidable PII exposure in logs/messages.

🧹 Suggested safer messaging
-            System.out.println(toList.size() == 1
-                    ? "Test plan results email sent successfully to " + to
-                    : "Test plan results email sent successfully to " + toList.size() + " recipients: " + to);
+            System.out.println("Test plan results email sent successfully to " + toList.size() + " recipient(s).");
 
-            setSuccessMessage(toList.size() == 1
-                    ? "Test plan results email sent successfully to " + to
-                    : "Test plan results email sent successfully to " + toList.size() + " recipients: " + to);
+            setSuccessMessage("Test plan results email sent successfully to " + toList.size() + " recipient(s).");

Also applies to: 836-836

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@send_testplan_results_to_email_latest/src/main/java/com/testsigma/addons/hook/SendTestPlanResultsToEmailLatest.java`
around lines 128 - 134, The current System.out.println and setSuccessMessage in
SendTestPlanResultsToEmailLatest expose full recipient email addresses via the
variables to and toList; change both places (the block using
System.out.println/setSuccessMessage and the other occurrence around line 836)
to avoid PII by logging only the recipient count and an optional non-identifying
summary (e.g., "1 recipient" or "N recipients") or a masked representation
(e.g., show only the domain or replace local-part with ****), and ensure
variables toList and to are not concatenated directly into log or message
strings.

Comment on lines +813 to +817
Properties props = new Properties();
props.put("mail.smtp.host", host);
props.put("mail.smtp.port", port);
props.put("mail.smtp.auth", String.valueOf(user != null && !user.isEmpty()));
props.put("mail.smtp.starttls.enable", "true");
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

find . -name "SendTestPlanResultsToEmailLatest.java" -type f

Repository: testsigmahq/testsigma-addons

Length of output: 1895


🌐 Web query:

Java Mail SMTP timeout properties mail.smtp.connectiontimeout mail.smtp.timeout

💡 Result:

In JavaMail/Jakarta Mail’s SMTP provider, these properties control socket-level timeouts (values are milliseconds, set as strings in the Properties used to create the Session):

  • mail.smtp.connectiontimeout: connect timeout (time allowed to establish the TCP connection). Default: infinite. [1]
  • mail.smtp.timeout: read timeout (time blocked waiting for a server response / socket read). Default: infinite. [1]

Related (often used alongside them):

  • mail.smtp.writetimeout: write timeout (time allowed for socket writes; implemented by closing the socket via a scheduled task; overhead: one thread per connection). Default: infinite. [1]

Notes:

  • If you use SMTP-over-SSL via the smtps protocol, the equivalent properties are mail.smtps.connectiontimeout, mail.smtps.timeout, etc. [1]
  • These timeouts are not a “total send deadline”; they apply to individual connect/read/write operations. [2]

Example:

Properties props = new Properties();
props.put("mail.smtp.connectiontimeout", "5000");
props.put("mail.smtp.timeout", "5000");
props.put("mail.smtp.writetimeout", "5000");

Sources: JavaMail SMTP provider docs [1]; explanation of timeout behavior [2].


Configure SMTP timeout properties to prevent indefinite blocking.

Transport.send(msg) at line 835 will block indefinitely if the SMTP server doesn't respond, since JavaMail defaults to infinite socket timeouts. This can freeze the hook thread. Add the following timeout properties (values in milliseconds):

         props.put("mail.smtp.host", host);
         props.put("mail.smtp.port", port);
         props.put("mail.smtp.auth", String.valueOf(user != null && !user.isEmpty()));
         props.put("mail.smtp.starttls.enable", "true");
+        props.put("mail.smtp.connectiontimeout", "30000");
+        props.put("mail.smtp.timeout", "30000");
+        props.put("mail.smtp.writetimeout", "30000");
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@send_testplan_results_to_email_latest/src/main/java/com/testsigma/addons/hook/SendTestPlanResultsToEmailLatest.java`
around lines 813 - 817, The SMTP send can block indefinitely because JavaMail
defaults to infinite socket timeouts; update the Properties object used to
create the mail Session (the props variable in SendTestPlanResultsToEmailLatest)
to include explicit timeout settings such as mail.smtp.connectiontimeout,
mail.smtp.timeout and mail.smtp.writetimeout (values in milliseconds, e.g.
"10000" for 10s) so Transport.send(msg) cannot hang indefinitely; add
props.put("mail.smtp.connectiontimeout", "10000"),
props.put("mail.smtp.timeout", "10000") and props.put("mail.smtp.writetimeout",
"10000") (or configurable values) alongside the existing mail.smtp.* properties
before creating the Session/calling Transport.send.

@@ -0,0 +1 @@
testsigma-sdk.api.key=eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiIzMmYwYTg1MC02NjMyLWIyN2ItOTBhYS1jZDkwMDcwNzRlMWUiLCJ1bmlxdWVJZCI6IjE3MyIsImlkZW50aXR5QWNjb3VudFVVSWQiOiJmZTJhMzhjYi04Yjg5LTc3YTQtODk0Yi04MGYzYjlhMzcxM2UifQ.9hbvEw3JT8CeT_gneBWPoymTn__kZ4XaR6v_tVcNok94-YOn4yQjeRWWaOCubOMR2AuFBg8snf3t5kBt9dDhlw No newline at end of file
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Remove committed API credential and rotate it immediately.

Line 1 includes a JWT-like API key in plaintext. For a public addon, this is a release blocker: revoke/rotate this key and inject it at runtime from secure secret input instead of source control.

🔐 Suggested immediate change
-testsigma-sdk.api.key=eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiIzMmYwYTg1MC02NjMyLWIyN2ItOTBhYS1jZDkwMDcwNzRlMWUiLCJ1bmlxdWVJZCI6IjE3MyIsImlkZW50aXR5QWNjb3VudFVVSWQiOiJmZTJhMzhjYi04Yjg5LTc3YTQtODk0Yi04MGYzYjlhMzcxM2UifQ.9hbvEw3JT8CeT_gneBWPoymTn__kZ4XaR6v_tVcNok94-YOn4yQjeRWWaOCubOMR2AuFBg8snf3t5kBt9dDhlw
+testsigma-sdk.api.key=
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
testsigma-sdk.api.key=eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiIzMmYwYTg1MC02NjMyLWIyN2ItOTBhYS1jZDkwMDcwNzRlMWUiLCJ1bmlxdWVJZCI6IjE3MyIsImlkZW50aXR5QWNjb3VudFVVSWQiOiJmZTJhMzhjYi04Yjg5LTc3YTQtODk0Yi04MGYzYjlhMzcxM2UifQ.9hbvEw3JT8CeT_gneBWPoymTn__kZ4XaR6v_tVcNok94-YOn4yQjeRWWaOCubOMR2AuFBg8snf3t5kBt9dDhlw
testsigma-sdk.api.key=
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@send_testplan_results_to_email_latest/src/main/resources/testsigma-sdk.properties`
at line 1, The committed API credential value for the property
testsigma-sdk.api.key must be removed and rotated immediately; replace the
literal value in testsigma-sdk.properties with a placeholder (e.g. empty or
${TESTSIGMA_API_KEY}) and change the application to read the real key from a
secure runtime source (environment variable, secret manager, or CI/CD secret
injection) rather than from source control; after replacing the file,
revoke/rotate the exposed JWT/API key in the provider console and update
deployments to use the new secret via your chosen secret-injection mechanism.

@akhil-testsigma akhil-testsigma merged commit c7db8a5 into dev Mar 5, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants