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

Browser Kit Laravel Package

symfony/browser-kit

Symfony BrowserKit simulates a web browser in PHP for testing and automation. Make requests, follow links, and submit forms programmatically, with a built-in implementation that uses Symfony HttpClient to perform real HTTP requests.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require symfony/browser-kit
    

    BrowserKit is a standalone component but works seamlessly with Laravel’s built-in HTTP clients (e.g., Guzzle, Symfony HttpClient).

  2. First Use Case: Simulate a browser request to test a Laravel route:

    use Symfony\Component\BrowserKit\HttpBrowser;
    use Symfony\Component\HttpClient\HttpClient;
    
    $client = HttpClient::create();
    $browser = new HttpBrowser($client);
    
    // Navigate to a Laravel route
    $browser->request('GET', 'http://your-laravel-app.test/login');
    
    // Check response
    $response = $browser->getResponse();
    $content = $response->getContent();
    
  3. Where to Look First:

    • Official Documentation
    • History class for tracking navigation (e.g., $browser->getHistory()).
    • DomCrawler integration for parsing HTML responses (included in Symfony’s DOM component).

Implementation Patterns

Core Workflows in Laravel

1. Functional Testing

Replace manual testing or Laravel Dusk with BrowserKit for server-side rendered routes:

use Symfony\Component\BrowserKit\AbstractBrowser;
use Symfony\Component\DomCrawler\Crawler;

$browser = new HttpBrowser(HttpClient::create());
$browser->request('GET', '/dashboard');

// Assert content
$crawler = new Crawler($browser->getResponse()->getContent());
expect($crawler->filter('h1')->text())->toContain('Dashboard');

// Simulate form submission
$form = $crawler->selectButton('Submit')->form();
$browser->submit($form);

2. Data Scraping

Extract structured data from Laravel-powered pages (e.g., admin panels):

$browser = new HttpBrowser(HttpClient::create());
$browser->request('GET', '/admin/products', [
    'auth' => ['[email protected]', 'password'],
]);

$crawler = new Crawler($browser->getResponse()->getContent());
$products = $crawler->filter('.product-card')->each(function (Crawler $node) {
    return [
        'name' => $node->filter('.name')->text(),
        'price' => $node->filter('.price')->text(),
    ];
});

3. CI/CD Validation

Add a pre-deploy check in Laravel Forge/Envoyer:

// In a Laravel Artisan command or Envoyer hook
$browser = new HttpBrowser(HttpClient::create());
$browser->request('GET', 'https://staging-app.test/checkout');

// Verify critical elements
$this->assertTrue($browser->getHistory()->current()->getStatus() === 200);
$this->assertStringContainsString('Payment Successful', $browser->getResponse()->getContent());

4. Integration with Laravel Testing

Use BrowserKit in PHPUnit/Pest tests:

use Tests\TestCase;
use Symfony\Component\BrowserKit\HttpBrowser;

class CheckoutTest extends TestCase
{
    public function testCheckoutFlow()
    {
        $browser = new HttpBrowser(HttpClient::create());
        $browser->request('GET', '/cart');

        // Add item to cart (simulate user action)
        $browser->clickLink('Add to Cart');

        // Proceed to checkout
        $browser->clickLink('Checkout');

        $this->assertEquals(200, $browser->getHistory()->current()->getStatus());
    }
}

5. Handling Forms and Authentication

Simulate login and form submissions:

$browser = new HttpBrowser(HttpClient::create());

// Login
$browser->request('GET', '/login');
$form = $browser->getCrawler()->selectButton('Login')->form([
    'email' => '[email protected]',
    'password' => 'password123',
]);
$browser->submit($form);

// Verify auth
$this->assertStringContainsString('Welcome', $browser->getResponse()->getContent());

6. Cookie and Session Management

Persist sessions across requests:

$browser = new HttpBrowser(HttpClient::create());
$browser->request('GET', '/login'); // Set session cookie

// Subsequent requests reuse cookies
$browser->request('GET', '/dashboard');
$this->assertTrue($browser->getCookieJar()->has('laravel_session'));

7. Asynchronous Scraping with Queues

Offload scraping to Laravel Queues:

use Illuminate\Support\Facades\Queue;

Queue::push(function () {
    $browser = new HttpBrowser(HttpClient::create());
    $browser->request('GET', 'https://target-site.com/products');

    // Process data and store in DB
    $products = $browser->getCrawler()->filter('.product')->each(...);
    Product::insert($products);
});

Laravel-Specific Tips

Leverage Laravel’s HTTP Client

BrowserKit works with Laravel’s default HTTP client (Symfony HttpClient):

use Illuminate\Support\Facades\Http;

$browser = new HttpBrowser(Http::create());

Combine with Laravel Mix/Vite

Test static assets in CI:

$browser->request('GET', mix('assets/app.js'));
$this->assertEquals(200, $browser->getResponse()->getStatusCode());

Debugging with Telescope

Inspect BrowserKit requests in Laravel Telescope:

$browser->request('GET', '/admin');
Telescope::log('BrowserKit Request', [
    'url' => $browser->getHistory()->current()->getUri(),
    'status' => $browser->getResponse()->getStatusCode(),
]);

Custom Middleware

Add Laravel middleware to BrowserKit requests:

$client = HttpClient::create([
    'headers' => [
        'X-Custom-Header' => 'value',
    ],
    'auth_basic' => ['user', 'pass'],
]);
$browser = new HttpBrowser($client);

Gotchas and Tips

Pitfalls

1. No JavaScript Execution

  • Issue: BrowserKit cannot execute JavaScript. For SPAs or AJAX-heavy apps, use Symfony Panther (headless Chrome) instead.
  • Workaround: Pre-render JavaScript-heavy pages on the server or mock API responses.

2. Cookie Handling Quirks

  • Issue: Cookies may not persist across requests if the domain/path doesn’t match.
  • Fix: Ensure cookies are set with the correct Domain and Path attributes:
    $browser->getCookieJar()->set('laravel_session', 'value', [
        'domain' => '.yourdomain.test',
        'path' => '/',
    ]);
    

3. Redirect Loops

  • Issue: BrowserKit follows redirects by default, which can cause infinite loops if misconfigured.
  • Fix: Limit redirects or handle them manually:
    $browser->getClient()->setOptions([
        'max_redirects' => 3,
    ]);
    

4. Form Submission Edge Cases

  • Issue: Empty file inputs or CSRF tokens may break form submissions.
  • Fix: Use the submit() method with all required fields:
    $form = $browser->getCrawler()->selectButton('Upload')->form([
        'file' => null, // Handle empty files
        '_token' => $browser->getCrawler()->filter('input[name="_token"]')->attr('value'),
    ]);
    $browser->submit($form);
    

5. History Tracking

  • Issue: The History object may not reflect expected navigation if requests fail silently.
  • Fix: Check response statuses:
    $history = $browser->getHistory();
    $this->assertEquals(200, $history->current()->getStatus());
    

6. PHP 8.4+ HTML5 Parser

  • Issue: In PHP 8.4+, BrowserKit uses the native HTML5 parser, which may change parsing behavior.
  • Fix: Test edge cases (e.g., malformed HTML) in your CI pipeline.

Debugging Tips

1. Log Requests and Responses

$browser->getClient()->on('request', function ($event) {
    \Log::debug('Request:', [
        'url' => $event->getRequest()->getUri(),
        'headers' => $event->getRequest()->getHeaders(),
    ]);
});

$browser->getClient()->on('response', function ($event) {
    \Log::debug('Response:', [
        'status' => $event->getResponse()->getStatusCode(),
        'content' => $event->getResponse()->getContent(false),
    ]);
});
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.
calmfox/watch-sylius
damienfern/grpc-symfony-bundle
atoolo/index-bundle
atoolo/genai-bundle
coprotoai/laravel-ticket
davidjln/llm-carbon-bundle
cryonighter/valid-request-bundle
coolms/taxonomy-bundle
coolms/field-bundle
articulate-orm/symfony
aaix/laravel-tall-architect
ephoto/akeneo-connector
emmanuelballery/eb-plantumlbundle
emielburgman/symfony-visitor-beacon
emielburgman/symfony-visit-storage
emielburgman/symfony-security-headers
emielburgman/symfony-log-viewer
emarref/xdebug-bundle
emarref/pubnub-bundle
elriseio/finance-money-bundle