#17 - Laravel Dusk tests
This commit is contained in:
parent
db4be79c91
commit
03f1295194
@ -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
|
||||
|
24
app/Architecture/Providers/DuskServiceProvider.php
Normal file
24
app/Architecture/Providers/DuskServiceProvider.php
Normal 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;
|
||||
});
|
||||
}
|
||||
}
|
@ -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
4
composer.lock
generated
@ -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"
|
||||
}
|
||||
|
@ -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
2
package-lock.json
generated
@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "toby",
|
||||
"name": "application",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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 = [
|
||||
|
@ -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");
|
||||
});
|
||||
}
|
||||
}
|
84
tests/Browser/VacationRequestTest.php
Normal file
84
tests/Browser/VacationRequestTest.php
Normal 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
2
tests/Browser/console/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
*
|
||||
!.gitignore
|
Loading…
x
Reference in New Issue
Block a user