Currently we have it so that if you were doing only backend code development, you would be set. However in the web world that is PHP, being only a back end developer is a rare task. Sooner or later (usually sooner) you’re going to have to test front end code as well. Wouldn’t it be great if you could do tests on front end code as well? With that in mind, the folks at Selenium have developed a tool where you can have testing code developed for you! Let’s give it a whirl.

First we’ll need to get the plugin for firefox (you are using firefox right?) that will allow us to record our session so that Selenium can build our code based upon it. Stop by this link (http://seleniumhq.org/download/), and download the Selenium IDE. It’ll quickly download and then ask to restart firefox, which you’ll need to do. Then go to tools and you should see an entry for Seleium IDE. Click on that and there we are.

So now that it works, what do we do with it? First you’d navigate to your site that you are working on in the browser. Once that is done, go to the Selenium window that appeared when you clicked on the Selenium IDE option in the tools menu. Near the top right, you will see a red circle that looks oddly enough like a record button. Click that, and then navigate your site as you wish. As you’ll see, the window in the selenium IDE will auto-populate itself with your actions until you stop recording.

Now that’s all well and good, but how is this supposed to make building Unit tests easier? Well for that we will need to convert the view to get the pre-built code. Go to the Options menu that is at the top of the Selenium window, and click on format. You’ll see a lot of different languages listed here, but for our purposes, PHP is what we’ll exclusively use. Click on it, and watch as the main window is populated with your code. Then it’s just a simple matter of cut and paste into your test script and viola! You are done! Here is an example of the code that was generated from my test.

<?php
require_once 'PHPUnit/Extensions/SeleniumTestCase.php';
class Example extends PHPUnit_Extensions_SeleniumTestCase
{
protected function setUp()
{
$this->setBrowser("*chrome");
$this->setBrowserUrl("http://example.com/");
}
public function testMyTestCase()
{
$this->open("/");
$this->click("//input[@value='Login']");
$this->waitForPageToLoad("30000");
$this->click("link=Account");
$this->waitForPageToLoad("30000");
$this->click("link=Edit Account");
$this->waitForPageToLoad("30000");
$this->type("userTitle", "ff");
$this->click("save");
$this->waitForPageToLoad("30000");
$this->type("userPasswordConfirm", "password");
$this->click("save");
$this->waitForPageToLoad("30000");
$this->click("link=Logout");
$this->waitForPageToLoad("30000");
$this->click("logout");
$this->waitForPageToLoad("30000");
}
}
?>

As you can see, the main content has click events, time to page before processing a new page load, and type events where data is entered. You can edit it to your hearts content to test and see if everything is working as intended, and it saves a bit of typing, which is never a bad thing.

However one problem will arise and that is that PHPUnit doesn’t really understand how to handle this code effectively. For this will need another tool to add to our toolbox, which is also from Selenium, named Selenium RC, which can be found in the same spot as the Selenium IDE. This will act as a bridge between the Selenium code that is generated, and the PHPUnit code itself.

Once it is downloaded, you can install it wherever (the root of C works as well as anywhere) and run selenium-server-1.0.x/selenium-server.jar . You’ll want to open up port 4444 in the event you have a firewall, and should be prompted in most cases. Now you’ll need to run the jar file if you reboot your computer, but we’ll look into a solution for that in a moment. Once that is done, you just run a test on the script from before, and see if you get any errors or if it checks out fine. You’ll see a few windows popup upon loading of the runtest.bat file, but that is to be expected to run your code.

Now to have it so that you don’t need to manually start that jar file on boot? For that we’ll need to install a program that will allow us to start a jar as a service named Java Service Wrapper (http://wrapper.tanukisoftware.org/doc/english/download.jsp). Download the community version that fits your system, and then configure your selenium server directory as follows:

Conf – holds the wrapper.conf file, which will be outlined further in this writeup.

lib – holds the wrapper.dll and jar that comes with the Java Service Wrapper package

logs – for any log files created by the wrapper when operating

sslsupport & javadocs – from the Java Service Wrapper package

wrapper – holds the following files:

  • App.bat(in /src/bin/ in the Java Service Wrapper package)
  • InstallApp-NT.bat(in /src/bin/ in the Java Service Wrapper package)
  • UninstallApp-NT.bat(in /src/bin/ in the Java Service Wrapper package)
  • Wrapper.exe(in / bin/ in the Java Service Wrapper package)

Once this is complete, we’ll need to create the conf file to tell this program how to run and what jar file to load on startup. Here’s the conf file that is used with the default install.

#********************************************************************
# Wrapper License Properties (Ignored by Community Edition)
#********************************************************************
# Professional and Standard Editions of the Wrapper require a valid
# License Key to start. Licenses can be purchased or a trial license
# requested on the following pages:
# http://wrapper.tanukisoftware.org/purchase
# http://wrapper.tanukisoftware.org/trial
# Include file problems can be debugged by removing the first ‘#’
# from the following line:
##include.debug
# The Wrapper will look for either of the following optional files for a
# valid License Key. License Key properties can optionally be included
# directly in this configuration file.
#include ../conf/wrapper-license.conf
#include ../conf/wrapper-license-%WRAPPER_HOST_NAME%.conf# The following property will output information about which License Key(s)
# are being found, and can aid in resolving any licensing problems.
#wrapper.license.debug=TRUE
#********************************************************************
# Wrapper Java Properties
#********************************************************************
# Java Application
wrapper.java.command=java
# Tell the Wrapper to log the full generated Java command line.
#wrapper.java.command.loglevel=INFO
# Java Main class. This class must implement the WrapperListener interface
# or guarantee that the WrapperManager class is initialized. Helper
# classes are provided to do this for you. See the Integration section
# of the documentation for details.
wrapper.java.mainclass=org.tanukisoftware.wrapper.WrapperSimpleApp
# Java Classpath (include wrapper.jar) Add class path elements as
# needed starting from 1
wrapper.java.classpath.1=../lib/wrapper.jar
# Specific Selenium JAR paths
wrapper.java.classpath.2=../../selenium-server-1.0.3/selenium-server.jar
wrapper.java.classpath.3=../../selenium-server-1.0.3/selenium-server-coreless.jar
wrapper.java.classpath.4=../../selenium-server-1.0.3/selenium-server-sources.jar
wrapper.java.classpath.5=../../selenium-server-1.0.3/selenium-server-tests.jar
wrapper.java.classpath.6=../../selenium-server-1.0.3/selenium-server-test-sources.jar
# Java Library Path (location of Wrapper.DLL or libwrapper.so)
wrapper.java.library.path.1=../lib
# Java Additional Parameters
# Java Bits. On applicable platforms, tells the JVM to run in 32 or 64-bit mode.
wrapper.java.additional.auto_bits=TRUE
# Log file to use for wrapper output logging.
wrapper.logfile=../logs/wrapper.log
wrapper.commandfile=./dump.command
wrapper.ntservice.console=true
# Application parameters. Add parameters as needed starting from 1
wrapper.app.parameter.1=org.openqa.selenium.server.SeleniumServer
#Log Level
wrapper.console.loglevel=DEBUG
wrapper.logfile.loglevel=DEBUG
#********************************************************************
# Wrapper Logging Properties
#********************************************************************
# Enables Debug output from the Wrapper.
# wrapper.debug=TRUE
# Format of output for the console. (See docs for formats)
wrapper.console.format=PM
# Log Level for console output. (See docs for log levels)
wrapper.console.loglevel=INFO
# Log file to use for wrapper output logging.
wrapper.logfile=../logs/wrapper.log
# Format of output for the log file. (See docs for formats)
wrapper.logfile.format=LPTM
# Log Level for log file output. (See docs for log levels)
wrapper.logfile.loglevel=INFO
# Maximum size that the log file will be allowed to grow to before
# the log is rolled. Size is specified in bytes. The default value
# of 0, disables log rolling. May abbreviate with the ‘k’ (kb) or
# ‘m’ (mb) suffix. For example: 10m = 10 megabytes.
wrapper.logfile.maxsize=0
# Maximum number of rolled log files which will be allowed before old
# files are deleted. The default value of 0 implies no limit.
wrapper.logfile.maxfiles=0
# Log Level for sys/event log output. (See docs for log levels)
wrapper.syslog.loglevel=NONE
#********************************************************************
# Wrapper Windows Properties
#********************************************************************
# Title to use when running as a console
wrapper.console.title=SeleniumService
#********************************************************************
# Wrapper Windows NT/2000/XP Service Properties
#********************************************************************
# WARNING – Do not modify any of these properties when an application
# using this configuration file has been installed as a service.
# Please uninstall the service before modifying this section. The
# service can then be reinstalled.
# Name of the service
wrapper.ntservice.name=SeleniumService
# Display name of the service
wrapper.ntservice.displayname=SeleniumService
# Description of the service
wrapper.ntservice.description=SeleniumService
# Service dependencies. Add dependencies as needed starting from 1
wrapper.ntservice.dependency.1=
# Mode in which the service is installed. AUTO_START or DEMAND_START
wrapper.ntservice.starttype=AUTO_START
# Allow the service to interact with the desktop.
wrapper.ntservice.interactive=true

Once this is saved, execute the installapp-nt.bat file and then load the services application. You should see a new service that has the name specified (SeleniumService)and is set to automatically start, but is not running. Start the service, and after a minute a command line window should open. If this happens, your service is now ready to go. Do not close this window as it will kill the service.

Now when you run the tests that selenium has created for your front end code, it will work as intended, and help you to isolate any issues that may exist.