diff --git a/pom.xml b/pom.xml
index 24ae19c68503e128e80a0d595dc0a33ef4a01252..8033128a6c70fc972cafef5b87f9d321120fd1f5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -63,6 +63,8 @@
         <materializecss.version>1.0.0</materializecss.version>
         <fontawesome.version>5.0.10</fontawesome.version>
         <sortablejs.version>1.8.1</sortablejs.version>
+        <webdrivermanager.version>2.2.1</webdrivermanager.version>
+        <selenium.version>3.141.59</selenium.version>
 
         <app.versionDate>${maven.build.timestamp}</app.versionDate>
         <maven.build.timestamp.format>dd.MM.yy</maven.build.timestamp.format>
@@ -181,6 +183,24 @@
             <artifactId>sortablejs</artifactId>
             <version>${sortablejs.version}</version>
         </dependency>
+        <dependency>
+            <groupId>io.github.bonigarcia</groupId>
+            <artifactId>webdrivermanager</artifactId>
+            <version>${webdrivermanager.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.seleniumhq.selenium</groupId>
+            <artifactId>selenium-api</artifactId>
+            <version>${selenium.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.seleniumhq.selenium</groupId>
+            <artifactId>selenium-firefox-driver</artifactId>
+            <version>${selenium.version}</version>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
     <build>
diff --git a/src/test/java/de/deadlocker8/budgetmaster/integration/IntegrationTestHelper.java b/src/test/java/de/deadlocker8/budgetmaster/integration/IntegrationTestHelper.java
new file mode 100644
index 0000000000000000000000000000000000000000..61b74c81ec16f3a147d59806bf0e39aea72517a6
--- /dev/null
+++ b/src/test/java/de/deadlocker8/budgetmaster/integration/IntegrationTestHelper.java
@@ -0,0 +1,20 @@
+package de.deadlocker8.budgetmaster.integration;
+
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebElement;
+
+import java.util.List;
+
+public class IntegrationTestHelper
+{
+	public static String getTextNode(WebElement e)
+	{
+		String text = e.getText().trim();
+		List<WebElement> children = e.findElements(By.xpath("./*"));
+		for(WebElement child : children)
+		{
+			text = text.replaceFirst(child.getText(), "").trim();
+		}
+		return text;
+	}
+}
diff --git a/src/test/java/de/deadlocker8/budgetmaster/integration/LoginControllerTest.java b/src/test/java/de/deadlocker8/budgetmaster/integration/LoginControllerTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..667368b40ce640550de691d7316a245ade406e38
--- /dev/null
+++ b/src/test/java/de/deadlocker8/budgetmaster/integration/LoginControllerTest.java
@@ -0,0 +1,50 @@
+package de.deadlocker8.budgetmaster.integration;
+
+import io.github.bonigarcia.wdm.WebDriverManager;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.firefox.FirefoxDriver;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
+public class LoginControllerTest
+{
+	private WebDriver driver;
+
+	@Before
+	public void before()
+	{
+		WebDriverManager.firefoxdriver().setup();
+		driver = new FirefoxDriver();
+	}
+
+	@Test
+	public void getSearchPage()
+	{
+		driver.get("https://localhost:9000");
+		WebElement input = driver.findElement(By.id("login-password"));
+		assertNotNull(input);
+
+		WebElement label = driver.findElement(By.cssSelector(".input-field label"));
+		assertEquals("Password", label.getText());
+
+		WebElement button = driver.findElement(By.tagName("button"));
+		assertEquals("Login", IntegrationTestHelper.getTextNode(button));
+	}
+
+	@After
+	public void closeBrowser()
+	{
+		driver.close();
+	}
+}
\ No newline at end of file
diff --git a/src/test/java/de/deadlocker8/budgetmaster/TransactionRepositoryTest.java b/src/test/java/de/deadlocker8/budgetmaster/unit/TransactionRepositoryTest.java
similarity index 99%
rename from src/test/java/de/deadlocker8/budgetmaster/TransactionRepositoryTest.java
rename to src/test/java/de/deadlocker8/budgetmaster/unit/TransactionRepositoryTest.java
index 2328d7c93fdc739e84d0938917b7566522cf2c3d..c4a7ac951036198513861d5b915aa783ff7842c0 100644
--- a/src/test/java/de/deadlocker8/budgetmaster/TransactionRepositoryTest.java
+++ b/src/test/java/de/deadlocker8/budgetmaster/unit/TransactionRepositoryTest.java
@@ -1,4 +1,4 @@
-package de.deadlocker8.budgetmaster;
+package de.deadlocker8.budgetmaster.unit;
 
 import de.deadlocker8.budgetmaster.accounts.AccountRepository;
 import de.deadlocker8.budgetmaster.categories.CategoryRepository;
diff --git a/src/test/java/de/deadlocker8/budgetmaster/database/DatabaseImportTest.java b/src/test/java/de/deadlocker8/budgetmaster/unit/database/DatabaseImportTest.java
similarity index 99%
rename from src/test/java/de/deadlocker8/budgetmaster/database/DatabaseImportTest.java
rename to src/test/java/de/deadlocker8/budgetmaster/unit/database/DatabaseImportTest.java
index b8b8b9fb458ed95be1178102b67491e69a046dc3..16a39b39706931f10d825d0b1e61d832a9f27146 100644
--- a/src/test/java/de/deadlocker8/budgetmaster/database/DatabaseImportTest.java
+++ b/src/test/java/de/deadlocker8/budgetmaster/unit/database/DatabaseImportTest.java
@@ -1,4 +1,4 @@
-package de.deadlocker8.budgetmaster.database;
+package de.deadlocker8.budgetmaster.unit.database;
 
 import de.deadlocker8.budgetmaster.accounts.Account;
 import de.deadlocker8.budgetmaster.accounts.AccountType;
diff --git a/src/test/java/de/deadlocker8/budgetmaster/database/DatabaseParser_v3Test.java b/src/test/java/de/deadlocker8/budgetmaster/unit/database/DatabaseParser_v3Test.java
similarity index 97%
rename from src/test/java/de/deadlocker8/budgetmaster/database/DatabaseParser_v3Test.java
rename to src/test/java/de/deadlocker8/budgetmaster/unit/database/DatabaseParser_v3Test.java
index bc2537e99175e31dc0865f1d90b8f63fb71c33e2..21062266c859f706a50134a2352e2cd775458bbc 100644
--- a/src/test/java/de/deadlocker8/budgetmaster/database/DatabaseParser_v3Test.java
+++ b/src/test/java/de/deadlocker8/budgetmaster/unit/database/DatabaseParser_v3Test.java
@@ -1,9 +1,11 @@
-package de.deadlocker8.budgetmaster.database;
+package de.deadlocker8.budgetmaster.unit.database;
 
 import de.deadlocker8.budgetmaster.accounts.Account;
 import de.deadlocker8.budgetmaster.accounts.AccountType;
 import de.deadlocker8.budgetmaster.categories.Category;
 import de.deadlocker8.budgetmaster.categories.CategoryType;
+import de.deadlocker8.budgetmaster.database.Database;
+import de.deadlocker8.budgetmaster.database.DatabaseParser_v3;
 import de.deadlocker8.budgetmaster.tags.Tag;
 import de.deadlocker8.budgetmaster.transactions.Transaction;
 import de.deadlocker8.budgetmaster.repeating.RepeatingOption;
diff --git a/src/test/java/de/deadlocker8/budgetmaster/database/LegacyParserTest.java b/src/test/java/de/deadlocker8/budgetmaster/unit/database/LegacyParserTest.java
similarity index 98%
rename from src/test/java/de/deadlocker8/budgetmaster/database/LegacyParserTest.java
rename to src/test/java/de/deadlocker8/budgetmaster/unit/database/LegacyParserTest.java
index cd2dee4081febf921d62899fcd30856e9adb347e..6a9027c1ea5694146dc074f4cb639ebd0e462f7e 100644
--- a/src/test/java/de/deadlocker8/budgetmaster/database/LegacyParserTest.java
+++ b/src/test/java/de/deadlocker8/budgetmaster/unit/database/LegacyParserTest.java
@@ -1,17 +1,18 @@
-package de.deadlocker8.budgetmaster.database;
+package de.deadlocker8.budgetmaster.unit.database;
 
-import de.deadlocker8.budgetmaster.database.legacy.LegacyParser;
 import de.deadlocker8.budgetmaster.accounts.Account;
 import de.deadlocker8.budgetmaster.accounts.AccountType;
 import de.deadlocker8.budgetmaster.categories.Category;
 import de.deadlocker8.budgetmaster.categories.CategoryType;
-import de.deadlocker8.budgetmaster.tags.Tag;
-import de.deadlocker8.budgetmaster.transactions.Transaction;
+import de.deadlocker8.budgetmaster.database.Database;
+import de.deadlocker8.budgetmaster.database.legacy.LegacyParser;
 import de.deadlocker8.budgetmaster.repeating.RepeatingOption;
 import de.deadlocker8.budgetmaster.repeating.endoption.RepeatingEndDate;
 import de.deadlocker8.budgetmaster.repeating.endoption.RepeatingEndNever;
 import de.deadlocker8.budgetmaster.repeating.modifier.RepeatingModifierDays;
 import de.deadlocker8.budgetmaster.repeating.modifier.RepeatingModifierMonths;
+import de.deadlocker8.budgetmaster.tags.Tag;
+import de.deadlocker8.budgetmaster.transactions.Transaction;
 import org.joda.time.DateTime;
 import org.joda.time.format.DateTimeFormat;
 import org.junit.Test;
diff --git a/src/test/java/de/deadlocker8/budgetmaster/repeating/RepeatingOptionTest.java b/src/test/java/de/deadlocker8/budgetmaster/unit/repeating/RepeatingOptionTest.java
similarity index 98%
rename from src/test/java/de/deadlocker8/budgetmaster/repeating/RepeatingOptionTest.java
rename to src/test/java/de/deadlocker8/budgetmaster/unit/repeating/RepeatingOptionTest.java
index 10ea6eb128920e1741a676852cc42cc2f92070f0..5513c067b71363c6449977956d7e8e52a31cf95f 100644
--- a/src/test/java/de/deadlocker8/budgetmaster/repeating/RepeatingOptionTest.java
+++ b/src/test/java/de/deadlocker8/budgetmaster/unit/repeating/RepeatingOptionTest.java
@@ -1,5 +1,6 @@
-package de.deadlocker8.budgetmaster.repeating;
+package de.deadlocker8.budgetmaster.unit.repeating;
 
+import de.deadlocker8.budgetmaster.repeating.RepeatingOption;
 import de.deadlocker8.budgetmaster.repeating.endoption.RepeatingEndAfterXTimes;
 import de.deadlocker8.budgetmaster.repeating.endoption.RepeatingEndDate;
 import de.deadlocker8.budgetmaster.repeating.endoption.RepeatingEndNever;