← All skills

Laravel Dusk Skill

E2e testingPHP

Copy and Paste in your Terminal

npx skills add https://github.com/LambdaTest/agent-skills.git --skill laravel-dusk-skill

Advanced patterns

Advanced topics and patterns for experienced users.

Laravel Dusk — Advanced Patterns & Playbook

Component & Page Objects

// tests/Browser/Pages/LoginPage.php
class LoginPage extends Page
{
    public function url() { return '/login'; }
    public function assert(Browser $browser) { $browser->assertPathIs($this->url()); }

    public function elements()
    {
        return [
            '@username' => '#email',
            '@password' => '#password',
            '@submit' => 'button[type="submit"]',
        ];
    }

    public function loginAs(Browser $browser, string $email, string $password)
    {
        $browser->type('@username', $email)
                ->type('@password', $password)
                ->click('@submit');
    }
}

// Component
class DatePicker extends Component
{
    public function selector() { return '.date-picker'; }

    public function selectDate(Browser $browser, string $date)
    {
        $browser->click('.trigger')
                ->waitFor('.calendar')
                ->click("[data-date='{$date}']");
    }
}

// Test
class LoginTest extends DuskTestCase
{
    public function test_admin_login(): void
    {
        $this->browse(function (Browser $browser) {
            $browser->visit(new LoginPage)
                    ->loginAs('admin@test.com', 'password')
                    ->assertPathIs('/dashboard')
                    ->assertSee('Welcome');
        });
    }

    // Multiple browsers
    public function test_chat(): void
    {
        $this->browse(function (Browser $first, Browser $second) {
            $first->loginAs(User::find(1))->visit('/chat');
            $second->loginAs(User::find(2))->visit('/chat');
            $first->type('#message', 'Hello!')->press('Send');
            $second->waitForText('Hello!');
        });
    }
}

Authentication Helpers

public function test_authenticated_page(): void
{
    $user = User::factory()->create();
    $this->browse(function (Browser $browser) use ($user) {
        $browser->loginAs($user)
                ->visit('/settings')
                ->assertSee($user->name);
    });
}

Anti-Patterns

  • ❌ Raw CSS selectors in tests — use dusk="name" attributes and @name syntax
  • $browser->pause(3000) — use waitFor, waitForText, waitUntilMissing
  • ❌ Database state from previous tests — use DatabaseMigrations trait
  • ❌ Missing ->screenshot() on failure — add to tearDown for debugging