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 cee7c90..02934cc 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 6e34c8a..3d13d3f 100644 --- a/composer.json +++ b/composer.json @@ -21,6 +21,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/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 7a47b79..c24807a 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 @@ - - - - - - - - - + + + + + + + + + + + + diff --git a/resources/js/Pages/Login.vue b/resources/js/Pages/Login.vue index 66b0f0f..e3ba099 100644 --- a/resources/js/Pages/Login.vue +++ b/resources/js/Pages/Login.vue @@ -38,6 +38,7 @@
Open user menu user = User::factory()->create(); + } + + public function testUserCanLogout(): void + { + $this->browse(function (Browser $browser): void { + $browser->loginAs($this->user) + ->visit(new HomePage()) + ->assertVisible("@user-menu") + ->click("@user-menu") + ->assertVisible("@user-menu-list") + ->assertSee("Sign out") + ->press("Sign out") + ->on(new HomePage()) + ->waitFor("@login-link"); + }); + } +} diff --git a/tests/Browser/Pages/HomePage.php b/tests/Browser/Pages/HomePage.php new file mode 100644 index 0000000..8e12114 --- /dev/null +++ b/tests/Browser/Pages/HomePage.php @@ -0,0 +1,20 @@ +assertPathIs($this->url()); + } +} diff --git a/tests/Browser/Pages/Page.php b/tests/Browser/Pages/Page.php new file mode 100644 index 0000000..954c185 --- /dev/null +++ b/tests/Browser/Pages/Page.php @@ -0,0 +1,17 @@ + "#selector", + ]; + } +} diff --git a/tests/DuskTestCase.php b/tests/DuskTestCase.php new file mode 100644 index 0000000..baaee44 --- /dev/null +++ b/tests/DuskTestCase.php @@ -0,0 +1,65 @@ +addArguments( + collect( + [ + "--window-size=1920,1080", + ], + )->unless( + $this->hasHeadlessDisabled(), + function ($items) { + return $items->merge( + [ + "--disable-gpu", + "--headless", + ], + ); + }, + )->all(), + ); + + return RemoteWebDriver::create( + env("DUSK_DRIVER_URL") ?? "http://localhost:" . env("SELENIUM_PORT"), + DesiredCapabilities::chrome()->setCapability( + ChromeOptions::CAPABILITY, + $options, + ), + ); + } + + protected function hasHeadlessDisabled(): bool + { + return isset($_SERVER["DUSK_HEADLESS_DISABLED"]) || + isset($_ENV["DUSK_HEADLESS_DISABLED"]); + } + + protected static function runningInDocker(): bool + { + return isset($_ENV["DUSK_IN_DOCKER"]) && $_ENV["DUSK_IN_DOCKER"] === "true"; + } +}