From c9b5c220e9f677291ddce3e49b57b5e031109a17 Mon Sep 17 00:00:00 2001 From: EwelinaLasowy Date: Fri, 14 Jan 2022 13:44:14 +0100 Subject: [PATCH] #17 - set up Laravel Dusk --- .env.dusk.local | 28 ++++++ .env.example | 18 ++-- composer.json | 1 + composer.lock | 140 ++++++++++++++++++++++++++- config/database.php | 5 - docker-compose.yml | 32 +++++- package-lock.json | 2 +- phpunit.xml | 7 +- resources/js/Pages/Login.vue | 1 + resources/js/Shared/MainMenu.vue | 2 + tests/Browser/AuthenticationTest.php | 35 +++++++ tests/Browser/Pages/HomePage.php | 41 ++++++++ tests/Browser/Pages/Page.php | 20 ++++ tests/DuskTestCase.php | 65 +++++++++++++ 14 files changed, 377 insertions(+), 20 deletions(-) create mode 100644 .env.dusk.local create mode 100644 tests/Browser/AuthenticationTest.php create mode 100644 tests/Browser/Pages/HomePage.php create mode 100644 tests/Browser/Pages/Page.php create mode 100644 tests/DuskTestCase.php diff --git a/.env.dusk.local b/.env.dusk.local new file mode 100644 index 0000000..9055004 --- /dev/null +++ b/.env.dusk.local @@ -0,0 +1,28 @@ +APP_NAME=Laravel +APP_ENV=testing +APP_KEY=base64:uuizKfYGhrBB+ecWuxg570hdUgKwZ1sqEgHPngW15Xw= +APP_URL=http://toby-web +APP_DEBUG=false + +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/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..acee22b 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -22,8 +22,11 @@ - - + + + + + diff --git a/resources/js/Pages/Login.vue b/resources/js/Pages/Login.vue index 66b0f0f..7bef9d2 100644 --- a/resources/js/Pages/Login.vue +++ b/resources/js/Pages/Login.vue @@ -47,6 +47,7 @@ Zaloguj się za pomocą Google Open user menu user = User::factory()->create(); + } + + public function testUserCanLogout() + { + $this->browse(function (Browser $browser) { + $browser->loginAs($this->user) + ->visit("/") + ->assertVisible("@user-menu") + ->click("@user-menu") + ->assertVisible("@user-menu-list") + ->assertSee("Sign out") + ->press("Sign out") + ->assertPathIs("/"); + }); + } +} diff --git a/tests/Browser/Pages/HomePage.php b/tests/Browser/Pages/HomePage.php new file mode 100644 index 0000000..26bf174 --- /dev/null +++ b/tests/Browser/Pages/HomePage.php @@ -0,0 +1,41 @@ + '#selector', + ]; + } +} diff --git a/tests/Browser/Pages/Page.php b/tests/Browser/Pages/Page.php new file mode 100644 index 0000000..f8d7622 --- /dev/null +++ b/tests/Browser/Pages/Page.php @@ -0,0 +1,20 @@ + '#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"; + } +}