How to write AJAX tests with Selenium
Requirements
- Selenium Remote Control (Selenium RC)
- Selenium IDE (Firefox plugin - optional)
- Java Runtime (I run Selenium Server on a Java2 v1.5.019)
- Firefox
- PHPUnit
Installation
Virtual Host changes
Add this line to your Virtual Host definition:
ServerAlias siwapp.test
You should add a line in your hosts file to match that alias with the same siwapp installation IP so when you point to http://siwapp.test/siwapp_dev.php you get the same response. This is done so because Selenium needs a browserUrl to navigate to and it is an easy way of doing it without modifying every test class.
Selenium Server
Extract the compressed file containing the Selenium RC and copy the selenium-server.jar located inside the selenium-server-1.* folder into a path where you could find it easily.
To start the server you should execute the .jar file with your java executable:
java -jar /path/to/your/selenium-server.jar
You should see some info output.
IDE (Optional)
Install the IDE as you usually do with other Firefox Addons. See this.
It allows you to "record" user interactions and get the code in PHP to include it as a test.
PHPUnit
Testing
A Basic Example
We are going to test that Google's page title is 'Google'.
Once installed and with Selenium server running create a file called 'WebTest?.php' and write:
<?php
require_once 'PHPUnit/Extensions/SeleniumTestCase.php';
class WebTest extends PHPUnit_Extensions_SeleniumTestCase
{
protected function setUp()
{
$this->setBrowser('*firefox');
$this->setBrowserUrl('http://www.google.es/');
}
public function testTitle()
{
$this->open('http://www.google.es/');
$this->assertTitleEquals('Google');
}
}
?>
You can use multiple browsers too (see).
Execute the test:
$ cd /path/to/my /path/to/my $ phpunit WebTest
This should open a Firefox instance and you should see how it magically reproduces the actions you wrote inside the WebTest.php file.
Testing Siwapp
Very basic example
We will reproduce the prior example with a few changes. Navigate to the /path/to/your/siwapp/test/selenium directory and create an ExampleTest.php file there:
<?php
require_once(dirname(__FILE__).'/../bootstrap/Selenium.php');
class ExampleTest extends SiwappSeleniumTest
{
protected function setUp()
{
$this->setBrowser('*firefox');
$this->setBrowserUrl($this->getAppBaseUrl());
}
public function testTitle()
{
$this->open($this->getAppBaseUrl().'/');
$this->assertTitleEquals('siwapp');
}
}
?>
$this->getAppBaseUrl() returns 'http://siwapp.test/siwapp_dev.php/' by default. You can change it with $this->setAppBaseUrl('http://demo.siwapp.org') or similar.
/path/to/siwapp/test/selenium $ phpunit Example
This should open a Firefox instance, load the base url and check if the title is 'siwapp'.
Dashboard Example
<?php
require_once(dirname(__FILE__).'/../bootstrap/Selenium.php');
class DashboardTest extends SiwappSeleniumTest
{
public function testShowPayments()
{
$this->login();
$this->log("::testShowPayments()");
$this->open("dashboard");
$this->log("show payment details for the most recent invoice (top table).", 'click');
$this->click("//*/table[@class=\"listing\"][1]/tbody/tr[1]/td[8]/a");
$ret = $this->waitForCondition("selenium.isElementPresent('//*/table[@class=\"listing\"][1]/tbody/tr[2]/td[1]/form[@class=\"payments-form\"]') == true");
$this->log("show payment details for the most recent overdue invoice (bottom table).", 'click');
// Bottom Table
$this->click("//*/table[@class=\"listing\"][2]/tbody/tr[1]/td[7]/a");
$this->waitForCondition("selenium.isElementPresent('//*/table[@class=\"listing\"][2]/tbody/tr[2]/td[1]/form[@class=\"payments-form\"]') == true");
}
}
?>
The login method performs the login action if you are not logged in. It is recommended to put that line in every test function if you don't know which one is going to be executed first.
Important: Try to use relative xpath routes as much as you can because if we change the layout the test could fail. Let's see an example:
BAD: //tr[@id="invoice-50"]/td[8]/a/span/span //form[@id="invoice-50_payments"]
OK: //*/table[@class="listing"][1]/tbody/tr[1]/td[8]/a
In this case we got the payments button of the first row in the first listing table.
Notes
- All test classes must be placed in the /path/to/siwapp/test/selenium directory and named as the class with .php extension (Example: class CarTest? => CarTest?.php).
- Selenium tests must be executed from the /path/to/siwapp/test/selenium directory or will throw an error.
- Read the documentation to learn Selenium: http://seleniumhq.org/docs/
- You can use /path/to/siwapp/doc/selenium-commands.txt and /path/to/siwapp/web/js/core/selenium-api.js as reference.

