From a35b50bec62cd246a724332971a668a8077b3b95 Mon Sep 17 00:00:00 2001 From: Daan Meijer Date: Tue, 23 Jun 2026 15:03:34 +0200 Subject: [PATCH] added browser tests --- .gitignore | 5 +- AGENTS.md | 1 + composer.json | 1 + composer.lock | 142 +++++++++++++++++- ...23_121123_drop_users_uuid_unique_index.php | 28 ++++ tests/Browser/AuthenticationTest.php | 38 ----- tests/Browser/AuthorizationTest.php | 82 ---------- tests/Browser/BasicViewsTest.php | 138 +++++++++++++++++ tests/Browser/DashboardTest.php | 19 +++ tests/Browser/LoginTest.php | 27 ++++ tests/Browser/Pages/HomePage.php | 36 +++++ tests/Browser/Pages/Page.php | 20 +++ tests/Browser/RealtimeChatTest.php | 115 ++++++++------ tests/DuskTestCase.php | 6 +- tests/Pest.php | 4 + 15 files changed, 491 insertions(+), 171 deletions(-) create mode 100644 database/migrations/2026_06_23_121123_drop_users_uuid_unique_index.php delete mode 100644 tests/Browser/AuthenticationTest.php delete mode 100644 tests/Browser/AuthorizationTest.php create mode 100644 tests/Browser/BasicViewsTest.php create mode 100644 tests/Browser/DashboardTest.php create mode 100644 tests/Browser/LoginTest.php create mode 100644 tests/Browser/Pages/HomePage.php create mode 100644 tests/Browser/Pages/Page.php diff --git a/.gitignore b/.gitignore index c174ff5..a6431ce 100644 --- a/.gitignore +++ b/.gitignore @@ -28,4 +28,7 @@ yarn-error.log /.vscode /.zed /public/sw.js -/public/workbox-*.js \ No newline at end of file +/public/workbox-*.js +/tests/Browser/console +/tests/Browser/screenshots +/tests/Browser/source \ No newline at end of file diff --git a/AGENTS.md b/AGENTS.md index d1aa2a2..95cd5d0 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -19,6 +19,7 @@ This application is a Laravel application and its main Laravel ecosystems packag - tightenco/ziggy (ZIGGY) - v2 - larastan/larastan (LARASTAN) - v3 - laravel/boost (BOOST) - v2 +- laravel/dusk (DUSK) - v8 - laravel/mcp (MCP) - v0 - laravel/pail (PAIL) - v1 - laravel/pint (PINT) - v1 diff --git a/composer.json b/composer.json index 34e72fd..a644f8e 100644 --- a/composer.json +++ b/composer.json @@ -24,6 +24,7 @@ "fakerphp/faker": "^1.24", "larastan/larastan": "^3.9", "laravel/boost": "^2.2", + "laravel/dusk": "^8.6", "laravel/pail": "^1.2.5", "laravel/pao": "^1.0.6", "laravel/pint": "^1.27", diff --git a/composer.lock b/composer.lock index 121a434..8def08c 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": "f4c79dcf0b7f9f54487404715d1085c1", + "content-hash": "26618424deaf53a19e8fe992032eef9c", "packages": [ { "name": "bacon/bacon-qr-code", @@ -9714,6 +9714,80 @@ }, "time": "2026-06-09T10:21:08+00:00" }, + { + "name": "laravel/dusk", + "version": "v8.6.0", + "source": { + "type": "git", + "url": "https://github.com/laravel/dusk.git", + "reference": "e7fd48762c6a82ad2cd311db07587aa2a97ce143" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/dusk/zipball/e7fd48762c6a82ad2cd311db07587aa2a97ce143", + "reference": "e7fd48762c6a82ad2cd311db07587aa2a97ce143", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-zip": "*", + "guzzlehttp/guzzle": "^7.5", + "illuminate/console": "^10.0|^11.0|^12.0|^13.0", + "illuminate/support": "^10.0|^11.0|^12.0|^13.0", + "php": "^8.1", + "php-webdriver/webdriver": "^1.15.2", + "symfony/console": "^6.2|^7.0|^8.0", + "symfony/finder": "^6.2|^7.0|^8.0", + "symfony/process": "^6.2|^7.0|^8.0", + "vlucas/phpdotenv": "^5.2" + }, + "require-dev": { + "laravel/framework": "^10.0|^11.0|^12.0|^13.0", + "mockery/mockery": "^1.6", + "orchestra/testbench-core": "^8.19|^9.17|^10.8|^11.0", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^10.1|^11.0|^12.0.1", + "psy/psysh": "^0.11.12|^0.12", + "symfony/yaml": "^6.2|^7.0|^8.0" + }, + "suggest": { + "ext-pcntl": "Used to gracefully terminate Dusk when tests are running." + }, + "type": "library", + "extra": { + "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/v8.6.0" + }, + "time": "2026-04-15T14:50:40+00:00" + }, { "name": "laravel/mcp", "version": "v0.8.1", @@ -10967,6 +11041,72 @@ }, "time": "2022-02-21T01:04:05+00:00" }, + { + "name": "php-webdriver/webdriver", + "version": "1.16.0", + "source": { + "type": "git", + "url": "https://github.com/php-webdriver/php-webdriver.git", + "reference": "ac0662863aa120b4f645869f584013e4c4dba46a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-webdriver/php-webdriver/zipball/ac0662863aa120b4f645869f584013e4c4dba46a", + "reference": "ac0662863aa120b4f645869f584013e4c4dba46a", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "ext-json": "*", + "ext-zip": "*", + "php": "^7.3 || ^8.0", + "symfony/polyfill-mbstring": "^1.12", + "symfony/process": "^5.0 || ^6.0 || ^7.0 || ^8.0" + }, + "replace": { + "facebook/webdriver": "*" + }, + "require-dev": { + "ergebnis/composer-normalize": "^2.20.0", + "ondram/ci-detector": "^4.0", + "php-coveralls/php-coveralls": "^2.4", + "php-mock/php-mock-phpunit": "^2.0", + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpunit/phpunit": "^9.3", + "squizlabs/php_codesniffer": "^3.5", + "symfony/var-dumper": "^5.0 || ^6.0 || ^7.0 || ^8.0" + }, + "suggest": { + "ext-simplexml": "For Firefox profile creation" + }, + "type": "library", + "autoload": { + "files": [ + "lib/Exception/TimeoutException.php" + ], + "psr-4": { + "Facebook\\WebDriver\\": "lib/" + } + }, + "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.16.0" + }, + "time": "2025-12-28T23:57:40+00:00" + }, { "name": "phpstan/phpstan", "version": "2.2.2", diff --git a/database/migrations/2026_06_23_121123_drop_users_uuid_unique_index.php b/database/migrations/2026_06_23_121123_drop_users_uuid_unique_index.php new file mode 100644 index 0000000..fce4167 --- /dev/null +++ b/database/migrations/2026_06_23_121123_drop_users_uuid_unique_index.php @@ -0,0 +1,28 @@ +dropUnique('users_uuid_unique'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('users', function (Blueprint $table) { + $table->unique('uuid'); + }); + } +}; diff --git a/tests/Browser/AuthenticationTest.php b/tests/Browser/AuthenticationTest.php deleted file mode 100644 index 400e5e8..0000000 --- a/tests/Browser/AuthenticationTest.php +++ /dev/null @@ -1,38 +0,0 @@ -browse(function (Browser $browser) { - // 1. Test Registration - $browser->visit('/register') - ->waitForText('Create an account') - ->type('name', 'New Browser User') - ->type('email', 'newbrowseruser@example.com') - ->type('password', 'password') - ->type('password_confirmation', 'password') - ->press('Create account') - ->waitForLocation('/dashboard') - ->assertPathIs('/dashboard') - ->assertSee('New Browser User'); - - // 2. Test Logout - // Open the user menu (trigger button shows initials or user name) - $browser->click('button[aria-haspopup="menu"]') - ->waitForText('Log out') - ->clickLink('Log out') - ->waitForLocation('/login') // Fortify logs out and redirects to login or home - ->assertPathIs('/login'); - - // 3. Test Login - $browser->type('email', 'newbrowseruser@example.com') - ->type('password', 'password') - ->press('Log in') - ->waitForLocation('/dashboard') - ->assertPathIs('/dashboard') - ->assertSee('New Browser User'); - }); -}); diff --git a/tests/Browser/AuthorizationTest.php b/tests/Browser/AuthorizationTest.php deleted file mode 100644 index cda7829..0000000 --- a/tests/Browser/AuthorizationTest.php +++ /dev/null @@ -1,82 +0,0 @@ -create([ - 'name' => 'Owner Alice', - 'email' => 'alice-owner@example.com', - 'password' => bcrypt('password'), - ]); - - $participant = User::factory()->create([ - 'name' => 'Participant Bob', - 'email' => 'bob-sub@example.com', - 'password' => bcrypt('password'), - ]); - - $outsider = User::factory()->create([ - 'name' => 'Outsider Charlie', - 'email' => 'charlie-outsider@example.com', - 'password' => bcrypt('password'), - ]); - - $dynamic = Dynamic::create([ - 'name' => 'Private Club', - 'rules' => 'Strict access control.', - ]); - - $dynamic->participants()->attach($owner->id, ['role' => 'owner']); - $dynamic->participants()->attach($participant->id, ['role' => 'participant']); - - $ledger = Ledger::create([ - 'dynamic_id' => $dynamic->id, - 'name' => 'Rules Compliance', - 'rules' => 'Score rules.', - 'score' => 100, - 'alignment' => 'neutral', - ]); - - $this->browse(function (Browser $sessionOwner, Browser $sessionParticipant, Browser $sessionOutsider) use ($dynamic, $ledger, $owner, $participant, $outsider) { - - // 1. Test Outsider trying to access dynamic they DO NOT belong to (should be forbidden / 403) - $sessionOutsider->loginAs($outsider) - ->visit(route('dynamics.show', $dynamic)) - ->assertSee('403') // Laravel / Inertia forbidden page - ->assertDontSee('Private Club'); - - // 2. Test Participant accessing dynamic they DO belong to (should be allowed) - $sessionParticipant->loginAs($participant) - ->visit(route('dynamics.show', $dynamic)) - ->waitForText('Private Club') - ->assertSee('Private Club') - ->assertSee('Participant Bob'); - - // 3. Test Participant adding a mutation suggestion - $sessionParticipant->visit(route('dynamics.ledgers.show', [$dynamic, $ledger])) - ->waitForText('Add Mutation') - ->type('amount', '20') - ->type('description', 'Cleaned the main room') - ->press('Add Mutation') - ->waitForText('PENDING') - ->assertSee('PENDING') // Mutation should show up as pending - ->assertDontSee('Approve'); // Standard participant should NOT see approve button! - - // 4. Test Owner logging in, seeing the pending suggestion, and approving it! - $sessionOwner->loginAs($owner) - ->visit(route('dynamics.ledgers.show', [$dynamic, $ledger])) - ->waitForText('Cleaned the main room') - ->assertSee('PENDING') - ->assertSee('Approve') // Owner should see the Approve button! - ->press('Approve') - ->waitForText('Score: 120') // Score updated from 100 to 120 after approval! - ->assertDontSee('PENDING'); // No longer pending! - }); -}); diff --git a/tests/Browser/BasicViewsTest.php b/tests/Browser/BasicViewsTest.php new file mode 100644 index 0000000..6f66d4a --- /dev/null +++ b/tests/Browser/BasicViewsTest.php @@ -0,0 +1,138 @@ +browse(function (Browser $browser) { + $browser->visit('/') + ->waitForText("Let's get started") + ->assertSee("Let's get started"); + }); + } + + /** + * Test that authenticated users can visit the dynamics index and see their dynamics. + */ + public function test_authenticated_users_can_visit_the_dynamics_index(): void + { + $user = User::factory()->create(); + $dynamic = Dynamic::factory()->create([ + 'name' => 'Dusk Automated Dynamic Index Test', + ]); + $dynamic->participants()->attach($user->id, ['role' => 'owner']); + + $this->browse(function (Browser $browser) use ($user, $dynamic) { + $browser->loginAs($user) + ->visit('/dynamics') + ->waitForText('Your Dynamics') + ->assertSee('Your Dynamics') + ->assertSee($dynamic->name); + }); + + // Clean up + $dynamic->participants()->detach(); + $dynamic->delete(); + $user->delete(); + } + + /** + * Test that authenticated users can visit a dynamic show page. + */ + public function test_authenticated_users_can_visit_a_dynamic_show_page(): void + { + $user = User::factory()->create(); + $dynamic = Dynamic::factory()->create([ + 'name' => 'Dusk Dynamic Show Test', + 'rules' => 'Rule 1: Always obey the automation.', + ]); + $dynamic->participants()->attach($user->id, ['role' => 'owner']); + + $this->browse(function (Browser $browser) use ($user, $dynamic) { + $browser->loginAs($user) + ->visit('/dynamics/' . $dynamic->uuid) + ->waitForText($dynamic->name) + ->assertSee($dynamic->name) + ->assertSee($dynamic->rules); + }); + + // Clean up + $dynamic->participants()->detach(); + $dynamic->delete(); + $user->delete(); + } + + /** + * Test that authenticated users can visit a ledger show page. + */ + public function test_authenticated_users_can_visit_a_ledger_show_page(): void + { + $user = User::factory()->create(); + $dynamic = Dynamic::factory()->create([ + 'name' => 'Dusk Dynamic Ledger Show Test', + ]); + $dynamic->participants()->attach($user->id, ['role' => 'owner']); + + $ledger = Ledger::factory()->create([ + 'dynamic_id' => $dynamic->id, + 'name' => 'Dusk Ledger Test', + 'score' => 42, + 'rules' => 'Scores are tracked for Dusk automated verification.', + ]); + + $this->browse(function (Browser $browser) use ($user, $dynamic, $ledger) { + $browser->loginAs($user) + ->visit('/dynamics/' . $dynamic->uuid . '/ledgers/' . $ledger->uuid) + ->waitForText($ledger->name) + ->assertSee($ledger->name) + ->assertSee('Score: 42') + ->assertSee($ledger->rules); + }); + + // Clean up + $ledger->delete(); + $dynamic->participants()->detach(); + $dynamic->delete(); + $user->delete(); + } + + /** + * Test that authenticated users can visit a participant profile page. + */ + public function test_authenticated_users_can_visit_a_participant_profile_page(): void + { + $user = User::factory()->create(); + $dynamic = Dynamic::factory()->create([ + 'name' => 'Dusk Participant Profile Test', + ]); + $dynamic->participants()->attach($user->id, ['role' => 'owner', 'display_name' => 'The Master']); + + $otherUser = User::factory()->create(); + $dynamic->participants()->attach($otherUser->id, ['role' => 'participant', 'display_name' => 'Bitch Bob']); + + $this->browse(function (Browser $browser) use ($user, $dynamic, $otherUser) { + $browser->loginAs($user) + ->visit('/dynamics/' . $dynamic->uuid . '/users/' . $otherUser->uuid) + ->waitForText('Bitch Bob') + ->assertSee('Bitch Bob') + ->assertSee('participant'); + }); + + // Clean up + $dynamic->participants()->detach(); + $dynamic->delete(); + $user->delete(); + $otherUser->delete(); + } +} diff --git a/tests/Browser/DashboardTest.php b/tests/Browser/DashboardTest.php new file mode 100644 index 0000000..97da67e --- /dev/null +++ b/tests/Browser/DashboardTest.php @@ -0,0 +1,19 @@ +create(); + + $this->browse(function (Browser $browser) use ($user) { + $browser->loginAs($user) + ->visit('/dashboard') + ->assertSee('Recent Activity'); + }); + } +} diff --git a/tests/Browser/LoginTest.php b/tests/Browser/LoginTest.php new file mode 100644 index 0000000..6d6310f --- /dev/null +++ b/tests/Browser/LoginTest.php @@ -0,0 +1,27 @@ +delete(); + + $user = User::factory()->create([ + 'email' => 'dusk@example.com', + ]); + + $this->browse(function (Browser $browser) use ($user) { + $browser->visit('/login') + ->waitFor('#email') + ->type('email', $user->email) + ->type('password', 'wrong-password') + ->press('[data-test="login-button"]') + ->assertPathIs('/login') + ->screenshot('login-error'); + }); + } +} diff --git a/tests/Browser/Pages/HomePage.php b/tests/Browser/Pages/HomePage.php new file mode 100644 index 0000000..45d9283 --- /dev/null +++ b/tests/Browser/Pages/HomePage.php @@ -0,0 +1,36 @@ + + */ + public function elements(): array + { + return [ + '@element' => '#selector', + ]; + } +} diff --git a/tests/Browser/Pages/Page.php b/tests/Browser/Pages/Page.php new file mode 100644 index 0000000..eb9a2de --- /dev/null +++ b/tests/Browser/Pages/Page.php @@ -0,0 +1,20 @@ + + */ + public static function siteElements(): array + { + return [ + '@element' => '#selector', + ]; + } +} diff --git a/tests/Browser/RealtimeChatTest.php b/tests/Browser/RealtimeChatTest.php index a8c2a39..dceadfc 100644 --- a/tests/Browser/RealtimeChatTest.php +++ b/tests/Browser/RealtimeChatTest.php @@ -5,61 +5,82 @@ namespace Tests\Browser; use App\Models\Dynamic; use App\Models\User; use Laravel\Dusk\Browser; +use Tests\DuskTestCase; -test('multiple sessions can communicate in real time through websockets', function () { - // 1. Create realistic database state - $owner = User::factory()->create([ - 'name' => 'TU Test User', - 'email' => 'test-owner@example.com', - 'password' => bcrypt('password'), - ]); +class RealtimeChatTest extends DuskTestCase +{ + /** + * Test that multiple browser sessions can communicate in real time through websockets. + */ + public function test_multiple_sessions_can_communicate_in_real_time(): void + { + // 1. Create realistic database state + $owner = User::factory()->create([ + 'name' => 'Owner Alice', + 'email' => 'alice-owner-' . uniqid() . '@example.com', + 'password' => bcrypt('password'), + ]); - $participant = User::factory()->create([ - 'name' => 'Submissive Bob', - 'email' => 'test-sub@example.com', - 'password' => bcrypt('password'), - ]); + $participant = User::factory()->create([ + 'name' => 'Submissive Bob', + 'email' => 'bob-participant-' . uniqid() . '@example.com', + 'password' => bcrypt('password'), + ]); - $dynamic = Dynamic::create([ - 'name' => 'The Test Sanctuary', - 'rules' => 'Rules for realtime testing.', - ]); + $dynamic = Dynamic::create([ + 'name' => 'The Velvet Realtime Test Sanctuary', + 'rules' => 'Rules for realtime testing.', + ]); - $dynamic->participants()->attach($owner->id, ['role' => 'owner']); - $dynamic->participants()->attach($participant->id, ['role' => 'participant']); + $dynamic->participants()->attach($owner->id, ['role' => 'owner']); + $dynamic->participants()->attach($participant->id, ['role' => 'participant']); - // 2. Spawn two separate browser sessions/browsers in parallel - $this->browse(function (Browser $sessionA, Browser $sessionB) use ($dynamic, $owner, $participant) { + // 2. Spawn two separate browser sessions/browsers in parallel + $this->browse(function (Browser $sessionA, Browser $sessionB) use ($dynamic, $owner, $participant) { + try { + // --- SESSION A: Owner --- + $sessionA->loginAs($owner) + ->visit('/dynamics/' . $dynamic->uuid) + ->waitForText('The Velvet Realtime Test Sanctuary') + ->assertSee('Owner Alice'); - // --- SESSION A: Owner --- - $sessionA->loginAs($owner) - ->visit(route('dynamics.show', $dynamic)) - ->waitForText('The Test Sanctuary') - ->assertSee('TU Test User'); // Verify loaded in as Owner + // --- SESSION B: Participant --- + $sessionB->loginAs($participant) + ->visit('/dynamics/' . $dynamic->uuid) + ->waitForText('The Velvet Realtime Test Sanctuary') + ->assertSee('Submissive Bob'); - // --- SESSION B: Participant --- - $sessionB->loginAs($participant) - ->visit(route('dynamics.show', $dynamic)) - ->waitForText('The Test Sanctuary') - ->assertSee('Submissive Bob'); // Verify loaded in as Submissive/Participant + // --- REAL-TIME COMMUNICATING --- + // Owner types and sends a message in chat + $sessionA->type('#content', 'Hello Submissive Bob, did you complete your daily chores?') + ->click('.c-chat__button') + ->waitForText('Hello Submissive Bob, did you complete your daily chores?'); - // --- REAL-TIME COMMUNICATING --- - // Owner types and sends a message in chat - $sessionA->type('#content', 'Hello Submissive Bob, did you complete your daily chores?') - ->click('.c-chat__button') - ->waitForText('Hello Submissive Bob'); + // Since websockets broadcast in real-time, Session B receives it without reloading + $sessionB->waitForText('Hello Submissive Bob, did you complete your daily chores?', 10) + ->assertSee('Hello Submissive Bob, did you complete your daily chores?'); - // Since websockets broadcast in real-time, Session B receives it without reloading - $sessionB->waitForText('Hello Submissive Bob', 5) - ->assertSee('Hello Submissive Bob, did you complete your daily chores?'); + // Participant replies in real-time + $sessionB->type('#content', 'Yes Master, everything is complete and logged!') + ->click('.c-chat__button') + ->waitForText('Yes Master, everything is complete and logged!'); - // Participant replies in real-time - $sessionB->type('#content', 'Yes Master, everything is complete and logged in the ledger!') - ->click('.c-chat__button') - ->waitForText('Yes Master, everything is complete'); + // Session A receives the reply in real-time without reloading + $sessionA->waitForText('Yes Master, everything is complete and logged!', 10) + ->assertSee('Yes Master, everything is complete and logged!'); + } catch (\Exception $e) { + echo "\n=== SESSION A CONSOLE LOGS ===\n"; + print_r($sessionA->driver->manage()->getLog('browser')); + echo "\n=== SESSION B CONSOLE LOGS ===\n"; + print_r($sessionB->driver->manage()->getLog('browser')); + throw $e; + } + }); - // Session A receives the reply in real-time without reloading - $sessionA->waitForText('Yes Master, everything is complete', 5) - ->assertSee('Yes Master, everything is complete and logged in the ledger!'); - }); -}); + // Clean up + $dynamic->participants()->detach(); + $dynamic->delete(); + $owner->delete(); + $participant->delete(); + } +} diff --git a/tests/DuskTestCase.php b/tests/DuskTestCase.php index 0ad682c..b1ff66e 100644 --- a/tests/DuskTestCase.php +++ b/tests/DuskTestCase.php @@ -7,6 +7,8 @@ use Facebook\WebDriver\Remote\DesiredCapabilities; use Facebook\WebDriver\Remote\RemoteWebDriver; use Laravel\Dusk\TestCase as BaseTestCase; +use Illuminate\Support\Collection; + abstract class DuskTestCase extends BaseTestCase { /** @@ -26,13 +28,13 @@ abstract class DuskTestCase extends BaseTestCase */ protected function driver(): RemoteWebDriver { - $options = (new ChromeOptions)->addArguments(collect([ + $options = (new ChromeOptions)->addArguments((new Collection([ $this->shouldStartMaximized() ? '--start-maximized' : '--window-size=1920,1080', '--disable-gpu', '--headless=new', '--no-sandbox', '--disable-dev-shm-usage', - ])->unless(static::runningInSail(), function (collect $arguments) { + ]))->unless(static::runningInSail(), function (Collection $arguments) { return $arguments->push('--disable-smooth-scrolling'); })->all()); diff --git a/tests/Pest.php b/tests/Pest.php index 97e9b1a..e91411e 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'); + use Illuminate\Foundation\Testing\RefreshDatabase; use Tests\TestCase;