Laravel Dusk: Simplifying Browser Testing for Web Developers

WhoAmI => notes.sohag.pro/author
Search for a command to run...

WhoAmI => notes.sohag.pro/author
No comments yet. Be the first to comment.
Understanding Feature Testing - The Restaurant Analogy Think of feature testing like being a food critic at a restaurant. Before giving a review, you test everything: from walking in the door, being seated, ordering food, to paying the bill. Similarl...
I had a solid list of reasons my life wasn't moving faster, until a grainy old lecture pointed out the one name missing from it

The finale isn't a victory lap. It's the story of the control I shipped that did nothing, the footgun still sitting in my demo, and the handful of things I'd keep exactly as they are.

How do you hold a large payment for a second pair of eyes without ever letting the unapproved money touch a balance, and how do you stream that decision to the outside world without standing up a broker?

How do you show the total under a parent account when the whole system refuses to store a balance? A recursive query, a trigger that refuses to draw a circle, and a rule about what actually has to sum to zero.

Every time I wanted to change an FX rate I had to edit a file on the server and restart the app. So I moved rates and markup into a live admin API, and then audited it hard enough to find the bug that quietly undid the whole thing.

Imagine you're building a complex web application and want to ensure everything works perfectly from a user's perspective. Enter Laravel Dusk – your friendly neighborhood browser testing companion! 🕵️♀️🌐
Laravel Dusk is an elegant browser automation and testing tool that allows you to write and run end-to-end tests for your web applications as if a real user were interacting with your site. No more manual clicking and checking – Dusk does the heavy lifting for you!

Laravel Dusk provides a simple, expressive API for automating and testing your web applications in a real browser environment. Unlike traditional unit or feature tests that check individual components, Dusk tests the entire user experience from start to finish.
Real browser testing
No JavaScript configuration required
Chrome and Firefox support
Easy element selection
Automatic screenshot capture on test failure
Interaction simulation (clicking, typing, scrolling)
Let's walk through a step-by-step setup process:
composer create-project --prefer-dist laravel/laravel dusk-demo
cd dusk-demo
composer require --dev laravel/dusk
php artisan dusk:install
php artisan dusk:chrome-driver
Let's explore some relatable testing scenarios that demonstrate Dusk's capabilities:
Imagine you're building a recipe sharing platform. You want to ensure users can successfully register.
<?php
namespace Tests\Browser;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Laravel\Dusk\Browser;
use Tests\DuskTestCase;
class RegistrationTest extends DuskTestCase
{
use DatabaseMigrations;
public function testSuccessfulRegistration()
{
$this->browse(function (Browser $browser) {
$browser->visit('/register')
->type('name', 'Jamie Oliver')
->type('email', 'jamie@example.com')
->type('password', 'SecureChef123!')
->type('password_confirmation', 'SecureChef123!')
->press('Register')
->assertPathIs('/dashboard')
->assertSee('Welcome, Jamie!');
});
}
}
Consider an e-commerce site where you want to test the complete checkout process:
public function testCompleteCheckoutProcess()
{
$this->browse(function (Browser $browser) {
$browser->visit('/products')
->clickLink('Add to Cart')
->assertSee('1 item in cart')
->click('@proceed-to-checkout')
->type('@card-number', '4111111111111111')
->type('@expiry-date', '12/25')
->type('@cvv', '123')
->press('Complete Purchase')
->waitForText('Order Confirmed')
->assertPathIs('/order/confirmation');
});
}
Dusk shines when dealing with dynamic content:
public function testAutocompleteFunctionality()
{
$this->browse(function (Browser $browser) {
$browser->visit('/search')
->type('#search-input', 'Laravel')
->waitForText('Laravel Dusk')
->clickLink('Laravel Dusk')
->assertPathIs('/docs/dusk');
});
}
Test how your site looks across different screen sizes:
public function testResponsiveNavigation()
{
$this->browse(function (Browser $browser) {
$browser->resize(375, 812) // iPhone X size
->visit('/')
->assertVisible('@mobile-menu-toggle')
->click('@mobile-menu-toggle')
->assertSee('Mobile Navigation Menu');
});
}
Testing scenarios for authenticated users is crucial for many web applications. Laravel Dusk makes it incredibly simple to simulate logged-in user interactions. Let's explore a comprehensive example that demonstrates authentication and subsequent actions.
<?php
namespace Tests\Browser;
use App\Models\User;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Laravel\Dusk\Browser;
use Tests\DuskTestCase;
class AuthenticatedUserTest extends DuskTestCase
{
use DatabaseMigrations;
/**
* A detailed test for an authenticated user's profile management
*/
public function testUserProfileManagement()
{
// Create a test user
$user = User::factory()->create([
'name' => 'John Doe',
'email' => 'john@example.com',
'password' => bcrypt('password123')
]);
$this->browse(function (Browser $browser) use ($user) {
$browser
// Navigate to login page
->visit('/login')
// Perform login
->type('email', $user->email)
->type('password', 'password123')
->press('Login')
// Assert successful login
->assertAuthenticated()
->assertPathIs('/dashboard')
// Navigate to profile page
->clickLink('Profile Settings')
->assertPathIs('/profile')
// Update profile information
->type('@name-input', 'John Smith')
->type('@bio-input', 'Software Engineer | Laravel Enthusiast')
// Upload profile picture (simulating file upload)
->attach('@profile-picture', storage_path('test-avatar.jpg'))
// Save profile changes
->press('Update Profile')
// Assert success message and updated information
->waitForText('Profile Updated Successfully')
->assertSee('John Smith')
->assertSee('Software Engineer | Laravel Enthusiast')
// Optional: Check notification or toast message
->assertVisible('@success-notification');
});
}
/**
* Test secure areas and authorization
*/
public function testUnauthorizedAccessRestriction()
{
$user = User::factory()->create();
$adminUser = User::factory()->create(['is_admin' => true]);
$this->browse(function (Browser $browser) use ($user, $adminUser) {
// Test regular user cannot access admin panel
$browser->loginAs($user)
->visit('/admin/dashboard')
->assertPathIs('/dashboard')
->assertSee('Unauthorized Access');
// Test admin user can access admin panel
$browser->loginAs($adminUser)
->visit('/admin/dashboard')
->assertPathIs('/admin/dashboard')
->assertSee('Admin Control Panel');
});
}
/**
* Simulate a complex workflow like creating a project
*/
public function testProjectCreationWorkflow()
{
$user = User::factory()->create();
$this->browse(function (Browser $browser) use ($user) {
$browser->loginAs($user)
->visit('/projects')
->clickLink('Create New Project')
// Fill out project details
->type('@project-name', 'Laravel Dusk Testing Guide')
->type('@project-description', 'A comprehensive guide to browser testing')
// Select project type
->select('@project-type', 'documentation')
// Invite team members
->type('@team-member-email', 'colleague@example.com')
->press('Add Team Member')
// Submit project
->press('Create Project')
// Assertions
->waitForText('Project Created Successfully')
->assertSee('Laravel Dusk Testing Guide')
->assertPathBeginsWith('/projects/');
});
}
}
Demonstrates logging in with a created user
Shows how to interact with form elements
Simulates file upload
Checks for successful profile updates
Verifies different user roles
Checks access restrictions
Demonstrates login with specific user types
Simulates a multi-step project creation process
Shows interaction with dropdowns, text inputs
Demonstrates team collaboration features
User Factory: Use Laravel's model factories to create test users
Login Methods:
Manual login via form
loginAs() method for quick authentication
Role-Based Testing: Verify different user permissions
Workflow Simulation: Test complete user journeys
Keep tests focused and specific
Use meaningful assertion messages
Leverage Dusk's built-in waiting mechanisms
Organize tests logically
Use environment-specific configurations
# Run all Dusk tests
php artisan dusk
# Run a specific test
php artisan dusk tests/Browser/RegistrationTest.php
Always reset the database between tests
Use different user roles and scenarios
Cover both positive and negative authentication flows
Test edge cases like password reset, email verification
Login with valid/invalid credentials
Password reset process
Email verification
Multi-factor authentication
Session management
Logout functionality
Laravel Dusk transforms browser testing from a tedious chore into an enjoyable, efficient process. By simulating real user interactions, you can catch issues before they reach production and ensure a smooth user experience.
Start with simple scenarios
Gradually increase test complexity
Integrate Dusk into your CI/CD pipeline
Keep your test suite lean and meaningful
Happy testing, Laravel developers! 🚀👩💻👨💻
Pro Tip: Combine Dusk with continuous integration tools like GitHub Actions or GitLab CI to automatically run tests on every code push.