From 1e35e485ade2a16c65b79089e83fe3691ee10db3 Mon Sep 17 00:00:00 2001 From: jon brookes Date: Mon, 5 Jan 2026 14:56:40 +0000 Subject: [PATCH 01/10] initial partically working --- tests/Browser/LoginDashAdminTest.php | 60 ++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 tests/Browser/LoginDashAdminTest.php diff --git a/tests/Browser/LoginDashAdminTest.php b/tests/Browser/LoginDashAdminTest.php new file mode 100644 index 0000000..b5d2bc3 --- /dev/null +++ b/tests/Browser/LoginDashAdminTest.php @@ -0,0 +1,60 @@ +createTestUser("login-test@example.com"); + + $this->browse(function (Browser $browser) use ($user) { + $this->loginUser($browser, $user); + $this->assertWithDebugPause($browser, fn($b) => + $b->assertPathIs('/dashboard'), + 1000 // Custom pause time for this test + ); + }); + } + + public function test_invalid_login(): void + { + $user = $this->createTestUser("invalid-email@example.com"); + + $this->browse(function (Browser $browser) use ($user) { + $this->loginUser($browser, $user); + $this->assertWithDebugPause($browser, fn($b) => + $b->visit('/admin') + ->waitForLocation('/admin') + ->assertPathIs('/admin') + ->assertSee('FORBIDDEN'), + 1000 // Custom pause time for this test + ); + }); + } + + public function test_access_admin_panel(): void + { + $user = $this->createTestUser("login-test@example.com"); + + $this->browse(function (Browser $browser) use ($user) { + $this->loginUser($browser, $user); + $this->assertWithDebugPause($browser, fn($b) => + $b->visit('/admin') + ->waitForLocation('/admin') + ->assertPathIs('/admin') + ->assertTitleContains('Dashboard') + ->assertDontSee('FORBIDDEN'), + 1000 // Custom pause time for this test + ); + }); + } +} \ No newline at end of file From 4cb9d078b1ed00a64e6fffb2b7ecd380f75ae7e0 Mon Sep 17 00:00:00 2001 From: jon brookes Date: Mon, 5 Jan 2026 15:05:27 +0000 Subject: [PATCH 02/10] initial partically working --- tests/Browser/UploadImageAdminTest.php | 45 ++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 tests/Browser/UploadImageAdminTest.php diff --git a/tests/Browser/UploadImageAdminTest.php b/tests/Browser/UploadImageAdminTest.php new file mode 100644 index 0000000..bd94b6d --- /dev/null +++ b/tests/Browser/UploadImageAdminTest.php @@ -0,0 +1,45 @@ +createTestUser("login-test@example.com"); + + $filePath = base_path('tests/Browser/fixtures/robot.webp'); + + $this->browse(function (Browser $browser ) use ($user, $filePath) { + $this->loginUser($browser, $user); + $this->assertWithDebugPause( + $browser, + fn($b) => + $b->visit('/admin/media') + ->waitForLocation('/admin/media') + ->assertPathIs('/admin/media') + ->assertTitleContains('Media') + ->clickLink('New media') + ->waitForText('Create Media') + ->pause(1000) + ->assertVisible('.filepond--drop-label') + ->attach('.filepond--browser', $filePath) + ->waitforText('Create') + ->clickLink('Create') + // ->assertSee('Upload successful') + ->pause(10000), + 1000 // Custom pause time for this test + ); + }); + } +} From bef3ae7f41df6597fb6d1f5041c0f0358fb52a07 Mon Sep 17 00:00:00 2001 From: jon brookes Date: Mon, 5 Jan 2026 16:37:06 +0000 Subject: [PATCH 03/10] feat: implement user authentication traits and tests for admin panel image uploads --- tests/Browser/Concerns/AuthenticatesUsers.php | 38 +++++++ tests/Browser/CreateEntryAdminTest.php | 61 +++++++++++ tests/Browser/LoginTest.php | 98 ------------------ tests/Browser/UploadImageAdminTest.php | 13 +-- tests/Browser/fixtures/robot.webp | Bin 0 -> 15864 bytes 5 files changed, 106 insertions(+), 104 deletions(-) create mode 100644 tests/Browser/Concerns/AuthenticatesUsers.php create mode 100644 tests/Browser/CreateEntryAdminTest.php delete mode 100644 tests/Browser/LoginTest.php create mode 100644 tests/Browser/fixtures/robot.webp diff --git a/tests/Browser/Concerns/AuthenticatesUsers.php b/tests/Browser/Concerns/AuthenticatesUsers.php new file mode 100644 index 0000000..640fbd0 --- /dev/null +++ b/tests/Browser/Concerns/AuthenticatesUsers.php @@ -0,0 +1,38 @@ +create([ + 'email' => $email, + 'password' => bcrypt('password'), + 'two_factor_secret' => null, + 'two_factor_recovery_codes' => null, + ]); + } + + private function loginUser(Browser $browser, User $user): void + { + $browser->visit('/login') + ->type('email', $user->email) + ->type('password', 'password') + ->press('Log in') + ->waitForLocation('/dashboard'); + } + + private function assertWithDebugPause(Browser $browser, callable $assertions, int $pauseMs = 10000): void + { + try { + $assertions($browser); + } catch (\Exception $e) { + $browser->pause($pauseMs); + throw $e; + } + } +} \ No newline at end of file diff --git a/tests/Browser/CreateEntryAdminTest.php b/tests/Browser/CreateEntryAdminTest.php new file mode 100644 index 0000000..25598bc --- /dev/null +++ b/tests/Browser/CreateEntryAdminTest.php @@ -0,0 +1,61 @@ +createTestUser("login-test@example.com"); + + $filePath = base_path('tests/Browser/fixtures/robot.webp'); + + $this->browse(function (Browser $browser) use ($user, $filePath) { + $this->loginUser($browser, $user); + $this->assertWithDebugPause( + $browser, + fn($b) => + $b->visit('/admin/media') + ->waitForLocation('/admin/media') + ->assertPathIs('/admin/media') + ->assertTitleContains('Media') + ->clickLink('New media') + ->waitForText('Create Media') + ->type('#form\\.name', 'test image') + ->assertVisible('.filepond--drop-label') + ->attach('.filepond--browser', $filePath) + ->pause(7000) + ->waitForText('Create') + ->waitFor('#key-bindings-1:not([disabled])') + ->click('#key-bindings-1') + ->assertSee('Collection name') + ->pause(5000) + + ->visit('/admin/entries') + ->waitForLocation('/admin/entries') + ->assertPathIs('/admin/entries') + ->assertTitleContains('Entries') + ->clickLink('New entry') + ->waitForText('Create Entry') + ->type('#form\\.title', 'TEST ENTRY') + ->keys('#form\\.title', '{tab}') + ->waitForText('Create') + + ->click('#key-bindings-1') + ->waitForText('Updated at') + ->assertSee('Updated at') + ->visit('/admin/entries/1/edit') + ->pause(10000), + 1000 // Custom pause time for this test + ); + }); + } +} diff --git a/tests/Browser/LoginTest.php b/tests/Browser/LoginTest.php deleted file mode 100644 index eecd256..0000000 --- a/tests/Browser/LoginTest.php +++ /dev/null @@ -1,98 +0,0 @@ -create([ - 'email' => $email, - 'password' => bcrypt('password'), - 'two_factor_secret' => null, - 'two_factor_recovery_codes' => null, - ]); - } - - private function loginUser(Browser $browser, User $user): void - { - $browser->visit('/login') - ->type('email', $user->email) - ->type('password', 'password') - ->press('Log in') - ->waitForLocation('/dashboard'); - } - - public function test_login(): void - { - $user = $this->createTestUser("login-test@example.com"); - - $this->browse(function (Browser $browser) use ($user) { - $this->loginUser($browser, $user); - try { - $browser->assertPathIs('/dashboard'); // Or wherever successful login redirects - } catch (\Exception $e) { - $browser->pause(10000); // Pause for 10 seconds on failure to debug - throw $e; - } - }); - } - - /* - public function test_invalid_login(): void - { - $user = $this->createTestUser("invalid-email@example.com"); - - - $this->browse(function (Browser $browser) use ($user) { - $this->loginUser($browser, $user); - try { - $browser->visit('/admin') - ->waitForLocation('/admin') - ->assertPathIs('/admin') - ->assertTitleContains('Dashboard') - ->assertDontSee('Forbidden') - ->pause(1000); - } catch (\Exception $e) { - $browser->pause(1000); // Pause for 1 second on failure to debug - throw $e; - } - }); - - - - - } -*/ - - public function test_access_admin_panel(): void - { - - $user = $this->createTestUser("login-test@example.com"); - - $this->browse(function (Browser $browser) use ($user) { - $this->loginUser($browser, $user); - try { - $browser->visit('/admin') - ->waitForLocation('/admin') - ->assertPathIs('/admin') - ->assertTitleContains('Dashboard') - ->assertDontSee('Forbidden') - ->pause(1000); - } catch (\Exception $e) { - $browser->pause(1000); // Pause for 1 second on failure to debug - throw $e; - } - }); - } -} diff --git a/tests/Browser/UploadImageAdminTest.php b/tests/Browser/UploadImageAdminTest.php index bd94b6d..915078c 100644 --- a/tests/Browser/UploadImageAdminTest.php +++ b/tests/Browser/UploadImageAdminTest.php @@ -7,7 +7,7 @@ use Laravel\Dusk\Browser; use Tests\Browser\Concerns\AuthenticatesUsers; use Tests\DuskTestCase; -class LoginTest extends DuskTestCase +class UploadImageAdminTest extends DuskTestCase { use DatabaseTruncation; use AuthenticatesUsers; @@ -31,13 +31,14 @@ class LoginTest extends DuskTestCase ->assertTitleContains('Media') ->clickLink('New media') ->waitForText('Create Media') - ->pause(1000) + ->type('#form\\.name', 'test image') ->assertVisible('.filepond--drop-label') ->attach('.filepond--browser', $filePath) - ->waitforText('Create') - ->clickLink('Create') - // ->assertSee('Upload successful') - ->pause(10000), + ->pause(7000) + ->waitForText('Create') + ->waitFor('#key-bindings-1:not([disabled])') + ->click('#key-bindings-1') + ->assertSee('Collection name'), 1000 // Custom pause time for this test ); }); diff --git a/tests/Browser/fixtures/robot.webp b/tests/Browser/fixtures/robot.webp new file mode 100644 index 0000000000000000000000000000000000000000..3dd400ba7f62396a2332cfa072ef414f75f5d9b4 GIT binary patch literal 15864 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 O?SH2pZmT Date: Mon, 5 Jan 2026 17:17:48 +0000 Subject: [PATCH 04/10] feat: custom class in entry form and update Dusk test for featured image selection --- app/Filament/Resources/Entries/Schemas/EntryForm.php | 3 ++- tests/Browser/CreateEntryAdminTest.php | 7 ++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/app/Filament/Resources/Entries/Schemas/EntryForm.php b/app/Filament/Resources/Entries/Schemas/EntryForm.php index 6c029f6..b7bdf36 100644 --- a/app/Filament/Resources/Entries/Schemas/EntryForm.php +++ b/app/Filament/Resources/Entries/Schemas/EntryForm.php @@ -43,8 +43,9 @@ class EntryForm ->dehydrated(false) ->hintAction( Action::make('featured_picker') - ->label('Pick from Gallery') + ->label('Featured Image from Gallery') ->icon('heroicon-m-photo') + ->extraAttributes(['id' => 'featured-picker-button']) ->schema([ Select::make('image_id') ->label('Select an existing image') diff --git a/tests/Browser/CreateEntryAdminTest.php b/tests/Browser/CreateEntryAdminTest.php index 25598bc..b874411 100644 --- a/tests/Browser/CreateEntryAdminTest.php +++ b/tests/Browser/CreateEntryAdminTest.php @@ -7,7 +7,7 @@ use Laravel\Dusk\Browser; use Tests\Browser\Concerns\AuthenticatesUsers; use Tests\DuskTestCase; -class UploadImageAdminTest extends DuskTestCase +class CreateEntryAdminTest extends DuskTestCase { use DatabaseTruncation; use AuthenticatesUsers; @@ -53,6 +53,11 @@ class UploadImageAdminTest extends DuskTestCase ->waitForText('Updated at') ->assertSee('Updated at') ->visit('/admin/entries/1/edit') + ->waitForText('Edit TEST ENTRY') + ->pause(2000) + ->waitForText('Featured Image') + ->click('#featured-picker-button') + ->pause(10000), 1000 // Custom pause time for this test ); From 50e5fb7f3fb79c0dcec8352b07dcf8ece85e32b0 Mon Sep 17 00:00:00 2001 From: jon brookes Date: Mon, 5 Jan 2026 17:40:22 +0000 Subject: [PATCH 05/10] feat: enhance media entry test to select existing images --- tests/Browser/CreateEntryAdminTest.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/Browser/CreateEntryAdminTest.php b/tests/Browser/CreateEntryAdminTest.php index b874411..38ab34f 100644 --- a/tests/Browser/CreateEntryAdminTest.php +++ b/tests/Browser/CreateEntryAdminTest.php @@ -57,7 +57,9 @@ class CreateEntryAdminTest extends DuskTestCase ->pause(2000) ->waitForText('Featured Image') ->click('#featured-picker-button') - + ->waitForText('Select an existing image') + ->click('.fi-select-input-btn') + ->keys('.fi-select-input-btn', '{enter}') ->pause(10000), 1000 // Custom pause time for this test ); From 33688b55be7d414a4ecb50c1f25d787f482c0d33 Mon Sep 17 00:00:00 2001 From: jon brookes Date: Mon, 5 Jan 2026 18:38:05 +0000 Subject: [PATCH 06/10] feat: add critical testing approach guidelines for Laravel Dusk --- .github/copilot-instructions.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index a715f25..0077032 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -44,6 +44,13 @@ This application is a Laravel application and its main Laravel ecosystems packag ## Documentation Files - You must only create documentation files if explicitly requested by the user. +## Testing Approach - CRITICAL +- **THE APPLICATION IS 100% WORKING** - All functionality works perfectly in production. +- When writing or debugging browser tests (Laravel Dusk), focus ONLY on test syntax, selectors, and Dusk interaction methods. +- NEVER assume the application has bugs or suggest app fixes - the issue is always in the test code. +- Trust the existing functionality and work on getting the correct CSS selectors, XPath expressions, and Dusk methods. +- If manual interaction works but the test fails, the problem is the test implementation, not the app. + === boost rules === From b0fc008530eb920669e1daf02d3d8ba80b538aff Mon Sep 17 00:00:00 2001 From: jon brookes Date: Mon, 5 Jan 2026 18:42:02 +0000 Subject: [PATCH 07/10] feat: complete image upload to entry test enhance entry creation test to select existing images and submit --- tests/Browser/CreateEntryAdminTest.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tests/Browser/CreateEntryAdminTest.php b/tests/Browser/CreateEntryAdminTest.php index 38ab34f..dc05e3b 100644 --- a/tests/Browser/CreateEntryAdminTest.php +++ b/tests/Browser/CreateEntryAdminTest.php @@ -59,8 +59,14 @@ class CreateEntryAdminTest extends DuskTestCase ->click('#featured-picker-button') ->waitForText('Select an existing image') ->click('.fi-select-input-btn') - ->keys('.fi-select-input-btn', '{enter}') - ->pause(10000), + ->pause(2000) + ->click('li:first-child') + ->waitForText('Submit') + ->clickAtXPath('//button[contains(., "Submit")]') + + ->waitForText('Edit TEST ENTRY') + ->click('#key-bindings-1'), + // ->pause(20000), 1000 // Custom pause time for this test ); }); From cfb93534759ab6175ff2b2fd9ba30dee2bbf2ee4 Mon Sep 17 00:00:00 2001 From: jon brookes Date: Mon, 5 Jan 2026 18:44:24 +0000 Subject: [PATCH 08/10] feat: extend Pest with DuskTestCase for browser testing --- tests/Pest.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/Pest.php b/tests/Pest.php index b3a25b7..59833e1 100644 --- a/tests/Pest.php +++ b/tests/Pest.php @@ -1,5 +1,9 @@ extend(Tests\DuskTestCase::class) +// ->use(Illuminate\Foundation\Testing\DatabaseMigrations::class) + ->in('Browser'); + /* |-------------------------------------------------------------------------- | Test Case From 56ce59fc22533838dfa598cade4ccf95537c4290 Mon Sep 17 00:00:00 2001 From: jon brookes Date: Mon, 5 Jan 2026 18:48:13 +0000 Subject: [PATCH 09/10] feat: add DuskTestCase for enhanced browser testing setup --- tests/DuskTestCase.php | 48 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 tests/DuskTestCase.php diff --git a/tests/DuskTestCase.php b/tests/DuskTestCase.php new file mode 100644 index 0000000..020699d --- /dev/null +++ b/tests/DuskTestCase.php @@ -0,0 +1,48 @@ +addArguments(collect([ + $this->shouldStartMaximized() ? '--start-maximized' : '--window-size=1920,1080', + '--disable-search-engine-choice-screen', + '--disable-smooth-scrolling', + ])->unless($this->hasHeadlessDisabled(), function (Collection $items) { + return $items->merge([ + '--disable-gpu', + '--headless=new', + ]); + })->all()); + + return RemoteWebDriver::create( + $_ENV['DUSK_DRIVER_URL'] ?? env('DUSK_DRIVER_URL') ?? 'http://localhost:9515', + DesiredCapabilities::chrome()->setCapability( + ChromeOptions::CAPABILITY, $options + ) + ); + } +} From 22393b5954e0fee7b48b09b9d6f70bebc81ecaef Mon Sep 17 00:00:00 2001 From: jon brookes Date: Mon, 5 Jan 2026 19:04:04 +0000 Subject: [PATCH 10/10] feat: change order of Dusk tests for login, image upload, and entry creation in admin panel --- .../{LoginDashAdminTest.php => 001_LoginDashAdminTest.php} | 0 .../{UploadImageAdminTest.php => 002_UploadImageAdminTest.php} | 0 .../{CreateEntryAdminTest.php => 003_CreateEntryAdminTest.php} | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename tests/Browser/{LoginDashAdminTest.php => 001_LoginDashAdminTest.php} (100%) rename tests/Browser/{UploadImageAdminTest.php => 002_UploadImageAdminTest.php} (100%) rename tests/Browser/{CreateEntryAdminTest.php => 003_CreateEntryAdminTest.php} (100%) diff --git a/tests/Browser/LoginDashAdminTest.php b/tests/Browser/001_LoginDashAdminTest.php similarity index 100% rename from tests/Browser/LoginDashAdminTest.php rename to tests/Browser/001_LoginDashAdminTest.php diff --git a/tests/Browser/UploadImageAdminTest.php b/tests/Browser/002_UploadImageAdminTest.php similarity index 100% rename from tests/Browser/UploadImageAdminTest.php rename to tests/Browser/002_UploadImageAdminTest.php diff --git a/tests/Browser/CreateEntryAdminTest.php b/tests/Browser/003_CreateEntryAdminTest.php similarity index 100% rename from tests/Browser/CreateEntryAdminTest.php rename to tests/Browser/003_CreateEntryAdminTest.php