Jasmine Custom Reporter ↔ Slack Notification: Selecting Alerts Without Noise
0 reputation · 04 Dec 2023, 14:06 UTC
0 reputation · 04 Dec 2023, 14:06 UTC
The objective is to emit Slack alerts only for failing specs while suppressing notifications for passing ones. The custom reporter must filter events, send an HTTP POST to a webhook, and avoid generating noise during a CI run.
CI=true is set, the reporter should conditionally silence alerts, but the interaction between environment variables and reporter execution is not documented.31275 reputation · 05 Dec 2023, 00:13 UTC
To emit Slack alerts only for failing specs, implement the specDone method in your custom reporter and wrap the HTTP request in a conditional check for the result status. To avoid noise, avoid sending a request for every individual failure; instead, collect failures in an array and send a single aggregated summary during the jasmineDone hook.
The following approach ensures that only failed tests trigger a notification and leverages environment variables to handle CI silencing.
class SlackReporter {
constructor() {
this.failures = [];
}
specDone(result) {
if (result.status === 'failed') {
this.failures.push(result.fullName);
}
}
async jasmineDone() {
// Silence alerts if CI=true is set in the environment
if (process.env.CI === 'true' || this.failures.length === 0) {
return;
}
const payload = {
text: `🚨 *Test Failures Detected*\n${this.failures.join('\n')}`
};
try {
await fetch(process.env.SLACK_WEBHOOK_URL, {
method: 'POST',
body: JSON.stringify(payload),
headers: { 'Content-Type': 'application/json' }
});
} catch (err) {
console.error('Slack notification failed:', err);
}
}
}
Asynchronous Completion: Jasmine does not natively await promises returned from reporter methods. If you use async/await in jasmineDone, the Node.js process may exit before the HTTP request completes. To verify this, check your CI logs for truncated requests. A reliable workaround is to use a synchronous request library or manually handle the process exit via process.on('exit'), though the latter is less predictable.
CI Environment Variables: Accessing process.env.CI within the reporter class is the standard way to conditionally silence alerts. Ensure these variables are exported in your CI pipeline configuration (e.g., GitHub Actions or GitLab CI) before the test command is executed.
Registration Timing: To ensure no events are missed, the reporter must be registered during the initial configuration phase. In a standard Jasmine setup, use jasmine.getEnv().addReporter(new SlackReporter()) within the jasmine.configure block or the helper file that runs before the spec discovery phase.
CI=true in your shell and run a failing suite; verify the reporter suppresses the alert.Diagnostic Detail Needed: Are you running Jasmine via the standalone CLI or integrated through a runner like Karma? (This changes how the process lifecycle is managed and how jasmineDone behaves regarding process termination).
Use comments to ask for clarification. Post a solution as an answer.
31,275 reputation · 04 Dec 2023, 18:45 UTC
Jasmine versions 4 and later treat a reporter method that returns a promise as asynchronous and will wait for it to resolve before ending the test run. If you are on Jasmine 3 or earlier, you must use the done callback signature (e.g., jasmineDone(done)) and call done() after the Slack POST finishes; otherwise the Node process may exit while the HTTP request is still in flight.
Instead of a loose if (process.env.CI), normalize the value: const isCI = ['true', '1', 'yes'].includes((process.env.CI || '').toLowerCase());. This prevents accidental silencing when CI is set to 'false' or '0'.