// Laravel Dusk - Browser automation and testing API for Laravel applications. Use when writing browser tests, automating UI testing, testing JavaScript interactions, or implementing end-to-end tests in Laravel.
| name | laravel-dusk |
| description | Laravel Dusk - Browser automation and testing API for Laravel applications. Use when writing browser tests, automating UI testing, testing JavaScript interactions, or implementing end-to-end tests in Laravel. |
Comprehensive assistance with Laravel Dusk browser automation and testing, providing expert guidance on writing expressive, easy-to-use browser tests for your Laravel applications.
This skill should be triggered when:
public function testBasicExample(): void
{
$this->browse(function (Browser $browser) {
$browser->visit('/login')
->type('email', 'user@example.com')
->type('password', 'password')
->press('Login')
->assertPathIs('/home');
});
}
<!-- In your Blade template -->
<button dusk="login-button">Login</button>
<input dusk="email-input" name="email" />
// In your test - use @ prefix for dusk selectors
$browser->type('@email-input', 'user@example.com')
->click('@login-button');
public function testMultiUserInteraction(): void
{
$this->browse(function (Browser $first, Browser $second) {
$first->loginAs(User::find(1))
->visit('/home');
$second->loginAs(User::find(2))
->visit('/home');
});
}
// Wait for element to appear
$browser->waitFor('.modal')
->assertSee('Confirmation Required');
// Wait for text to appear
$browser->waitForText('Hello World');
// Wait for JavaScript condition
$browser->waitUntil('App.data.servers.length > 0');
// Wait when element is available
$browser->whenAvailable('.modal', function (Browser $modal) {
$modal->assertSee('Delete Account')
->press('OK');
});
// Text input
$browser->type('email', 'user@example.com')
->append('notes', 'Additional text')
->clear('description');
// Dropdown selection
$browser->select('size', 'Large')
->select('categories', ['Art', 'Music']); // Multiple
// Checkboxes and radio buttons
$browser->check('terms')
->radio('gender', 'male');
// File upload
$browser->attach('photo', __DIR__.'/photos/profile.jpg');
// Generate page object
// php artisan dusk:page Login
// app/tests/Browser/Pages/Login.php
class Login extends Page
{
public function url(): string
{
return '/login';
}
public function elements(): array
{
return [
'@email' => 'input[name=email]',
'@password' => 'input[name=password]',
'@submit' => 'button[type=submit]',
];
}
public function login(Browser $browser, $email, $password): void
{
$browser->type('@email', $email)
->type('@password', $password)
->press('@submit');
}
}
// Use in test
$browser->visit(new Login)
->login('user@example.com', 'password')
->assertPathIs('/dashboard');
// In AppServiceProvider or DuskServiceProvider
use Laravel\Dusk\Browser;
Browser::macro('scrollToElement', function (string $element) {
$this->script("$('html, body').animate({
scrollTop: $('{$element}').offset().top
}, 0);");
return $this;
});
// Use in tests
$browser->scrollToElement('#footer')
->assertSee('Copyright 2024');
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTruncation;
class ExampleTest extends DuskTestCase
{
// Option 1: Run migrations before each test (slower)
use DatabaseMigrations;
// Option 2: Truncate tables after first migration (faster)
use DatabaseTruncation;
// Exclude specific tables from truncation
protected $exceptTables = ['migrations'];
}
// Execute JavaScript
$browser->script('document.documentElement.scrollTop = 0');
// Get JavaScript return value
$path = $browser->script('return window.location.pathname');
// Wait for reload after action
$browser->waitForReload(function (Browser $browser) {
$browser->press('Submit');
})->assertSee('Success');
// Page assertions
$browser->assertPathIs('/dashboard')
->assertRouteIs('dashboard')
->assertTitle('Dashboard')
->assertSee('Welcome Back')
->assertDontSee('Error');
// Form assertions
$browser->assertInputValue('email', 'user@example.com')
->assertChecked('remember')
->assertSelected('role', 'admin')
->assertEnabled('submit-button');
// Element assertions
$browser->assertVisible('.success-message')
->assertMissing('.error-alert')
->assertPresent('button[type=submit]');
// Authentication assertions
$browser->assertAuthenticated()
->assertAuthenticatedAs($user);
Dusk selectors (recommended) use HTML dusk attributes that won't change with UI updates:
@ prefix in tests: $browser->click('@submit-button')<button dusk="submit-button">Submit</button>CSS selectors are more brittle but sometimes necessary:
.class-name, #id, div > buttonAlways wait explicitly rather than using arbitrary pauses:
waitFor('.selector') - Wait for element to existwaitUntilMissing('.selector') - Wait for element to disappearwaitForText('text') - Wait for text to appearwaitUntil('condition') - Wait for JavaScript conditionwhenAvailable('.selector', callback) - Run callback when availableOrganize complex test logic into Page classes:
php artisan dusk:page PageNameDefine reusable browser methods for common patterns:
boot() methodThis skill includes comprehensive documentation in references/:
Use the reference file when you need:
visit(), type(), press(), and assertSee() methodsdusk attributes to your HTML for stable selectorswaitFor() instead of pause() for reliable testsphp artisan dusk to see resultsDatabaseMigrations or DatabaseTruncationloginAs() to bypass login screenswaitUntil() for dynamic content and AJAXwaitUsing() for complex conditionsother.md for complete API reference# Install Laravel Dusk
composer require laravel/dusk --dev
# Run installation
php artisan dusk:install
# Update ChromeDriver
php artisan dusk:chrome-driver
# Make binaries executable (Unix)
chmod -R 0755 vendor/laravel/dusk/bin/
# Run tests
php artisan dusk
# Generate new test
php artisan dusk:make LoginTest
# Generate page object
php artisan dusk:page Dashboard
# Generate component
php artisan dusk:component Modal
# Run all tests
php artisan dusk
# Run specific test
php artisan dusk tests/Browser/LoginTest.php
# Run failed tests only
php artisan dusk:fails
# Run with filter
php artisan dusk --group=authentication
# Update ChromeDriver
php artisan dusk:chrome-driver --detect
references/other.md for complete method listingsThe reference documentation includes:
dusk attributes) instead of CSS classes for stabilitywaitFor() methods instead of arbitrary pause()with() or elsewhere() for specific page regionsloginAs() to skip login flowsscreenshot() for debugging failures--group flag for targeted executionChromeDriver version mismatch:
php artisan dusk:chrome-driver --detect
Elements not found:
waitFor('.selector') before interactingTests failing randomly:
pause() with explicit waitswaitFor('.selector', 10)waitUntil() for JavaScript conditionsDatabase state issues:
DatabaseTruncation traitsetUp() methodtests/Browser directorytests/Browser/Pagestests/Browser/screenshots on failuretests/Browser/console for debugging