Compare commits

...

1 Commits

Author SHA1 Message Date
EwelinaLasowy
03f1295194 #17 - Laravel Dusk tests 2022-03-14 14:24:22 +01:00
12 changed files with 135 additions and 57 deletions

View File

@ -19,8 +19,8 @@ DB_PASSWORD=password
BROADCAST_DRIVER=log
CACHE_DRIVER=array
QUEUE_CONNECTION=redis
SESSION_DRIVER=redis
QUEUE_CONNECTION=sync
SESSION_DRIVER=file
SESSION_LIFETIME=120
FILESYSTEM_DISK=local
MAIL_MAILER=array

View File

@ -0,0 +1,24 @@
<?php
declare(strict_types=1);
namespace Toby\Architecture\Providers;
use Illuminate\Support\ServiceProvider;
use Laravel\Dusk\Browser;
class DuskServiceProvider extends ServiceProvider
{
public function boot(): void
{
Browser::macro("fillMonth", function ($month) {
$this->select("div.flatpickr-calendar > div.flatpickr-months select", $month - 1);
return $this;
});
Browser::macro("fillDay", function ($day) {
$this->click("div.flatpickr-calendar.animate.arrowTop.arrowLeft.open > div.flatpickr-innerContainer > div > div.flatpickr-days > div > span:nth-child({$day})");
return $this;
});
}
}

View File

@ -24,12 +24,12 @@
},
"require-dev": {
"blumilksoftware/codestyle": "^0.10.0",
"spatie/laravel-ignition": "^1.0",
"fakerphp/faker": "^1.9.1",
"laravel/dusk": "^6.21",
"laravel/dusk": "^6.22",
"mockery/mockery": "^1.4.4",
"nunomaduro/collision": "^6.1",
"phpunit/phpunit": "^9.5.10"
"phpunit/phpunit": "^9.5.10",
"spatie/laravel-ignition": "^1.0"
},
"autoload": {
"psr-4": {

4
composer.lock generated
View File

@ -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": "937eef6310bd4bb12f1d0ccb623946d1",
"content-hash": "9dcd821442cec43ff77ef5045cd041c8",
"packages": [
{
"name": "asm89/stack-cors",
@ -10986,5 +10986,5 @@
"ext-pdo": "*"
},
"platform-dev": [],
"plugin-api-version": "2.1.0"
"plugin-api-version": "2.2.0"
}

View File

@ -44,5 +44,6 @@ return [
Toby\Architecture\Providers\TelescopeServiceProvider::class,
Toby\Architecture\Providers\ObserverServiceProvider::class,
Barryvdh\DomPDF\ServiceProvider::class,
Toby\Architecture\Providers\DuskServiceProvider::class,
],
];

2
package-lock.json generated
View File

@ -1,5 +1,5 @@
{
"name": "toby",
"name": "application",
"lockfileVersion": 2,
"requires": true,
"packages": {

View File

@ -121,7 +121,7 @@
>
</span>
<div class="ml-3">
<div class="text-sm font-medium text-gray-900">
<div class="text-sm font-medium text-gray-900" dusk="name-input">
{{ auth.user.name }}
</div>
</div>
@ -139,6 +139,7 @@
<div class="mt-1 relative sm:mt-0 sm:col-span-2">
<ListboxButton
class="bg-white relative w-full max-w-lg border rounded-md shadow-sm pl-3 pr-10 py-2 text-left cursor-default sm:text-sm focus:ring-1"
dusk="type-select"
:class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': form.errors.type, 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': !form.errors.type }"
>
<span class="block truncate">{{ form.type.label }}</span>
@ -154,6 +155,7 @@
>
<ListboxOptions
class="absolute z-10 mt-1 w-full max-w-lg bg-white shadow-lg max-h-60 rounded-md py-1 text-base ring-1 ring-black ring-opacity-5 overflow-auto focus:outline-none sm:text-sm"
dusk="type-options"
>
<ListboxOption
v-for="type in vacationTypes"
@ -163,7 +165,7 @@
:value="type"
>
<li
:class="[active ? 'text-white bg-blumilk-600' : 'text-gray-900', 'cursor-default select-none relative py-2 pl-3 pr-9']"
:class="[active ? 'text-white bg-blumilk-600' : 'text-gray-900', 'cursor-default select-none relative py-2 pl-3 pr-9']" :dusk="type.value"
>
<span :class="[selected ? 'font-semibold' : 'font-normal', 'block truncate']">
{{ type.label }}
@ -194,7 +196,7 @@
>
Planowany urlop od
</label>
<div class="mt-1 sm:mt-0 sm:col-span-2">
<div class="mt-1 sm:mt-0 sm:col-span-2" dusk="date-from-input">
<FlatPickr
id="date_from"
v-model="form.from"
@ -212,7 +214,7 @@
</p>
</div>
</div>
<div class="sm:grid sm:grid-cols-3 py-4 items-center">
<div class="sm:grid sm:grid-cols-3 py-4 items-center" dusk="date-to-input">
<label
for="date_from"
class="block text-sm font-medium text-gray-700 sm:mt-px"
@ -258,6 +260,7 @@
v-model="form.comment"
rows="4"
class="shadow-sm focus:ring-blumilk-500 focus:border-blumilk-500 block w-full max-w-lg sm:text-sm border-gray-300 rounded-md"
dusk="comment-input"
/>
</div>
</div>
@ -296,6 +299,7 @@
type="submit"
:disabled="form.processing"
class="inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-blumilk-600 hover:bg-blumilk-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blumilk-500"
dusk="save-button"
>
Zapisz
</button>

View File

@ -11,6 +11,7 @@
<InertiaLink
href="/vacation-requests/create"
class="inline-flex items-center px-4 py-3 border border-transparent text-sm leading-4 font-medium rounded-md shadow-sm text-white bg-blumilk-600 hover:bg-blumilk-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blumilk-500"
dusk="create-vacation-request-button"
>
Dodaj wniosek
</InertiaLink>

View File

@ -119,6 +119,7 @@
v-for="item in navigation"
:key="item.name"
:href="item.href"
:dusk="item.dusk"
:class="[$page.url === item.href ? 'bg-blumilk-800 text-white' : 'text-blumilk-100 hover:text-white hover:bg-blumilk-600', 'group flex items-center px-2 py-2 text-sm leading-6 font-medium rounded-md']"
>
<component
@ -329,12 +330,12 @@ export default {
const navigation = computed(() =>
[
{name: 'Moje wnioski', href: '/vacation-requests/me', icon: DocumentTextIcon, can: true},
{name: 'Wnioski urlopowe', href: '/vacation-requests', icon: CollectionIcon, can: auth.value.can.listAllVacationRequests},
{name: 'Kalendarz urlopów', href: '/vacation-calendar', icon: CalendarIcon, can: true},
{name: 'Dni wolne', href: '/holidays', icon: StarIcon, can: true},
{name: 'Limity urlopów', href: '/vacation-limits', icon: SunIcon, can: auth.value.can.manageVacationLimits},
{name: 'Użytkownicy', href: '/users', icon: UserGroupIcon, can: auth.value.can.manageUsers},
{name: 'Moje wnioski', href: '/vacation-requests/me', icon: DocumentTextIcon, can: true, dusk: 'my-vacation-requests-menu-item'},
{name: 'Wnioski urlopowe', href: '/vacation-requests', icon: CollectionIcon, can: auth.value.can.listAllVacationRequests, dusk: 'vacation-requests-menu-item'},
{name: 'Kalendarz urlopów', href: '/vacation-calendar', icon: CalendarIcon, can: true, dusk: 'vacation-calendar-menu-item'},
{name: 'Dni wolne', href: '/holidays', icon: StarIcon, can: true, dusk: 'holidays-menu-item'},
{name: 'Limity urlopów', href: '/vacation-limits', icon: SunIcon, can: auth.value.can.manageVacationLimits, dusk: 'vacation-limits-menu-item'},
{name: 'Użytkownicy', href: '/users', icon: UserGroupIcon, can: auth.value.can.manageUsers, dusk: 'users-menu-item'},
].filter(item => item.can))
const userNavigation = [

View File

@ -1,39 +0,0 @@
<?php
declare(strict_types=1);
namespace Tests\Browser;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Laravel\Dusk\Browser;
use Tests\Browser\Pages\HomePage;
use Tests\DuskTestCase;
use Toby\Eloquent\Models\User;
class AuthenticationTest extends DuskTestCase
{
use DatabaseMigrations;
protected User $user;
protected function setUp(): void
{
parent::setUp();
$this->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");
});
}
}

View File

@ -0,0 +1,84 @@
<?php
declare(strict_types=1);
namespace Tests\Browser;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Support\Carbon;
use Illuminate\Support\Str;
use Laravel\Dusk\Browser;
use Tests\Browser\Pages\HomePage;
use Tests\DuskTestCase;
use Tests\Traits\InteractsWithYearPeriods;
use Toby\Domain\Enums\EmploymentForm;
use Toby\Domain\Enums\Role;
use Toby\Eloquent\Models\User;
use Toby\Eloquent\Models\VacationLimit;
use Toby\Eloquent\Models\VacationRequest;
use Toby\Eloquent\Models\YearPeriod;
class VacationRequestTest extends DuskTestCase
{
use DatabaseMigrations;
use InteractsWithYearPeriods;
protected User $employee;
protected function setUp(): void
{
parent::setUp();
Carbon::setTestNow(Carbon::createFromDate(2022, 1, 1));
$this->createCurrentYearPeriod();
$currentYearPeriod = YearPeriod::query()->where("year", 2022)->first();
$this->employee = User::factory([
"first_name" => "Jan",
"last_name" => "Kowalski",
"email" => env("LOCAL_EMAIL_FOR_LOGIN_VIA_GOOGLE"),
"employment_form" => EmploymentForm::EmploymentContract,
"position" => "programista",
"role" => Role::Employee,
"employment_date" => Carbon::createFromDate(2022, 01, 03),
"remember_token" => Str::random(10),
])
->create();
VacationLimit::factory([
"days" => 26,
])
->for($currentYearPeriod)
->for($this->employee)
->create();
}
public function testUserCanCreateVacationRequest(): void
{
$this->browse(function (Browser $browser): void {
$browser->loginAs($this->employee)
->visit(new HomePage())
->click("@my-vacation-requests-menu-item")
->waitForLocation("/vacation-requests/me")
->click("@create-vacation-request-button")
->waitForLocation("/vacation-requests/create")
->assertSeeIn("@name-input", $this->employee->fullName)
->click("@type-select")
->assertVisible("@type-options")
->click("@vacation")
->click("@date-from-input")
->fillMonth("2")
->fillDay("22")
// ->clickAndWaitForReload("@save-button");
->press("Zapisz");
// ->waitForLocation("/vacation-requests/1")
// ->screenshot("xd")
// ;
});
$vacationRequest = VacationRequest::query()->first();
dd($vacationRequest);
}
}

2
tests/Browser/console/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
*
!.gitignore