In Part 1 of this series, we explored how to use GitHub Actions matrix strategy to run UI automation tests across multiple browsers like Chrome and Firefox in parallel. It was fast, flexible, and scalable.

But once your matrix jobs run… how do you get notified when something breaks — and more importantly, which browser failed?

In this article, we’ll take it one step further by sending smart email notifications per browser, including:

  • 📬 Pass/fail status
  • 🧪 Commit SHA
  • 📎 Direct link to the HTML test report (via GitHub Artifacts)
  • ✅ Fully integrated with EmailJS dynamic templates

Let’s dive in!


📬 Why Use EmailJS?

💡 What is EmailJS?

EmailJS allows developers to send emails directly from frontend apps or serverless environments — without needing to set up their own email server or SMTP credentials.

You define templates with variables (like {{result}}, {{browser}}), and send data via a simple REST API. It’s perfect for tools like GitHub Actions or CI/CD pipelines.


🛠 Other Tools You Could Use

Tool Highlights Notes
SendGrid Full-featured transactional email API Setup is more involved
Mailgun Developer-focused with detailed tracking Ideal for backend use
SMTP2GO Traditional SMTP service Works well with SMTP clients
Postmark Reliable transactional delivery and analytics Paid plan, high deliverability
EmailJS No server needed, simple setup, free tier Best for client-side & CI/CD

✅ Why I Chose EmailJS

  • No backend needed – works directly from GitHub Actions
  • Easy template setup – fully customizable UI
  • Free plan – generous for small projects or teams
  • Quick integration – REST API is simple and secure
  • Works well with matrix workflows – send dynamic info per job

📄 Dynamic Email Templates in EmailJS

Instead of hardcoding email content in your GitHub workflow, you can define a template in EmailJS like this:

Tamplate

Now we just pass values to these placeholders from GitHub Actions using template_params.

⚙️ Updated GitHub Actions Workflow (with EmailJS Integration)

Here's the key part of your workflow that:

  • Sends an email for each matrix browser job
  • Uses dynamic data
  • Links directly to the uploaded HTML test report

✅ Success Email Step

- name: Send Success Email for ${{ matrix.browser }}
  if: success()
  env:
    EMAILJS_SERVICE_ID: ${{ secrets.EMAILJS_SERVICE_ID }}
    EMAILJS_TEMPLATE_ID: ${{ secrets.EMAILJS_TEMPLATE_ID }}
    EMAILJS_USER_ID: ${{ secrets.EMAILJS_USER_ID }}
  run: |
    ARTIFACTS_LINK="https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"

    cat < email-payload-success.json
    {
      "service_id": "${EMAILJS_SERVICE_ID}",
      "template_id": "${EMAILJS_TEMPLATE_ID}",
      "user_id": "${EMAILJS_USER_ID}",
      "template_params": {
        "title": "✅ UI Test Passed",
        "result": "passed successfully",
        "browser": "${{ matrix.browser }}",
        "commit": "${{ github.sha }}",
        "artifacts_link": "${ARTIFACTS_LINK}"
      }
    }
EOF

    curl -X POST https://api.emailjs.com/api/v1.0/email/send \
      -H 'origin: http://localhost' \
      -H 'Content-Type: application/json' \
      -d @email-payload-success.json

❌ Failure Email Step

- name: Send Failure Email for ${{ matrix.browser }}
  if: failure()
  env:
    EMAILJS_SERVICE_ID: ${{ secrets.EMAILJS_SERVICE_ID }}
    EMAILJS_TEMPLATE_ID: ${{ secrets.EMAILJS_TEMPLATE_ID }}
    EMAILJS_USER_ID: ${{ secrets.EMAILJS_USER_ID }}
  run: |
    ARTIFACTS_LINK="https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"

    cat < email-payload-failure.json
    {
      "service_id": "${EMAILJS_SERVICE_ID}",
      "template_id": "${EMAILJS_TEMPLATE_ID}",
      "user_id": "${EMAILJS_USER_ID}",
      "template_params": {
        "title": "❌ UI Test Failed",
        "result": "failed",
        "browser": "${{ matrix.browser }}",
        "commit": "${{ github.sha }}",
        "artifacts_link": "${ARTIFACTS_LINK}"
      }
    }
EOF

    curl -X POST https://api.emailjs.com/api/v1.0/email/send \
      -H 'origin: http://localhost' \
      -H 'Content-Type: application/json' \
      -d @email-payload-failure.json

📬 Real Email Example

Here's what the email looks like when a test passes for the Firefox browser:

Email

This is powered by an EmailJS template using variables like {{browser}}, {{commit}}, and {{artifacts_link}}. Everything is injected dynamically per matrix job.

You can even include emojis, links, or styling directly in the EmailJS editor!

🎁 Final Thoughts

This setup gives you full visibility over your GitHub test matrix:

  • Who broke what browser
  • Direct link to test artifacts
  • Stylish notifications in your inbox

No backend. No SMTP. Just clean, dynamic emails — in under 10 minutes.

🧩 What’s Next?

In the next article (Part 3), I’ll show you how to:

  • Combine multi-browser reports into one HTML dashboard
  • Attach that in a Slack or Teams notification
  • Make your matrix strategy 100% team-ready

💬 Questions or improvements?
💼 Connect with me on LinkedIn
🌐 More at serhatozdursun.com