Your nightly cross-browser regression suite stopped reporting results four days ago. Nobody noticed until a layout bug reached production across three browsers at once. Selenium Grid had no errors to show — the scheduled test run simply wasn't reaching the hub anymore. Your email alerts only fire on explicit failures, and there's no failure to report when the grid never receives jobs.
This is the silent browser test failure problem. HTTP monitors can't catch it because there's no endpoint to poll for test completion. The fix is heartbeat monitoring: your Selenium test suite pings a unique URL at the end of every successful run, and if Vigilmon doesn't receive that ping within the expected window, you get alerted.
This tutorial shows you how to instrument Selenium Grid test runs with Vigilmon heartbeat monitors so you know when your browser tests stop running.
What You'll Cover
- Heartbeat monitoring for scheduled Selenium Grid test suites
- Catching grid hub failures and node disconnections
- Alerting when browser tests stop executing entirely
- Multi-browser environment monitoring
- Detecting test runner drift on remote grids
Prerequisites
- A running Selenium Grid hub (local or remote)
- A test suite using Selenium WebDriver (Java, Python, JavaScript, or C#)
- A free account at vigilmon.online
The Problem: What Standard Selenium Monitoring Misses
Selenium Grid logs hub and node activity — but it won't alert you when:
- The scheduled job that triggers the test suite stops running
- A Grid node goes offline and the suite hangs waiting for capacity
- A test suite runner process crashes silently between runs
- Browser binary versions fall out of sync with driver versions, causing silent skips
- The Grid hub becomes unreachable but the scheduler doesn't know
Vigilmon's heartbeat pattern closes all of these gaps.
Step 1: Create a Heartbeat Monitor in Vigilmon
A heartbeat monitor expects a ping on a regular interval. No ping → alert.
- Log in to Vigilmon and click New Monitor → Heartbeat.
- Give it a name like
Selenium Grid — Nightly Regression. - Set the Expected interval to match your test schedule. For a nightly suite, use 24 hours. For hourly smoke tests, use 90 minutes (adds buffer for slow grids).
- Set the Grace period to 1 hour for long-running suites, or 15 minutes for quick smoke tests.
- Save and copy the Ping URL — it looks like
https://vigilmon.online/api/heartbeat/<unique-id>.
Step 2: Monitor the Selenium Grid Hub Directly
Before monitoring test runs, monitor the hub itself with a simple HTTP monitor.
- In Vigilmon, click New Monitor → HTTP.
- Name it
Selenium Grid Hub. - Set the URL to your grid hub status endpoint:
http://<grid-host>:4444/status - Set the Check interval to 1 minute and enable alerts on non-200 responses.
This catches hub crashes and network issues independently of test run monitoring.
Step 3: Add Heartbeat Pings to Your Test Suite
Java (JUnit 5 / TestNG)
Add a heartbeat ping in your suite teardown using Java's HttpClient:
// src/test/java/com/example/VigilmonHeartbeat.java
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class VigilmonHeartbeat {
public static void ping() {
String heartbeatUrl = System.getenv("VIGILMON_HEARTBEAT_URL");
if (heartbeatUrl == null || heartbeatUrl.isEmpty()) return;
try {
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(heartbeatUrl))
.POST(HttpRequest.BodyPublishers.noBody())
.build();
client.send(request, HttpResponse.BodyHandlers.discarding());
} catch (Exception e) {
System.err.println("Vigilmon heartbeat failed: " + e.getMessage());
}
}
}
In your JUnit 5 suite class:
// src/test/java/com/example/RegressionSuite.java
import org.junit.platform.suite.api.*;
import org.junit.jupiter.api.AfterAll;
@Suite
@SelectPackages("com.example.tests")
public class RegressionSuite {
@AfterAll
static void afterSuite() {
VigilmonHeartbeat.ping();
}
}
For TestNG, use a ISuiteListener:
import org.testng.ISuite;
import org.testng.ISuiteListener;
public class VigilmonSuiteListener implements ISuiteListener {
@Override
public void onFinish(ISuite suite) {
boolean allPassed = suite.getResults().values().stream()
.allMatch(r -> r.getTestContext().getFailedTests().size() == 0);
if (allPassed) {
VigilmonHeartbeat.ping();
}
}
}
Register it in testng.xml:
<suite name="Regression">
<listeners>
<listener class-name="com.example.VigilmonSuiteListener"/>
</listeners>
<!-- test configurations -->
</suite>
Python (pytest + pytest-selenium)
# conftest.py
import os
import urllib.request
def pytest_sessionfinish(session, exitstatus):
# Only ping on full success (exitstatus 0)
if exitstatus == 0:
heartbeat_url = os.environ.get("VIGILMON_HEARTBEAT_URL")
if heartbeat_url:
try:
req = urllib.request.Request(heartbeat_url, method="POST")
urllib.request.urlopen(req, timeout=10)
except Exception as e:
print(f"Vigilmon heartbeat failed: {e}")
Run your suite normally — the heartbeat fires automatically on success:
VIGILMON_HEARTBEAT_URL="https://vigilmon.online/api/heartbeat/<id>" \
pytest tests/ --selenium-host=<grid-host> --selenium-port=4444
JavaScript (WebdriverIO / Mocha runner)
// test/helpers/vigilmon.js
const https = require("https");
function pingHeartbeat() {
const url = process.env.VIGILMON_HEARTBEAT_URL;
if (!url) return Promise.resolve();
return new Promise((resolve) => {
const req = https.request(url, { method: "POST" }, resolve);
req.on("error", (e) => console.error("Vigilmon heartbeat failed:", e.message));
req.setTimeout(10000, () => req.destroy());
req.end();
});
}
module.exports = { pingHeartbeat };
// test/hooks.js (Mocha global hooks)
const { pingHeartbeat } = require("./helpers/vigilmon");
after(async function () {
if (this.test.parent._currentRetry === 0) {
// Only ping when no tests failed
const stats = this.test.parent.parent._stats;
if (!stats || stats.failures === 0) {
await pingHeartbeat();
}
}
});
Step 4: Schedule the Test Run and Verify Heartbeats
Wrap the test execution in a shell script that handles scheduling:
#!/bin/bash
# scripts/run-selenium-suite.sh
set -euo pipefail
GRID_URL="${SELENIUM_GRID_URL:-http://localhost:4444}"
HEARTBEAT_URL="${VIGILMON_HEARTBEAT_URL}"
# Verify grid is reachable before running tests
echo "Checking Selenium Grid status..."
curl -fsS "${GRID_URL}/status" --max-time 10 || {
echo "Grid unreachable — aborting"
exit 1
}
echo "Running test suite..."
if mvn test -Dselenium.grid.url="${GRID_URL}"; then
echo "Tests passed — pinging Vigilmon heartbeat"
curl -fsS -X POST "${HEARTBEAT_URL}" \
--max-time 10 \
--retry 3 \
--retry-delay 2
else
echo "Tests failed — heartbeat suppressed"
exit 1
fi
Add this script to your cron scheduler:
# Run nightly Selenium regression suite at 01:00 UTC
0 1 * * * /opt/selenium/scripts/run-selenium-suite.sh >> /var/log/selenium-suite.log 2>&1
Step 5: Multi-Browser Heartbeat Monitoring
For suites that run across multiple browsers, create one heartbeat monitor per browser profile:
| Suite | Browser | Monitor name | Interval |
|---|---|---|---|
| Nightly regression | Chrome | Selenium — Chrome — Nightly | 25 h |
| Nightly regression | Firefox | Selenium — Firefox — Nightly | 25 h |
| Nightly regression | Edge | Selenium — Edge — Nightly | 25 h |
| Hourly smoke tests | Chrome | Selenium — Smoke — Chrome | 90 min |
Use environment variables to parameterize the heartbeat URL:
# Chrome run
VIGILMON_HEARTBEAT_URL="${VIGILMON_CHROME_HEARTBEAT}" BROWSER=chrome ./run-suite.sh
# Firefox run
VIGILMON_HEARTBEAT_URL="${VIGILMON_FIREFOX_HEARTBEAT}" BROWSER=firefox ./run-suite.sh
Step 6: Alert Channels
In Vigilmon, go to Notifications → New Channel and configure:
- Email — immediate alert when a heartbeat is missed
- Slack webhook — ping your
#qa-alertsor#testingchannel
When a test suite stops pinging:
🔴 MISSED HEARTBEAT: Selenium Grid — Nightly Regression
Last ping: 27 hours ago
Expected interval: 24 hours
When it resumes:
✅ HEARTBEAT RECOVERED: Selenium Grid — Nightly Regression
Gap: 27 hours
What You're Now Catching
| Silent failure mode | How Vigilmon detects it | |---|---| | Scheduled cron job stops running | No ping arrives → alert after grace period | | Selenium Grid hub goes offline | HTTP monitor alerts + no test pings | | Grid node disconnects, suite hangs | Suite timeout → no ping → alert | | Browser driver version mismatch skips tests | No ping on empty run → alert | | Test runner process crashes silently | No ping → alert after grace period | | Network partition between runner and grid | Suite abort → no ping → alert |
Selenium Grid can run thousands of browser tests reliably — until it quietly stops. Vigilmon's heartbeat monitors give you the external signal that Selenium itself can't provide: a definitive alert when your browser test suite hasn't completed in longer than expected.
Add heartbeat monitoring to your Selenium Grid today — register free at vigilmon.online.