Saturday, September 04
29

I attended the Day of DotNetNuke held on May 28th in Paris. One of the session I found particularly interesting was given by Kelly Ford, of xMod fame. This was a session on testing your modules using the Web application testing system, Selenium. Selenium is available as a free download from http://seleniumhq.org/

Shortly after my return from Paris I was asked, by Sebastian Leupold, to help in the testing of the latest version of the Events module (5.1.1). I have previously done some testing on this module. Ernst-Peter, the team lead, emailed me asking if I had ever used Selenium and would I be interested in assisting in the preparation of some Selenium tests for the module. This was timely after watching Kelly's presentation and Selenium looked like a very useful tool to add to my collection. Anything that would save repetitive data entry must be a huge time saver.

At this point I must state clearly that I am by no means expert in the use of Selenium. I am just starting down what looks like a very interesting path and thought I would share my experience so far. There are a number of elements to Selenium:

To get started, all you need do is download and install the IDE. This will add Selenium IDE to the Tools menu of FireFox. You will find the download here.

Before I continue describing Selenium I will describe my test setup for the Events module. This starts with a fresh install of DotNetNuke Community Edition. Version 5.4.2 in this case. The URL of my test instance is http://localhost/events542. The next step is to install the latest Release Candidate of the events module using the install package. I add a page named Event Page for the main events calendar and a sub page named Sub Cal for a sub calendar (titled Slave).

Once I had the environment setup I fired up Selenium and was presented with the screen shown below. Note that I have set the Base URL to the URL of my test DNN instance.

By default the record button at the top right is in the “ON” position - waiting to record mouse clicks and keyboard entry. Assuming that you have the test DNN instance open in FireFox, click on the login link and you will see commands are recorded in the main pane of the Selenium IDE. The first is an open command for the home page followed by a clickAndWait command applied to the LogIn link. Enter a valid username and password and click Login. Your username and password will be recorded as will the clickAndWait command for the Login button.

Click the red button to stop recording.

You should now have something similar to the screen grab below. The test commands are recorded in a html document. A table structure is used where each row contains a command comprising of the command to be executed, the target of the command and a value, if appropriate. There are two tabs for Table and Source showing the commands in a list and the source HTML respectively. 

A very useful feature in “command view” is that you can double click on any row to execute the command. This is very helpful when building up a test case allowing you to step through each command in turn and watch it play-out in your browser.

In developing test cases for the Events module I needed to ensure that any tests I created would run in the test environment of others that may wish to run the same tests. To do this I had to find a solution to DNN (Asp.Net) giving different ID values to controls on the page. Using FireBug, another FireFox add-in, to inspect the Login link you will see something like:

<a href="javascript:__doPostBack('dnn$dnnLOGIN$cmdLogin','')"  class="user" id="dnn_dnnLOGIN_cmdLogin">Login</a>

I changed the Target of the first clickAndWait from dnn_dnnLOGIN_cmdLogin to use an XPath command in order to locate the link.

    //a[contains(@id,'_cmdLogin')]

I repeated this process for each element and the result is:

This looks for an link whose ID contains the string ‘_cmdLogin’, clicks it and waits for the relevant page to display. It then looks for a textbox control whose ID contains the string ‘_Login_DNN_txtUserName’ and types the text for the username - ‘admin’. This is repeated for the password and finally the Login button is clicked.

You now have a test case that will log you into your test site as admin. Save your test case, using the File menu, giving it a meaningful name, LogAdminIn in my case. You can now run all the steps in this test case by selecting the test in the left column under Test Case and clicking the play button. You will see the command steps highlighted one by one as they are executed. Each step, as it is executed, will be logged in the bottom Log window.

I then followed the same process to Add, Modify and Delete events for both single instance events and recurring events. I also prepared test cases for adding Categories and Locations as well as all the other scenarios defined in the test cases script.

I encountered a couple of issues on the way; The first was a difficulty in selecting items from the Action menu. When I recorded these steps and played them back they executed without error. However when I tried to make the scripts generic by using “XPath contains” as described above, I found the commands failed. A quick email to Kelly Ford, for the benefit of his experience, gave me the solution. Kelly suggested that I use the full URL. To open the Edit Categories page I now use and “open” command with a target of:

    EventPage/tabid/61/ctl/Categories/mid/382/Default.aspx

The page for Location Edit is at:

    EventPage/tabid/61/ctl/Locations/mid/382/Default.aspx

Note that 382 is the Module ID and will change for each installed instance of the Events Module. 61 is the Tab ID. These values may need to be changed when passing test scripts for use on a different DNN instance or when testing the events module on a different page of the same DNN instance.

The second issue arose when I wished to create a number of individual events on different subsequent days. How do I select a date and increment it? Javascript can be used as the value field and this is what I used to increment the day by 1. I did not include any checking to see if my new date value was valid. I am sure some one will come up with a solution for this but as I planned to complete the testing before running over month end, this would not cause me any trouble at this time ;)

javascript{(new Date().getMonth()+1)+'/'+(new Date().getDate()+5)+'/'+new Date().getFullYear()}

Note: the month is zero based so to get the current month you need to use (new Date().getMonth()+1)

Test script DNNEvents 510, part of which is shown below, shows the creation of 6 events on subsequent days in the sub calendar.




<tr>
<td>open</td>
<td>EventPage/SubCal.aspx</td>
<td></td>
</tr>
<tr>
<td>clickAndWait</td>
<td>//input[contains(@id,'_EventIcons_btnAdd')]</td>
<td></td>
</tr>
<tr>
<td>type</td>
<td>//input[contains(@id,'_EditEvents_txtTitle')]</td>
<td>Test Event 1</td>
</tr>
<tr>
<td>type</td>
<td>//input[contains(@id,'_EditEvents_txtStartDate')]</td>
<td>javascript{(new Date().getMonth()+1)+'/'+new Date().getDate()+'/'+new Date().getFullYear()}</td>
</tr>
<tr>
<td>clickAndWait</td>
<td>//table[contains(@id,'tblEvent')]/tbody/tr[3]/td[@class='SubHead'][2]/a </td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>//input[contains(@id,'_EditEvents_ftbDesktopText_optView_0')]</td>
<td></td>
</tr>
<tr>
<td>type</td>
<td>//textarea</td>
<td>This is descr for test event 1</td>
</tr>
<tr>
<td>clickAndWait</td>
<td>//span[contains(@id,'EditEvents_updateButton')]/a</td>
<td></td>
</tr>

The steps shown here are:

  1. Click the Add Event link and wait for the page to load
  2. Type in a title
  3. Type in a date, the current date in this case.
  4. Click Copy to End Date
  5. Click the option Basic Textbox
  6. Type a description
  7. Click Update link

Trying to get test scripts working with the rich text editors was problematic so I opted to use the basic text box.

This test case does no checking to see if the test worked. Test script DNN 210 Add Single Event is basically the same as the test above with the addition of an assertText command which looks for the event title on the page after the update link has been clicked.



<tr>
<td>assertText</td>
<td>//a[contains(@href,'/EventDetails')]</td>
<td>Test Event One</td>
</tr>

I have organised my test scripts so that each set of tests starts with a blank calendar (no events at all). The required tests are then created, edited and deleted taking the module back to it's start position. By adding assertions within each test I can be sure that each passes. Selenium will show a resulting status indicating the number of tests that passed and failed. In the event of a test failure the Log at the bottom of the IDE will detail the offending item.

Automated UI testing can be very helpful and a huge time saver. However, do run through your tests manually at least once. Just because the test you setup to check for a given text string on the page passed, this does not mean the string was found where you expected it to be!

Below is a link to a short video, just 1 min 30 seconds, showing some tests running.

Happy testing!

Posted in: DotNetNuke

Comments

There are currently no comments, be the first to post one.

Post Comment

Name (required)

Email (required)

Website

CAPTCHA image
Enter the code shown above in the box below

Text/HTML

The revolutionary skinning engine for DotNetNuke

A working demo can be seen at
www.thinkofdesign.com

buy now
Snowcovered