A few months ago I was trying to compare different client libraries that are used for browser automation with Selenium. There is no official PHP client yet, so for PHP testing developers wrote their own implementation of webdriver clients.

Currently there are 4 major libraries:

PHPUnit Selenium2TestCase

PHPUnit Extension, based on earlier implementation for Selenium RC (first version of Selenium). It is widely used with PHPUnit, yet it has really strange syntax and very bad documentation. For instance some of its parts actually demonstrate examples with Selenium RC (previous webdriver version, outdated). In this case its pretty important to stick with Selenium2TestCase as it allows you to incorporate all features of Selenium Server, as well as other tool that support WebDriver protocol, for instance that can be PhantomJS. Selenium2TestCase comes with handy assertion methods that can show you better descriptions on failure.

Example:

<?php $this->url(self::URL); $this->selectDestination('station_from', 'stations_from', self::FROM_INPUT, self::FROM_FIND); $this->selectDestination('station_till', 'stations_till', self::TO_INPUT, self::TO_FIND); $dateElement = $this->byId('date_dep'); $this->assertNotEmpty($dateElement); $dateElement->clear(); $this->keys(date('m.d.Y', time() + 86400)); $search = $this->byName('search'); $search->click(); $trainsTable = new Element('id', 'ts_res', $this, $this); $trainsTable = $trainsTable->waitForElement(); $trainRow = $trainsTable->byTag('tbody')->byTag('tr'); $places = $trainRow->byClassName('place'); $places = $places->elements($this->using('tag name')->value('div')); $this->assertNotEmpty($places); ?>

Element34/php-webdriver

This is patched version of standalone Selenium client library initially developed by Facebook. In July 2013 Facebook dropped their version entirely and recommended to use fork of element34. It has some important features which initial version lacked, still it has really ugly syntax and poor documentation.

Example:

<?php $this->session->open('http://booking.uz.gov.ua/'); $from = $this->fillStation('station_from', $this->fromInput); $this->pickStation('stations_from', $this->from); $this->assertEquals("Kyiv", $from->attribute('value')); $to = $this->fillStation('station_till', $this->toInput); $this->pickStation('stations_till', $this->to); $this->assertEquals("Lviv", $to->attribute('value')); $this->forTomorrow(); $this->session->element('name', 'search')->click(); $result = $this->trains(); (new PHPWebDriver_WebDriverWait($this->session))->until( function($session) { return $session->element(PHPWebDriver_WebDriverBy::ID, 'ts_res')->displayed(); } ); $trains = $result->elements(PHPWebDriver_WebDriverBy::TAG_NAME, 'tr'); $this->assertNotEmpty($trains); ?>

Instaclick/php-webdriver

Patched version of element34 webdriver that was brought to modern PHP era. It follows PSR standards and can be installed by Composer. It is used in popular Mink library, but in case of Mink some interactions, like clicks, are done via JavaScript, and not by using native events of WebDriver. Those JavaScript events are simulated, and make tests written with Mink to not completely reproduce user's actions on site. Anyway, instaclick library itself works very similar to element34

Example:

$this->session->open('http://booking.uz.gov.ua/'); $from = $this->fillStation('station_from', $this->fromInput); $this->pickStation('stations_from', $this->from); $this->assertEquals("Kyiv", $from->attribute('value')); $to = $this->fillStation('station_till', $this->toInput); $this->pickStation('stations_till', $this->to); $this->assertEquals("Lviv", $to->attribute('value')); $this->forTomorrow(); $this->session->element('name', 'search')->click(); $result = $this->trains(); $this->session->timeouts()->wait( function($session) { return $session->element(\WebDriver\LocatorStrategy::ID, 'ts_res')->displayed(); } , 20, 1, [$this->session]); $trains = $result->elements(\Webdriver\LocatorStrategy::TAG_NAME, 'tr'); $this->assertNotEmpty($trains);

Facebook/php-webdriver

The most modern and complete client library for Selenium2. Facebook started it in July 2013 and aimed to make it as most close to official Java version of Selenium bindings. This library is not documented well, yet its really easy in use as you can always refer to Java syntax and do practically the same in PHP. It supports Composer and PSR standards, yet has its classes placed in global namespace. Unlike all libraries listed here facebook/php-webdriver has really nice methods for conditional waiting of element, i.e. you can wait for element on page to appear or disappear.

Example

<?php $this->wd->get('http://booking.uz.gov.ua/'); $from = $this->fillStation(WebDriverBy::name('station_from'), $this->fromInput); $this->pickStattion(WebDriverBy::id('stations_from'), $this->from); $this->assertEquals("Kyiv", $from->getAttribute('value')); $to = $this->fillStation(WebDriverBy::name('station_till'), $this->toInput); $this->pickStattion(WebDriverBy::id('stations_till'), $this->to); $this->assertEquals("Lviv", $to->getAttribute('value')); $this->forTomorrow(); $this->wd->findElement(WebDriverBy::name('search'))->click(); $result = $this->trains(); (new WebDriverWait($this->wd, 20)) ->until(WebDriverExpectedCondition::visibilityOf($result)); ?>

Upd: Facebook released their Webdriver API documentation

Conclusion

For modern project I'd suggest you to use facebook/php-webdriver library. It is the most modern, it has the most complete webdriver protocol implementation, and has really useful features like conditional waiting. It also produces the most clean and readable code.

You can review posted examples and compare them on GitHub.