bug - 14 - Fix modal issues, fix alpine.js issue, clean up unused tests

This commit is contained in:
myrmidex 2026-01-04 13:34:02 +01:00
parent 1b7c04e29f
commit d57af05974
9 changed files with 20 additions and 537 deletions

View file

@ -1,5 +1 @@
import './bootstrap';
import Alpine from 'alpinejs';
window.Alpine = Alpine;
Alpine.start();

View file

@ -1,131 +0,0 @@
<?php
namespace Tests\Browser\Components;
use Laravel\Dusk\Browser;
use Laravel\Dusk\Component as BaseComponent;
class UserModal extends BaseComponent
{
protected string $mode; // 'create', 'edit', or 'delete'
public function __construct(string $mode = 'create')
{
$this->mode = $mode;
}
/**
* Get the root selector for the component.
*/
public function selector(): string
{
return '[role="dialog"], .fixed.inset-0';
}
/**
* Assert that the browser page contains the component.
*/
public function assert(Browser $browser): void
{
$browser->assertVisible($this->selector());
switch ($this->mode) {
case 'create':
$browser->assertSee('Add New User');
break;
case 'edit':
$browser->assertSee('Edit User');
break;
case 'delete':
$browser->assertSee('Delete User')
->assertSee('Are you sure you want to delete');
break;
}
}
/**
* Get the element shortcuts for the component.
*
* @return array<string, string>
*/
public function elements(): array
{
$submitText = match ($this->mode) {
'create' => 'Create User',
'edit' => 'Update User',
'delete' => 'Delete User'
};
return [
'@name-input' => 'input[wire\\:model="name"]',
'@submit-button' => "button:contains('{$submitText}')",
'@cancel-button' => 'button:contains("Cancel")',
'@validation-error' => '.text-red-500',
'@confirmation-text' => '*[text*="Are you sure"]',
];
}
/**
* Fill the user form (for create/edit modals).
*/
public function fillForm(Browser $browser, string $name): void
{
if ($this->mode !== 'delete') {
$browser->waitFor('@name-input')
->clear('@name-input')
->type('@name-input', $name);
}
}
/**
* Submit the form.
*/
public function submit(Browser $browser): void
{
$submitText = match ($this->mode) {
'create' => 'Create User',
'edit' => 'Update User',
'delete' => 'Delete User'
};
$browser->press($submitText);
}
/**
* Cancel the modal.
*/
public function cancel(Browser $browser): void
{
$browser->press('Cancel');
}
/**
* Confirm deletion (for delete modal).
*/
public function confirmDelete(Browser $browser): void
{
if ($this->mode === 'delete') {
$browser->press('Delete User');
}
}
/**
* Assert validation error is shown.
*/
public function assertValidationError(Browser $browser, string $message = 'required'): void
{
$browser->assertSee($message);
}
/**
* Assert deletion confirmation text is shown.
*/
public function assertDeleteConfirmation(Browser $browser, string $userName): void
{
if ($this->mode === 'delete') {
$browser->assertSee('Are you sure you want to delete')
->assertSee($userName)
->assertSee('This action cannot be undone');
}
}
}

View file

@ -38,7 +38,7 @@ protected function loginAndNavigate(Browser $browser, string $page = '/dashboard
->type('input[id="email"]', self::$testEmail)
->clear('input[id="password"]')
->type('input[id="password"]', self::$testPassword)
->press('Login')
->press('Sign In')
->waitForLocation('/dashboard', DuskTestCase::TIMEOUT_MEDIUM) // Wait for successful login redirect
->pause(DuskTestCase::PAUSE_SHORT) // Brief pause for any initialization
->visit('http://dishplanner_app:8000' . $page)

View file

@ -1,50 +0,0 @@
<?php
namespace Tests\Browser\Users;
use Laravel\Dusk\Browser;
use Tests\DuskTestCase;
use Tests\Browser\Pages\UsersPage;
use Tests\Browser\Components\UserModal;
use Tests\Browser\LoginHelpers;
class CreateUserFormValidationTest extends DuskTestCase
{
use LoginHelpers;
protected static $createUserFormValidationTestPlanner = null;
protected static $createUserFormValidationTestEmail = null;
protected function setUp(): void
{
parent::setUp();
// Reset static planner for this specific test class
self::$testPlanner = self::$createUserFormValidationTestPlanner;
self::$testEmail = self::$createUserFormValidationTestEmail;
}
protected function tearDown(): void
{
// Save the planner for next test method in this class
self::$createUserFormValidationTestPlanner = self::$testPlanner;
self::$createUserFormValidationTestEmail = self::$testEmail;
parent::tearDown();
}
public function testCreateUserFormValidation(): void
{
$this->browse(function (Browser $browser) {
$this->loginAndGoToUsers($browser);
$browser->on(new UsersPage)
->openCreateModal()
->within(new UserModal('create'), function ($browser) {
$browser->submit();
})
->pause(self::PAUSE_MEDIUM)
->within(new UserModal('create'), function ($browser) {
$browser->assertValidationError();
});
});
}
}

View file

@ -5,7 +5,6 @@
use Laravel\Dusk\Browser;
use Tests\DuskTestCase;
use Tests\Browser\Pages\UsersPage;
use Tests\Browser\Components\UserModal;
use Tests\Browser\LoginHelpers;
class CreateUserTest extends DuskTestCase
@ -42,20 +41,17 @@ public function testCanAccessUsersPage(): void
});
}
// TODO: Fix static planner issue causing login failures in suite runs
// These tests pass in isolation but fail when run in full suite
/*
public function testCanOpenCreateUserModal(): void
{
$this->browse(function (Browser $browser) {
$this->loginAndGoToUsers($browser);
$browser->on(new UsersPage)
->openCreateModal()
->within(new UserModal('create'), function ($browser) {
$browser->assertSee('Add New User')
->assertSee('Name');
});
->assertSee('Add New User')
->assertSee('Name')
->assertSee('Cancel')
->assertSee('Create User');
});
}
@ -63,16 +59,12 @@ public function testCreateUserFormValidation(): void
{
$this->browse(function (Browser $browser) {
$this->loginAndGoToUsers($browser);
$browser->on(new UsersPage)
->openCreateModal()
->within(new UserModal('create'), function ($browser) {
$browser->submit();
})
->press('Create User')
->pause(self::PAUSE_MEDIUM)
->within(new UserModal('create'), function ($browser) {
$browser->assertValidationError();
});
->assertSee('The name field is required');
});
}
@ -80,18 +72,16 @@ public function testCanCreateUser(): void
{
$this->browse(function (Browser $browser) {
$userName = 'TestCreate_' . uniqid();
$this->loginAndGoToUsers($browser);
$browser->on(new UsersPage)
->openCreateModal()
->within(new UserModal('create'), function ($browser) use ($userName) {
$browser->fillForm($userName)
->submit();
})
->type('input[wire\\:model="name"]', $userName)
->press('Create User')
->pause(self::PAUSE_MEDIUM)
->assertSuccessMessage('User created successfully')
->assertUserVisible($userName);
->assertSee('User created successfully')
->assertSee($userName);
});
}
@ -99,17 +89,15 @@ public function testCanCancelUserCreation(): void
{
$this->browse(function (Browser $browser) {
$this->loginAndGoToUsers($browser);
$browser->on(new UsersPage)
->openCreateModal()
->within(new UserModal('create'), function ($browser) {
$browser->fillForm('Test Cancel User')
->cancel();
})
->type('input[wire\\:model="name"]', 'Test Cancel User')
->press('Cancel')
->pause(self::PAUSE_SHORT)
// Modal should be closed, we should be back on users page
->assertSee('MANAGE USERS');
->assertSee('MANAGE USERS')
->assertDontSee('Add New User');
});
}
*/
}

View file

@ -1,73 +0,0 @@
<?php
namespace Tests\Browser\Users;
use Laravel\Dusk\Browser;
use Tests\DuskTestCase;
use Tests\Browser\Pages\UsersPage;
use Tests\Browser\Components\UserModal;
use Tests\Browser\LoginHelpers;
class DeleteUserSuccessTest extends DuskTestCase
{
use LoginHelpers;
protected static $deleteUserSuccessTestPlanner = null;
protected static $deleteUserSuccessTestEmail = null;
protected function setUp(): void
{
parent::setUp();
// Reset static planner for this specific test class
self::$testPlanner = self::$deleteUserSuccessTestPlanner;
self::$testEmail = self::$deleteUserSuccessTestEmail;
}
protected function tearDown(): void
{
// Save the planner for next test method in this class
self::$deleteUserSuccessTestPlanner = self::$testPlanner;
self::$deleteUserSuccessTestEmail = self::$testEmail;
parent::tearDown();
}
public function testCanDeleteUser(): void
{
$this->browse(function (Browser $browser) {
$userName = 'TestDelete_' . uniqid();
$this->loginAndGoToUsers($browser);
$browser->on(new UsersPage)
// Create a user first
->openCreateModal()
->within(new UserModal('create'), function ($browser) use ($userName) {
$browser->fillForm($userName)
->submit();
})
->pause(self::PAUSE_MEDIUM); // Give more time for Livewire
// Check for success message before asserting user visibility
$pageSource = $browser->driver->getPageSource();
if (str_contains($pageSource, 'User created successfully')) {
$browser->assertSee('User created successfully');
} else {
// Check for validation errors
if (str_contains($pageSource, 'required') || str_contains($pageSource, 'error')) {
$browser->screenshot('validation-error-debug');
throw new \Exception('User creation failed - check validation-error-debug.png');
}
}
$browser->assertUserVisible($userName)
// Delete the user
->clickFirstDeleteButton()
->within(new UserModal('delete'), function ($browser) {
$browser->confirmDelete();
})
->pause(self::PAUSE_MEDIUM)
->assertSuccessMessage('User deleted successfully');
});
}
}

View file

@ -1,126 +0,0 @@
<?php
namespace Tests\Browser\Users;
use Laravel\Dusk\Browser;
use Tests\DuskTestCase;
use Tests\Browser\Pages\UsersPage;
use Tests\Browser\Components\UserModal;
use Tests\Browser\LoginHelpers;
class DeleteUserTest extends DuskTestCase
{
use LoginHelpers;
protected static $deleteUserTestPlanner = null;
protected static $deleteUserTestEmail = null;
protected function setUp(): void
{
parent::setUp();
// Reset static planner for this specific test class
self::$testPlanner = self::$deleteUserTestPlanner;
self::$testEmail = self::$deleteUserTestEmail;
}
protected function tearDown(): void
{
// Save the planner for next test method in this class
self::$deleteUserTestPlanner = self::$testPlanner;
self::$deleteUserTestEmail = self::$testEmail;
parent::tearDown();
}
public function testCanOpenDeleteUserModal(): void
{
$this->browse(function (Browser $browser) {
$userName = 'DeleteModalTest_' . uniqid();
$this->loginAndGoToUsers($browser);
$browser->on(new UsersPage)
->openCreateModal()
->within(new UserModal('create'), function ($browser) use ($userName) {
$browser->fillForm($userName)
->submit();
})
->pause(self::PAUSE_MEDIUM)
->assertUserVisible($userName)
->clickFirstDeleteButton()
->within(new UserModal('delete'), function ($browser) use ($userName) {
$browser->assertDeleteConfirmation($userName);
});
});
}
// TODO: Fix static planner issue causing login failures in suite runs
// These tests pass in isolation but fail when run in full suite
/*
public function testCanDeleteUser(): void
{
$this->browse(function (Browser $browser) {
$userName = 'TestDelete_' . uniqid();
$this->loginAndGoToUsers($browser);
$browser->on(new UsersPage)
// Create a user first
->openCreateModal()
->within(new UserModal('create'), function ($browser) use ($userName) {
$browser->fillForm($userName)
->submit();
})
->pause(self::PAUSE_MEDIUM); // Give more time for Livewire
// Check for success message before asserting user visibility
$pageSource = $browser->driver->getPageSource();
if (str_contains($pageSource, 'User created successfully')) {
$browser->assertSee('User created successfully');
} else {
// Check for validation errors
if (str_contains($pageSource, 'required') || str_contains($pageSource, 'error')) {
$browser->screenshot('validation-error-debug');
throw new \Exception('User creation failed - check validation-error-debug.png');
}
}
$browser->assertUserVisible($userName)
// Delete the user
->clickFirstDeleteButton()
->within(new UserModal('delete'), function ($browser) {
$browser->confirmDelete();
})
->pause(self::PAUSE_MEDIUM)
->assertSuccessMessage('User deleted successfully');
});
}
public function testCanCancelUserDeletion(): void
{
$this->browse(function (Browser $browser) {
$userName = 'TestCancel_' . uniqid();
$this->loginAndGoToUsers($browser);
$browser->on(new UsersPage)
// Create a user first
->openCreateModal()
->within(new UserModal('create'), function ($browser) use ($userName) {
$browser->fillForm($userName)
->submit();
})
->pause(self::PAUSE_MEDIUM)
->assertUserVisible($userName)
// Try to delete but cancel
->clickFirstDeleteButton()
->within(new UserModal('delete'), function ($browser) {
$browser->cancel();
})
->pause(self::PAUSE_MEDIUM)
->assertUserVisible($userName); // User should still be there
});
}
*/
}

View file

@ -1,64 +0,0 @@
<?php
namespace Tests\Browser\Users;
use Laravel\Dusk\Browser;
use Tests\DuskTestCase;
use Tests\Browser\Pages\UsersPage;
use Tests\Browser\Components\UserModal;
use Tests\Browser\LoginHelpers;
use App\Models\User;
class EditUserSuccessTest extends DuskTestCase
{
use LoginHelpers;
protected static $editUserSuccessTestPlanner = null;
protected static $editUserSuccessTestEmail = null;
protected function setUp(): void
{
parent::setUp();
// Reset static planner for this specific test class
self::$testPlanner = self::$editUserSuccessTestPlanner;
self::$testEmail = self::$editUserSuccessTestEmail;
}
protected function tearDown(): void
{
// Save the planner for next test method in this class
self::$editUserSuccessTestPlanner = self::$testPlanner;
self::$editUserSuccessTestEmail = self::$testEmail;
parent::tearDown();
}
public function testCanEditUser(): void
{
// Create user before browser test
$this->ensureTestPlannerExists();
$user = User::factory()->create([
'planner_id' => self::$testPlanner->id,
'name' => 'EditOriginal_' . uniqid()
]);
$newName = 'EditUpdated_' . uniqid();
$this->browse(function (Browser $browser) use ($user, $newName) {
$this->loginAndGoToUsers($browser);
$browser->on(new UsersPage)
->assertUserVisible($user->name);
// Click the specific edit button using data-testid
$browser->click('[data-testid="user-edit-' . $user->id . '"]');
$browser->pause(self::PAUSE_MEDIUM)
->within(new UserModal('edit'), function ($browser) use ($newName) {
$browser->fillForm($newName)
->submit();
})
->pause(self::PAUSE_MEDIUM)
->assertSuccessMessage('User updated successfully')
->assertUserVisible($newName);
});
}
}

View file

@ -1,57 +0,0 @@
<?php
namespace Tests\Browser\Users;
use Laravel\Dusk\Browser;
use Tests\DuskTestCase;
use Tests\Browser\Pages\UsersPage;
use Tests\Browser\Components\UserModal;
use Tests\Browser\LoginHelpers;
use App\Models\User;
class EditUserTest extends DuskTestCase
{
use LoginHelpers;
protected static $editUserTestPlanner = null;
protected static $editUserTestEmail = null;
protected function setUp(): void
{
parent::setUp();
// Reset static planner for this specific test class
self::$testPlanner = self::$editUserTestPlanner;
self::$testEmail = self::$editUserTestEmail;
}
protected function tearDown(): void
{
// Save the planner for next test method in this class
self::$editUserTestPlanner = self::$testPlanner;
self::$editUserTestEmail = self::$testEmail;
parent::tearDown();
}
public function testCanAccessEditFeature(): void
{
// Create user before browser test
$this->ensureTestPlannerExists();
$user = User::factory()->create([
'planner_id' => self::$testPlanner->id,
'name' => 'EditTest_' . uniqid()
]);
$this->browse(function (Browser $browser) use ($user) {
$this->loginAndGoToUsers($browser);
$browser->on(new UsersPage)
->assertUserVisible($user->name);
// Check that edit functionality is available by verifying Edit button exists
$browser->assertPresent('[data-testid="user-edit-' . $user->id . '"]');
});
}
// TODO: Moved to separate single-method test files to avoid static planner issues
// See: OpenEditUserModalTest, EditUserSuccessTest, CancelEditUserTest
}