Download FitNesse
Go to http://fitnesse.org/FitNesseDevelopment.DownLoad and download the the “Full Distribution (fitnesse200#####.zip)”. Unpack the zip into c:\program files. Once extracted you must have a directory c:\program files\fitnesse.
Download Selenium Remote Control (Selenium RC)
Go to http://selenium-rc.openqa.org/download.jsp and download the latest version (1.0-beta-2 at the time of writing this page). Unpack the zip into c:\program files. Once extracted you must have a directory c:\program files\selenium. Current version for Selenium-RC is 1.0-beta-2 and these instructions are written assuming you are using this version.
Create a smart start script
Copy and paste following script into a file called run.vbs under the directory “C:\Program Files\selenium\selenium-remote-control-1.0-beta-2\selenium-server-1.0-beta-2″. This script will start both FitNesse servers and Selenium remote control servers on their default ports 8000 and 4444 respectively. This script will ONLY start these processes if these processes are not running, so this script can be safely run any time.
PS: Please note that this script is starting Selenium in an experimental Proxy Injection Mode which lets you run your web test across multiple domains. If you don’t want to use this feature feel free to change this start script.
Function IsProcessRunning( strServer, strProcess )
Dim Process, strObject
IsProcessRunning = False
strObject = "winmgmts://" & strServer
For Each Process in GetObject( strObject ).InstancesOf( "win32_process" )
If UCase( Process.name ) = UCase( strProcess ) Then
IsProcessRunning = True
Exit Function
End If
Next
End Function
sServer = "." ' "." for local machine
Set objShell = WScript.CreateObject("WScript.Shell")
Set objEnv = objShell.Environment("Process")
FitNesse = "java -cp fitnesse.jar fitnesse.FitNesse -p 8000"
If( IsProcessRunning( sServer, FitNesse ) = False ) Then
objshell.CurrentDirectory = "C:\program files\fitnesse"
f = objshell.Run ( FitNesse, 6, false )
End If
Selenium = "java -jar selenium-server.jar -browserSessionReuse -proxyInjectionMode"
If( IsProcessRunning( sServer, Selenium ) = False ) Then
objshell.CurrentDirectory = _
"C:\program files\selenium\selenium-remote-control-1.0-beta-2\selenium-server-1.0-beta-2"
result = objshell.Run ( Selenium, 5, true )
End If
Wscript.Quit
Download and Install Generic Fixture
Just follow simple instructions at this page or just download genericfixture.jar from here and drop it into “C:\Program Files\fitnesse” directory.
Copy selenium-java-client-driver.jar from “C:\program files\selenium\selenium-remote-control-1.0-beta-1\selenium-java-client-driver-1.0-beta-1″ to “C:\program files\fitnesse” directory.
Run startup script
Using Windows explorer go to the directory “C:\Program Files\selenium\selenium-remote-control-1.0-beta-1\selenium-server-1.0-beta-1″ and double click on the run.vbs. This will start 2 Java process in 2 separate command windows with Selenium window in normal and FitNesse window in minimized state.
Create a page on FitNesse for Google Web Test using Generic Fixture
- Open your browser and goto the URL http://localhost:8000/FrontPage. Look for the Edit button on the left hand navigation column. If Edit button is not present then goto the URL http://localhost:8000/FrontPage?properties and select the “Edit” check box and click on Save Properties. Now click on Edit button and once on the Edit Page add a new line at the end of all the text already there and save your changes.
|[[Web Test Suites][FitNesse.SuiteWebTests]]|FitNesse's suite of Web Tests|
- Now on the Front Page it will display a text like “Web Test Suites?” with ? as hyper link. Click on ? link.
- Once in the Edit Page copy paste following text into text area and save your changes:
!*> Class Path & Global Defines !path selenium-java-client-driver.jar !path genericfixture.jar !define IE {*piiexplore} !define FF {*pifirefox} !define sel {selenium=} !define ds {com.thoughtworks.selenium.DefaultSelenium} !define host {localhost} !define port {4444} !define COLLAPSE_SETUP {true} !define COLLAPSE_TEARDOWN {true} *! ---- SuiteWebTests.SetUp SuiteWebTests.TearDown SuiteWebTests.GoogleTest - You will notice 3 ? links on the page. Now lets create each and every missing page.
- Click on the ? link next to SuiteWebTests.SetUp text and on the “Edit Page” text area copy-paste following code an save your changes.
!| DSL Adapter | | user types | % | into | % | field | type | {2}, {1} | | user starts the browser | start | | | users opens the URL | % | open | {1} | | page has the title | getTitle | | | user sees the text on the page | % | isTextPresent | {1} | | page has an element named | % | isElementPresent | {1} | | page loads in less than | % | seconds | waitForPageToLoad | {1}000 | | page has URL | getLocation | | | user clicks on submit button | click | //button[@type='submit'] | | user clicks on the link named | % | click | link={1} | | user clicks on the button named | % | clickAt | {1},"" | | get text from element named | % | getText | xpath=id('{1}') | | user stops the browser | stop | | | add a key-value with key | % | and value | % | put | {1}, {2} | | get value for the key | % | get | {1} | | show | toString | | !|Generic Fixture|${sel}${ds}|${host}|${port}|${FF}|http://${host}| | user starts the browser | - Go back to the page: http://localhost:8000/FitNesse.SuiteWebTests
- Click on the ? link next to SuiteWebTests.TearDown text and on the “Edit Page” text area copy-paste following code an save your changes.
!| Generic Fixture | ${sel} | | user stops the browser | - Again go back to the page: http://localhost:8000/FitNesse.SuiteWebTests
- Now click on ? link next to SuiteWebTests.GoogleTest text and on the “Edit Page” text area copy-paste following code an save your changes.
!define q {fitnesse generic fixture} !| Generic Fixture | ${sel} | | users opens the URL | http://www.google.com | | page has the title | | Google | | page has an element named | q | | true | | page has an element named | btnG | | true | | user types | ${q} | into | q | field | | user clicks on the button named | btnG | | page loads in less than | 5 | seconds | | page has the title | | ${q} - Google Search | | user clicks on the link named | Next | | page loads in less than | 5 | seconds | | user clicks on the link named | Next | | page loads in less than | 5 | seconds | | user sees the text on the page | Results 21 - 30 | | true | - After saving your changes click on Properties button from the left hand navigation menu and click on check box left to Test property and save your changes. Now you should see Test button on the top of the lest navigation menu.
Execute your Google Web Test Page on FitNesse using Selenium
Just click on the Test click on this page: http://localhost:8000/FitNesse.SuiteWebTests.GoogleTest and watch the magic of web test being run. Test will open a new Firefox browser and go to www.google.com and search Google with query text “fitnesse generic fixture”
Upon completion of test you should see this on the top of the results page:
Assertions: 5 right, 0 wrong, 0 ignored, 0 exceptions
Optional but Recommended Installations
You are all set to to write your test tables in FitNesse.
However if you are doing web testing using Selenium, there are two very handy add-ons for Firefox that will be extremely useful for writing web tests:
- XPath Checker: Download it from https://addons.mozilla.org/en-US/firefox/addon/1095
- Selenium IDE: Download it from http://selenium-ide.openqa.org/download.jsp
Hi Anubhava,
Thats a great post I must say. I followed all these setup instructions and was able to run my first automated web test in no time.
However after accomplishing that I would like to know if there is a way I can validate the text from an HTML element (let’s say some html text field) against a value from database table by running a database query? In other words I want to get a value from a web page and compare that value with a value in a database table.
cheers,
Martin
Hi Martin,
Thanks for the nice words.
Sure you can cross-check a value from web page against a database value. You can take a look at my post on running database queries using Generic Fixture at: http://anubhava.wordpress.com/2008/05/07/database-testing-using-generic-fixture/
Using example query on that page you can execute the database query and store “age” of the given employee in a variable age as follows:
| age=getInt | age | |
And then using the DSL defined in above post you can simply compare variable age with text of an HTML element as follows:
| get text from element named | age_element | | age= |
FitNesse will turn above cell to green if HTML element “age_element” has same value as the value in emp table otherwise it will be marked red.
happy testing,
Anubhava
Hi Anubhava,
I was struggling to learn FitNesse & Selenium since I am new to them. I truly appreciate the tips and examples which you have put up here, keep up the good work!
Yong
Dear Anubhava,
Thank you for all you have created and keep offering to us.
Could someone show the way to implement (or provide ready-made) the WaitForElement type functionality of Selenium through the Generic Fixture?
—-
While trying to evaluate whether to use Generic Fixture and DSL for our test definitions we came across the ‘WaitForElement Issue’ which, after our extensive research, we believe boils down to:
1 » During web testing, especially for Ajax functionalities, waiting for an element or text to appear/disappear/be created/removed/etc.. becomes very important
2 » Selenium itself does provide many great functions to do this but Selenium RC does NOT (Selenium Remote Control is the API used by Fitnesse to execute Selenium commands)
3 » It is ‘apparently easy’ to create such functionality using e.g. java classes and there is an example online of the little code necessary
However: we have spent many hours and have not managed yet to implement these commands and use them easily through the Generic Fixture DSL.
Considering the fundamental importance of commands such as WaitForElement for web testing, I would think that providing them ready, or at least showing the way to implement them, would mean a dramatic decrease in the effort needed to put Generic Fixture + DSL running and testing.
Sorry for the long post,
Thanks in advance.
Dear Aristotelis,
Your post is not that long
I believe that Selenium RC has all the functions/features that are supported by Selenium. I use Selenium IDE (in Firefox) to record my test and then change the format to Java to get the API that needs to run in Selenium RC.
Regarding your question WaitForElement short answer is use waitForCondition method in Selenium RC. It has 2 parameters: 1. a javascript conditions and 2. timeout value
To illustrate its use in the form of a DSL I made a small test script to open a FAQ page. This FAQ page only shows questions to users initially and all answers elements remain in hidden div elements. Once user clicks on a question its answer is loaded up using AJAX and its div container becomes visible.
| user clicks on the xpath link named | id(’Q1′) |
| get text from element named | A1 | |
| wait for the answer # | 1 | to show up in | 5 | seconds |
| get text from element named | A1 | |
Once run the first get text command shows blank text since answer hasn’t been loaded. But the second get text command correctly displays the answer because there is a waitForCondition method call in between.
Here is the relevant DSL for above script:
!| DSL Adapter |
| user clicks on the xpath link named | % | click | xpath={1} |
| get text from element named | % | getText | xpath=id(’{1}’) |
| wait for the answer # | % | to show up in | % | seconds | waitForCondition | document.getElementById(’A{1}’).style.display == ‘block’, {2}000 |
| wait for the 1st answer to show up in | % | seconds | waitForCondition | document.getElementById(’A1′).style.display == ‘block’, {1}000 |
I will respond to your suggestion of classifying DSL on other post where the comment was made.
cheers,
Anubhava