Your Jasmine suite ran clean this morning. Or did it? The scheduled job that triggers it was quietly dropped from the CI pipeline when someone reorganised the YAML two weeks ago. Jasmine produces zero failures when it runs zero specs — and without an external signal, nobody notices until a regression ships to production.
This is the silent suite-failure problem. HTTP monitors can't help — there is nothing to ping. The answer is heartbeat monitoring: your Jasmine run pings a unique URL after every successful execution, and if Vigilmon doesn't receive that ping within the expected window, you get alerted.
This tutorial shows you how to instrument Jasmine test pipelines with Vigilmon heartbeat monitors so you know when tests stop running, not just when they fail.
What You'll Cover
- Heartbeat monitoring for Jasmine test suites
- Detecting suites that stop running entirely
- Custom Jasmine reporters that ping on completion
- Multi-environment test monitoring (unit, integration, e2e)
- Integrating with CI/CD pipelines (GitHub Actions, GitLab CI)
Prerequisites
- A Node.js project with Jasmine configured
- A free account at vigilmon.online
The Problem: What Jasmine's Built-In Reporting Misses
Jasmine gives you spec counts, failure details, and timing information — but only when it actually runs. It won't alert you when:
- A CI path filter silently excludes your spec directory
- A
spec_dirorspec_filesglob matches nothing (zero specs run, exit code 0) - A scheduled test job is disabled or never triggered
- Jasmine hangs on an async spec with no
done()call and the CI runner times out - A misconfigured
jasmine.jsonpoints to the wrong directory
Vigilmon's heartbeat pattern closes these gaps by requiring an explicit "I finished successfully" signal from a reporter wired directly to Jasmine's completion lifecycle.
Step 1: Create a Heartbeat Monitor in Vigilmon
- Log in to Vigilmon and click New Monitor → Heartbeat.
- Name it something specific:
Jasmine Unit Tests — mainorJasmine E2E — nightly. - Set the Expected interval to match your test schedule. For suites that run on every push, use 2 hours (buffers CI queue time). For nightly suites, use 25 hours.
- Set the Grace period to 30 minutes for push-triggered suites, or 1 hour for scheduled suites.
- Save and copy the Ping URL — it looks like
https://vigilmon.online/api/heartbeat/<unique-id>.
Step 2: Write a Custom Jasmine Reporter
Jasmine's reporter API exposes a jasmineDone callback that fires after all specs complete. Wire the heartbeat ping there.
Create vigilmon-reporter.js in your project root:
// vigilmon-reporter.js
const https = require("https");
class VigilmonReporter {
jasmineDone(suiteInfo) {
const heartbeatUrl = process.env.VIGILMON_HEARTBEAT_URL;
if (!heartbeatUrl) {
return; // skip in local dev if the env var isn't set
}
// Only ping on a fully successful run (no failures, no pending-that-broke)
const failed = suiteInfo.failedExpectations
? suiteInfo.failedExpectations.length
: 0;
if (failed > 0) {
return; // let the heartbeat window expire — Vigilmon will alert
}
const url = new URL(heartbeatUrl);
const req = https.request(
{
hostname: url.hostname,
path: url.pathname + url.search,
method: "POST",
timeout: 10000,
},
(res) => {
res.resume();
}
);
req.on("error", (err) => {
console.error("[Vigilmon] Heartbeat ping failed:", err.message);
});
req.on("timeout", () => {
req.destroy();
console.error("[Vigilmon] Heartbeat ping timed out");
});
req.end();
}
}
module.exports = VigilmonReporter;
Step 3: Register the Reporter in Jasmine
Node.js / jasmine npm package
In your spec/support/jasmine.json or programmatic runner:
// spec/support/jasmine.json
{
"spec_dir": "spec",
"spec_files": ["**/*[sS]pec.js"],
"helpers": [],
"reporters": [],
"stopSpecOnExpectationFailure": false,
"random": true
}
Then in a helper file, e.g. spec/helpers/vigilmon.js:
const VigilmonReporter = require("../../vigilmon-reporter");
jasmine.getEnv().addReporter(new VigilmonReporter());
Or if you run Jasmine programmatically:
// run-tests.js
const Jasmine = require("jasmine");
const VigilmonReporter = require("./vigilmon-reporter");
const runner = new Jasmine();
runner.loadConfigFile("spec/support/jasmine.json");
runner.addReporter(new VigilmonReporter());
runner.execute();
Add the helper to your Jasmine config:
{
"helpers": ["helpers/**/*.js"]
}
Step 4: Integrate with GitHub Actions
# .github/workflows/test.yml
name: Jasmine Tests
on:
push:
branches: [main, develop]
schedule:
- cron: "0 3 * * *" # nightly 03:00 UTC
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
cache: "npm"
- name: Install dependencies
run: npm ci
- name: Run Jasmine
env:
VIGILMON_HEARTBEAT_URL: ${{ secrets.VIGILMON_JASMINE_HEARTBEAT_URL }}
run: npx jasmine
# VigilmonReporter.jasmineDone fires here on success and pings Vigilmon
Store the heartbeat URL in GitHub repo → Settings → Secrets and variables → Actions → New repository secret:
- Name:
VIGILMON_JASMINE_HEARTBEAT_URL - Value: ping URL from Step 1
If you prefer to own the ping at the workflow level rather than inside Jasmine:
- name: Run Jasmine
run: npx jasmine
- name: Ping Vigilmon heartbeat
if: success()
run: |
curl -fsS -X POST "${{ secrets.VIGILMON_JASMINE_HEARTBEAT_URL }}" \
--max-time 10 \
--retry 3 \
--retry-delay 2
Use the reporter approach for granular control (individual spec-suite success). Use the workflow step approach when you want the CI config to own the monitoring signal.
Step 5: Integrate with GitLab CI
# .gitlab-ci.yml
test:jasmine:
image: node:20-alpine
stage: test
script:
- npm ci
- VIGILMON_HEARTBEAT_URL=$VIGILMON_JASMINE_HEARTBEAT_URL npx jasmine
only:
- main
- schedules
Set VIGILMON_JASMINE_HEARTBEAT_URL in GitLab → Settings → CI/CD → Variables.
For the after-script approach:
test:jasmine:
image: node:20-alpine
stage: test
script:
- npm ci
- npx jasmine
after_script:
- |
if [ "$CI_JOB_STATUS" = "success" ]; then
curl -fsS -X POST "$VIGILMON_JASMINE_HEARTBEAT_URL" --max-time 10 --retry 3
fi
Step 6: Monitor Multiple Suites Separately
Large projects often split specs into unit, integration, and end-to-end groups with different run schedules. Create one heartbeat monitor per suite:
| Suite | Config file | Monitor name | Interval |
|---|---|---|---|
| Unit specs | jasmine.unit.json | Jasmine Unit — push | 2 h |
| Integration specs | jasmine.integration.json | Jasmine Integration — push | 4 h |
| E2E specs | jasmine.e2e.json | Jasmine E2E — nightly | 25 h |
# .github/workflows/test.yml (multi-suite)
jobs:
unit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: "20", cache: "npm" }
- run: npm ci
- run: npx jasmine --config=jasmine.unit.json
env:
VIGILMON_HEARTBEAT_URL: ${{ secrets.VIGILMON_JASMINE_UNIT_HEARTBEAT_URL }}
integration:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: "20", cache: "npm" }
- run: npm ci
- run: npx jasmine --config=jasmine.integration.json
env:
VIGILMON_HEARTBEAT_URL: ${{ secrets.VIGILMON_JASMINE_INTEGRATION_HEARTBEAT_URL }}
Step 7: Alert Channels
In Vigilmon, go to Notifications → New Channel and configure:
- Email — immediate alert when a heartbeat is missed
- Slack webhook — ping your
#devor#ci-alertschannel
When a Jasmine suite stops pinging:
🔴 MISSED HEARTBEAT: Jasmine Unit — push
Last ping: 3 hours ago
Expected interval: 2 hours
When it recovers:
✅ HEARTBEAT RECOVERED: Jasmine Unit — push
Gap: 3 hours
What You're Now Catching
| Silent failure mode | How Vigilmon detects it |
|---|---|
| Path filter excludes spec directory | No specs run, no reporter fires, no ping → alert |
| spec_files glob matches nothing | Exit code 0, reporter fires with 0 specs, no ping |
| CI job skipped by branch filter | No ping within interval → alert |
| Async spec hangs with no done() | Jasmine times out, no jasmineDone → no ping → alert |
| Nightly suite accidentally disabled | No ping → alert after interval |
| Specs fail and suite exits non-zero | Reporter skips ping → alert |
Jasmine tells you when specs fail. Vigilmon tells you when Jasmine stops running. Together, both failure modes get covered.
Start monitoring your Jasmine pipelines today — register free at vigilmon.online.