Add failure notifications via slack

Change-Id: If9f5711497c838a8f307fbc078b59672353ed5d3
diff --git a/Readme.md b/Readme.md
index 43bbe4c..0cd9887 100644
--- a/Readme.md
+++ b/Readme.md
@@ -22,18 +22,27 @@
  npm test
 ```
 
+
+
+
 ### Comments on Environment Variables
 
 - Use `KORAP_LOGIN="" npm test` to skip login and logout tests, e.g. to run tests against Kustvakt-lite.
 - The tests respect the current locale, consider e.g. `LC_ALL=C npm test`
 
+#### Notifications
+
+If you run KorAP-E2E-tests as a cronjob or in scheduled pipelines and
+want to get notified about failed tests via slack, set the environment variable `SLACK_WEBHOOK_URL` to the URL of your [slack webhook](https://api.slack.com/messaging/webhooks).
+
+
 ## Development and License
 
 **Authors**:
 
 - [Marc Kupietz](https://www.ids-mannheim.de/digspra/personal/kupietz.html)
 
-Copyright (c) 2022, [Leibniz Institute for the German Language](http://www.ids-mannheim.de/), Mannheim, Germany
+Copyright (c) 2024, [Leibniz Institute for the German Language](http://www.ids-mannheim.de/), Mannheim, Germany
 
 This package is developed as part of the [KorAP](http://korap.ids-mannheim.de/) Corpus Analysis Platform at the Leibniz Institute for German Language ([IDS](http://www.ids-mannheim.de/)).
 
diff --git a/package-lock.json b/package-lock.json
index 0a77d7e..81e67e1 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -11,7 +11,8 @@
       "dependencies": {
         "chai": "^4.4.1",
         "mocha": "^10.6.0",
-        "puppeteer": "^22.1.0"
+        "puppeteer": "^22.1.0",
+        "slack-notify": "^2.0.7"
       }
     },
     "node_modules/@babel/code-frame": {
@@ -1618,6 +1619,14 @@
         "randombytes": "^2.1.0"
       }
     },
+    "node_modules/slack-notify": {
+      "version": "2.0.7",
+      "resolved": "https://registry.npmjs.org/slack-notify/-/slack-notify-2.0.7.tgz",
+      "integrity": "sha512-DZ4J3RVszHUaJf5zXtAocxEhZRAvwWoswB6a/8sAG/QMWkuZdvk3e8d2YQQlPJNYNSbfak+rCtn3zrZ5UmMnYg==",
+      "engines": {
+        "node": ">=13.2.x"
+      }
+    },
     "node_modules/smart-buffer": {
       "version": "4.2.0",
       "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
diff --git a/package.json b/package.json
index 11fdbfb..8ac4d12 100644
--- a/package.json
+++ b/package.json
@@ -19,6 +19,7 @@
   "dependencies": {
     "chai": "^4.4.1",
     "mocha": "^10.6.0",
-    "puppeteer": "^22.1.0"
+    "puppeteer": "^22.1.0",
+    "slack-notify": "^2.0.7"
   }
 }
diff --git a/test/korap-ui.js b/test/korap-ui.js
index 9adfbc8..42cd5dd 100644
--- a/test/korap-ui.js
+++ b/test/korap-ui.js
@@ -4,6 +4,7 @@
 const { doesNotMatch } = require('assert');
 const assert = chai.assert;
 const should = chai.should();
+var slack = null;
 
 const KORAP_URL = process.env.KORAP_URL || "http://localhost:64543";
 const KORAP_LOGIN = 'KORAP_LOGIN' in process.env ? process.env.KORAP_LOGIN : "user2"
@@ -11,6 +12,11 @@
 const KORAP_QUERIES = process.env.KORAP_QUERIES || 'geht, [orth=geht & cmc/pos=VVFIN]'
 const korap_rc = require('../lib/korap_rc.js').new(KORAP_URL)
 
+const slack_webhook = process.env.SLACK_WEBHOOK_URL;
+if (slack_webhook) {
+    slack = require('slack-notify')(slack_webhook);
+}
+
 function ifConditionIt(title, condition, test) {
     return condition ? it(title, test) : it.skip(title + " (skipped)", test)
 }
@@ -36,6 +42,11 @@
     afterEach(async function () {
         if (this.currentTest.state == "failed") {
             await page.screenshot({path: "failed_" + this.currentTest.title.replaceAll(/[ &\/]/g, "_") + '.png'});
+            if (slack) {
+                slack.alert({
+                    text: 'Test on ' + KORAP_URL + ' failed: ' + this.currentTest.title,
+                })
+            }
         }
      })