diff --git a/bin/build b/bin/build
index 9e7b287fb7d04d95af9ebf9b91e3f011672fb4df..5bc52d532c6b7b2ccbcb836029522cb839bac5e7 100755
--- a/bin/build
+++ b/bin/build
@@ -18,11 +18,15 @@ version() {
 }
 
 frontend() {
+    if [ -z ${WEBPACK_OPTS+x} ]; then
+        WEBPACK_OPTS="-p"
+    fi
+
     echo "Running 'npm install' to download javascript dependencies..." &&
     npm install &&
 
-    echo "Running 'webpack -p' to assemble and minify frontend assets..." &&
-    ./node_modules/webpack/bin/webpack.js -p
+    echo "Running 'webpack $WEBPACK_OPTS' to assemble and minify frontend assets..." &&
+    ./node_modules/.bin/webpack $WEBPACK_OPTS
 }
 
 sample-dataset() {
diff --git a/frontend/test/e2e/auth/login.spec.js b/frontend/test/e2e/auth/login.spec.js
index 6840d4826da82c1cb5375c695329d1563701aa58..2759f3d07913c9a9ff3d31afff0546c62c6ac3da 100644
--- a/frontend/test/e2e/auth/login.spec.js
+++ b/frontend/test/e2e/auth/login.spec.js
@@ -1,30 +1,74 @@
-import { startServer, stopServer, isReady } from "../support/start-server";
+import { startServer, isReady } from "../support/start-server";
 import webdriver, { By, until } from "selenium-webdriver";
 
 jasmine.DEFAULT_TIMEOUT_INTERVAL = 60000;
 
+async function loginMetabase(driver, username, password) {
+    await driver.wait(until.elementLocated(By.css("[name=email]")));
+    await driver.findElement(By.css("[name=email]")).sendKeys(username);
+    await driver.findElement(By.css("[name=password]")).sendKeys(password);
+    await driver.manage().timeouts().implicitlyWait(1000);
+    await driver.findElement(By.css(".Button.Button--primary")).click();
+}
+
+function waitForUrl(driver, url, timeout = 5000) {
+    return driver.wait(async () => await driver.getCurrentUrl() === url, timeout);
+}
+
 describe("auth/login", () => {
-    let host, driver;
+    let server, driver;
 
     beforeAll(async () => {
-        host = await startServer("metabase");
+        server = await startServer("frontend/test/e2e/support/fixtures/setup.db");
         driver = new webdriver.Builder()
             .forBrowser('chrome')
             .build();
-        await driver.navigate().to(`${host}/`);
     });
 
-    it("should start", async () => {
-        expect(await isReady(host)).toEqual(true);
+    it ("should start", async () => {
+        expect(await isReady(server.host)).toEqual(true);
+    });
+
+    describe("has no cookie", () => {
+        beforeEach(async () => {
+            await driver.get(`${server.host}/`);
+            await driver.manage().deleteAllCookies();
+        });
+
+        it ("should take you to the login page", async () => {
+            await driver.get(`${server.host}/`);
+            await waitForUrl(driver, `${server.host}/auth/login?redirect=%2F`);
+            expect(await driver.isElementPresent(By.css("[name=email]"))).toEqual(true);
+        });
+
+        it ("should log you in", async () => {
+            await driver.get(`${server.host}/`);
+            await loginMetabase(driver, "bob@metabase.com", "12341234");
+            await waitForUrl(driver, `${server.host}/`);
+        });
+
+        it ("should redirect you after logging in", async () => {
+            await driver.get(`${server.host}/questions`);
+            await waitForUrl(driver, `${server.host}/auth/login?redirect=%2Fquestions`);
+            await loginMetabase(driver, "bob@metabase.com", "12341234");
+            await waitForUrl(driver, `${server.host}/questions`);
+        });
     });
 
-    it("should take you to the login page", async () => {
-        driver.wait(until.elementLocated(By.css("[name=email]")));
-        expect(await driver.isElementPresent(By.css("[name=email]"))).toEqual(true);
+    describe("valid session cookie", () => {
+        beforeEach(async () => {
+            await driver.get(`${server.host}/`);
+            await driver.manage().addCookie("metabase.SESSION_ID", "d65a297d-860b-46b6-a2dd-8f98d37fb2cd");
+        });
+
+        it ("is logged in", async () => {
+            await driver.get(`${server.host}/`);
+            await waitForUrl(driver, `${server.host}/`);
+        });
     });
 
     afterAll(async () => {
-        driver.quit();
-        await stopServer("metabase");
+        await server.stop();
+        await driver.quit();
     });
 });
diff --git a/frontend/test/e2e/support/fixtures/setup.db.h2.db b/frontend/test/e2e/support/fixtures/setup.db.h2.db
new file mode 100644
index 0000000000000000000000000000000000000000..6cda36762c740ce12cbc2047d0fd266b1c99ba19
Binary files /dev/null and b/frontend/test/e2e/support/fixtures/setup.db.h2.db differ
diff --git a/frontend/test/e2e/support/start-server.js b/frontend/test/e2e/support/start-server.js
index 8a29e2c71d43d75f0edde266773e7d231d11ebc0..ad91bf30984d2c8a36fa5d8777226d4bcd72ce40 100644
--- a/frontend/test/e2e/support/start-server.js
+++ b/frontend/test/e2e/support/start-server.js
@@ -1,43 +1,82 @@
+import fs from "fs-promise";
+import os from "os";
+import path from "path";
 import { spawn } from "child_process";
+
 import fetch from 'isomorphic-fetch';
 import { delay } from '../../../src/metabase/lib/promise';
 
+let testDbId = 0;
+const getDbFile = () => path.join(os.tmpdir(), `metabase-test-${process.pid}-${testDbId++}.db`);
+
 let port = 4000;
 const getPort = () => port++;
 
 const servers = new Map();
 
-export async function startServer(dbFile) {
-    if (!servers.has(dbFile)) {
-        const port = getPort();
-        let server = {
-            dbFile: dbFile,
-            port: port,
-            host: `http://localhost:${port}`,
-            process: spawn("java", ["-jar", "target/uberjar/metabase.jar"], {
+class Server {
+    constructor(dbKey, dbFile) {
+        this.dbKey = dbKey;
+        this.dbFile = dbFile;
+
+        this.port = getPort();
+        this.host = `http://localhost:${this.port}`;
+    }
+
+    async start() {
+        if (!this.process) {
+            if (this.dbKey !== this.dbFile) {
+                await fs.copy(`${this.dbKey}.h2.db`, `${this.dbFile}.h2.db`);
+            }
+            this.count = 0;
+            this.process = spawn("java", ["-jar", "target/uberjar/metabase.jar"], {
                 env: {
-                    MB_DB_FILE: dbFile,
-                    MB_JETTY_PORT: port
+                    MB_DB_FILE: this.dbFile,
+                    MB_JETTY_PORT: this.port
                 },
-            }),
-            count: 0
+            })
+            this.process.on("close", () => {
+                this.kill();
+            })
+        }
+        this.count++;
+        return this.wait();
+    }
+
+    async stop() {
+        if (--this.count === 0) {
+            await this.kill();
+        }
+    }
+
+    async wait() {
+        while (!(await isReady(this.host))) {
+            await delay(500);
+        }
+    }
+
+    async kill() {
+        if (servers.has(this.dbKey)) {
+            servers.delete(this.dbKey);
+            this.process.kill('SIGKILL');
+            await fs.unlink(`${this.dbFile}.h2.db`);
         }
-        server.process.on("close", () => {
-            killServer(server);
-        })
-        servers.set(dbFile, server);
     }
-    const server = servers.get(dbFile);
-    server.count++;
-    await wait(server);
-    return server.host;
 }
 
-export async function stopServer(dbFile) {
-    const server = servers.get(dbFile);
-    if (--server.count === 0) {
-        killServer(server);
+export async function startServer(dbKey) {
+    let dbFile = getDbFile();
+    if (!dbKey) {
+        dbKey = dbFile;
     }
+
+    if (!servers.has(dbKey)) {
+        servers.set(dbKey, new Server(dbKey, dbFile));
+    }
+    let server = servers.get(dbKey);
+
+    await server.start();
+    return server;
 }
 
 export async function isReady(host) {
@@ -51,20 +90,8 @@ export async function isReady(host) {
     return false;
 }
 
-async function wait(server) {
-    while (!(await isReady(server.host))) {
-        await delay(500);
-    }
-}
-
-function killServer(server) {
-    console.log("shutting down " + server.dbFile);
-    servers.delete(server.dbFile);
-    server.process.kill();
-}
-
 process.once("exit", () => {
     for (const server of servers) {
-        killServer(server);
+        server.kill();
     }
 });
diff --git a/package.json b/package.json
index 6aa5a0c64e9bea786846d3a5b7111e19ea93bbf0..b9ea6ee1607fe4e1e41e1dcac32f5544c89108fa 100644
--- a/package.json
+++ b/package.json
@@ -87,6 +87,7 @@
     "file-loader": "^0.8.5",
     "flow-bin": "^0.24.2",
     "flow-status-webpack-plugin": "^0.1.4",
+    "fs-promise": "^0.5.0",
     "glob": "^5.0.15",
     "html-webpack-plugin": "^2.14.0",
     "istanbul-instrumenter-loader": "^0.2.0",