diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9cc5b17f0dad80ced68f9bf8628604db6cc18688..a0b6919ecbeb6e9087607140ab3fb76ac6bc3d13 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -16,6 +16,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 
 ### Fixed ###
 
+* [#247](https://gitlab.com/linkahead/linkahead-webui/-/issues/247) Linkify absorbs commas 
+  etc. (, . : ;) into link adress
 * Query shortcuts are now displayed when using the new query panel.
 * [249](https://gitlab.com/linkahead/linkahead-webui/-/issues/249) only the
   first ≈100 options were shown in edit-mode reference dropdown menus in case
diff --git a/DEPENDENCIES.md b/DEPENDENCIES.md
index 1562baadf8948f3efcf4c2d8e09b8c172e173d4a..c96629cd9081bad240999f431a1f9306b8cfa704 100644
--- a/DEPENDENCIES.md
+++ b/DEPENDENCIES.md
@@ -31,5 +31,19 @@
   editor plugins. Please refer to the `package.json` within
   `libs/ckeditor...zip` for a full list of said plugins.
 
-## For testing
+## For unit testing
 * qunit-2.9.2
+
+### Debian 12 (also on WSL)
+* unzip
+* gettext
+* firefox-esr
+* xvfb
+* libpci-dev
+* libegl1
+* imagemagick (to use `convert` on `screenshot.xwd`)
+
+Install test dependencies on Debian
+```bash
+sudo apt install unzip gettext firefox-esr xvfb x11-apps libpci-dev libegl1 imagemagick
+```
diff --git a/README_SETUP.md b/README_SETUP.md
index 3a27cb5e34d1785991a2379c703561926913e96a..9b8a6457d9a0b79fe0d6acf3e8df9294f0074981 100644
--- a/README_SETUP.md
+++ b/README_SETUP.md
@@ -63,10 +63,16 @@ See `build.properties.d/00_default.properties` for more information.
 
 ## Test
 
+* See [DEPENDENCIES](DEPENDENCIES#for-unit-testing) for the requirements to run the unit tests.
 * Run `make test` to compile/copy the web interface and the tests to a newly
   created `public` folder.
 * Run `make run-test-server` to start a python http server.
 * The test suite can be started with `firefox http://localhost:8000/`.
+* *On WSL (as of Feb 2024, WSL v2.0.14.0)*, port 8000 is sometimes not properly forwarded to the host
+  resulting in an unreachable test suite. Switching to a different port can be done easily
+  by using the `TEST_PORT` environment variable, e.g. with `TEST_PORT=8111 make
+  run-test-server`. Using the X11 `firefox` from within WSL always works.
+* To run the test suite non-interactively (as in CI/CD) use `make -d run-qunit`
 
 ## Clean
 
diff --git a/src/core/js/ext_cosmetics.js b/src/core/js/ext_cosmetics.js
index 9443bf65c8fa3effa57a64491563479ca51c91d0..aeb88cc9763ccc48dc01f0a25670fb67cf471198 100644
--- a/src/core/js/ext_cosmetics.js
+++ b/src/core/js/ext_cosmetics.js
@@ -1,10 +1,11 @@
 /*
  * This file is a part of the LinkAhead Project.
  *
- * Copyright (C) 2021-2023 IndiScale GmbH <info@indiscale.com>
+ * Copyright (C) 2021-2024 IndiScale GmbH <info@indiscale.com>
  * Copyright (C) 2021 Timm Fitschen <t.fitschen@indiscale.com>
  * Copyright (C) 2023 Florian Spreckelsen <f.spreckelsen@indiscale.com>
  * Copyright (C) 2023 Daniel Hornung <d.hornung@indiscale.com>
+ * Copyright (C) 2024 Joscha Schmiedt <joscha@schmiedt.dev>
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License as
@@ -51,66 +52,81 @@ var cosmetics = new function () {
         });
     }
 
-  /**
-   * Remove all the custom datetime elements again, for example when entering the edit mode.
-   */
-  var _custom_datetime_clear = function() {
-    $('.caosdb-v-property-datetime-customized-newvalue').each(function () {
-      $(this).remove();
+    /**
+     * Remove all the custom datetime elements again, for example when entering the edit mode.
+     */
+    var _custom_datetime_clear = function () {
+        $('.caosdb-v-property-datetime-customized-newvalue').each(function () {
+            $(this).remove();
+        }
+        )
     }
-                                                             )
-  }
 
-    var _linkify = function () {
-        $('.caosdb-f-property-text-value').each(function (index) {
-            if (!($(this).hasClass("caosdb-v-property-linkified")) && (/https?:\/\//.test(this.innerText))) {
-                var result = this.innerText.replace(/https?:\/\/[^\s]*/g, function (href, index) {
-                    var link_text = href;
-                    if (_link_cut_off_length > 4 && link_text.length > _link_cut_off_length) {
-                        link_text = link_text.substring(0, _link_cut_off_length - 5) + "[...]";
-                    }
+    /**
+     * Return a string with all occurences of a http(s) url in a given string replaced by <a> elements
+     * @param {string} text - The text to be searched for URLs
+     * @returns {string} text with <a> elements instead of raw links
+     */
+    function linkify_string(text) {
+        // const match_url_regex = /https?:\/\/[^\s]*/g // original
+        // https://regexr.com helps you design regex
+        const match_url_regex = /https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.?[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)/g
+
+        return text.replace(match_url_regex, function (href) {
+            var link_text = href;
+            if (_link_cut_off_length > 4 && link_text.length > _link_cut_off_length) {
+                link_text = link_text.substring(0, _link_cut_off_length - 5) + "[...]";
+            }
 
-                    return `<a title="Open ${href} in a new tab." target="_blank" class="caosdb-v-property-href-value" href="${href}">${link_text} <i class="bi bi-box-arrow-up-right"></i></a>`;
-                });
+            return `<a title="Open ${href} in a new tab." target="_blank" class="caosdb-v-property-href-value" href="${href}">${link_text} <i class="bi bi-box-arrow-up-right"></i></a>`;
+        });
+    }
 
+    /**
+     * Turn all URLs in .caosdb-f-property-text-value DOM elements into actual links
+     */
+    var _linkify_all_text_values = function () {
+        $('.caosdb-f-property-text-value').each(function (index) {
+            if (!($(this).hasClass("caosdb-v-property-linkified")) && (/https?:\/\//.test(this.innerText))) {
+                var linkified_text_value = linkify_string(this.innerText);
                 // add class to highlight that this has been linkified already
                 // (see https://gitlab.com/caosdb/caosdb-webui/-/issues/199).
                 $(this).addClass("caosdb-v-property-linkified")
                 $(this).hide();
-                $(this).after(result);
+                $(this).after(linkified_text_value);
             }
         });
     }
 
     /**
-     * Customize datetime formatting.
+     * Convert any substring of a text-value beginning with 'http(s)://' into a
+     * link.
      *
      * A listener detects edit-mode changes and previews
      */
-    var custom_datetime = function () {
-        _custom_datetime();
+    var linkify = function () {
+        _linkify_all_text_values();
 
-        // edit-mode-listener to delete replacement
-        document.body.addEventListener(edit_mode.start_edit.type, _custom_datetime_clear, true);
-        // edit-mode-listener to recreate
-        document.body.addEventListener(edit_mode.end_edit.type, _custom_datetime, true);
+        // edit-mode-listener
+        document.body.addEventListener(edit_mode.end_edit.type, _linkify_all_text_values, true);
         // preview listener
-        document.body.addEventListener(preview.previewReadyEvent.type, _custom_datetime, true);
+        document.body.addEventListener(preview.previewReadyEvent.type, _linkify_all_text_values, true);
     }
 
     /**
-     * Convert any substring of a text-value beginning with 'http(s)://' into a
-     * link.
+     * Customize datetime formatting.
      *
      * A listener detects edit-mode changes and previews
      */
-    var linkify = function () {
-        _linkify();
+    var custom_datetime = function () {
+        _custom_datetime();
 
-        // edit-mode-listener
-        document.body.addEventListener(edit_mode.end_edit.type, _linkify, true);
+        // edit-mode-listener to delete replacement
+        document.body.addEventListener(edit_mode.start_edit.type, _custom_datetime_clear, true);
+        // edit-mode-listener to recreate
+        document.body.addEventListener(edit_mode.end_edit.type, _custom_datetime, true);
         // preview listener
-        document.body.addEventListener(preview.previewReadyEvent.type, _linkify, true);
+        document.body.addEventListener(preview.previewReadyEvent.type, _custom_datetime, true);
     }
 
     this.init = function () {
@@ -123,7 +139,6 @@ var cosmetics = new function () {
             linkify();
         }
     }
-
 }
 
 
diff --git a/test/core/js/modules/ext_cosmetics.js.js b/test/core/js/modules/ext_cosmetics.js.js
index f903469c6512779aea4df737e01eadd22a374daa..32ecd1750b96846187e24dfe2f44f6db6bc9785d 100644
--- a/test/core/js/modules/ext_cosmetics.js.js
+++ b/test/core/js/modules/ext_cosmetics.js.js
@@ -1,9 +1,10 @@
 /*
  * This file is a part of the LinkAhead Project.
  *
- * Copyright (C) 2021-2023 IndiScale GmbH <info@indiscale.com>
+ * Copyright (C) 2021-2024 IndiScale GmbH <info@indiscale.com>
  * Copyright (C) 2021 Timm Fitschen <t.fitschen@indiscale.com>
  * Copyright (C) 2023 Daniel Hornung <d.hornung@indiscale.com>
+ * Copyright (C) 2024 Joscha Schmiedt <joscha@schmiedt.dev>
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License as
@@ -51,12 +52,12 @@ QUnit.test("custom datetime", function (assert) {
         const text_value = $(`<span class="caosdb-f-property-datetime-value">${test_case[0]}</span>`);
         container.append(text_value);
         assert.equal($(container).find(" ").length, 0, "Test original datetime.");
-      cosmetics.custom_datetime();
-      const newValueElement =
+        cosmetics.custom_datetime();
+        const newValueElement =
             container[0].querySelector("span.caosdb-v-property-datetime-customized-newvalue");
-      assert.ok(newValueElement, "Datetime customization: Test if result exists.");
-      assert.equal(newValueElement.innerHTML, test_case[1],
-                   "Datetime customization: compared result.");
+        assert.ok(newValueElement, "Datetime customization: Test if result exists.");
+        assert.equal(newValueElement.innerHTML, test_case[1],
+            "Datetime customization: compared result.");
         container.remove();
     }
 });
@@ -64,22 +65,22 @@ QUnit.test("custom datetime", function (assert) {
 QUnit.test("linkify - https", function (assert) {
     assert.ok(cosmetics.linkify, "linkify available");
     var test_cases = [
-        ["https://link", 1],
-        ["this is other text https://link", 1],
-        ["https://link this is other text", 1],
-        ["this is other text https://link and this as well", 1],
-        ["this is other text https://link", 1],
-        ["this is other text https://link and here comes another link https://link and more text", 2],
+        ["https://link", 1, "https://link",],
+        ["this is other text https://link.com", 1, "https://link.com"],
+        ["https://link; this is other text", 1, "https://link"],
+        ["this is other text https://link.de and this as well", 1, "https://link.de"],
+        ["this is other text https://link:3000", 1, "https://link:3000"],
+        ["this is other text https://link.org/test, and here comes another link https://link.org/test and more text", 2, "https://link.org/test"],
     ];
 
     for (let test_case of test_cases) {
-        const container = $('<div></div>');
+        var container = $('<div></div>');
         $(document.body).append(container);
         const text_value = $(`<div class="caosdb-f-property-text-value">${test_case[0]}</div>`);
         container.append(text_value);
-        assert.equal($(container).find("a[href='https://link']").length, 0, "no link present");
+        assert.equal($(container).find(`a[href='${test_case[2]}']`).length, 0, "no link present");
         cosmetics.linkify();
-        assert.equal($(container).find("a[href='https://link']").length, test_case[1], "link is present");
+        assert.equal($(container).find(`a[href='${test_case[2]}']`).length, test_case[1], `link is present: ${$(container)[0].outerHTML}`);
         container.remove();
     }
 });