orchestra/testbench-dusk
Helper for testing Laravel packages with Laravel Dusk. Provides a Testbench-based setup to run browser tests in a package development workflow, maintained under the Orchestra namespace with ongoing support and community contributions.
Install Dependencies:
composer require --dev orchestra/testbench-dusk
composer require --dev laravel/dusk
Configure Dusk:
Add DuskTestCase to your test class and extend Orchestra\Testbench\DuskTestCase:
use Orchestra\Testbench\DuskTestCase;
class ExampleDuskTest extends DuskTestCase
{
// Test methods here
}
First Use Case: Test a package's frontend functionality (e.g., a dashboard widget):
public function test_package_dashboard_widget()
{
$this->browse(function (Browser $browser) {
$browser->visit('/dashboard')
->assertSee('Package Widget Title');
});
}
Key Files:
tests/DuskTestCase.php (base class)tests/BrowserTests/ (Dusk test directory)phpunit.xml (ensure Dusk is enabled)Package Integration Testing:
beforeServingApplication() to mock package dependencies:
protected function beforeServingApplication()
{
$this->app->singleton('package.service', fn() => MockService::class);
}
Browser Automation:
$browser->visit('/admin')
->click('@submit-button')
->assertPathIs('/confirmation')
->assertSee('Success!');
Test Isolation:
beforeApplicationCreated():
protected function beforeApplicationCreated()
{
$this->app->make('db')->connection()->getSchemaBuilder()->dropAllTables();
}
Custom Commands:
$browser->visit('/')
->packageCommand('triggerEvent', ['param1', 'param2'])
->assertDumped('Expected output');
Testbench + Dusk Synergy:
Combine createApplication() with Dusk’s browser automation:
$this->app = $this->createApplication();
$this->app->register(\Your\Package\ServiceProvider::class);
Headless Mode: Run Dusk tests headless in CI:
php artisan dusk --headless --chrome-args="--no-sandbox"
Parallel Testing:
Use phpunit --group=dusk with parallel workers:
<!-- phpunit.xml -->
<phpunit>
<groups>
<group name="dusk">Dusk tests</group>
</groups>
</phpunit>
ChromeDriver Path:
CHROME_DRIVER environment variable points to the correct binary:
export CHROME_DRIVER=/usr/local/bin/chromedriver
--debug flag to see Dusk’s ChromeDriver resolution.Package Registration:
beforeServingApplication():
// ❌ Missing registration
protected function beforeServingApplication() {}
// ✅ Correct
protected function beforeServingApplication()
{
$this->app->register(\Your\Package\ServiceProvider::class);
}
State Persistence:
// ❌ Anti-pattern: Assumes state persists
$browser->visit('/')->click('@button');
// ✅ Pattern: Reset state explicitly
$this->app['cache']->forget('key');
Deprecated Methods:
tweakApplication() (use beforeServingApplication() instead):
// ❌ Deprecated
$this->tweakApplication(function ($app) {});
// ✅ Modern
protected function beforeServingApplication() {}
Slow Tests:
--chrome-args="--headless --disable-gpu" to speed up CI runs.DuskTestCase::useBrowserCache().Element Not Found:
@ prefix (e.g., @submit-button):
$browser->click('@submit-button')->assertSee('Error'); // Debug missing element
ChromeDriver Errors:
laravel/dusk and chromedriver versions.Custom Assertions:
$browser->assertPackageFeature('widget_visible', fn() => $browser->assertSee('Widget'));
Hooks:
beforeApplicationCreated()/afterApplicationCreated() for setup/teardown:
protected function beforeApplicationCreated()
{
$this->loadMigrationsFrom(__DIR__.'/../database/migrations');
}
Environment Config:
.env.testing for Dusk-specific settings:
BROWSER_DRIVER=chrome
CHROME_DRIVER=/path/to/chromedriver
Visual Regression:
How can I help you explore Laravel packages today?