Installation Require the package via Composer (ensure PHP version compatibility):
composer require alexandresalome/php-selenium
Note: Test with PHP 5.6+ due to Laravel 5.x compatibility. For Laravel 8/9/10, this may require polyfills or a fork.
First Use Case: Basic Selenium Interaction Create a standalone test script (not Laravel test) to verify functionality:
use Alexandresalome\Selenium\Selenium;
$selenium = new Selenium('http://localhost', 4444);
$selenium->start();
$selenium->open('/');
$selenium->type('id=username', 'testuser');
$selenium->click('id=submit');
$selenium->stop();
Key: Run this outside Laravel’s test suite first to isolate issues.
Where to Look First
src/Selenium.php for available methods (e.g., type(), click(), waitForPageToLoad()).selenium/standalone-firefox) running on localhost:4444.Combine Laravel’s TestCase with Selenium for UI testing:
use Alexandresalome\Selenium\Selenium;
use Illuminate\Foundation\Testing\TestCase;
class SeleniumTest extends TestCase
{
protected $selenium;
public function setUp(): void
{
$this->selenium = new Selenium('http://localhost', 4444);
$this->selenium->start();
$this->selenium->open('/login');
}
public function tearDown(): void
{
$this->selenium->stop();
}
public function testLoginForm()
{
$this->selenium->type('id=email', 'user@example.com');
$this->selenium->type('id=password', 'password123');
$this->selenium->click('id=submit');
$this->assertEquals('Dashboard', $this->selenium->getTitle());
}
}
Tip: Avoid Laravel’s RefreshDatabase trait—it conflicts with Selenium’s session management.
Bind the Selenium client to Laravel’s IoC container for dependency injection:
// app/Providers/AppServiceProvider.php
public function register()
{
$this->app->singleton(Selenium::class, function () {
return new Selenium(config('selenium.host'), config('selenium.port'));
});
}
Config in config/selenium.php:
return [
'host' => env('SELENIUM_HOST', 'localhost'),
'port' => env('SELENIUM_PORT', 4444),
];
Create a command to run Selenium scripts (e.g., for CI/CD):
php artisan make:command RunSeleniumScript
// app/Console/Commands/RunSeleniumScript.php
public function handle()
{
$selenium = app(Selenium::class);
$selenium->start();
$selenium->open('https://example.com');
$this->info('Selenium script executed.');
$selenium->stop();
}
Use Laravel’s Str helper to generate selectors dynamically:
use Illuminate\Support\Str;
$selector = 'css=' . Str::of($elementId)->prepend('#');
$selenium->click($selector);
Docker Setup: Use a Docker container for Selenium Server to avoid local installation:
# docker-compose.yml
services:
selenium:
image: selenium/standalone-firefox
ports:
- "4444:4444"
Run with docker-compose up -d before tests.
Error Handling: Wrap Selenium calls in try-catch blocks:
try {
$selenium->click('id=submit');
} catch (\Exception $e) {
$this->fail("Selenium error: " . $e->getMessage());
}
Laravel Queues: Offload Selenium tasks to queues (e.g., for long-running scripts):
use Illuminate\Support\Facades\Queue;
Queue::push(function () {
$selenium = app(Selenium::class);
$selenium->start();
// Heavy Selenium logic here
$selenium->stop();
});
Environment-Specific Config: Use Laravel’s config('selenium') to switch between local/staging/prod Selenium servers.
PHP Version Conflicts
call_user_func_array() errors in PHP 7.4+.if (!function_exists('call_user_func_array')) {
function call_user_func_array($callback, $args) {
return $callback(...$args);
}
}
Selenium Server Compatibility
selenium/standalone-chrome:latest) instead of outdated versions.Laravel Test Case Conflicts
setUp()/tearDown() not working as expected.PHPUnit\Framework\TestCase instead of Laravel’s TestCase:
use PHPUnit\Framework\TestCase;
class SeleniumTest extends TestCase { ... }
No Headless Support
java -jar selenium-server.jar -Dwebdriver.gecko.driver=geckodriver -Dwebdriver.firefox.marionette=true
Flaky Tests
ElementNotVisibleException.$selenium->waitForPageToLoad(10000);
$selenium->waitForElementPresent('id=element', 5000);
No Laravel Facades
Selenium::open() like a Facade.// app/Facades/Selenium.php
namespace App\Facades;
use Illuminate\Support\Facades\Facade;
class Selenium extends Facade { protected static function getFacadeAccessor() { return 'selenium'; } }
Register the binding in AppServiceProvider.Missing Modern Features
async/await or PHP 8 attributes.Selenium class to use modern PHP syntax.Enable Verbose Logging Add this to your Selenium instance to debug WebDriver commands:
$selenium = new Selenium('http://localhost', 4444, [
'browser' => '*firefox',
'verbose' => true,
]);
Check Selenium Server Logs If tests fail silently, inspect the Selenium Server logs:
docker logs <selenium-container-id>
Isolate Laravel vs. Selenium Issues Test the package in a plain PHP script first to rule out Laravel conflicts.
Custom Commands
Extend the Selenium class to add domain-specific methods:
class CustomSelenium extends Selenium
{
public function login($email, $password)
{
$this->type('id=email', $email);
$this->type('id=password', $password);
$this->click('id=submit');
}
}
Laravel Service Provider Add Laravel-specific features (e.g., session sharing):
// app/Providers/SeleniumServiceProvider.php
public function boot()
{
if ($this->app->runningInConsole()) {
$this->commands([
\App\Console\Commands\RunSeleniumScript::class,
]);
}
}
Test Helpers Create a trait for reusable Selenium assertions:
How can I help you explore Laravel packages today?