diff --git a/.env.ci b/.env.ci
new file mode 100644
index 0000000..dd6472b
--- /dev/null
+++ b/.env.ci
@@ -0,0 +1,23 @@
+APP_NAME=Laravel
+APP_ENV=testing
+APP_KEY=base64:4Hjdxw6l/vsqukgRVRk5YwKHNJfX9N+44dJdnDesrcc=
+APP_DEBUG=false
+APP_URL=http://127.0.0.1
+
+LOG_CHANNEL=stack
+LOG_LEVEL=debug
+
+DB_CONNECTION=mysql
+DB_HOST=127.0.0.1
+DB_PORT=3306
+DB_DATABASE=toby
+DB_USERNAME=toby
+DB_PASSWORD=password
+
+BROADCAST_DRIVER=log
+CACHE_DRIVER=array
+QUEUE_CONNECTION=sync
+SESSION_DRIVER=array
+SESSION_LIFETIME=120
+FILESYSTEM_DRIVER=local
+MAIL_MAILER=array
diff --git a/.env.dusk.local b/.env.dusk.local
new file mode 100644
index 0000000..c68513c
--- /dev/null
+++ b/.env.dusk.local
@@ -0,0 +1,28 @@
+APP_NAME=Laravel
+APP_ENV=testing
+APP_KEY=base64:uuizKfYGhrBB+ecWuxg570hdUgKwZ1sqEgHPngW15Xw=
+APP_DEBUG=false
+APP_URL=http://toby-web
+
+DUSK_IN_DOCKER=true
+DUSK_DRIVER_URL=http://toby-selenium:4444/wd/hub
+
+LOG_CHANNEL=stack
+LOG_LEVEL=debug
+
+DB_CONNECTION=mysql
+DB_HOST=toby-db-test
+DB_PORT=3306
+DB_DATABASE=toby
+DB_USERNAME=toby
+DB_PASSWORD=password
+
+BROADCAST_DRIVER=log
+CACHE_DRIVER=array
+QUEUE_CONNECTION=sync
+SESSION_DRIVER=file
+SESSION_LIFETIME=120
+FILESYSTEM_DRIVER=local
+MAIL_MAILER=array
+
+TELESCOPE_ENABLED=false
diff --git a/.env.example b/.env.example
index 30e2550..b4d8f7a 100644
--- a/.env.example
+++ b/.env.example
@@ -8,18 +8,24 @@ LOG_CHANNEL=stack
 LOG_LEVEL=debug
 
 DB_CONNECTION=mysql
-DB_HOST=toby-db
+DB_HOST=toby-db-dev
 DB_PORT=3306
 DB_DATABASE=toby
 DB_USERNAME=toby
 DB_PASSWORD=password
 DB_ROOT_PASSWORD=example
 
-DOCKER_DB_EXTERNAL_PORT=3306
-DOCKER_DB_DATABASE=${DB_DATABASE}
-DOCKER_DB_USERNAME=${DB_USERNAME}
-DOCKER_DB_PASSWORD=${DB_PASSWORD}
-DOCKER_DB_ROOT_PASSWORD=${DB_ROOT_PASSWORD}
+DOCKER_DEV_DB_EXTERNAL_PORT=3306
+DOCKER_DEV_DB_DATABASE=${DB_DATABASE}
+DOCKER_DEV_DB_USERNAME=${DB_USERNAME}
+DOCKER_DEV_DB_PASSWORD=${DB_PASSWORD}
+DOCKER_DEV_DB_ROOT_PASSWORD=${DB_ROOT_PASSWORD}
+
+DOCKER_TEST_DB_EXTERNAL_PORT=3307
+DOCKER_TEST_DB_DATABASE=${DB_DATABASE}
+DOCKER_TEST_DB_USERNAME=${DB_USERNAME}
+DOCKER_TEST_DB_PASSWORD=${DB_PASSWORD}
+DOCKER_TEST_DB_ROOT_PASSWORD=${DB_ROOT_PASSWORD}
 
 EXTERNAL_WEBSERVER_PORT=
 XDG_CONFIG_HOME=/tmp
diff --git a/.github/workflows/test-and-lint-php.yml b/.github/workflows/test-and-lint-php.yml
index 430fdf6..d287df0 100644
--- a/.github/workflows/test-and-lint-php.yml
+++ b/.github/workflows/test-and-lint-php.yml
@@ -10,6 +10,16 @@ jobs:
   test-and-lint-php:
     name: Test & lint PHP stuff
     runs-on: ubuntu-20.04
+    services:
+      mysql:
+        image: mysql:8.0
+        env:
+          MYSQL_DATABASE: toby
+          MYSQL_USER: toby
+          MYSQL_PASSWORD: password
+          MYSQL_ALLOW_EMPTY_PASSWORD: 1
+        ports:
+          - 3306:3306
 
     steps:
       - uses: actions/checkout@v2
diff --git a/composer.json b/composer.json
index 83abbee..d597c15 100644
--- a/composer.json
+++ b/composer.json
@@ -20,6 +20,7 @@
         "enlightn/enlightn": "^1.22",
         "facade/ignition": "^2.5",
         "fakerphp/faker": "^1.9.1",
+        "laravel/dusk": "^6.21",
         "mockery/mockery": "^1.4.4",
         "nunomaduro/collision": "^5.10",
         "phpunit/phpunit": "^9.5.10"
diff --git a/composer.lock b/composer.lock
index e9f029f..f58b160 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
         "This file is @generated automatically"
     ],
-    "content-hash": "6c0c7586f9003a71d9299165b3d5030d",
+    "content-hash": "f5d5c19c36f856c3d336c36a43aa23e4",
     "packages": [
         {
             "name": "asm89/stack-cors",
@@ -6864,6 +6864,79 @@
             },
             "time": "2021-07-22T09:24:00+00:00"
         },
+        {
+            "name": "laravel/dusk",
+            "version": "v6.21.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/laravel/dusk.git",
+                "reference": "45c1005ec73ab46504a666b6b52dddf1108b3eb4"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/laravel/dusk/zipball/45c1005ec73ab46504a666b6b52dddf1108b3eb4",
+                "reference": "45c1005ec73ab46504a666b6b52dddf1108b3eb4",
+                "shasum": ""
+            },
+            "require": {
+                "ext-json": "*",
+                "ext-zip": "*",
+                "illuminate/console": "^6.0|^7.0|^8.0|^9.0",
+                "illuminate/support": "^6.0|^7.0|^8.0|^9.0",
+                "nesbot/carbon": "^2.0",
+                "php": "^7.2|^8.0",
+                "php-webdriver/webdriver": "^1.9.0",
+                "symfony/console": "^4.3|^5.0|^6.0",
+                "symfony/finder": "^4.3|^5.0|^6.0",
+                "symfony/process": "^4.3|^5.0|^6.0",
+                "vlucas/phpdotenv": "^3.0|^4.0|^5.2"
+            },
+            "require-dev": {
+                "mockery/mockery": "^1.0",
+                "orchestra/testbench": "^4.16|^5.17.1|^6.12.1|^7.0",
+                "phpunit/phpunit": "^7.5.15|^8.4|^9.0"
+            },
+            "suggest": {
+                "ext-pcntl": "Used to gracefully terminate Dusk when tests are running."
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "6.x-dev"
+                },
+                "laravel": {
+                    "providers": [
+                        "Laravel\\Dusk\\DuskServiceProvider"
+                    ]
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Laravel\\Dusk\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Taylor Otwell",
+                    "email": "taylor@laravel.com"
+                }
+            ],
+            "description": "Laravel Dusk provides simple end-to-end testing and browser automation.",
+            "keywords": [
+                "laravel",
+                "testing",
+                "webdriver"
+            ],
+            "support": {
+                "issues": "https://github.com/laravel/dusk/issues",
+                "source": "https://github.com/laravel/dusk/tree/v6.21.0"
+            },
+            "time": "2022-01-12T18:00:01+00:00"
+        },
         {
             "name": "mockery/mockery",
             "version": "1.4.4",
@@ -7290,6 +7363,71 @@
             },
             "time": "2021-02-23T14:00:09+00:00"
         },
+        {
+            "name": "php-webdriver/webdriver",
+            "version": "1.12.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/php-webdriver/php-webdriver.git",
+                "reference": "99d4856ed7dffcdf6a52eccd6551e83d8d557ceb"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/php-webdriver/php-webdriver/zipball/99d4856ed7dffcdf6a52eccd6551e83d8d557ceb",
+                "reference": "99d4856ed7dffcdf6a52eccd6551e83d8d557ceb",
+                "shasum": ""
+            },
+            "require": {
+                "ext-curl": "*",
+                "ext-json": "*",
+                "ext-zip": "*",
+                "php": "^5.6 || ~7.0 || ^8.0",
+                "symfony/polyfill-mbstring": "^1.12",
+                "symfony/process": "^2.8 || ^3.1 || ^4.0 || ^5.0 || ^6.0"
+            },
+            "replace": {
+                "facebook/webdriver": "*"
+            },
+            "require-dev": {
+                "ondram/ci-detector": "^2.1 || ^3.5 || ^4.0",
+                "php-coveralls/php-coveralls": "^2.4",
+                "php-mock/php-mock-phpunit": "^1.1 || ^2.0",
+                "php-parallel-lint/php-parallel-lint": "^1.2",
+                "phpunit/phpunit": "^5.7 || ^7 || ^8 || ^9",
+                "squizlabs/php_codesniffer": "^3.5",
+                "symfony/var-dumper": "^3.3 || ^4.0 || ^5.0 || ^6.0"
+            },
+            "suggest": {
+                "ext-SimpleXML": "For Firefox profile creation"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Facebook\\WebDriver\\": "lib/"
+                },
+                "files": [
+                    "lib/Exception/TimeoutException.php"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "description": "A PHP client for Selenium WebDriver. Previously facebook/webdriver.",
+            "homepage": "https://github.com/php-webdriver/php-webdriver",
+            "keywords": [
+                "Chromedriver",
+                "geckodriver",
+                "php",
+                "selenium",
+                "webdriver"
+            ],
+            "support": {
+                "issues": "https://github.com/php-webdriver/php-webdriver/issues",
+                "source": "https://github.com/php-webdriver/php-webdriver/tree/1.12.0"
+            },
+            "time": "2021-10-14T09:30:02+00:00"
+        },
         {
             "name": "phpdocumentor/reflection-common",
             "version": "2.2.0",
diff --git a/config/database.php b/config/database.php
index 6408789..c3831fc 100644
--- a/config/database.php
+++ b/config/database.php
@@ -5,11 +5,6 @@ declare(strict_types=1);
 return [
     "default" => env("DB_CONNECTION", "mysql"),
     "connections" => [
-        "testing" => [
-            "driver" => "sqlite",
-            "database" => ":memory:",
-            "prefix" => "",
-        ],
         "mysql" => [
             "driver" => "mysql",
             "url" => env("DATABASE_URL"),
diff --git a/docker-compose.yml b/docker-compose.yml
index 851001f..e649c7a 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -36,12 +36,12 @@ services:
 
   database:
     image: mysql:8.0
-    container_name: toby-db
+    container_name: toby-db-dev
     environment:
-      - MYSQL_ROOT_PASSWORD=${DOCKER_DB_ROOT_PASSWORD}
-      - MYSQL_DATABASE=${DOCKER_DB_DATABASE}
-      - MYSQL_USER=${DOCKER_DB_USERNAME}
-      - MYSQL_PASSWORD=${DOCKER_DB_PASSWORD}
+      - MYSQL_ROOT_PASSWORD=${DOCKER_DEV_DB_ROOT_PASSWORD}
+      - MYSQL_DATABASE=${DOCKER_DEV_DB_DATABASE}
+      - MYSQL_USER=${DOCKER_DEV_DB_USERNAME}
+      - MYSQL_PASSWORD=${DOCKER_DEV_DB_PASSWORD}
     ports:
       - ${DOCKER_DB_EXTERNAL_PORT:-3306}:3306
     volumes:
@@ -50,6 +50,20 @@ services:
       - toby-dev
     restart: unless-stopped
 
+  database-test:
+    image: mysql:8.0
+    container_name: toby-db-test
+    environment:
+      - MYSQL_ROOT_PASSWORD=${DOCKER_TEST_DB_ROOT_PASSWORD}
+      - MYSQL_DATABASE=${DOCKER_TEST_DB_DATABASE}
+      - MYSQL_USER=${DOCKER_TEST_DB_USERNAME}
+      - MYSQL_PASSWORD=${DOCKER_TEST_DB_PASSWORD}
+    ports:
+      - ${DOCKER_TEST_DB_EXTERNAL_PORT:-3307}:3306
+    networks:
+      - toby-dev
+    restart: unless-stopped
+
   node:
     image: node:17.2.0-alpine3.14
     container_name: toby-node
@@ -70,6 +84,14 @@ services:
       - toby-dev
     restart: unless-stopped
 
+  selenium:
+    image: selenium/standalone-chrome
+    container_name: toby-selenium
+    volumes:
+      - /dev/shm:/dev/shm
+    networks:
+      - toby-dev
+
 networks:
   toby-dev:
     driver: bridge
diff --git a/package-lock.json b/package-lock.json
index f5d5036..8cb4e0f 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,5 +1,5 @@
 {
-    "name": "toby",
+    "name": "application",
     "lockfileVersion": 2,
     "requires": true,
     "packages": {
diff --git a/phpunit.xml b/phpunit.xml
index c4a1bad..c1b2a5c 100644
--- a/phpunit.xml
+++ b/phpunit.xml
@@ -19,14 +19,17 @@