Service

Selenium --- HTML to Image Conversion

Selenium is used to convert HTML elements into images. Its main use case is exporting reports to PDF or capturing the current page as an image.

How it Works

Selenium operates as a persistent web browser instance that remains open and available, controllable via the php-webdriver/webdriver SDK.

  • In production: The instance is accessible via a dedicated URL and must run in headless mode for performance optimization. https://admin:[email protected]
  • In local development: Selenium runs in docker-compose. It can be used in non-headless mode to visually observe actions via a VNC viewer.

Local URLs:


Local URL Management

Locally, Selenium runs inside Docker and cannot reach localhost. The Docker network alias bx.feedier.test is configured so that Selenium can access the application.

[!IMPORTANT] Local Configuration Required: For Selenium to correctly capture elements, it is imperative that you run the frontend using the following command: sail npm run dev. The use of sail here is crucial so that the asset server is accessible within the Docker network.

Docker Configuration

# docker-compose.yml
networks:
    sail:
        aliases:
            - bx.feedier.test
            - api.bx.feedier.test

URL Resolution

The INTERNAL_URL environment variable is used to build URLs that Selenium can resolve:

INTERNAL_URL=http://bx.feedier.test

The URL builder in ReportDownloader handles this automatically:

protected function getInternalLink(): string
{
    $token = encrypt([
        'report_id' => $this->report->id,
        'ttl'       => now()->addSeconds(self::LINK_VALIDITY_IN_SECONDS),
        'user_id'   => $this->user->id,
    ]);

    $params = [
        'reportId'         => $this->report->id,
        'token'            => $token,
        'type'             => 'internal',
        'locale'           => app()->getLocale(),
        'transition'       => false,
        'disableAnimation' => true,
        'maxPage'          => self::REPORT_DOWNLOAD_MAX_PAGES,
    ];

    if ($internalUrl = config('app.internal_url')) {
        return rtrim($internalUrl, '/') . route('report.shareable', $params, false);
    }

    return route('report.shareable', $params, true);
}

Configuration

// config/selenium.php
return [
    'url'     => env('SELENIUM_URL', 'http://localhost:4444'),
    'browser' => [
        'name' => 'firefox',
        'args' => ['-headless'],
    ],
];

Code snippet

# .env
SELENIUM_URL=http://selenium:4444

Technical Implementation

Creating a Remote WebDriver Instance

$remoteDriver = RemoteWebDriver::create(
    config('selenium.url'),
    $this->getBrowserCapabilities()
);

Viewport Settings

$remoteDriver->manage()
    ->window()
    ->setSize(new WebDriverDimension(1920, 1080));

Screenshot Capture

$element->takeElementScreenshot($path);

Download Pipelines

Image Capture

// app/Services/Report/Downloaders/ImageDownload.php
Bus::chain([
    new ConvertHTMLElementToImage(
        url: $this->getInternalLink(),
        cssSelector: '[data-capture]',
        savingPath: $temporaryPath,
        paginate: true,
        extension: $this->format->value,
        user: $this->user,
        taskId: $this->taskId,
        maxPages: ReportDownloader::REPORT_DOWNLOAD_MAX_PAGES,
    ),
    new FinalizeImageDownload(...),
])->dispatch();

PDF Capture

The PDF pipeline chains the Selenium capture with the Dompdf merge:

// app/Services/Report/Downloaders/PdfDownload.php
Bus::chain([
    new ConvertHTMLElementToImage(...),
    new MergeImagesInFolderToPDF(...),
])->dispatch();

Scale (Pixel Density)

The recommended viewport size follows a 16:9 ratio: 1920×1080.

The scale factor (scale) controls the pixel density:

  • Debug Mode: Use a scale of 1 (default).
  • Production: Use a scale of 5 (recommended minimum: 3).

A high scale factor is essential for readability. Without it, screenshots will be blurry.


Key Reference Files

  • config/selenium.php --- Selenium Configuration
  • config/report-download.php --- Timeout Configuration
  • app/Jobs/Report/Download/ConvertHTMLElementToImage.php --- Main Selenium Job
  • app/Services/Report/ReportDownloader.php --- URL Generator
  • app/Services/Report/Downloaders/ImageDownload.php --- Image Pipeline
  • app/Services/Report/Downloaders/PdfDownload.php --- PDF Pipeline
Previous
Autopilot