behat/mink-browserkit-driver
Install Dependencies
composer require --dev behat/mink behat/mink-browserkit-driver symfony/browser-kit
--dev as this is a testing tool.Basic Configuration
Create a tests/Feature/ExampleTest.php:
use Behat\Mink\Mink;
use Behat\Mink\Session;
use Behat\Mink\Driver\BrowserKitDriver;
use Symfony\Component\HttpKernel\Client;
class ExampleTest extends \Tests\TestCase
{
public function testBrowserKitDriver()
{
$client = new Client($this->app); // Laravel's HTTP test client
$driver = new BrowserKitDriver($client);
$session = new Session($driver);
$mink = new Mink(['default' => $session]);
$page = $mink->getSession()->getPage();
$page->open('/');
$this->assertEquals('Home', $page->getTitle());
}
}
First Use Case
Integration with Laravel’s HTTP Tests
Extend Laravel’s HttpTestCase to reuse the Client:
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
class MinkTestCase extends BaseTestCase
{
protected function createMinkSession()
{
$client = $this->createClient();
$driver = new BrowserKitDriver($client);
return new Session($driver);
}
}
Reusable Mink Helper Methods
Add to tests/TestCase.php:
protected function mink()
{
static $mink;
if (!$mink) {
$mink = new Mink(['default' => $this->createMinkSession()]);
}
return $mink;
}
protected function visit($uri)
{
$this->mink()->getSession()->visit($uri);
}
Testing Forms and Submissions
$page = $this->mink()->getSession()->getPage();
$page->fillField('email', 'user@example.com');
$page->pressButton('Login');
$this->assertPathIs('/dashboard');
Assertions
$this->assertSession()->statusCodeEquals(200);
$this->assertSession()->elementExists('css', '.alert-success');
mix() helper in tests to generate URLs:
$page->open(mix('js/app.js'));
$this->actingAs(User::first());
$this->visit('/profile');
public function setUp(): void
{
parent::setUp();
$this->withoutExceptionHandling();
$this->artisan('migrate:fresh');
$this->beginDatabaseTransaction();
}
Session Management
actingAs() or manually set cookies:
$session = $this->mink()->getSession();
$session->setCookie(new Cookie('laravel_session', $this->app['session']->getId()));
Client between tests or use Laravel’s refreshApplication() in setUp().JavaScript Limitations
CSRF Token Mismatches
routes/web.php:
Route::middleware('web')->group(function () {
Route::middleware('guest')->group(function () {
// Test routes here
});
});
actingAs() with a user that has CSRF tokens pre-generated.Static Assets (CSS/JS)
APP_URL is set and mix() is configured:
putenv('APP_URL=http://localhost');
Inspect Responses Dump the raw response:
$response = $this->mink()->getSession()->getDriver()->getClient()->getResponse();
dd($response->getContent());
Enable Debug Mode Configure BrowserKitDriver to log requests:
$client = new Client($this->app, [
'debug' => true,
'headers' => ['HTTP_ACCEPT' => 'text/html'],
]);
Handle Redirects BrowserKitDriver follows redirects by default. Disable with:
$client->followRedirects(false);
Custom Middleware
Attach middleware to the Client for testing:
$client = new Client($this->app);
$client->getKernel()->addMiddleware(new \App\Middleware\TestMiddleware());
Mocking HTTP Requests
Use Http::fake() alongside Mink:
Http::fake();
$this->visit('/api/data');
Http::assertSent(function ($request) {
return $request->hasHeader('Authorization');
});
Headless Testing
Combine with Laravel’s HttpTestCase for hybrid tests:
public function testHybrid()
{
$response = $this->get('/');
$this->assertEquals(200, $response->status());
// Use Mink for DOM assertions
$this->visit('/');
$this->assertSession()->elementExists('css', 'h1');
}
Parallel Testing
BrowserKitDriver is not thread-safe. Run tests sequentially or use a separate Client per test class.
APP_URL in .env.testing or override in setUp():
putenv('APP_URL=http://test.example.com');
APP_ENV=testing is set to avoid caching issues.array or database session drivers for consistency:
'session' => [
'driver' => 'array',
],
How can I help you explore Laravel packages today?