= How to write AJAX tests with Selenium = == Requirements == * [http://seleniumhq.org/download/ Selenium Remote Control] (Selenium RC) * [http://seleniumhq.org/download/ 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. [http://seleniumhq.org/docs/03_selenium_ide.html See this.] It allows you to "record" user interactions and get the code in PHP to include it as a test. === PHPUnit === [http://www.phpunit.de/manual/3.1/en/installation.html See this.] == Testing == [http://www.phpunit.de/manual/3.4/en/selenium.html See this.] == 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: {{{ 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 ([http://www.phpunit.de/manual/3.4/en/selenium.html#selenium.seleniumtestcase.examples.WebTest3.php 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: {{{ 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 === {{{ 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.