UPDATE: My thinking on this has changed significantly in the years following this post, but according to Google it’s still quite popular. If you’re interested in combining FitNesse and Selenium, make sure to read this post as well: How to implement UI Testing without shooting yourself in the foot. It explains how to avoid some of the most common problems.
Web user interfaces have traditionally been hard to integrate into an automated test process. Selenium+FitNesse combination, with just a bit of coding, solves this task incredibly well.
Selenium is a free browser automation and testing library, written by folks at ThoughtWorks. It can simulate text input, mouse events and execute various tests on page content. It’s written in JavaScript, and is compatible with all major browsers and platforms.
FitNesse is an open-source test and collaboration server, based on the Framework for integrated tests (FIT), and supports testing Java, .Net, Python and even some other code. I think that it is a good choice for the second side of the web UI testing coin, because it enables tests to be written almost like in English language. As the UI is very close to clients’ eyes, tests can and should be written so that clients can verify them (and if you are really lucky, even help with writing and maintaining the tests).
Installing Selenium
The core of Selenium is written in JavaScript, and is compatible with all major browsers. The Selenium Remote Console provides the glue between a test browser and .Net, Java or Python code, and enables us to write and run Selenium tests from almost all popular test frameworks.
Just download Selenium Remote Console from http://www.openqa.org/selenium-rc. Unpack the files somewhere on your disk, and then start the server from the server folder of the package, by executing java -jar selenium-server.jar. The server starts on port 4444 by default, if that port is taken you can change it by adding -port number to the command line.
Selenium works by embedding the test site, along with some control scripts, in a frameset web page. The control scripts are then used to automate the test page in the main frame, and execute various tests. That method of work will clash with browser security rules if both frames do not come from the same domain. Remote console can open Internet Explorer and Firefox with a security tweak to allow cross-domain scripting, but if you don’t want that, or want to use a different browser, then put Selenium JavaScript files into your web site. Download them from http://www.openqa.org/selenium-core/, and put the files from core folder in the archive into the selenium-server folder of your web site (so that RemoteRunner.html is available on /selenium-server/RemoteRunner.html).
A quick test
Let’s first do a quick test to make sure that Selenium RC is running correctly. We’ll start a browser window, go to Google, enter a search phrase and click on the Search button. I’ll do the examples in C#, but you can also use Java – interfaces are very similar. Create a new .Net project, add thoughtworks.selenium.core.dll as a reference (it’s in the dotnet folder of Remote Control installation), and then create this class:
using System;
using Selenium;
namespace SeleniumTest
{
class Console
{
static void Main(string[] args)
{
ISelenium sel = new DefaultSelenium(
"localhost", 4444, "*iehta", "http://www.google.com");
sel.Start();
sel.Open("http://www.google.com/");
sel.Type("q", "FitNesse");
sel.Click("btnG");
sel.WaitForPageToLoad("3000");
}
}
}
Make sure that Selenium RC is running, close all open Internet explorer windows, and then execute the program. Selenium RC will open a new IE window (it may be minimised on start, but you will see a new button in the task bar), and then go to Google and execute a search.

click for full-size image
Selenium window has three frames. Top-left enables the user to display the log and debug the execution by examining the DOM tree. Top-right frame displays the last four executed Selenium commands, which comes useful when troubleshooting tests. The page under test is displayed in the central frame.
The first line initialises a selenium console instance, connecting it to a remote console on localhost port 4444.
ISelenium sel = new DefaultSelenium( "localhost", 4444, "*iehta", "http://www.google.com");
The third argument is a browser string, and *iehta is the code for security-tweaked Internet Explorer which allows cross-domain scripting. Use *chrome for firefox with cross-domain scripting, or *iexplore, *firefox and *opera for Internet Explorer, Firefox and Opera without cross-domain security tweaks. You can also specify a full path to the executable instead of these special keywords.
The fourth argument is the URL to the selenium test site, and is really important only if you do not use cross-domain scripting, but want Selenium to run the scripts from the local domain. In this case, it will try to get the remote runner from http://www.google.com/selenium-server/RemoteRunner.html, but since Google is not hosting a Selenium installation, it will run the local scripts instead. In any case, this argument needs to be specified, so just set it to some live site even if you use cross-domain scripting (like in this case).
As you can guess from the names, method Type will simulate entering data from keyboard into a text field, and Click will simulate a mouse click. We accessed the text field and the button by their names, q and btnG. Selenium can also find elements by their ID (prefix it with “identifier=”), XPath expression (prefix it with “xpath=”), DOM path or a CSS property. See http://www.openqa.org/selenium-core/reference.html for more information on locators.
Connecting from FitNesse
FitNesse is really great for automating acceptance tests, and if you have not had a chance to play with it yet, I suggest reading through the online user guide for testing Java code, or my tutorial Getting fit with .Net for working in the .Net environment.
Instead of writing a new fixture type for every page or web site, we use a generic WebTest fixture. It extends DoFixture, so that other fixtures can be easily embedded into it (for checking the back-end data after a web script, or preparing the stage for the web test). Web test fixture allows the scripts to be described almost like English prose, like this:
User opens URL http://localhost:7711/login.aspx
User types testuser into username field
User types testpassword into password field
User clicks on Log In
Page reloads in less than 3 seconds
Page contains text You have logged in
To achieve the best effect, the script must relate to what users see on the screen. However, that is easier said than done. Text fields, check boxes and buttons are all instances of the “input” element, and although text fields are mostly distinguished by name, buttons names are typically not important, and users only see the “value” attribute of a button. WebTest fixture looks for various combinations of attributes: for example, when searching for a button, it first looks for an input element with type equal to submit or button, and the name attribute matching the query. If no such element is found, it looks for similar elements, with value attribute matching the query. On the end, it looks for a button with matching ID. All these combinations are listed in the buttonLocators array in the code:
public static readonly string[] buttonLocators = new String[] {
"xpath=//input[@type='submit' and @name='{0}']",
"xpath=//input[@type='button' and @name='{0}']",
"xpath=//input[@type='submit' and @value='{0}']",
"xpath=//input[@type='button' and @value='{0}']",
"xpath=//input[@type='submit' and @id='{0}']",
"xpath=//input[@type='button' and @id='{0}']"};
Although looking for an element by ID or name would be quicker, we intentionally use Xpath and add extra information, to catch errors caused by wrong element types. GetLocator method checks a list of XPath expressions and returns the first matching element from the active document, so UserClicksOn method is very simple:
public void UserClicksOn(String buttonCaption){
instance.Click(GetLocator(buttonCaption, buttonLocators));
}
We use the same technique to put text into text fields, areas and password fields. An array of Xpath expressions is used to check for various combinations of valid element types and attribute values, and the first matching element is then passed to Selenium Type method.
public void UserTypesIntoField(String what, String where){
instance.Type(GetLocator(where.Replace(" ", ""), textFieldLocators), what);
}
Because text fields will mostly be referenced by a name or ID, but users will see the text before the field on the page (and probably try to reference it with that), we also strip the blanks from the name. So the test script line:
User types 10109 into security number field
will correctly map into an element named “securitynumber”.
With web tests, we typically want to check if the result was correct and if the site was responsive enough, and Selenium method WaitForPageToLoad can be used to check if a page loads in any given amount of time. The API is a bit weird, as it expects a string containing the number of milliseconds. We wrapped that into this WebTest fixture call:
public void PageReloadsInLessThanSeconds(String sec){
instance.WaitForPageToLoad(sec + "000");
}
On the end, we need a method to verify that page contents are correct. Selenium method IsTextPresent can help with that:
public bool PageContainsText(String s){
return instance.IsTextPresent(s);
}
We’ll also need to open a browser and set up the Selenium environment from the test fixture. To keep the test script format in english-like prose, we’ll use the following syntax:
Start Browser *iehta with selenium console on localhost at port 4444 and scripts at http://localhost:7711
In WebTest fixture, that is covered by the following method:
public void StartBrowserWithSeleniumConsoleOnAtPortAndScriptsAt
(String browser, String rcServer, int rcPort, String seleniumURL){
instance = new DefaultSelenium(
rcServer, rcPort, browser, seleniumURL);
instance.Start();
}
On the end of each test, we need to shut down the browser, so that remote console does not run out of resources. For that, we’ll use the following method:
public void ShutdownBrowser(){
instance.Stop();
}
With all that, the web test can be easily described with this FitSesse script:
!|webfixture.WebTest| !|Start Browser|*iehta|With Selenium Console On| localhost| At Port |4444|And Scripts At|http://localhost:7711| |User Opens URL|http://localhost:7711/login.aspx| |User types|testuser|into|username|field| |User types|testpassword|into|password|field| |User clicks on|Log In| |Page reloads in less than|3|seconds| |Page contains text|You have logged in| |Shutdown browser|
Ajax testing
With web 2.0 pages, waiting for the page to reload before we continue testing is not the best choice. Selenium also supports
waiting for a JavaScript condition. Remember that Selenium script is being executed in a different frame, so referencing DOM elements and JS functions in your test site page will not work straight away. Prefix the references with
selenium.browserbot.getCurrentWindow() to get from the Selenium frame to your test page. Here’s an example:
instance.WaitForCondition( "(selenium.browserbot.getCurrentWindow().get_username()!=null)", timeout);
Remote execution
Selenium Remote Console will try to open a new browser session with different security settings, but under the profile of the current user (in fact, the user which started the remote console). This may cause problems when you already have an open browser on the same machine. The workaround is to use a different browser for testing. For example, I use Firefox for normal browsing, so RC can start IE and play with it. But, there is a much better solution.
As the name suggests, Remote Console can run on a dedicated test server, and be accessed remotely. Any browsers that RC opens will run on that machine. That enables developers to work with browsers on their machines and run the tests, without clashing with test execution. It also enables us to re-use the same FitNesse scripts to check how various browsers are behaving, even on different platforms. Just separate the initialisation and browser shut-down into SetUp and TearDown scripts, and then create a couple of different test suites with different SetUps which will use various browsers and remote console installations. Then, use symbolic links to import scripts from one test suite into all others. You will maintain scripts in one place, and they will test multiple browsers and platforms.
Extending WebTest
WebTest currently supports two more interesting methods: PageURLIs(String s) and UserSelectsFrom(String what, String where). The first allows you to verify the page URL (and test redirections). The second automates selecting an option from a drop-down menu (HTML select element), in the form of User Selects NY from Countries.
Feel free to modify and adjust WebTest to your needs. For start, see dotnet/doc/index.html in your remote control installation for more information on ISelenium interface. You can a add search by ID to the top of all locator arrays, so that tests run faster, but that will make them more error-prone. You will probably want to add a few different expressions to the textbox, button or select lists. If you add something which may be useful to others, please share it by writing a comment on the WebTest fixture page.
Photo credits:Sanja Gjenero/SXC



Hi there,
good work you have done with Fitnesse… anyway, does Selenium supports HTTP header manipulation? thanks.
Hi bengchuan,
I don’t think that Selenium does HTTP header manipulation… What kind of manipulation were you going for? There’s a brief discussion on that topic on http://forums.openqa.org/message.jspa?messageID=11406
Great job as usual. I had done something similar before (http://www.cornetdesign.com/2006/09/fitnesse-selenium-wrapper.html) but I like some of the commands like the page reloads in less than 3 seconds.
The only comment would be that the startup script could probably be mapped to something clearer to your customers entering the tests. Maybe use some variables or something else behind the scenes so that they don’t have to know things like the ports, or even *iehta.
Gojko,
I have also been thinking about how to translate what FIT bring to unit testing to
user interface web testing. So far I did not find any great answer.
But it seems to me that FIT tables and the Fitness script mentioned in your post are different.
• FIT Tables are a way first to define business logic and then later to validate it.
• The Fitness script mentioned in your post is just another language to automate UI testing.
o Your example in your pdf fitnesse.pdf “Simple scripts: ActionFixture“ go further by introduction some concepts of user interactions, but as you mentioned it.
These are metaphors (You might be onto something though).
But I do not see myself writing 1000 of lines using Fitness script similar to the one from your post..
Here is the test that you wrote using InCisif.net and C#.
For now I will stick with that but I will continue to read you excellent blog.
using ( InCisif.net.Library.Test t = new InCisif.net.Library.Test(Language.CSharp, this) ) {
Page.URL = “http://localhost:7711/login.aspx”;
Page.WaitForPage(“/login.aspx”);
Page.Control(“username”).Text = “testuser”;
Page.Control(“password”).Text = “testpassword”;
Page.Control(“Log In”).Click();
Page.WaitForPage(@”/WhatEverisThePage.aspx”);
t.ASSERT( Page.Contains(“You have logged in”) , “”);
t.Passed = true;
}.
Hi Gojko,
We are currently trying to implement the same.
The only difficulty we r facing is, how to repeat this test for multiple values.
e.g. in selenium we could have had a file which could be used as test data.
Is there something in FIT as well
Hi Sheila,
sure, you can parameterise test pages with fitnesse variables (use SetUp page to define them) and have different test suites with same tests and different setups. Use symbolic links to re-use test pages in different suites without duplicating them.
Hi
Does selenium support transaction testing? for example I want to test Mail Login and check my inbox etc. And my inbox is based on ajax. All I am looking for us get a page load time measured across different connections for ajax driven pages that are on web mail.
thanks
Hi,
Selenium supports waiting up to a given amount of time to complete certain operations. See my later article http://gojko.net/2008/02/14/ajax-selenium-fitnesse/ for more information. Recording exact time spent is not supported in the fixtures at the moment, but that can be easily implemented. The fixtures described in this article are released under an opensource GPL license, and you can get them from sourceforge and modify to add timing.
Hi, does someone know how to verify field length in Selenium.
Hi Tony,
have a look at assertEval and verifyEval, they should do the trick for you.
Hi Gojko, thanks for advice
Hi,
I have couple of questions refarding Selenium.
1. Can I use multiple values in the selenium element locator? e.g: I have three image link on the same page with the same captions. How do I identify these?
2. How can I get row count in a table. (I need to loop thru some records with in my report displayed at UI).
3. I did record a script using Selenium IDE. It did identidy it as “link=Add”. I want to replace this with X-Path. How do I find the xpath ?
Thanks,
Saurabh
Hi Saurabh,
1. A single locator maps to a single element on the page, as far as I know. You can use XPath array expressions to index elements that would be matched with the same XPath expression.
2. you’ll have to write a custom javascript expression and then evaluate that
3. see XPathChecker on https://addons.mozilla.org/en-US/firefox/addon/1095
Does anybody know if it’s possible to pass parameters from Selenium to FitNesse? If it is, how do you do it? I would like to pass a value displayed on the website to my FitNesse test that checks if that value displayed is in the database. Thanks!
Hi apprentice
depends which version of fitnesse test runner you are using. If you are working in a .NET environment, then you can load the cell handlers for symbols in FitLibrary fixtures and store the results of any verification (eg check the value of a text field) but instead of comparing to expected values, store the current value in a symbol. then you could use that symbol in fitnesse later on.
if you are using java, you will have to extend webtest fixtures to fetch the required value from selenium
Hi,
I´m making a script test on Selenium and I´m already able to test a popup window that is opened from the main window. When I click on a certain button, the popup window is closed. How can I check if that popup window has really been closed?
thanks
Hi,
I already got it. Just for the record, I used “verifyNotAllWindowTitles”.
Thanks any way.
Hi,
I got a situation here. I need to do browser testing for functionality at client side which means that, Can I run all the functionality tests again Firefox2.0, Firefox 3.0, IE 7.0, IE 6.0 in different systems. I m working on Plain Selenium.
Hi,
I want to enter some 20 fields ( Text fields, Dropdown list etc) in one URL.These fields are stored in some database(say excel). Could you please tell me how to transfer these data in excel to the respective fields one after the other. Iam using Selenium IDE and Mozilla 3.0
Hi Srinivas,
you will not be able to do that with selenium IDE. in order to have dynamic data from the database or excel file put into the test, you need to use selenium remote control and script that from java/.net. see http://selenium-rc.openqa.org for more information.
Hi Gojko!
I have a question : How can I log on mail server /yahoo, gmail/ . Come message that is not valid session id!?
ISelenium sel = new DefaultSelenium( “localhost”, 4444, “*iehta”, “http://www.google.com”);
sel.Start();
sel.Open(“http://www.google.com/”);
sel.Type(“q”, “FitNesse”);
sel.Click(“btnG”);
sel.WaitForPageToLoad(“3000″);
After this must I write something else?
Ths
Hi Grigoriy,
I don’t really understand the problem. You say that you want to log on a mail server, but your script opens the google search page. Are you sure that is the correct script?
Sorry, Gojko!
Wrong paste. But I allready fix the problem- it was in IE cookies!
Hi,
i am using fitnesse framework and selenium RC for web UI testing.
In some pages of my application certain portion of the pages are loading through the Ajax call. In my wiki pages i am testing these messages which are loading through the Ajax.
here selenium doesn’t give a call to Ajax and my selenium test fails.
I am using the following wiki page code:
|setCondition|selenium.browserbot.getCurrentWindow().document.getElementById(‘bodyMain_thumbnails’)|Timeout|20|
|Page contains Label|Uploaded|
actually ‘bodyMain_thumbnails’ div is loading through Ajax at run time with “Uploaded” message. And this called soon after the login.
and my fixture code is like:
public void setWaitTimeout(String milliSec)
{
String locator=”//div[@id='bodyMain_title']“;
instance.waitForPageToLoad(milliSec+”000″);
}
So,please can anybody look into this, and give your valuable suggestions.
while testing if i look into selenium RC browser instead of Ajax call being executed it’s loading the “login page”. In our application if a page fails to load or timeout it is redirected to login page. Here it is evident that either the Ajax call is not executed.
setWaitTimeout is being called only after the page is getting loaded.
Regards
sAs
We are running Fitnesse with the WebTest fixture to run a number of tests.
One of the tests however triggers a pop-up window. Is it possible to switch to this popup window to test contents and then close both it and the previous window?
Thanks
Andy
Hi Andy,
i’m really not sure about this. you can use selenium to evaluate any arbitrary javascript, and you can use dom to access different windows, so theoretically you should be able to do that with plainseleniumfixture. can you try to create your test using selenium ide and send it to me, i’ll see what i can do about providing the required functionality in webtest
Hi Gojko,
Many thanks for your quick reply. I have attempted to record using the IDE however the site we are trying to test only works using IE, so i am unable to record!
What I am doing is accessing a webpage to log in to a management console, once logged in the management console appears new ‘popup’ window.
I am new to Fit and WebTest so I am struggling to work out how to use dom to access the new window.
Andy
Hi Andy,
Can you record your test on a similar site with FF or create a very simple version of the site with popups that works in FF just to record the test?
Hello,
I am trying to test a employee login page where in A javascript oriented Popup window is put in to select the Date of birth. I recorded the test. Details has been perfectly uploaded. When I try to run the test again on my machine, the control from selenium goes to Popup window and never comwes back to main browser. I tried with Selectwindow Traget=null and verifyNotAllWindowNames commands. Still not moving further. I need it done very soon. PL HELP…
Andy, Gojko (re:06 Nov 2008 at 1:07 pm)
I had a similar issue and overcame it by using the IE Tab addon for Firefox. This allowed me to load the pop up under IE mode and then switch to Firefox mode and inspect my elements as I would normally. This may work for you.
Gojko – like the blog, own the book and regularly use DBFit too – thanks for all the contributions.
Hi Gojko
I’m not sure if you want purely Selenium related stuff in this thread but I am including a link to a google spreadsheet of the Selenium Api that Keith Sterling of Magnetic Reason collated as a result of the general lack of documentation on Selenium.
http://spreadsheets.google.com/ccc?key=pq3bDQaoQ3jphqQfHrfKRYw
It’s already proved invaluable to me several times over.
Hi,
I am new to Fitnesse..
I have a question ,Can anyone help me …
I am trying to test a web application .the application is developed in dotnet. The application supports only IE . i am not able to open it in firefox,so I am not able to use selenium IDE.. In this case how to get the links and xpath of the element.
Hi,
I am trying to pass file path(D://mywork//test.xsl) from Fitnesse IDE to call my java function which accepts String for file path and I am trying to use that file path to load in
java function.
my problem is :
I was unable to pass File Path as string from Fitnesse to selenium.
following command I am using in Fitnesse IDE
|parseFile|D://mywork//test.xsl|
I am getting Exception:
SeleniumException:Element not found ,
How could I pass file path to my java function?
Thanks in advance.
Venkat,
parseFile is not supported with web test fixtures out of the box. you’ll have to edit the source, add that and recompile the library.
Thanks gojko,
I am new to Fitnesse,
Is Fit supports to edit .xsl files?
my requirement is:
I have to use.xsl values to call my java Fixture code.
Could any one explain the steps that I need to folllow.
no, to edit .xsl files you need an XML editor. fitnesse is a test automation and management tool.
Hi gojko,
Is web testing is possible by reading input values from spreadsheet (.xls files) with Fitnesse+Selenium along with java code ?
if possible could you suggest some urls for reference?
Thanks,
Venkat
Hi,
I want to count and print the number of links available in particular web page using fitnesse+selenium along with java.
please let me know if any body knows.
Thanks in advance.
Hi gojko,
I want to count and print the number of links available in particular web page using fitnesse+selenium along with java.
is possible with selenium?
hi gojko,
I want to repeat my testsuit or test scripts. Is there any way to do that. Pls give clear flow.
Thanks,
Satish.P
hi gojko,
I’m new in FitNesse and open source tools.
Could you please answer, is it possible to use Fitnesse for commercial products testing?
Fitnesse is redestributed under GPL license, but does it mean that if i would write fixture which is extend from e.g Fitnesse ColumnFixture i should share my fixtures (as well as tested code) to open source community?
Thanks,
mango
Hi Mango,
I’m not a lawyer and if you are concerned with legal implications of using GPL software, you should seek legal advice from your company’s lawyers. my understanding of it (but don’t take this for granted) is that the viral GPL nature applies to distribution of software – so if you plan to resell and distribute your fixtures then you need to share their source with the customers.
Hi Gojko,
Your website and the selenium /fitnesse articles are just great.
I have been keenly reading up on the webtest work you have done.What worries me with Selenium the most is ,support for extraordinary things like -handling Download/upload dialogs,Silverlight.
Please let me know your thoughts on the same.Based on your experience with this framework,I am sure you must have found out some workarounds/solutions with these issues.
Thanks for sharing your knowledge,
Regards,
Ketan
Hi Ketan,
Confirming alerts and things like that can be done, but I have no experience with handling download dialogs, silverlight etc.
Hi Gojko.
I was wondering whether there is any way to use Selenium to test an application running in a browser window that has /not/ been opened from Selenium (in production, such a window would not be launched by the user, but by a standalone execututable running on the local machine). My goal is to use the same framework to test the whole user interaction path spanning both the standalone executable application and the web application started by the former.
Thanks a lot!
Regards,
Diego
Diego,
no there is not.
Hi Gojko.
I have many href’s in my webpage which have a similiar link name. When clicked, it calls a javascript with different parameters. Is there a way I can identify a href using web test fixture?
Thanks
Found a way. Gave a unique “name” to each tag, assigned the javascript call to the onclick event and used “fire event” web test action.
Hi Gojko,
We are using Fitnesse and Selenium RC. We would like to have the wiki page in a main server, so business users and testers can launch the test suite any time they want. Although a user can launch the test by accessing the wiki URL, the UI actions are happening in the main server, and the user sitting in his/her PC will not see the UI tests. Unless the user does the “remote desktop”, he/she will not be able to see the UI activities on a test. If we use the “WikiImport” feature, the business users will have to install Fitnesse in their PC and configure their Front page to launch the RemoteURL.
Is there a better way to host a Fitnesse Wiki Page (With UI tests) remotely?
Can you please advise us?
Thanks.
Hi Gojko
I am new to Selenium IDE and FitNesse. I would like to use the two together, but I have no idea how. I would appreciate some advice and tips.
Thanks