Table of contents

What are the debugging options available in Symfony Panther?

Symfony Panther provides extensive debugging capabilities to help developers troubleshoot browser automation and web scraping issues. These tools are essential for identifying problems in end-to-end tests and understanding browser behavior during scraping operations.

Visual Debugging

Screenshots

Capture the browser's visual state at any point during execution:

// Basic screenshot
$client->takeScreenshot('debug.png');

// Screenshot with timestamp
$client->takeScreenshot('screenshot_' . date('Y-m-d_H-i-s') . '.png');

// Automatic error screenshots (set via environment)
// PANTHER_ERROR_SCREENSHOT_DIR=/path/to/screenshots

Page Source Inspection

Examine the current DOM structure and content:

// Get complete page source
$html = $client->getPageSource();
file_put_contents('page_source.html', $html);

// Get specific element content
$crawler = $client->getCrawler();
$content = $crawler->filter('body')->html();
echo $content;

Console and Log Debugging

Browser Console Logs

Access JavaScript console output for debugging client-side issues:

$logs = $client->manage()->getLog('browser');
foreach ($logs as $log) {
    echo sprintf(
        "[%s] %s: %s\n",
        $log['level'],
        date('Y-m-d H:i:s', $log['timestamp'] / 1000),
        $log['message']
    );
}

WebDriver Logging

Enable detailed WebDriver communication logs:

use Facebook\WebDriver\Remote\WebDriverCapabilityType;

$client = \Symfony\Component\Panther\PantherTestCase::createPantherClient([
    'capabilities' => [
        WebDriverCapabilityType::LOGGING_PREFS => [
            'browser' => 'ALL',
            'driver' => 'ALL',
            'performance' => 'ALL',
        ],
    ],
]);

// Retrieve different types of logs
$browserLogs = $client->manage()->getLog('browser');
$driverLogs = $client->manage()->getLog('driver');
$performanceLogs = $client->manage()->getLog('performance');

Environment Variables for Debugging

Essential Debug Environment Variables

# Disable headless mode (show browser window)
PANTHER_NO_HEADLESS=1 ./vendor/bin/phpunit

# Automatically save error screenshots
PANTHER_ERROR_SCREENSHOT_DIR=/tmp/panther-screenshots ./vendor/bin/phpunit

# Keep browser open after test completion
PANTHER_DEVTOOLS=1 ./vendor/bin/phpunit

# Custom browser arguments for debugging
PANTHER_BROWSER_ARGS="--disable-web-security --remote-debugging-port=9222"

Complete Debug Setup

# Comprehensive debugging environment
export PANTHER_NO_HEADLESS=1
export PANTHER_ERROR_SCREENSHOT_DIR=/tmp/debug-screenshots
export PANTHER_DEVTOOLS=1
export PANTHER_NO_SANDBOX=1

./vendor/bin/phpunit tests/E2E/

Advanced Debugging Techniques

Network Request Monitoring

Track HTTP requests and responses:

// Enable network logging
$client = \Symfony\Component\Panther\PantherTestCase::createPantherClient([
    'capabilities' => [
        WebDriverCapabilityType::LOGGING_PREFS => [
            'performance' => 'ALL',
        ],
    ],
]);

// Analyze network activity
$performanceLogs = $client->manage()->getLog('performance');
foreach ($performanceLogs as $log) {
    $message = json_decode($log['message'], true);
    if ($message['message']['method'] === 'Network.responseReceived') {
        $response = $message['message']['params']['response'];
        echo "URL: " . $response['url'] . "\n";
        echo "Status: " . $response['status'] . "\n";
    }
}

Wait Debugging

Debug timing and synchronization issues:

use Symfony\Component\Panther\DomCrawler\Crawler;

try {
    // Wait with custom timeout and debugging
    $client->waitFor('.dynamic-content', 10);
} catch (\Exception $e) {
    // Take screenshot before timeout
    $client->takeScreenshot('timeout_error.png');

    // Check what elements are currently present
    $crawler = $client->getCrawler();
    $elements = $crawler->filter('*[class*="dynamic"]');
    echo "Found " . $elements->count() . " dynamic elements\n";

    throw $e;
}

Error Handling and Exception Debugging

Comprehensive Error Handling

use Symfony\Component\Panther\Exception\RuntimeException;
use Facebook\WebDriver\Exception\TimeoutException;

try {
    $crawler = $client->request('GET', 'https://example.com');
    $client->waitFor('.content');

} catch (TimeoutException $e) {
    // Handle timeout specifically
    $client->takeScreenshot('timeout_' . time() . '.png');
    echo "Timeout waiting for element: " . $e->getMessage() . "\n";

} catch (RuntimeException $e) {
    // Handle Panther-specific errors
    $client->takeScreenshot('runtime_error_' . time() . '.png');
    echo "Runtime error: " . $e->getMessage() . "\n";

} catch (\Throwable $e) {
    // Catch-all for unexpected errors
    $client->takeScreenshot('unexpected_error_' . time() . '.png');
    file_put_contents('error_log.txt', $client->getPageSource());
    throw $e;
}

Symfony Profiler Integration

Accessing Profiler Data

// Only available when testing Symfony applications
$profile = $client->getProfile();
if ($profile) {
    // Database queries
    $dbCollector = $profile->getCollector('db');
    echo "Queries executed: " . $dbCollector->getQueryCount() . "\n";

    // HTTP kernel information
    $requestCollector = $profile->getCollector('request');
    echo "Controller: " . $requestCollector->getController() . "\n";

    // Memory usage
    $memoryCollector = $profile->getCollector('memory');
    echo "Memory usage: " . $memoryCollector->getMemory() . " bytes\n";
}

Interactive Debugging Workflow

Step-by-Step Debug Process

// 1. Enable visual debugging
$client = \Symfony\Component\Panther\PantherTestCase::createPantherClient();

// 2. Navigate and take initial screenshot
$crawler = $client->request('GET', 'https://example.com');
$client->takeScreenshot('step1_initial.png');

// 3. Check for JavaScript errors
$consoleLogs = $client->manage()->getLog('browser');
$errors = array_filter($consoleLogs, fn($log) => $log['level'] === 'SEVERE');
if (!empty($errors)) {
    echo "JavaScript errors found:\n";
    foreach ($errors as $error) {
        echo "- " . $error['message'] . "\n";
    }
}

// 4. Interact and capture state
$client->clickLink('Login');
$client->takeScreenshot('step2_after_click.png');

// 5. Fill forms with debugging
$form = $crawler->selectButton('Submit')->form();
$client->submit($form, ['username' => 'test', 'password' => 'test']);
$client->takeScreenshot('step3_form_submitted.png');

Best Practices for Debugging

  1. Use meaningful screenshot names with timestamps and step descriptions
  2. Combine multiple debugging methods for comprehensive troubleshooting
  3. Set up automatic error screenshots for CI/CD environments
  4. Monitor console logs for JavaScript-heavy applications
  5. Use environment variables to enable debugging only when needed
  6. Save page source along with screenshots for complete context

These debugging options make Symfony Panther a powerful tool for both development and production troubleshooting of browser automation tasks.

Try WebScraping.AI for Your Web Scraping Needs

Looking for a powerful web scraping solution? WebScraping.AI provides an LLM-powered API that combines Chromium JavaScript rendering with rotating proxies for reliable data extraction.

Key Features:

  • AI-powered extraction: Ask questions about web pages or extract structured data fields
  • JavaScript rendering: Full Chromium browser support for dynamic content
  • Rotating proxies: Datacenter and residential proxies from multiple countries
  • Easy integration: Simple REST API with SDKs for Python, Ruby, PHP, and more
  • Reliable & scalable: Built for developers who need consistent results

Getting Started:

Get page content with AI analysis:

curl "https://api.webscraping.ai/ai/question?url=https://example.com&question=What is the main topic?&api_key=YOUR_API_KEY"

Extract structured data:

curl "https://api.webscraping.ai/ai/fields?url=https://example.com&fields[title]=Page title&fields[price]=Product price&api_key=YOUR_API_KEY"

Try in request builder

Related Questions

Get Started Now

WebScraping.AI provides rotating proxies, Chromium rendering and built-in HTML parser for web scraping
Icon