Your Nightwatch.js suite ran every night for two months without a hitch. Then a routine Node.js upgrade changed how the Selenium server started, and the test job began silently exiting before any browser opened. No red CI badge — the job appeared to pass. No alert — nobody was watching. Three days later, a broken login form was live in production.
This is exactly what Vigilmon's heartbeat monitoring is designed to catch. When Nightwatch completes a fully successful run, it pings a unique URL. If that ping stops arriving, Vigilmon alerts you — no matter why the suite stopped running.
What You'll Cover
- Heartbeat monitoring for scheduled Nightwatch.js runs
- Catching Nightwatch runners that stop triggering entirely
- Alerting when the Selenium/WebDriver server fails to start
- Multi-environment browser test monitoring
- Detecting test schedule drift before it causes production issues
Prerequisites
- A Nightwatch.js test suite (version 2.x or 3.x)
- A free account at vigilmon.online
The Problem: What Standard Nightwatch Reporting Misses
Nightwatch has excellent built-in reporters and detailed exit codes — but none of them alert you when:
- The CI schedule trigger is paused or misconfigured
- The Selenium/WebDriver server fails silently before any test runs
- A glob or tag filter returns zero tests (job exits 0 with no coverage)
- The test machine goes offline and the queue backs up unnoticed
- A config change causes Nightwatch to exit before connecting to the browser
Vigilmon's heartbeat pattern covers all of these.
Step 1: Create a Heartbeat Monitor in Vigilmon
- Log in to Vigilmon and click New Monitor → Heartbeat.
- Name it something like
Nightwatch E2E — Nightly. - Set Expected interval to match your test schedule. For nightly runs, use 24 hours; for pre-deploy smoke tests, try 4 hours.
- Set Grace period to 1 hour to absorb browser startup delays and retries.
- Save and copy the Ping URL — it looks like
https://vigilmon.online/api/heartbeat/<unique-id>.
Step 2: Create a Custom Nightwatch Reporter
Nightwatch's global reporter hooks let you execute code after all tests complete. Create a file at nightwatch/reporters/vigilmon.js:
// nightwatch/reporters/vigilmon.js
const https = require("https");
function pingVigilmon(url) {
return new Promise((resolve, reject) => {
const req = https.request(url, { method: "POST" }, (res) => {
resolve(res.statusCode);
});
req.on("error", reject);
req.setTimeout(10000, () => {
req.destroy(new Error("Vigilmon ping timed out"));
});
req.end();
});
}
module.exports = {
async write(results, options, done) {
const heartbeatUrl = process.env.VIGILMON_HEARTBEAT_URL;
if (!heartbeatUrl) {
done();
return;
}
// results.failed is the count of failed tests; only ping on clean runs
const failed = results.failed || 0;
const errors = results.errors || 0;
if (failed === 0 && errors === 0) {
try {
await pingVigilmon(heartbeatUrl);
console.log("Vigilmon heartbeat sent");
} catch (e) {
console.error("Vigilmon heartbeat failed:", e.message);
}
}
done();
},
};
Step 3: Register the Reporter in Nightwatch Config
Add the custom reporter to your nightwatch.conf.js:
// nightwatch.conf.js
module.exports = {
src_folders: ["tests"],
custom_reporter: "./nightwatch/reporters/vigilmon.js",
test_settings: {
default: {
launch_url: process.env.APP_URL || "http://localhost:3000",
screenshots: {
enabled: true,
path: "tests/screenshots",
on_failure: true,
},
desiredCapabilities: {
browserName: "chrome",
"goog:chromeOptions": {
args: ["--headless", "--no-sandbox", "--disable-dev-shm-usage"],
},
},
},
staging: {
launch_url: "https://staging.example.com",
},
production: {
launch_url: "https://example.com",
},
},
webdriver: {
start_process: true,
server_path: require("chromedriver").path,
port: 9515,
},
};
Local development
VIGILMON_HEARTBEAT_URL="https://vigilmon.online/api/heartbeat/<id>" \
npx nightwatch tests/
Step 4: Add to CI/CD Pipelines
GitHub Actions
# .github/workflows/e2e.yml
name: Nightwatch E2E
on:
schedule:
- cron: "0 2 * * *" # 02:00 UTC nightly
push:
branches: [main]
jobs:
nightwatch:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
- name: Install dependencies
run: npm ci
- name: Start application
run: npm run start:ci &
- name: Wait for server
run: npx wait-on http://localhost:3000 --timeout 30000
- name: Run Nightwatch
env:
VIGILMON_HEARTBEAT_URL: ${{ secrets.VIGILMON_NIGHTWATCH_HEARTBEAT_URL }}
run: npx nightwatch tests/ --env default
# Custom reporter automatically pings Vigilmon when all tests pass.
# If any test fails, no heartbeat is sent and Vigilmon alerts after the grace period.
GitLab CI
# .gitlab-ci.yml
nightwatch:nightly:
stage: test
image: node:20
variables:
VIGILMON_HEARTBEAT_URL: $VIGILMON_NIGHTWATCH_HEARTBEAT_URL
only:
- schedules
before_script:
- apt-get update -q && apt-get install -yq chromium
- export CHROME_BIN=$(which chromium)
script:
- npm ci
- npm run start:ci &
- npx wait-on http://localhost:3000
- npx nightwatch tests/ --env default
Step 5: Multi-Environment Monitoring
For teams running Nightwatch against staging and production:
| Suite | Environment | Monitor name | Interval |
|---|---|---|---|
| Nightly regression | Staging | Nightwatch E2E — Staging — Nightly | 25 h |
| Pre-deploy smoke | Staging | Nightwatch Smoke — Staging | 4 h |
| Post-deploy verify | Production | Nightwatch Smoke — Production | 2 h |
| Weekly cross-browser | Staging | Nightwatch Cross-Browser — Weekly | 8 days |
Parameterize the reporter by environment:
// nightwatch/reporters/vigilmon.js
async write(results, options, done) {
const env = process.env.NIGHTWATCH_ENV || "staging";
const heartbeatVar = `VIGILMON_${env.toUpperCase()}_HEARTBEAT_URL`;
const heartbeatUrl = process.env[heartbeatVar];
if (heartbeatUrl && results.failed === 0 && results.errors === 0) {
await pingVigilmon(heartbeatUrl).catch(console.error);
}
done();
},
NIGHTWATCH_ENV=production \
VIGILMON_PRODUCTION_HEARTBEAT_URL="..." \
npx nightwatch tests/ --env production
Step 6: Configure Alert Channels
In Vigilmon, go to Notifications → New Channel:
- Email — immediate alert when a heartbeat is missed
- Slack webhook — notify your
#qa-alertschannel
When a Nightwatch suite stops pinging:
🔴 MISSED HEARTBEAT: Nightwatch E2E — Nightly
Last ping: 26 hours ago
Expected interval: 24 hours
When it recovers:
✅ HEARTBEAT RECOVERED: Nightwatch E2E — Nightly
Gap: 26 hours
What You're Now Catching
| Silent failure mode | How Vigilmon detects it | |---|---| | CI schedule job is paused or deleted | No ping → alert after grace period | | Selenium/WebDriver fails to start | Process exits before tests → no ping → alert | | Zero tests match tag/filter (exit 0) | No ping on empty run → alert | | Test machine is offline | No ping → alert after grace period | | Nightwatch hangs waiting for a browser | Timeout → no ping → alert | | Node.js version mismatch causes silent exit | No ping → alert |
Nightwatch.js gives you powerful, cross-browser end-to-end coverage — but only while it's actually running. Vigilmon's heartbeat monitors give you the signal Nightwatch can't: confirmation that your test suite ran and passed within the expected window.
Add heartbeat monitoring to your Nightwatch.js suite today — register free at vigilmon.online.