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:
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:
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