diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 0a2ac7c31d6648b4fde30e7cc4a6378edf846d14..399c6096be9e3eb1e89eeaaf22c3243015b9fc68 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -5,6 +5,7 @@ default:
     - docker
 
 stages:
+  - setup
   - check
   - build
   - test
@@ -16,29 +17,22 @@ include:
 
 variables:
   CONTAINER_IMAGE: "$CI_REGISTRY_IMAGE:$CI_COMMIT_REF_NAME"
-  CYPRESS_CACHE_FOLDER: "cache/Cypress"
+  CYPRESS_CACHE_FOLDER: "$CI_PROJECT_DIR/cache/Cypress"
 
 install-dependencies:
-  stage: check
+  stage: setup
   script:
     - npm ci
   artifacts:
     paths:
+      - .cache/*
+      - cache/Cypress
       - node_modules
-      - ${CYPRESS_CACHE_FOLDER}  # for some inexplicable reason this path MUST be in a variable
-
-run-pre-commit:
-  needs:
-    - job: install-dependencies
-      artifacts: true
 
 lint:
   stage: check
   script:
     - npm run code-quality
-  needs:
-    - job: install-dependencies
-      artifacts: true
   artifacts:
     reports:
       codequality: gl-codequality.json
@@ -46,14 +40,14 @@ lint:
 build-container:
   stage: build
   image: docker:latest
-  needs:
-    - job: install-dependencies
-      artifacts: true
   before_script:
     - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
   script:
     - docker build -t $CONTAINER_IMAGE --build-arg REACT_APP_MUI_PRO_LICENSE_KEY=${REACT_APP_MUI_PRO_LICENSE_KEY} .
     - docker push $CONTAINER_IMAGE
+  needs:
+    - job: install-dependencies
+      artifacts: true
 
 build-storybook:
   stage: build
@@ -66,20 +60,30 @@ build-storybook:
     paths:
       - storybook-static
 
-test-components-chrome:
+.test-components:
   stage: test
   image: cypress/browsers:node16.14.0-slim-chrome99-ff97
   script:
-    - CHOKIDAR_USEPOLLING=true WATCHPACK_POLLING=true npx cypress run --component --browser chrome
-  needs:
-    - job: install-dependencies
-      artifacts: true
+    - npm ci
+    - npm start &
+    - CHOKIDAR_USEPOLLING=true WATCHPACK_POLLING=true npx cypress run --component --browser ${BROWSER}
+  needs: []  # no requirements since it does an install
   artifacts:
     when: on_failure
     paths:
       - cypress/videos
       - cypress/screenshots
 
+test-components-chrome:
+  extends: .test-components
+  variables:
+    BROWSER: chrome
+
+test-components-firefox:
+  extends: .test-components
+  variables:
+    BROWSER: firefox
+
 .deploy:
   stage: deploy
   image: registry.esss.lu.se/ics-docker/awxkit