diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index ccbd2be5991f936a2f834bd53f6ad728ecd5dc8c..79e763a4e58ae6445f89ce0bec32d813afe493df 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -19,13 +19,12 @@ stages:
 after_script:
   - if [ -f .env-gitlab-ci ]; then rm .env-gitlab-ci; fi
 
-test:
+tests:
   stage: test
   tags:
     - nixos-gen3
   script:
     -  nix develop .#gitlab --command run-ci-tests
-  # cahe node_modules
   cache:
     untracked: true
     key:
@@ -34,13 +33,12 @@ test:
     paths:
       - node_modules/
 
-web-test:
+web-tests:
   stage: test
   tags:
     - nixos-gen3
   script:
-    -  nix develop .#gitlab --command run-ci-tests
-  # cahe node_modules
+    -  nix develop .#gitlab --command run-web-tests
   cache:
     untracked: true
     key:
diff --git a/flake.lock b/flake.lock
new file mode 100644
index 0000000000000000000000000000000000000000..57ab63b4d87e9a7663a8711bad206fe36607b91e
--- /dev/null
+++ b/flake.lock
@@ -0,0 +1,191 @@
+{
+  "nodes": {
+    "common": {
+      "inputs": {
+        "nixpkgs": "nixpkgs"
+      },
+      "locked": {
+        "lastModified": 1,
+        "narHash": "sha256-VjRoAeu0HhpiJ/oCup7JyT8IEgO+CwLkxCTno3UwAK8=",
+        "path": "./common",
+        "type": "path"
+      },
+      "original": {
+        "path": "./common",
+        "type": "path"
+      }
+    },
+    "devFlakes": {
+      "inputs": {
+        "common": "common",
+        "git-commit": "git-commit",
+        "nixpkgs": "nixpkgs_3"
+      },
+      "locked": {
+        "lastModified": 1715272075,
+        "narHash": "sha256-AzweeNBIAnYohoBx6NXmSy7aayFr0H1DfEFvDnHIaLY=",
+        "ref": "refs/heads/master",
+        "rev": "4a30b23f6580958ff5e06af5534f03228f7be631",
+        "revCount": 28,
+        "type": "git",
+        "url": "https://gitlab.schukai.com/schukai/entwicklung/nix-flakes.git"
+      },
+      "original": {
+        "type": "git",
+        "url": "https://gitlab.schukai.com/schukai/entwicklung/nix-flakes.git"
+      }
+    },
+    "flake-utils": {
+      "inputs": {
+        "systems": "systems"
+      },
+      "locked": {
+        "lastModified": 1710146030,
+        "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
+        "owner": "numtide",
+        "repo": "flake-utils",
+        "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
+        "type": "github"
+      },
+      "original": {
+        "owner": "numtide",
+        "repo": "flake-utils",
+        "type": "github"
+      }
+    },
+    "git-commit": {
+      "inputs": {
+        "nixpkgs": "nixpkgs_2"
+      },
+      "locked": {
+        "lastModified": 1,
+        "narHash": "sha256-8hXrOA8SKy//ctoL1poIhJwuT7G4rvVu7FguROzEoDg=",
+        "path": "./git-commit",
+        "type": "path"
+      },
+      "original": {
+        "path": "./git-commit",
+        "type": "path"
+      }
+    },
+    "nixpkgs": {
+      "locked": {
+        "lastModified": 1714971268,
+        "narHash": "sha256-IKwMSwHj9+ec660l+I4tki/1NRoeGpyA2GdtdYpAgEw=",
+        "owner": "NixOS",
+        "repo": "nixpkgs",
+        "rev": "27c13997bf450a01219899f5a83bd6ffbfc70d3c",
+        "type": "github"
+      },
+      "original": {
+        "id": "nixpkgs",
+        "ref": "nixos-23.11",
+        "type": "indirect"
+      }
+    },
+    "nixpkgs_2": {
+      "locked": {
+        "lastModified": 1704874635,
+        "narHash": "sha256-YWuCrtsty5vVZvu+7BchAxmcYzTMfolSPP5io8+WYCg=",
+        "owner": "NixOS",
+        "repo": "nixpkgs",
+        "rev": "3dc440faeee9e889fe2d1b4d25ad0f430d449356",
+        "type": "github"
+      },
+      "original": {
+        "id": "nixpkgs",
+        "ref": "nixos-23.11",
+        "type": "indirect"
+      }
+    },
+    "nixpkgs_3": {
+      "locked": {
+        "lastModified": 1715106579,
+        "narHash": "sha256-gZMgKEGiK6YrwGBiccZ1gemiUwjsZ1Zv49KYOgmX2fY=",
+        "owner": "NixOS",
+        "repo": "nixpkgs",
+        "rev": "8be0d8a1ed4f96d99b09aa616e2afd47acc3da89",
+        "type": "github"
+      },
+      "original": {
+        "id": "nixpkgs",
+        "ref": "nixos-23.11",
+        "type": "indirect"
+      }
+    },
+    "nixpkgs_4": {
+      "locked": {
+        "lastModified": 1715542476,
+        "narHash": "sha256-FF593AtlzQqa8JpzrXyRws4CeKbc5W86o8tHt4nRfIg=",
+        "owner": "nixos",
+        "repo": "nixpkgs",
+        "rev": "44072e24566c5bcc0b7aa9178a0104f4cfffab19",
+        "type": "github"
+      },
+      "original": {
+        "owner": "nixos",
+        "ref": "nixos-23.11",
+        "repo": "nixpkgs",
+        "type": "github"
+      }
+    },
+    "nixpkgs_5": {
+      "locked": {
+        "lastModified": 1704145853,
+        "narHash": "sha256-G/1AMt9ibpeMlcxvD1vNaC8imGaK+g7zZ99e29BLgWw=",
+        "owner": "NixOS",
+        "repo": "nixpkgs",
+        "rev": "2d2ea8eab9e400618748ab1a6a108255233b602c",
+        "type": "github"
+      },
+      "original": {
+        "id": "nixpkgs",
+        "ref": "nixos-23.11",
+        "type": "indirect"
+      }
+    },
+    "root": {
+      "inputs": {
+        "devFlakes": "devFlakes",
+        "flake-utils": "flake-utils",
+        "nixpkgs": "nixpkgs_4",
+        "version": "version"
+      }
+    },
+    "systems": {
+      "locked": {
+        "lastModified": 1681028828,
+        "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
+        "owner": "nix-systems",
+        "repo": "default",
+        "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
+        "type": "github"
+      },
+      "original": {
+        "owner": "nix-systems",
+        "repo": "default",
+        "type": "github"
+      }
+    },
+    "version": {
+      "inputs": {
+        "nixpkgs": "nixpkgs_5"
+      },
+      "locked": {
+        "lastModified": 1715522646,
+        "narHash": "sha256-Cljp1vlqLuvP5oqvFZGwbZ0ypWnLkK2t+0qDe+rX13E=",
+        "ref": "refs/heads/master",
+        "rev": "abd140ed98b8ecb71212f388260a40c8ef0e2426",
+        "revCount": 122,
+        "type": "git",
+        "url": "https://gitlab.schukai.com/oss/utilities/version.git"
+      },
+      "original": {
+        "type": "git",
+        "url": "https://gitlab.schukai.com/oss/utilities/version.git"
+      }
+    }
+  },
+  "root": "root",
+  "version": 7
+}
diff --git a/flake.nix b/flake.nix
index c055246dfcbebab1556ee0735e9115f9dee5da1e..2671326cbb97a92884256521208eea2129bcf58d 100644
--- a/flake.nix
+++ b/flake.nix
@@ -4,8 +4,8 @@
   inputs = {
     nixpkgs = {url = "github:nixos/nixpkgs/nixos-23.11";};
     flake-utils = {url = "github:numtide/flake-utils";};
-    version = {url = "git+https://gitlab.schukai.com/oss/utilities/version.git/";};
-    devFlakes = {url = "git+https://gitlab.schukai.com/schukai/entwicklung/nix-flakes.git/";};
+    version = {url = "git+https://gitlab.schukai.com/oss/utilities/version.git";};
+    devFlakes = {url = "git+https://gitlab.schukai.com/schukai/entwicklung/nix-flakes.git";};
   };
 
   outputs = {
@@ -96,13 +96,9 @@
                 echo_ok "Node modules are already installed"
               else
                 echo_fail "Node modules are not installed, run task init-project"
+                exit 1
               fi
 
-             export PLAYWRIGHT_BROWSERS_PATH="${pkgs'.playwright.browsers}"
-             export PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1
-             export PLAYWRIGHT_SKIP_VALIDATE_HOST_REQUIREMENTS=true
-
-
               echo_section "Happy hacking!"
             '';
           };
diff --git a/nix/config/common-packages.nix b/nix/config/common-packages.nix
index 1d45d81b7b1afcd07fbd5dbee4f62d3ed2db49d3..253da1610017667a943c203684369962b2f5d633 100644
--- a/nix/config/common-packages.nix
+++ b/nix/config/common-packages.nix
@@ -33,6 +33,5 @@ with pkgs'; [
   vhs
   wget
   zlib
-  
 
 ]
diff --git a/nix/scripts/go-task.nix b/nix/scripts/go-task.nix
index f02ea44c2550f0291683faf138e9fc8a14ba314d..7d7b3e4c4c40159c7772be13a201be6188ab5755 100644
--- a/nix/scripts/go-task.nix
+++ b/nix/scripts/go-task.nix
@@ -8,7 +8,8 @@
   script-init-project = pkgs.callPackage ./init-project.nix {inherit commonScript versionBin;};
   script-build-stylesheets = pkgs.callPackage ./build-stylesheets.nix {inherit commonScript versionBin;};
   script-build-and-publish = pkgs.callPackage ./build-and-publish.nix {inherit commonScript versionBin;};
-  script-run-tests = pkgs.callPackage ./run-tests.nix {inherit commonScript versionBin;};
+  script-run-tests = pkgs.callPackage ./run-tests.nix {inherit commonScript;};
+  script-run-web-tests = pkgs.callPackage ./run-web-tests.nix {inherit commonScript;};
 
   taskfile = pkgs.writeTextFile {
     name = "taskfile.yml";
@@ -71,6 +72,16 @@
             desc: Run the tests
             cmds:
               - ${script-run-tests}/bin/run-tests
+              
+          run-web-tests:
+            silent: true
+            aliases:
+              - rt
+            env:
+              USER_WORKING_DIR: "{{.USER_WORKING_DIR}}"
+            desc: Run the tests
+            cmds:
+              - ${script-run-web-tests}/bin/run-web-tests
 
           build-and-publish:
             silent: true
diff --git a/nix/scripts/run-web-tests.nix b/nix/scripts/run-web-tests.nix
new file mode 100644
index 0000000000000000000000000000000000000000..223c42277db0e834914f2e6eb17a06ec488d9a3c
--- /dev/null
+++ b/nix/scripts/run-web-tests.nix
@@ -0,0 +1,24 @@
+{
+  pkgs,
+  lib,
+  commonScript,
+  ...
+}: let
+in
+  pkgs.writeShellScriptBin "run-web-tests" ''
+    source ${commonScript}
+
+    echo_section "run web tests"
+    echo_hint "This script will run web tests in the current working directory."
+    echo_hint "The command is executed in the current working directory and not in a nix derivation."
+    cd_working_dir
+
+    if ! ${pkgs.nodejs_21}/bin/node "$(pwd)/test/web/puppeteer.mjs" --browser ${pkgs.ungoogled-chromium}/bin/chromium --path "$(pwd)/test/web/test.html" 
+    then
+       echo_fail "Tests failed, check your JS!"
+       exit 1
+    fi
+    exit 0
+
+
+  ''
diff --git a/test/web/playwright.mjs b/test/web/playwright.mjs
deleted file mode 100644
index 20dd9b180a281b7a478a02545fdccff61395d587..0000000000000000000000000000000000000000
--- a/test/web/playwright.mjs
+++ /dev/null
@@ -1,28 +0,0 @@
-import { chromium } from 'playwright';
-import path from 'path';
-import { fileURLToPath } from 'url';
-
-// Nötig, um __dirname in ES-Modulen zu verwenden
-const __filename = fileURLToPath(import.meta.url);
-const __dirname = path.dirname(__filename);
-
-(async () => {
-    // Starten Sie den Browser
-    const browser = await chromium.launch({ headless: false }); // Setzen Sie headless auf false, um den Browser sichtbar zu machen
-    const page = await browser.newPage();
-
-    // Navigieren Sie zur lokalen HTML-Datei
-    const filePath = path.resolve(__dirname, 'test.html');
-    const fileUrl = 'file://' + filePath;
-    await page.goto(fileUrl);
-
-    // Überprüfen Sie den Titel der Seite
-    const title = await page.title();
-    console.log(`Title: ${title}`);
-
-    // Machen Sie einen Screenshot
-    await page.screenshot({ path: 'example.png' });
-
-    // Browser schließen
-    await browser.close();
-})();
diff --git a/test/web/puppeteer.mjs b/test/web/puppeteer.mjs
index f66aa140b552c01704dda7e0c9a2f8e32f220792..4d9e915fc4e50413e80a2bcc308192ae47c538c0 100644
--- a/test/web/puppeteer.mjs
+++ b/test/web/puppeteer.mjs
@@ -1,39 +1,63 @@
-import path from "path";
 import puppeteer from 'puppeteer';
 
-(async () => {
-    // Launch the browser and open a new blank page
-    const browser = await puppeteer.launch({
-        headless: 'new',
-    });
-    const page = await browser.newPage();
+// args auswerten mit --path und --browser, get from args
+const args = process.argv;
 
-    // Navigate the page to a URL
-    const filePath = path.resolve(__dirname, 'test.html');
-    const fileUrl = 'file://' + filePath;
+const config = {};
 
 
-    await page.goto(fileUrl);
+for (let i = 0; i < args.length; i++) {
+    if (args[i] === '--path') {
+        config.path = args[i + 1];
+    }
+    if (args[i] === '--browser') {
+        config.browser = args[i + 1];
+    }
+}
 
-    // Set screen size
-    await page.setViewport({width: 1080, height: 1024});
+if (!config.path) {
+    console.error('Path is required, please provide --path');
+    process.exit(1);
+}
 
-    // Type into search box
-    await page.type('.devsite-search-field', 'automate beyond recorder');
+if (!config.browser) {
+    console.error('Browser is required, please provide --browser');
+    process.exit(1);
+}
 
-    // Wait and click on first result
-    const searchResultSelector = '.devsite-result-item-link';
-    await page.waitForSelector(searchResultSelector);
-    await page.click(searchResultSelector);
 
-    // Locate the full title with a unique string
-    const textSelector = await page.waitForSelector(
-        'text/Customize and automate'
-    );
-    const fullTitle = await textSelector?.evaluate(el => el.textContent);
+(async () => {
+    const browser = await puppeteer.launch({
+        headless: 'new', // if you want to see the browser, set this to false
+        executablePath: config.browser,
+        args: ['--no-sandbox'],
+        userAgent: 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36',
+        
+    });
+    
+    const page = await browser.newPage();
+    const fileUrl = 'file://' + config.path;
+    await page.goto(fileUrl);
+    const searchResultSelector = '#mocha-done';
+    await page.waitForSelector(searchResultSelector);
 
-    // Print the full title
-    console.log('The title of this blog post is "%s".', fullTitle);
+    await page.waitForFunction('document.getElementById("mocha-done").textContent.length > 0');
+
+    const passes = await page.evaluate(() => document.getElementById('mocha-stats').querySelector('li.passes').textContent);
+    const failures = await page.evaluate(() => document.getElementById('mocha-stats').querySelector('li.failures').textContent);
+    const duration = await page.evaluate(() => document.getElementById('mocha-stats').querySelector('li.duration').textContent);
+    
+    const error = await page.evaluate(() => document.getElementById('mocha-errors').textContent);
+
+    console.log('Tests passed:', passes);
+    console.log('Tests failed:', failures);
+    console.log('Duration:', duration);
+    
+    if (error.length > 0) {
+        console.error('Tests failed: ', error);
+    } else {
+        console.log('Tests passed');
+    }
 
     await browser.close();
 })();
\ No newline at end of file