facebook/webdriver
Archived Selenium WebDriver bindings for PHP. Controls browsers via Selenium 2–4 using JsonWireProtocol and partial W3C WebDriver support. Install with Composer and connect to a running selenium-server. Use php-webdriver/php-webdriver for current updates.
Installation
composer require php-webdriver/php-webdriver
(Note: The original facebook/webdriver is archived; use php-webdriver/php-webdriver as the README suggests.)
Basic Usage
use Facebook\WebDriver\Remote\RemoteWebDriver;
use Facebook\WebDriver\WebDriverBy;
$host = 'http://localhost:4444/wd/hub'; // Selenium Server
$capabilities = Facebook\WebDriver\Remote\DesiredCapabilities::chrome();
$driver = RemoteWebDriver::create($host, $capabilities);
$driver->get('https://example.com');
echo $driver->getTitle();
$driver->quit();
First Use Case Automate a login flow:
$driver->findElement(WebDriverBy::name('username'))->sendKeys('user@example.com');
$driver->findElement(WebDriverBy::name('password'))->sendKeys('password123');
$driver->findElement(WebDriverBy::name('submit'))->click();
Page Object Pattern Encapsulate interactions in reusable classes:
class LoginPage {
private $driver;
public function __construct(RemoteWebDriver $driver) {
$this->driver = $driver;
}
public function login($username, $password) {
$this->driver->findElement(WebDriverBy::name('username'))->sendKeys($username);
$this->driver->findElement(WebDriverBy::name('password'))->sendKeys($password);
$this->driver->findElement(WebDriverBy::name('submit'))->click();
}
}
Test Integration Use with PHPUnit for E2E testing:
use Facebook\WebDriver\Testing\FBWebDriverTestCase;
class ExampleTest extends FBWebDriverTestCase {
public function testExample() {
$this->driver->get('https://example.com');
$this->assertEquals('Example Domain', $this->driver->getTitle());
}
}
Dynamic Element Handling Wait for elements with explicit waits:
use Facebook\WebDriver\WebDriverWait;
use Facebook\WebDriver\ExpectedCondition;
$wait = new WebDriverWait($driver, 10);
$element = $wait->until(ExpectedCondition::presenceOfElementLocated(WebDriverBy::id('dynamic-element')));
# docker-compose.yml
services:
selenium:
image: selenium/standalone-chrome
ports:
- "4444:4444"
$capabilities = Facebook\WebDriver\Remote\DesiredCapabilities::chrome();
$capabilities->setCapability('goog:chromeOptions', [
'args' => ['--headless', '--disable-gpu']
]);
Deprecation Warnings
facebook/webdriver package is archived; migrate to php-webdriver/php-webdriver.findElements()) may return WebElement objects that behave differently than expected. Always check for null or exceptions.Session Management
quit(): Always call $driver->quit() to release resources and avoid zombie sessions.WebDriverWait) for reliability.Cross-Browser Quirks
goog:chromeOptions for extensions or flags.Stale Elements
try {
$element->click();
} catch (\Facebook\WebDriver\Exception\StaleElementReferenceException $e) {
$element = $driver->findElement(WebDriverBy::id('element-id'));
$element->click();
}
Logs and Verbose Output Enable verbose logging for WebDriver:
$capabilities->setCapability('loggingPrefs', ['browser' => 'ALL']);
$logs = $driver->manage()->getLog('browser');
Screenshots on Failure Capture screenshots in tests:
try {
$driver->findElement(WebDriverBy::id('nonexistent'))->click();
} catch (\Exception $e) {
$driver->takeScreenshot('screenshot.png');
throw $e;
}
Common Exceptions
NoSuchElementException: Element not found. Verify selectors or waits.TimeoutException: Adjust wait times or check network conditions.WebDriverException: Server issues. Restart Selenium or check hub status.Custom Commands
Extend RemoteWebDriver for domain-specific actions:
class CustomDriver extends RemoteWebDriver {
public function scrollToBottom() {
$this->executeScript("window.scrollTo(0, document.body.scrollHeight);");
}
}
Event Listeners
Hook into browser events (e.g., beforeNavigate):
$driver->manage()->addEventListener('beforeNavigate', function ($event) {
// Log navigation events
});
W3C WebDriver Support
W3C capabilities for modern browsers (Chrome 78+, Firefox 70+):
$capabilities->setCapability('browserName', 'chrome');
$capabilities->setCapability('browserVersion', 'latest');
$capabilities->setCapability('platformName', 'Windows NT');
Proxy Configuration Route traffic through a proxy for testing:
$capabilities->setCapability('proxy', [
'httpProxy' => 'http://proxy.example.com:8080',
'sslProxy' => 'http://proxy.example.com:8080'
]);
PATH or specify its location:
$capabilities->setCapability('marionette', true);
putenv('PATH=' . getcwd() . '/path/to/geckodriver:' . getenv('PATH'));
webdriver.chrome.driver for Chrome:
putenv('webdriver.chrome.driver=' . getcwd() . '/chromedriver');
$host = 'http://hub.example.com:4444/wd/hub';
How can I help you explore Laravel packages today?