Some time ago I wrote about using Selenium with SimpleTest. It is a nice solution, but after working with it I had to experience that it doesn’t fit to my working style. I often forgot to start the Selenium server before running the tests, and as it is rather slow, it is not the ideal tool for doing TDD ;-)
So I had to go back to the Selenium helper. But somehow it felt no longer right to place the tests in app/views/pages/tests and to write them as thtml files. And so I wrote the Selenium test suite, which uses a different approach as you will see.
Let’s have a look at a simple example. Before we can start with the example, we have to install the test suite (please be aware that the test suite only works with the not yet released CakePHP 1.2):
- Download the Zip file from the download section
- Unpack the Zip file
- Add the following route to app/config/routes.php:
Router::connect('/selenium/*', array('controller' => 'selenium', 'action' => 'display'));
With that we are ready to start with the example. As the tests are organized in test suites, we start with such a test suite:
// app/tests/selenium/my_test_suite.php
class MyTestSuite extends SeleniumTestSuite {
var $title = 'My tests';
function execute() {
$this->addTestCase('Login', 'cases/LoginTest');
}
}
Each file placed in app/tests/selenium is considered to be a test suite, and must extend the class SeleniumTestSuite and implement the execute() function. This function is very simple: you just add the tests to the test suite.
The next step is to create our test case. A test case must extend SeleniumTestCase and, as a test suite, implement the execute() function. This function contains the test logic.
// app/tests/selenium/cases/login_test.php
class LoginTest extends SeleniumTestCase {
var $title = 'Login';
var $fixtures = array('Users');
function setUp() {
echo 'setUp';
}
function tearDown() {
echo 'tearDown';
}
function execute() {
$this->open('http://myproject.localhost');
$this->type('name=data[User][username]', $this->dho['username']);
$this->type('name=data[User][password]', $this->dho['password']);
$this->clickAndWait('submit');
$this->verifyLocation('http://myproject.localhost/projects');
}
}
You probably noticed the $fixtures array. It allows you to write some records to the database before the test case is executed. These records are also available in the test case (see $this->dho). Each fixture is a simple class with the same name as the database table:
// app/tests/fixtures/users.php
class Users {
var $columns = array('id', 'username', 'password');
var $dho = array(1, 'dho', 'geheim');
}
With that we are ready to execute the test suite. As I use the Selenium IDE, I just have to enter the following url in Firefox to load the test suite:
chrome://selenium-ide/content/selenium/TestRunner.html?test=http://myproject.localhost/selenium/MyTestSuite
And the tests can be executed :)
Please keep in mind that it is just a preview, so it is possible that some things will change in future versions. As always your feedback is welcome :)

Selenium is only as slow as the computer you run it on. :)
I have found that my 2GHz Core Duo will happily run Selenium RC just as fast as FireFox will let it. Granted, I run the tests with ruby’s Test::unit, but I wouldn’t expect SimpleTest to have too much overhead.
As for as forgetting to launch the proxy server, I added a rake task that loads lighttpd, selenium, and opens my app directory in TextMate. Automation means never having to remember things. :)
Just a couple of notes in case anyone else wants to keep to the remote control path.
Hey Daniel: Thanks for this release, that’s pretty cool stuff. I actually just bought an older computer (~1ghz, 768mb ram, 20gb hdd) from a friend that I plan to use as a dedicated test server in the future. This should solve the performance issues for me ; ).
@Scott: Well, it is not Selenium that’s slow, it is the starting of Firefox which is slow (it takes more than 10 seconds on my machine). So that is a lot of overhead if your tests run for 5-10 seconds and you run the tests very frequently. But I am also aware that I am abusing Selenium a bit, as Selenium is afaik not thought to be used in a TDD way.
And yes, you are right with “Automation means never having to remember things”, I like that sentence. But sometimes I am just too lazy to automate something and then I prefer to complain ;-)
@Felix: Whoa, a dedicated test server is cool :)
[...] You probably know this fixture. It is the same I have used in the article about the Selenium test suite. This means you can reuse fixtures in your Selenium tests. [...]
I’m sorry. I am new to using selenium with PHP and Cake. I followed all the steps in your article and couldn’t get the selenium to work. When bringing up the test in firefox, the “Test Suite” are displays this:
// app/tests/selenium/my_test_suite.php class MyTestSuite extends SeleniumTestSuite { var $title = ‘My tests’; function execute() { $this->addTestCase(‘Login’, ‘cases/LoginTest’); } }
and the “Current Test” is empty. Am I missing something?
Please can any body tell me where the test cases can be put to reflect in selenium ?
@Gururaj: Hm, I am not sure I understand your question. Do you ask where to put the test cases? They are in app/tests/selenium/cases.
HTH
hi folks ..
i have a doubt ,regarding automating application logins.
i have to write a test case ,so as to automate the process of login’s to an application .The login details can be taken from a file or directly from a database.
please do help me regarding this ..
regards
jannu
@jannu: With what do you need help?
Hi – I have a couple of diff’s to enhance your suite:
The first one just allows the ‘element’ type asserts to get rendered – I wanted to use a ‘verifyElementPresent’, and it wasn’t getting output in the test case.
The second one makes the test suite work if the cake application isn’t setup at the base of the server.
Thanks for all your tremendous contributions!
diff -r ./selenium_test_case.php /Volumes/yavin-1/var/www/sfl/vendors/selenium/selenium_test_case.php
97c97
$allowedKeywords = array(‘alert’, ‘confirmation’, ‘element’, ‘prompt’, ‘text’);
diff -r ./selenium_test_suite.php /Volumes/yavin-1/var/www/sfl/vendors/selenium/selenium_test_suite.php
21c21,23
< echo ‘‘.$title.’‘;
—
> $dispatcher = new Dispatcher();
> $base = $dispatcher->baseUrl();
> echo ‘‘.$title.’‘;
@Rich: Thanks for the fixes. I have applied them and uploaded a new version.
Great post!
Here is a bit improved version that can insert multiple rows and fix to insert null values. File: selenium_test_case.php
function __getUrlForCommand($command, $folder, $testCaseName) {
return ‘http://’.$_SERVER['SERVER_NAME'].’/’.’selenium’.'/’.$command.’/’.$folder.’/’.$testCaseName;
}
function loadFixtures() {
if (!empty($this->fixtures)) {
$db =& ConnectionManager::getDataSource(‘default’);
foreach ($this->fixtures as $fixture) {
require_once(APP.DS.’tests’.DS.’fixtures’.DS.Inflector::underscore($fixture).’.php’);
$f = new $fixture();
$variables = get_class_vars($fixture);
$db->execute(‘DELETE FROM ‘.Inflector::underscore($fixture));
foreach ($variables as $name => $data) {
if ($name != ‘columns’) {
foreach ($f->$name as $state => $row) {
$this->$name = array_combine($f->columns, $row);
$values = array();
foreach ($row as $value) {
if (is_string($value)) {
$values[] = $db->value($value);
} elseif (is_bool($value)) {
$values[] = $value == true ? ‘true’ : ‘false’;
} elseif (empty($value)) {
$values[] = ‘NULL’;
} else {
$values[] = $value;
}
}
$sql = ‘INSERT INTO ‘.Inflector::underscore($fixture).’ (‘.implode(‘,’, $f->columns).’) VALUES (‘.implode(‘,’, $values).’)';
$db->execute($sql);
}
}
}
}
}
}
This will require to define fixture data as:
var $dho = array(
‘created’ => array(’1′,’user1′,’123′),
‘activated’ => array(’1′,’user2′,’456′)
);
and in the unit test you can access the data as $this->dho['activated']['username']
Oops, here is correct version of loadFixtures:
function loadFixtures() {
if (!empty($this->fixtures)) {
$db =& ConnectionManager::getDataSource(‘default’);
foreach ($this->fixtures as $fixture) {
require_once(APP.DS.’tests’.DS.’fixtures’.DS.Inflector::underscore($fixture).’.php’);
$f = new $fixture();
$variables = get_class_vars($fixture);
$db->execute(‘DELETE FROM ‘.Inflector::underscore($fixture));
foreach ($variables as $name => $data) {
if ($name != ‘columns’) {
$rows = array();
foreach ($f->$name as $state => $row) {
$rows[$state] = array_combine($f->columns, $row);
$values = array();
foreach ($row as $value) {
if (is_string($value)) {
$values[] = $db->value($value);
} elseif (is_bool($value)) {
$values[] = $value == true ? ‘true’ : ‘false’;
} elseif (empty($value)) {
$values[] = ‘NULL’;
} else {
$values[] = $value;
}
}
$sql = ‘INSERT INTO ‘.Inflector::underscore($fixture).’ (‘.implode(‘,’, $f->columns).’) VALUES (‘.implode(‘,’, $values).’)';
$db->execute($sql);
}
$this->$name = $rows;
}
}
}
}
}
@Rostislav: Thanks for your patch! I have to test it and will then integrate it.
I have to write a test case ,so as to automate the process of register to an application .The register details can be taken from a file or directly from a database.
please do help me regarding this. How to connect a database or file to selenium test cases?
@mila: You could just call file_get_contents() from within the execute() method.
Hope that helps!
can u give me the steps?
@mila: Hm, where do you have problems? And what have you already done?
?php
require_once ‘PHPUnit/Extensions/SeleniumTestCase.php’;
class Example extends PHPUnit_Extensions_SeleniumTestCase
{
function setUp()
{
$this->setBrowser(“*iexplore”);
$this->setBrowserUrl(“website URL/”);
}
function testMyTestCase()
{
$this->open(“webpage.html”);
$this->type(“userEmail”, “boo@boo.com”);
$this->type(“myPassword”, “aaaaaa”);
$this->type(“confirmPassword”, “aaaaaa”);
$this->click(“confirmPassword”);
$this->click(“nextButton”);
$this->waitForPageToLoad(“30000″);
try {
$this->assertTrue($this->isTextPresent(“You have successfully registered.”));
} catch (PHPUnit_Framework_AssertionFailedError $e) {
array_push($this->verificationErrors, $e->toString());
}
$this->click(“link=log out”);
$this->waitForPageToLoad(“30000″);
}
}
?>
I am new to selenium and phpunit. Recorded the register page to be automated using selenium IDE. exported test case as php selenium -RC. selenium RC is running on my computer. my code is running smoothly.
My task is to register multiple users. i am struck here.
have to read from file or use array or use file_get_contents?
need help. thanks in advance.
-mila
@mila: The easiest case is probably to use an array. So your code could look like:
Hope that helps!
my code is running :-))
thank you so much
if register page contains many info other than user name and password. and i want to register 100+ users. is there any way like reading from external file??
@mila: Cool to hear it is working :)
Sure, if you have an external file you can read it with file() and extract the required data. But first I would question whether you really have to register more than 100 users for testing purposes…
Hope that helps!
creating multiple players for MMO game.
can file() command read from excel file?
while running selenium rc for another test case i came across another error ERROR: Element //input[@value='' and @type='submit'] not found. Selenium IDE also gives Invalid Xpath.
Just I recorded clicks from the UI and playing back.
Thanks.
I am using phpunit version 3.2.21 and selenium RC version 1.0 beta. The error is
RuntimeException: The response from the Selenium RC server is invalid: ERROR: Element //input[@value='' and @type='submit'] not found
@mila: No, the file() function is for plain text files. To read from an Excel file you need a special library for it, like PHPExcel.
Regarding your error, have a look at the source of the respective page. It seems Selenium doesn’t find a submit button with an empty value.
Hope that helps!
thank you.
checked the source it is submit button and empty value.
# info] Executing: |clickAndWait | link=Register | |
# [info] Executing: |type | New_Username | jjjjjj |
# [info] Executing: |clickAndWait | //input[@value='' and @type='submit'] | | //this is the error
# [info] Executing: |type | Password | jsvvm123 |
# [info] Executing: |type | Passconf | jsvvm123 |
# [info] Executing: |clickAndWait | //input[@value='' and @type='submit'] | |
# [info] Executing: |click | //input[@name='secret_question_id' and @value='3'] | |
# [info] Executing: |click | //input[@name='secret_question_id' and @value='2'] | |
# [info] Executing: |type | Answer | tetris |
# [info] Executing: |type | Answerconf | tetris |
# [info] Executing: |clickAndWait | //input[@value='' and @type='submit'] | |
# [info] Executing: |type | Email | aaa@bbb.com |
# [info] Executing: |type | Email_Conf | aaa.bbb.com |
# [info] Executing: |type | Code_Confirm | 42jTL |
# [info] Executing: |click | Agree_Conf | |
# [info] Executing: |clickAndWait | //input[@value='' and @type='submit'] | |
# [info] Executing: |verifyTextPresent | An email has been sent to the email address provided. | |
this is the code running smoothly on selenium IDE. But in SRC element //input[@value='' and @type='submit'] | | not found error.
Thanks in advance
@mila: Hm, are you sure that on your registration page the value of the submit button is an empty string? And what happens if you use //input[@type='submit']?
great! it is working. tons of thanks.
another question when registration process automated how to handle security cod? is there anyway to bypass security code?
@mila: I’m glad to hear it’s working!
What do you mean with “security code”? A captcha?
yes. how to bypass “captcha” when automating the registration process?
@mila: I think there are two approaches to “bypass” the captcha: you could generate a captcha with a known value, so in your tests you can use this known value. Or you could simply ignore what is entered for the captcha when your application is run in the testing environment.
Hope that helps!
in IDE how to record a disabled button. when password is less than 5 character the next button should be disabled. when recording i cant record the “disabled button”.
@mila: Well, you have to add an assertNotEditable/verifyNotEditable command manually while recording your scenario (or afterwards).
Hope that helps!
thanks. added verifyNotEditable and it is working.
@mila: You are welcome!
What is the ways to install phpunit?
what i did is installed PHP then installed phpunit.
what is the other way to install, using Selenium PHP client driver? can you give me the steps?
what is difference between these two?
browser = new Testing_Selenium(“*firefox”, “http://www.google.com”);
$this->browser->start();
}
public function tearDown()
{
$this->browser->stop();
}
public function testGoogle()
{
$this->browser->open(“/webhp?hl=en”);
$this->browser->type(“q”, “hello world”);
$this->browser->click(“btnG”);
$this->browser->waitForPageToLoad(10000);
$this->assertRegExp(“/Google Search/”, $this->browser->getTitle());
}
}
?>
and
setBrowser(“*iexplore”);
$this->setBrowserUrl(“http://www.google.com”);
}
public function tearDown()
{
}
public function testGoogle()
{
$this->open(“/webhp?hl=en”);
$this->type(“q”, “hello world”);
$this->click(“btnG”);
$this->waitForPageToLoad(10000);
$this->assertRegExp(“/Google Search/”, $this->getTitle());
}
}
?>
Thanks in advance.
another question. if i try to run my test suite from selenium RC with firefox i am getting following error. I am using FF3. i cleaned firefox instance from task manager and cleaned the customprofile dir. still i am having this issue.
C:\Documents and Settings\mila>java -jar selenium-server.jar -htmlsuite “*firefox” “http://google.com/” “T:\QA\selenium\links\parent_link_test_suite.html” “T:\QA\selenium\links\results.html
11:45:26.152 INFO – Java: Sun Microsystems Inc. 10.0-b23
11:45:26.152 INFO – OS: Windows XP 5.1 x86
11:45:26.152 INFO – v1.0-beta-1 [2201], with Core v1.0-beta-1 [1994]
11:45:26.214 INFO – Version Jetty/5.1.x
11:45:26.214 INFO – Started HttpContext[/selenium-server/driver,/selenium-server/driver]
11:45:26.214 INFO – Started HttpContext[/selenium-server,/selenium-server]
11:45:26.214 INFO – Started HttpContext[/,/]
11:45:26.230 INFO – Started SocketListener on 0.0.0.0:4444
11:45:26.230 INFO – Started org.mortbay.jetty.Server@32c41a
11:45:26.386 INFO – Preparing Firefox profile…
HTML suite exception seen:
java.lang.RuntimeException: Firefox refused shutdown while preparing a profile
at org.openqa.selenium.server.browserlaunchers.FirefoxCustomProfileLauncher.waitForFullProfileToBeCreated(FirefoxCustomProfileLauncher.java:277)
at org.openqa.selenium.server.browserlaunchers.FirefoxCustomProfileLauncher.launch(FirefoxCustomProfileLauncher.java:147)
at org.openqa.selenium.server.browserlaunchers.AbstractBrowserLauncher.launchHTMLSuite(AbstractBrowserLauncher.java:20)
at org.openqa.selenium.server.htmlrunner.HTMLLauncher.runHTMLSuite(HTMLLauncher.java:93)
at org.openqa.selenium.server.htmlrunner.HTMLLauncher.runHTMLSuite(HTMLLauncher.java:141)
at org.openqa.selenium.server.SeleniumServer.runHtmlSuite(SeleniumServer.java:1138)
at org.openqa.selenium.server.SeleniumServer.main(SeleniumServer.java:386)
Caused by: org.openqa.selenium.server.browserlaunchers.FirefoxCustomProfileLauncher$FileLockRemainedException: Lock file still present! C:\DOCUME~1\MIL~1\LOCALS~1\Temp\customProfileDir726277\parent.lock
at org.openqa.selenium.server.browserlaunchers.FirefoxCustomProfileLauncher.waitForFileLockToGoAway(FirefoxCustomProfileLauncher.java:235)
at org.openqa.selenium.server.browserlaunchers.FirefoxCustomProfileLauncher.waitForFullProfileToBeCreated(FirefoxCustomProfileLauncher.java:275)
… 6 more
11:45:47.440 INFO – Shutting down…
@mila: Well, the first example uses the PEAR Selenium library in a “normal” PhpUnit test case, whereas the second example uses the Selenium functionality provided by PhpUnit. Your installation steps sound fine to me (if you want to use the first example you also have to install the Selenium library from PEAR).
Regarding your second comment: you probably have to delete the file C:\DOCUME~1\MIL~1\LOCALS~1\Temp\customProfileDir726277\parent.lock manually.
Hope that helps!
error still exist after deleting the parent.lock file. is anyother workaround for this? in office they need the script should run with firefox .
@mila: It seems it is a known bug, see http://jira.openqa.org/browse/SRC-494.
In selenium IDE and RC
clickAndWait
//a[@id='clickToLogout']/div
is working properly. but when i run from selenium IDE using “play with selenium testrunner” getting this error
clickAndWait //a[@id='clickToLogout']/div Timed out after 30000ms
what could be the problem? thanks in advance.
@mila: Hm, difficult to say. What happens if you replace “clickAndWait” with “click”?
Regarding CAPTCHA: generated script with a know value. when rerun the script is gives as “image mismatch” error. how to ignore captcha when i run the script without any manual interruption?
your previous reply
————————-
I think there are two approaches to “bypass” the captcha: you could generate a captcha with a known value, so in your tests you can use this known value. Or you could simply ignore what is entered for the captcha when your application is run in the testing environment.
@mila: Hm, are the image and the value that is entered by your test identical when you watch the test run?
no they are different. should this take care of developers?
@mila: Well, if you want to automate the testing of a captcha, your script has to enter the value that is shown in the image (at least if you follow the first approach I mentioned). This means, your captcha has to show a pre-defined value in the test environment which you can then use in your test script.
Hope that helps!
java -jar selenium-server.jar -htmlSuite “*iexplore” “http://www.google.com/” “C:\google_test_suite.html” “C:\results.html”
What could be the reason for java.lang.StringIndexOutOfBoundsException: String index out of range: -1???
HTML suite exception seen:
java.lang.StringIndexOutOfBoundsException: String index out of range: -1
at java.lang.String.substring(Unknown Source)
at org.openqa.selenium.server.browserlaunchers.WindowsUtils$RegKeyValue.(WindowsUtils.java:622)
at org.openqa.selenium.server.browserlaunchers.WindowsUtils.deleteRegistryValue(WindowsUtils.java:577)
at org.openqa.selenium.server.browserlaunchers.WindowsProxyManager.handleEvilPopupMgrBackup(WindowsProxyManager.java:106)
at org.openqa.selenium.server.browserlaunchers.WindowsProxyManager.init(WindowsProxyManager.java:81)
at org.openqa.selenium.server.browserlaunchers.WindowsProxyManager.(WindowsProxyManager.java:65)
at org.openqa.selenium.server.browserlaunchers.InternetExplorerCustomProxyLauncher.(InternetExplorerCustomProxyLauncher.java:48
at org.openqa.selenium.server.browserlaunchers.InternetExplorerCustomProxyLauncher.(InternetExplorerCustomProxyLauncher.java:41
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at org.openqa.selenium.server.browserlaunchers.BrowserLauncherFactory.createBrowserLauncher(BrowserLauncherFactory.java:124)
at org.openqa.selenium.server.browserlaunchers.BrowserLauncherFactory.getBrowserLauncher(BrowserLauncherFactory.java:81)
at org.openqa.selenium.server.htmlrunner.HTMLLauncher.runHTMLSuite(HTMLLauncher.java:87)
at org.openqa.selenium.server.htmlrunner.HTMLLauncher.runHTMLSuite(HTMLLauncher.java:141)
at org.openqa.selenium.server.SeleniumServer.runHtmlSuite(SeleniumServer.java:1138)
at org.openqa.selenium.server.SeleniumServer.main(SeleniumServer.java:386)
i am using selenium ide for my web application testing
i am not aware of somuch
I am recording by selenium ide in firefox browser and running the application in IE by using command prompt, working fine
MY problem is:
Before i create the event , i should check whether that event is existed or not in the database
So please provide the script for me
please provide the script
how to verify any field value is existed in the database or not
@mila: Hm, maybe this thread helps.
@gayathri, vamsi: I’m sorry, but I don’t understand what you are trying to do…
@Daniel: Are all files in Downloads section are updated?
I find a lot of things missing after installing this.
@Abhimanyu: The Selenium helper is up-to-date, and I’m working on an update of the test suite.
Can you provide the steps how we can get teh Captcha information in environement so that i can use it in the Code. Or tell me how we can ignore the Captcha, without failing the test.
Can you provide the code how to ignore the Captcha from teh registration and run the test successfully, registed successfully
@Ramesh: I’m sorry, but I can’t help you as I don’t have any experience with testing captchas. See the comments above where I described two possible approaches to test them.
Hope that’s a starting point for you!
Thanks for response
But the above Appraochs are good, but how to implement is problem. How to ignore the Captcha and make my registration successfull and proceed. Or how to capture the text in Captcha, Can any one Help me out.
Thanks in advance
@Ramesh: Well, one idea is to modify your captcha verification method, so that it accepts any input when you run your application in the testing environment.
Hope that helps!
Thanks a lot
My IE not work.. after command “open” all stoped.. What is the reason, you know?
@Freenty: Hm, any errors? And does it work with Firefox?
Guys,
I am relatively new to selenium. need help in the following areas:
1. I have a PHP application (SUGAR CRM) which needs to be automated.
2. I have created some basic login logout scripts using IDE and exported them as PHP test cases.
3. individually i can run these test cases using the Phpunit command and they work fine.
4. I installed selenium Grid on my machine and was able to start the hub and RC on different machines.
I want to run these scripts as a test suite using grid, such that all the scripts mentioned in the suite are executed one after the other. I am not sure how to do this.
Secondly i also tried using bromine, but there too it executes only one test case from a requirement.
Any help is highly appreciated.
@Seleniumfan: I’m sorry, but I can’t help you with Selenium Grid as I never used it so far. Maybe you will have more luck in the Selenium Users Google Group?
Hello,
I am exporting all my testcases in PHP format from Selenium IDE and running the test case in NetBeans combined with PHPunit.
I want to create a test suite to be able to run a batch of test cases.
Can you please help out with what functions and classes i need to call or give me a sample?
I dont see any SeleniumTestSuite.php in the extensions folder of PHPunit.
Which file to include in the testsuite.php?
Thanks in advance.
Geeta
@Geeta: I’m sorry, but I don’t have any experience with PHPunit. Maybe the chapter Organizing Tests in the PHPunit documentation is helpful for you.
Hello, I have one scenario. Please tell me if it can be automated. If yes then how it can be done.
Scenario: I have s shopping site. I search for some products. Now my application allows me to sort the items displayed by price, brand etc.
So I want to know how I can validate the process of sorting, if it has been done correctly or not. Please help!
@Neeta: Sure, it’s possible to test such a scenario. You could use assertText() to verify whether the results are shown in the correct order.
Hope this helps!