Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Dusk Laravel Package

laravel/dusk

Laravel Dusk is Laravel’s browser automation and end-to-end testing tool, offering a clean, expressive API for driving real browsers. Runs with a bundled standalone Chromedriver by default (no Selenium/JDK required), but supports other drivers too.

View on GitHub
Deep Wiki
Context7
## Getting Started

### Minimal Setup
1. **Installation**:
   ```bash
   composer require --dev laravel/dusk
   laravel/dusk:install

This installs Chromedriver (standalone) and configures PHPUnit.

  1. First Test: Create a test in tests/Browser/ExampleTest.php:

    use Laravel\Dusk\Browser;
    use Tests\DuskTestCase;
    
    class ExampleTest extends DuskTestCase
    {
        /** @test */
        public function it_loads_the_homepage()
        {
            $this->browse(function (Browser $browser) {
                $browser->visit('/')
                        ->assertSee('Welcome');
            });
        }
    }
    

    Run with:

    php artisan dusk
    
  2. Key Files:

    • tests/Browser/ – Default test directory.
    • dusk.php – Configuration file (e.g., browser drivers, timeouts).
    • phpunit.xml – PHPUnit configuration (includes Dusk-specific settings).

Implementation Patterns

Core Workflows

  1. Browser Interaction: Use fluent methods for common actions:

    $browser->visit('/dashboard')
            ->click('@login-button')
            ->type('@email', 'user@example.com')
            ->press('@submit')
            ->assertPathIs('/dashboard');
    
    • Selectors: Use @id, .class, #element, or custom CSS selectors.
    • Dynamic Selectors: Chain methods like where():
      $browser->click('@submit')->where('disabled', false);
      
  2. Page Objects: Encapsulate complex pages in Page classes (auto-generated via php artisan dusk:page):

    namespace Tests\Browser\Pages;
    
    use Laravel\Dusk\Page;
    
    class DashboardPage extends Page
    {
        public function assertSeeUser($name)
        {
            return $this->assertSee($name);
        }
    }
    

    Usage:

    $this->browse(function (Browser $browser) {
        $browser->visit('/dashboard')
                ->assertSeeUser('John Doe');
    });
    
  3. Component Testing: Test Vue/React components with assertVue():

    $browser->assertVue('welcome', [
        'message' => 'Hello, Dusk!',
    ]);
    
  4. Data-Driven Tests: Use PHPUnit data providers:

    public function providerTestData()
    {
        return [
            ['user1@example.com', 'User 1'],
            ['user2@example.com', 'User 2'],
        ];
    }
    
    /** @dataProvider providerTestData */
    public function test_login($email, $name)
    {
        $this->browse(function (Browser $browser) use ($email, $name) {
            $browser->visit('/login')
                    ->type('@email', $email)
                    ->press('@submit')
                    ->assertSee($name);
        });
    }
    
  5. Debugging Tools:

    • Screenshots: $browser->screenshot('login-page');
    • Console Logs: $browser->dumpConsoleLogs();
    • Element Screenshots: $browser->elementScreenshot('@login-button');
  6. Custom Assertions: Extend MakesAssertions or create helper methods:

    $browser->assertElementVisible('@submit')
            ->assertAttributeContains('@input', 'value', 'test');
    

Integration Tips

  1. CI/CD:

    • Use DUSK_DRIVER=chrome to specify the browser.
    • Cache Chromedriver in CI (e.g., GitHub Actions):
      - name: Cache Chromedriver
        uses: actions/cache@v3
        with:
          path: ~/.cache/chromedriver
          key: ${{ runner.os }}-chromedriver
      
  2. Headless Mode: Configure in dusk.php:

    'headless' => [
        'chrome' => true,
        'firefox' => false,
    ],
    

    Or override per test:

    $this->browse(function (Browser $browser) {
        $browser->driver->setHeadless(true);
        // ...
    });
    
  3. Parallel Testing: Use PHPUnit’s --parallel flag:

    php artisan dusk --parallel
    
  4. Database Transactions: Leverage Laravel’s transactions in DuskTestCase:

    protected function setUp(): void
    {
        parent::setUp();
        $this->artisan('migrate:fresh');
    }
    
  5. Custom Drivers: Extend ChromeDriver or FirefoxDriver for custom logic:

    class CustomDriver extends ChromeDriver
    {
        public function customMethod()
        {
            // ...
        }
    }
    

    Register in dusk.php:

    'drivers' => [
        'custom' => [
            'class' => \Tests\Browser\CustomDriver::class,
        ],
    ],
    

Gotchas and Tips

Pitfalls

  1. Selector Ambiguity:

    • Avoid overly generic selectors (e.g., .btn). Use IDs or data attributes:
      <button data-testid="submit-btn">Submit</button>
      
      $browser->click('@submit-btn');
      
  2. Flaky Tests:

    • Solutions:
      • Add explicit waits:
        $browser->waitFor(5)->assertSee('Content');
        
      • Use waitForTextIn() for dynamic content:
        $browser->waitForTextIn('@element', 'Expected Text', 10);
        
      • Disable animations in dusk.php:
        'chrome' => [
            'args' => ['--disable-gpu', '--no-sandbox', '--disable-dev-shm-usage'],
        ],
        
  3. Chromedriver Version Mismatch:

    • Ensure Chrome and Chromedriver versions align. Update via:
      composer require --dev laravel/dusk --dev
      php artisan dusk:chrome-driver
      
  4. Slow Tests:

    • Optimizations:
      • Skip unnecessary assertions.
      • Use ->withoutMiddleware() for API-heavy tests:
        $this->browse(function (Browser $browser) {
            $browser->withoutMiddleware()->visit('/api/endpoint');
        });
        
      • Parallelize tests (see Integration Tips).
  5. Environment Issues:

    • Common Fixes:
      • Ensure .env exists in the project root.
      • Set APP_ENV=testing and DB_CONNECTION=sqlite for isolated tests.
      • For Docker, bind-mount Chromedriver or use a pre-installed image.
  6. Assertion Failures:

    • Debugging:
      • Use dd($browser->html()) to inspect the DOM.
      • Check for hidden elements with:
        $browser->assertVisible('@element');
        

Tips

  1. Reusable Test Logic: Create helper methods in DuskTestCase:

    protected function loginAsUser($email, $password)
    {
        $this->browse(function (Browser $browser) use ($email, $password) {
            $browser->visit('/login')
                    ->type('@email', $email)
                    ->type('@password', $password)
                    ->press('@submit');
        });
    }
    
  2. Visual Regression Testing: Use elementScreenshot() to compare UI states:

    $browser->elementScreenshot('@header', 'header-before-login');
    
  3. Custom Commands: Extend Browser for domain-specific actions:

    namespace Tests\Browser;
    
    use Laravel\Dusk\Browser;
    
    class CustomBrowser extends Browser
    {
        public function fillForm(array $data)
        {
            foreach ($data as $field => $value) {
                $this->type("@{$field}", $value);
            }
            return $this;
        }
    }
    

    Usage:

    $this->browse(function (CustomBrowser $browser) {
        $browser->fillForm(['email' => 'test@example.com', 'name' => 'Test']);
    });
    
  4. Performance Profiling: Measure test execution time:

    $start = microtime(true);
    $this->browse(function (Browser $browser) { /* ... */ });
    $time = microtime(true) - $start;
    $this->assertLessThan(2, $time, 'Test took too long');
    
  5. Cross-Browser Testing: Configure multiple drivers in dusk.php:

    'drivers' => [
        'chrome' => [
            'path' => '/path/to/chromedriver',
        ],
        'firefox' => [
            'path' => '/path/to/geckodriver',
        ],
    ],
    

    Run specific driver:

    DUSK_DRIVER
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport