diff --git a/Makefile b/Makefile
index 9aa05e461655f1ead6a16d5d8875b289d25d5c98..3b60ef1fcc6ae7a03155ff09074a4957936e26ee 100644
--- a/Makefile
+++ b/Makefile
@@ -30,6 +30,9 @@ install:
 test:
 	DJANGO_SETTINGS_MODULE=grady.settings pytest
 
+teste2e:
+	cd frontend && yarn build && cp dist/index.html ../core/templates && cd .. && python util/format_index.py && python manage.py collectstatic --no-input && HEADLESS_TESTS=$(headless) pytest --ds=grady.settings $(path); git checkout core/templates/index.html
+
 coverage:
 	DJANGO_SETTINGS_MODULE=grady.settings pytest --cov
 	coverage html
diff --git a/frontend/src/components/subscriptions/SubscriptionList.vue b/frontend/src/components/subscriptions/SubscriptionList.vue
index 0edd3ceddf96b1ef97e2aa05b6737157fcac62b0..316b1b0e4c8cfe76618b35b84ea262d7a8576c98 100644
--- a/frontend/src/components/subscriptions/SubscriptionList.vue
+++ b/frontend/src/components/subscriptions/SubscriptionList.vue
@@ -1,5 +1,5 @@
 <template>
-  <v-card>
+  <v-card name='subscription-list'>
     <v-toolbar color="teal" :dense="sidebar">
       <v-toolbar-side-icon><v-icon>assignment</v-icon></v-toolbar-side-icon>
       <v-toolbar-title v-if="showDetail" style="min-width: fit-content;">
diff --git a/functional_tests/test_front_pages.py b/functional_tests/test_front_pages.py
index 5aa9c73c3caefde5114339616122f8df8ef4c012..70e8dc0834a90b1b9744e7cb903f091700aa891f 100644
--- a/functional_tests/test_front_pages.py
+++ b/functional_tests/test_front_pages.py
@@ -1,38 +1,62 @@
-import os
-from typing import Sequence
+import time
 
 from django.test import LiveServerTestCase
 from selenium import webdriver
-from selenium.webdriver.remote.webelement import WebElement
 
-from functional_tests.util import get_frontend_url, login, create_browser
+from core import models
+from core.models import UserAccount
+from functional_tests.util import login, create_browser, extract_hrefs_hashes
 from util import factory_boys as fact
 
-LiveServerTestCase.port = int(os.environ.get('LIVE_SERVER_PORT', 0))
 
-
-class FrontPageTestsTutorReviewer():
-    def __init__(self):
-        self.browser: webdriver.Firefox = None
-
-    def _login(self):
-        login(self.browser, self.live_server_url, self.username, self.password)
-
-    def test_statistics_are_shown(self):
-        self._login()
-        statistcs = self.browser.find_element_by_id('correction-statistics')
-        title = statistcs.find_element_by_class_name('title')
-        self.assertEqual('Statistics', title.text)
-
-
-class FrontPageTestsTutor(LiveServerTestCase, FrontPageTestsTutorReviewer):
+class UntestedParent:
+    class FrontPageTestsTutorReviewer(LiveServerTestCase):
+        browser: webdriver.Firefox = None
+        username = None
+        password = None
+        role = None
+
+        def setUp(self):
+            fact.SubmissionFactory.create_batch(4)
+
+        def _login(self):
+            login(self.browser, self.live_server_url, self.username, self.password)
+
+        def test_statistics_are_shown(self):
+            self._login()
+            statistics = self.browser.find_element_by_id('correction-statistics')
+            title = statistics.find_element_by_class_name('title')
+            self.assertEqual('Statistics', title.text)
+
+        def test_available_tasks_are_shown(self):
+            self._login()
+            tasks = self.browser.find_element_by_name('subscription-list')
+            title = tasks.find_element_by_class_name('v-toolbar__title')
+            self.assertEqual('Tasks', title.text)
+            time.sleep(8)
+            subscription_links = extract_hrefs_hashes(
+                tasks.find_elements_by_tag_name('a')
+            )
+            subscriptions = models.SubmissionSubscription.objects.filter(
+                owner__username=self.username,
+                deactivated=False,
+                feedback_stage=models.SubmissionSubscription.FEEDBACK_CREATION
+            ).exclude(query_type=models.SubmissionSubscription.RANDOM)
+            for sub in subscriptions:
+                self.assertIn(f'/subscription/{sub.pk}', subscription_links)
+
+
+class FrontPageTestsTutor(UntestedParent.FrontPageTestsTutorReviewer):
     def setUp(self):
-        self.live_server_url = get_frontend_url(self.live_server_url)
+        super().setUp()
         self.browser = create_browser()
         self.username = 'tutor'
         self.password = 'p'
-        fact.UserAccountFactory(username=self.username, password=self.password)
-        fact.SubmissionFactory()
+        self.role = UserAccount.TUTOR
+        fact.UserAccountFactory(
+            username=self.username,
+            password=self.password
+        )
 
     def tearDown(self):
         self.browser.quit()
@@ -40,8 +64,9 @@ class FrontPageTestsTutor(LiveServerTestCase, FrontPageTestsTutorReviewer):
     def test_side_bar_contains_correct_items(self):
         self._login()
         drawer = self.browser.find_element_by_class_name('v-navigation-drawer')
-        links = extract_hrefs(drawer.find_elements_by_tag_name('a'))
-        self.assertTrue(all(link in links for link in ['#/home', '#/feedback']))
+        links = extract_hrefs_hashes(drawer.find_elements_by_tag_name('a'))
+        print(links)
+        self.assertTrue(all(link in links for link in ['/home', '/feedback']))
         task_title = drawer.find_element_by_class_name('v-toolbar__title')
         self.assertEqual('Tasks', task_title.text)
         footer = drawer.find_element_by_class_name('sidebar-footer')
@@ -51,13 +76,19 @@ class FrontPageTestsTutor(LiveServerTestCase, FrontPageTestsTutorReviewer):
                          feedback_link.get_attribute('href'))
 
 
-class FrontPageTestsReviewer(LiveServerTestCase, FrontPageTestsTutorReviewer):
+class FrontPageTestsReviewer(UntestedParent.FrontPageTestsTutorReviewer):
     def setUp(self):
-        self.live_server_url = get_frontend_url(self.live_server_url)
+        super().setUp()
+        self.browser = create_browser()
         self.browser = create_browser()
         self.username = 'reviewer'
         self.password = 'p'
-        fact.UserAccountFactory(username=self.username, password=self.password)
+        self.role = UserAccount.REVIEWER
+        fact.UserAccountFactory(
+            username=self.username,
+            password=self.password,
+            role=self.role
+        )
 
     def tearDown(self):
         self.browser.quit()
@@ -65,9 +96,9 @@ class FrontPageTestsReviewer(LiveServerTestCase, FrontPageTestsTutorReviewer):
     def test_side_bar_contains_correct_items(self):
         self._login()
         drawer = self.browser.find_element_by_class_name('v-navigation-drawer')
-        links = extract_hrefs(drawer.find_elements_by_tag_name('a'))
+        links = extract_hrefs_hashes(drawer.find_elements_by_tag_name('a'))
         self.assertTrue(all(link in links for link in
-                            ['#/home', '#/feedback', '#/student-overview', '#/tutor-overview']))
+                            ['/home', '/feedback', '/student-overview', '/tutor-overview']))
         task_title = drawer.find_element_by_class_name('v-toolbar__title')
         self.assertEqual('Tasks', task_title.text)
         footer = drawer.find_element_by_class_name('sidebar-footer')
@@ -75,7 +106,3 @@ class FrontPageTestsReviewer(LiveServerTestCase, FrontPageTestsTutorReviewer):
         self.assertEqual('Give us Feedback!', feedback_link.text)
         self.assertEqual('https://gitlab.gwdg.de/j.michal/grady/issues',
                          feedback_link.get_attribute('href'))
-
-
-def extract_hrefs(web_elements: Sequence[WebElement]):
-    return [el.get_attribute('href') for el in web_elements]
diff --git a/functional_tests/test_login_page.py b/functional_tests/test_login_page.py
index b564cc7627070c6c47ffb36168e162632014756f..21907957aef136fc4d1e216e0f60645b5ad1a7be 100644
--- a/functional_tests/test_login_page.py
+++ b/functional_tests/test_login_page.py
@@ -7,7 +7,6 @@ from selenium.webdriver.common.keys import Keys
 from selenium.webdriver.firefox.options import Options
 
 from core.models import UserAccount
-from functional_tests.util import get_frontend_url
 from util.factories import make_test_data
 
 
@@ -16,7 +15,6 @@ LiveServerTestCase.port = int(os.environ.get('LIVE_SERVER_PORT', 0))
 
 class LoginPageTest(LiveServerTestCase):
     def setUp(self):
-        self.live_server_url = get_frontend_url(self.live_server_url)
         options = Options()
         # funnily the method is marked deprecated but the alternative setter is not working...
         options.headless = bool(os.environ.get('HEADLESS_TESTS', False))
@@ -134,4 +132,3 @@ class LoginPageTest(LiveServerTestCase):
         tutor = UserAccount.objects.get(username=username)
         self.assertEqual(UserAccount.TUTOR, tutor.role)
         self.assertFalse(tutor.is_active, "Tutors should be inactive after registered")
-
diff --git a/functional_tests/util.py b/functional_tests/util.py
index 178ddd2596e1e51a82ea771b88f059b37ba489ea..c1ffba6f90c4a69fa92446446a6fecfd6294fe34 100644
--- a/functional_tests/util.py
+++ b/functional_tests/util.py
@@ -1,13 +1,12 @@
 import os
 import time
+from itertools import islice
+from typing import Sequence
 
 from selenium import webdriver
 from selenium.webdriver.common.keys import Keys
 from selenium.webdriver.firefox.options import Options
-
-
-def get_frontend_url(live_server_url):
-    return os.environ.get('FRONTEND_URL', live_server_url)
+from selenium.webdriver.remote.webelement import WebElement
 
 
 def create_browser():
@@ -26,3 +25,13 @@ def login(browser, live_server_url, username, password='p'):
     password_input.send_keys(password)
     browser.find_element_by_xpath('//button[@type="submit"]').send_keys(Keys.ENTER)
     time.sleep(1)
+
+
+def nth(iterable, n, default=None):
+    "Returns the nth item or a default value"
+    return next(islice(iterable, n, None), default)
+
+
+def extract_hrefs_hashes(web_elements: Sequence[WebElement]):
+    return [nth(el.get_attribute('href').split('#'), 1, '')
+            for el in web_elements if el.get_attribute('href')]
diff --git a/util/factory_boys.py b/util/factory_boys.py
index 38d21ed3924b62722ae4c3b4d504440f517cae23..4de7d9edabbbc291a926c2903a40b3fb41406c25 100644
--- a/util/factory_boys.py
+++ b/util/factory_boys.py
@@ -10,6 +10,8 @@ fake.seed(42)
 class ExamTypeFactory(DjangoModelFactory):
     class Meta:
         model = models.ExamType
+        django_get_or_create = ('module_reference',)
+
     module_reference = 'B.Inf.4242 Test Module'
     total_score = 90
     pass_score = 45
@@ -29,11 +31,12 @@ class SubmissionTypeFactory(DjangoModelFactory):
 class UserAccountFactory(DjangoModelFactory):
     class Meta:
         model = models.UserAccount
+        django_get_or_create = ('username',)
 
-    role = models.UserAccount.REVIEWER
-    fullname = fake.name()
-    username = fake.user_name()
-    password = factory.PostGenerationMethodCall('set_password', 'p')
+    role = models.UserAccount.TUTOR
+    fullname = fake.name
+    username = fake.user_name
+    password = factory.PostGenerationMethodCall('set_password', 'redrum-is-murder-reversed')
 
 
 class StudentInfoFactory(DjangoModelFactory):
@@ -49,7 +52,7 @@ class TestFactory(DjangoModelFactory):
         model = models.Test
 
     name = 'EmptyTest'
-    label = 'Epmty'
+    label = 'Empty'
     annotation = 'This is an annotation'